76 ,
n_quad_points(static_cast<int>(std::pow(degree + 2, lifex::dim)))
92 lifex::LinAlg::MPI::Vector
93 dubiner_to_fem(
const lifex::LinAlg::MPI::Vector &dub_solution)
const;
99 lifex::LinAlg::MPI::Vector
101 const std::string &FEM_mesh_path,
102 const std::string &subsection,
103 const MPI_Comm &mpi_comm_,
104 const unsigned int degree_fem = 1,
105 const double scaling_factor = 1)
const;
109 lifex::LinAlg::MPI::Vector
110 fem_to_dubiner(
const lifex::LinAlg::MPI::Vector &fem_solution)
const;
113 lifex::LinAlg::MPI::Vector
115 const std::string &FEM_mesh_path,
116 const std::string &subsection,
117 const MPI_Comm &mpi_comm_,
118 const unsigned int degree_fem = 1,
119 const double scaling_factor = 1)
const;
122 lifex::LinAlg::MPI::Vector
124 lifex::LinAlg::MPI::Vector dub_solution,
125 const std::shared_ptr<dealii::Function<lifex::dim>> &u_analytical)
const;
130 const double tol = 0)
const;
136 const lifex::LinAlg::MPI::Vector &dub_solution)
const
138 lifex::LinAlg::MPI::Vector fem_solution;
139 fem_solution.reinit(dub_solution);
148 const unsigned int degree_fem =
149 (this->poly_degree < 3) ? this->poly_degree : 2;
151 const dealii::FE_SimplexDGP<lifex::dim> fe_dg(degree_fem);
152 const std::vector<dealii::Point<lifex::dim>> support_points =
153 fe_dg.get_unit_support_points();
154 const unsigned int dofs_per_cell_fem = this->get_dofs_per_cell(degree_fem);
157 dealii::DoFHandler<lifex::dim> dof_handler_fem(
158 dof_handler.get_triangulation());
159 dof_handler_fem.distribute_dofs(fe_dg);
161 std::vector<unsigned int> dof_indices(this->dofs_per_cell);
162 std::vector<unsigned int> dof_indices_fem(dofs_per_cell_fem);
167 for (
const auto &cell : dof_handler_fem.active_cell_iterators())
169 dof_indices = dof_handler.get_dof_indices(cell);
170 cell->get_dof_indices(dof_indices_fem);
172 for (
unsigned int i = 0; i < dofs_per_cell_fem; ++i)
174 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
176 fem_solution[dof_indices_fem[i]] +=
177 dub_solution[dof_indices[j]] *
178 this->shape_value(j, support_points[i]);
190 const lifex::LinAlg::MPI::Vector &dub_solution,
191 const std::string &FEM_mesh_path,
192 const std::string &subsection,
193 const MPI_Comm &mpi_comm_,
194 const unsigned int degree_fem,
195 const double scaling_factor)
const
198 lifex::utils::MeshHandler triangulation_fem(subsection, mpi_comm_);
199 AssertThrow(std::filesystem::exists(FEM_mesh_path),
200 dealii::StandardExceptions::ExcMessage(
201 "This mesh file/directory does not exist."));
202 triangulation_fem.initialize_from_file(FEM_mesh_path, scaling_factor);
203 triangulation_fem.set_element_type(
204 lifex::utils::MeshHandler::ElementType::Tet);
205 triangulation_fem.create_mesh();
207 const dealii::FE_SimplexDGP<lifex::dim> fe_dg(degree_fem);
208 const std::vector<dealii::Point<lifex::dim>> support_points =
209 fe_dg.get_unit_support_points();
210 const unsigned int dofs_per_cell_fem = this->get_dofs_per_cell(degree_fem);
213 const std::unique_ptr<dealii::MappingFE<lifex::dim>> mapping(
214 std::make_unique<dealii::MappingFE<lifex::dim>>(fe_dg));
217 dealii::DoFHandler<lifex::dim> dof_handler_fem;
218 dof_handler_fem.reinit(triangulation_fem.get());
219 dof_handler_fem.distribute_dofs(fe_dg);
222 lifex::LinAlg::MPI::Vector fem_solution;
223 dealii::IndexSet owned_dofs = dof_handler_fem.locally_owned_dofs();
224 fem_solution.reinit(owned_dofs, mpi_comm_);
227 std::vector<unsigned int> dof_indices(this->dofs_per_cell);
228 std::vector<unsigned int> dof_indices_fem(dofs_per_cell_fem);
231 const double tol = 1e-10;
235 for (
const auto &cell_fem : dof_handler_fem.active_cell_iterators())
237 cell_fem->get_dof_indices(dof_indices_fem);
238 for (
unsigned int i = 0; i < dofs_per_cell_fem; ++i)
240 dealii::Point<lifex::dim> real_support_point =
241 mapping->transform_unit_to_real_cell(cell_fem, support_points[i]);
243 for (
const auto &cell : dof_handler.active_cell_iterators())
247 if (std::abs(fem_solution[dof_indices_fem[i]]) < tol)
249 dealii::Point<lifex::dim> unit_support_point_dub =
250 mapping->transform_real_to_unit_cell(cell,
252 if (is_in_unit_cell(unit_support_point_dub, tol))
254 dof_indices = dof_handler.get_dof_indices(cell);
255 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
257 fem_solution[dof_indices_fem[i]] +=
258 (dub_solution[dof_indices[j]] *
259 this->shape_value(j, unit_support_point_dub));
273 const lifex::LinAlg::MPI::Vector &fem_solution)
const
275 const dealii::FE_SimplexDGP<lifex::dim> fe_dg(this->poly_degree);
278 lifex::LinAlg::MPI::Vector dub_solution;
279 dub_solution.reinit(fem_solution);
281 std::vector<unsigned int> dof_indices(this->dofs_per_cell);
290 for (
const auto &cell : dof_handler.active_cell_iterators())
292 dof_indices = dof_handler.get_dof_indices(cell);
295 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
297 for (
unsigned int q = 0; q < n_quad_points; ++q)
301 for (
unsigned int j = 0; j < this->dofs_per_cell; ++j)
304 fem_solution[dof_indices[j]] *
308 dub_solution[dof_indices[i]] +=
323 const lifex::LinAlg::MPI::Vector &fem_solution,
324 const std::string &FEM_mesh_path,
325 const std::string &subsection,
326 const MPI_Comm &mpi_comm_,
327 const unsigned int degree_fem,
328 const double scaling_factor)
const
331 lifex::utils::MeshHandler triangulation_fem(subsection, mpi_comm_);
332 AssertThrow(std::filesystem::exists(FEM_mesh_path),
333 dealii::StandardExceptions::ExcMessage(
334 "This mesh file/directory does not exist."));
335 triangulation_fem.initialize_from_file(FEM_mesh_path, scaling_factor);
336 triangulation_fem.set_element_type(
337 lifex::utils::MeshHandler::ElementType::Tet);
338 triangulation_fem.create_mesh();
340 const dealii::FE_SimplexDGP<lifex::dim> fe_dg(degree_fem);
341 const std::vector<dealii::Point<lifex::dim>> support_points =
342 fe_dg.get_unit_support_points();
343 const unsigned int dofs_per_cell_fem = this->get_dofs_per_cell(degree_fem);
346 const std::unique_ptr<dealii::MappingFE<lifex::dim>> mapping(
347 std::make_unique<dealii::MappingFE<lifex::dim>>(fe_dg));
350 dealii::DoFHandler<lifex::dim> dof_handler_fem;
351 dof_handler_fem.reinit(triangulation_fem.get());
352 dof_handler_fem.distribute_dofs(fe_dg);
355 std::vector<unsigned int> dof_indices(this->dofs_per_cell);
356 std::vector<unsigned int> dof_indices_fem(dofs_per_cell_fem);
359 const double tol = 1e-10;
363 lifex::LinAlg::MPI::Vector dub_solution;
364 dealii::IndexSet owned_dofs = dof_handler.locally_owned_dofs();
365 dub_solution.reinit(owned_dofs, mpi_comm_);
375 for (
const auto &cell : dof_handler.active_cell_iterators())
377 dof_indices = dof_handler.get_dof_indices(cell);
380 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
382 for (
unsigned int q = 0; q < n_quad_points; ++q)
384 dealii::Point<lifex::dim> real_q =
385 mapping->transform_unit_to_real_cell(
388 for (
const auto &cell_fem :
389 dof_handler_fem.active_cell_iterators())
394 if (std::abs(eval_on_quad) < tol)
396 cell_fem->get_dof_indices(dof_indices_fem);
397 dealii::Point<lifex::dim> unit_q =
398 mapping->transform_real_to_unit_cell(cell_fem, real_q);
399 if (is_in_unit_cell(unit_q, tol))
401 for (
unsigned int j = 0; j < dofs_per_cell_fem; ++j)
403 eval_on_quad += fem_solution[dof_indices_fem[j]] *
404 fe_dg.shape_value(j, unit_q);
407 dub_solution[dof_indices[i]] +=
427 lifex::LinAlg::MPI::Vector dub_solution,
428 const std::shared_ptr<dealii::Function<lifex::dim>> &u_analytical)
const
432 dealii::IndexSet owned_dofs = dof_handler.locally_owned_dofs();
434 std::vector<unsigned int> dof_indices(this->dofs_per_cell);
441 for (
const auto &cell : dof_handler.active_cell_iterators())
443 dof_indices = dof_handler.get_dof_indices(cell);
446 for (
unsigned int i = 0; i < this->dofs_per_cell; ++i)
448 dub_solution[dof_indices[i]] = 0;
449 for (
unsigned int q = 0; q < n_quad_points; ++q)
454 dub_solution[dof_indices[i]] +=