#ifndef GRIDS_H #define GRIDS_H #include "nufi/cells.h" #include "nufi/parameters.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace dealii; template class PoissonProblem; template struct GridStructure { //==//==// // Vars // //==//==// std::unique_ptr> triangulation; std::unique_ptr> dof_handler; std::unique_ptr> mapping; std::unique_ptr> fe; std::unique_ptr> constraints; std::unique_ptr sparsity_pattern; std::unique_ptr> locator; unsigned int grid_version = 0; // === // === // // Evaluator // // === // === // std::vector eval_vector_grad(const Vector &solution, const std::vector> &points) const { std::vector values(points.size()); // Uses point_gradient // #pragma omp parallel for // for (unsigned int p = 0; p < points.size(); ++p) { // // const Tensor<1, dim> grad_phi = VectorTools::point_gradient( // *mapping, *dof_handler, solution, points[p]); // // values[p] = grad_phi[0]; // } // // return values; // } // Uses cell locator #pragma omp parallel { std::vector local_solution_buffer(fe->n_dofs_per_cell()); FEPointEvaluation evaluator(*mapping, *fe, update_gradients); #pragma omp for for (unsigned int p = 0; p < points.size(); ++p) { const auto cell_location = locator->locate(points[p]); cell_location.info->cell->get_dof_values(solution, local_solution_buffer.begin(), local_solution_buffer.end()); evaluator.reinit( cell_location.info->cell, ArrayView>(&cell_location.reference_point, 1)); evaluator.evaluate(local_solution_buffer, EvaluationFlags::gradients); values[p] = evaluator.get_gradient(0)[0]; } } return values; } }; template GridStructure make_grid_snapshot(PoissonProblem &poisson) { bool PRINT_GAUGE_DOF_POSITION = true; GridStructure grid; grid.grid_version = 0; grid.triangulation = std::make_unique>(); grid.triangulation->copy_triangulation(poisson.get_triangulation()); grid.fe = std::make_unique>(poisson.get_fe()); grid.dof_handler = std::make_unique>(*grid.triangulation); grid.dof_handler->distribute_dofs(*grid.fe); grid.mapping = std::make_unique>(poisson.get_mapping()); grid.constraints = std::make_unique>(); DoFTools::make_hanging_node_constraints(*grid.dof_handler, *grid.constraints); DoFTools::make_periodicity_constraints(*grid.dof_handler, 0, 1, 0, *grid.constraints); const auto support_points = DoFTools::map_dofs_to_support_points(*grid.mapping, *grid.dof_handler); types::global_dof_index gauge_dof = numbers::invalid_dof_index; // Search only inside the protected region for (const auto &[dof, point] : support_points) { if (grid.constraints->is_constrained(dof)) continue; const double x = point[0]; if (x <= Parameters::X_DOMAIN_LEFT + .5) { gauge_dof = dof; if (PRINT_GAUGE_DOF_POSITION) std::cout << " gauge_dof = " << gauge_dof << " gauge_point = " << point[0] << std::endl; break; } } Assert(gauge_dof != numbers::invalid_dof_index, ExcMessage("No gauge DoF found in protected gauge region.")); grid.constraints->add_line(gauge_dof); grid.constraints->set_inhomogeneity(gauge_dof, 0.0); grid.constraints->close(); grid.locator = std::make_unique>(); grid.locator->rebuild(*grid.dof_handler, *grid.triangulation); // START: diagnostics AssertThrow( poisson.get_constraints().n_constraints() == grid.constraints->n_constraints(), ExcMessage( "PoissonProblem constraints doesn't match Snapshot constraints")); // for (auto c1 = poisson.get_dof_handler().begin_active(), // c2 = grid.dof_handler->begin_active(); // c1 != poisson.get_dof_handler().end(); ++c1, ++c2) { // std::vector d1(c1->get_fe().dofs_per_cell); // std::vector d2(c2->get_fe().dofs_per_cell); // // c1->get_dof_indices(d1); // c2->get_dof_indices(d2); // // AssertThrow(d1 == d2, ExcInternalError()); // } // END: diagnostics return grid; } template struct SolutionSnapshot { unsigned int grid_version; Vector solution; }; template inline void update_grid_versions(std::vector> &grid_versions, PoissonProblem &poisson) { auto grid = make_grid_snapshot(poisson); if (!grid_versions.empty()) grid.grid_version = grid_versions.back().grid_version + 1; grid_versions.push_back(std::move(grid)); std::cout << "@ update_grid_history: " << "grid version " << grid.grid_version << " size " << poisson.get_solution().size() << "\n"; } template inline void update_solution_history(std::vector> &solution_history, PoissonProblem &poisson, unsigned int current_grid_version) { SolutionSnapshot snapshot; snapshot.grid_version = current_grid_version; // where I might need to change something to pass the correct solution or in // the correct form Vector solution = poisson.get_solution(); snapshot.solution = solution; std::cout << "@ update_solution_history: " << "grid version " << current_grid_version << " size " << poisson.get_solution().size() << "\n"; solution_history.push_back(std::move(snapshot)); } #endif // !GRIDS_H