27template <
int dim,
int spacedim>
28CoupledElasticityProblemParameters<dim, spacedim>::
29 CoupledElasticityProblemParameters()
31 , rhs(
"/Immersed Problem/Right hand side", spacedim)
32 , exact_solution(
"/Immersed Problem/Exact solution", spacedim)
33 , bc(
"/Immersed Problem/Dirichlet boundary conditions", spacedim)
34 , Neumann_bc(
"/Immersed Problem/Neumann boundary conditions", spacedim)
35 , inner_control(
"/Immersed Problem/Solver/Inner control")
36 , outer_control(
"/Immersed Problem/Solver/Outer control")
37 , convergence_table(
std::vector<
std::string>(spacedim,
"u"))
40 add_parameter(
"Output directory", output_directory);
41 add_parameter(
"Output name", output_name);
42 add_parameter(
"Output results", output_results);
43 add_parameter(
"Initial refinement", initial_refinement);
44 add_parameter(
"Dirichlet boundary ids", dirichlet_ids);
45 add_parameter(
"Neumann boundary ids", neumann_ids);
46 add_parameter(
"Normal flux boundary ids", normal_flux_ids);
47 enter_subsection(
"Grid generation");
49 add_parameter(
"Domain type", domain_type);
50 add_parameter(
"Grid generator", name_of_grid);
51 add_parameter(
"Grid generator arguments", arguments_for_grid);
54 enter_subsection(
"Refinement and remeshing");
56 add_parameter(
"Strategy",
61 add_parameter(
"Coarsening fraction", coarsening_fraction);
62 add_parameter(
"Refinement fraction", refinement_fraction);
63 add_parameter(
"Maximum number of cells", max_cells);
64 add_parameter(
"Number of refinement cycles", n_refinement_cycles);
67 enter_subsection(
"Physical constants");
69 add_parameter(
"Lame mu", Lame_mu);
70 add_parameter(
"Lame lambda", Lame_lambda);
73 enter_subsection(
"Exact solution");
75 add_parameter(
"Weight expression", weight_expression);
78 enter_subsection(
"Time dependency");
80 add_parameter(
"Initial time", initial_time);
81 add_parameter(
"Final time", final_time);
82 add_parameter(
"Time step", dt);
86 this->prm.enter_subsection(
"Error");
87 convergence_table.add_parameters(this->prm);
88 this->prm.leave_subsection();
92template <
int dim,
int spacedim>
93CoupledElasticityProblem<dim, spacedim>::CoupledElasticityProblem(
94 const CoupledElasticityProblemParameters<dim, spacedim> &par)
96 , mpi_communicator(MPI_COMM_WORLD)
98 , computing_timer(mpi_communicator,
102 , tria(mpi_communicator,
106 , inclusions(spacedim)
112template <
int dim,
int spacedim>
115 const std::string &ids_and_cad_file_names,
120 grid_in.
read(grid_file_name);
121# ifdef DEAL_II_WITH_OPENCASCADE
122 using map_type = std::map<types::manifold_id, std::string>;
124 for (
const auto &pair : Converter::to_value(ids_and_cad_file_names))
127 const auto &cad_file_name = pair.second;
128 const auto extension = boost::algorithm::to_lower_copy(
129 cad_file_name.substr(cad_file_name.find_last_of(
'.') + 1));
131 if (extension ==
"iges" || extension ==
"igs")
133 else if (extension ==
"step" || extension ==
"stp")
137 ExcNotImplemented(
"We found an extension that we "
138 "do not recognize as a CAD file "
139 "extension. Bailing out."));
141 if ((std::get<0>(n_elements) == 0))
145 else if (spacedim == 3)
148 t->set_manifold(manifold_id,
155 TopoDS::Face(shape)));
158 (void)ids_and_cad_file_names;
159 AssertThrow(
false, ExcNotImplemented(
"Generation of the grid failed."));
165template <
int dim,
int spacedim>
167CoupledElasticityProblem<dim, spacedim>::make_grid()
169 if (par.domain_type ==
"generate")
174 tria, par.name_of_grid, par.arguments_for_grid);
178 pcout <<
"Generating from name and argument failed." << std::endl
179 <<
"Trying to read from file name." << std::endl;
181 par.arguments_for_grid,
185 else if (par.domain_type ==
"cylinder")
187 Assert(spacedim == 2, ExcInternalError());
189 std::cout <<
" ATTENTION: GRID: cirle of radius 1." << std::endl;
191 else if (par.domain_type ==
"cheese")
193 Assert(spacedim == 2, ExcInternalError());
196 else if (par.domain_type ==
"file")
201 const std::string infile(par.name_of_grid);
202 Assert(!infile.empty(), ExcIO());
210 Assert(
false, ExcInternalError());
219template <
int dim,
int spacedim>
221CoupledElasticityProblem<dim, spacedim>::setup_fe()
224 fe = std::make_unique<FESystem<spacedim>>(
FE_Q<spacedim>(par.fe_degree),
226 quadrature = std::make_unique<QGauss<spacedim>>(par.fe_degree + 1);
227 face_quadrature_formula =
228 std::make_unique<
QGauss<spacedim - 1>>(par.fe_degree + 1);
232template <
int dim,
int spacedim>
234CoupledElasticityProblem<dim, spacedim>::setup_dofs()
237 dh.distribute_dofs(*fe);
239 owned_dofs.resize(2);
240 owned_dofs[0] = dh.locally_owned_dofs();
241 relevant_dofs.resize(2);
245 *face_quadrature_formula,
251 constraints.reinit(relevant_dofs[0]);
253 for (
const auto id : par.dirichlet_ids)
257 std::map<types::boundary_id, const Function<spacedim, double> *>
259 for (
const auto id : par.normal_flux_ids)
263 id, &par.Neumann_bc));
266 dh, 0, par.normal_flux_ids, function_map, constraints);
300 stiffness_matrix.clear();
301 stiffness_matrix.reinit(owned_dofs[0],
306 inclusion_constraints.close();
308 if (inclusions.n_dofs() > 0)
310 auto inclusions_set =
312 mpi_communicator, inclusions.n_inclusions());
314 owned_dofs[1] = inclusions_set.tensor_product(
321 relevant_dofs[1] = assemble_coupling_sparsity(dsp);
322 relevant_dofs[1].add_indices(owned_dofs[1]);
327 coupling_matrix.clear();
328 coupling_matrix.reinit(owned_dofs[0],
334 for (
const auto i : relevant_dofs[1])
341 inclusion_matrix.clear();
342 inclusion_matrix.reinit(owned_dofs[1],
348 locally_relevant_solution.reinit(owned_dofs, relevant_dofs, mpi_communicator);
349 system_rhs.reinit(owned_dofs, mpi_communicator);
350 solution.reinit(owned_dofs, mpi_communicator);
354 pcout <<
" Number of degrees of freedom: " << owned_dofs[0].size()
355 <<
" + " << owned_dofs[1].size()
356 <<
" (locally owned: " << owned_dofs[0].n_elements() <<
" + "
357 << owned_dofs[1].n_elements() <<
")" << std::endl;
361template <
int dim,
int spacedim>
363CoupledElasticityProblem<dim, spacedim>::assemble_elasticity_system()
365 stiffness_matrix = 0;
374 *face_quadrature_formula,
379 const unsigned int dofs_per_cell = fe->n_dofs_per_cell();
380 const unsigned int n_q_points = quadrature->size();
383 std::vector<Vector<double>> rhs_values(n_q_points,
Vector<double>(spacedim));
384 std::vector<Tensor<2, spacedim>> grad_phi_u(dofs_per_cell);
385 std::vector<double> div_phi_u(dofs_per_cell);
386 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
388 for (
const auto &cell : dh.active_cell_iterators())
389 if (cell->is_locally_owned())
393 fe_values.reinit(cell);
394 par.rhs.vector_value_list(fe_values.get_quadrature_points(),
396 for (
unsigned int q = 0; q < n_q_points; ++q)
398 for (
unsigned int k = 0; k < dofs_per_cell; ++k)
401 fe_values[displacement].symmetric_gradient(k, q);
402 div_phi_u[k] = fe_values[displacement].divergence(k, q);
404 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
406 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
410 scalar_product(grad_phi_u[i], grad_phi_u[j]) +
411 par.Lame_lambda * div_phi_u[i] * div_phi_u[j]) *
414 const auto comp_i = fe->system_to_component_index(i).first;
415 cell_rhs(i) += fe_values.shape_value(i, q) *
416 rhs_values[q][comp_i] * fe_values.JxW(q);
423 for (
unsigned int f = 0; f < GeometryInfo<spacedim>::faces_per_cell;
425 if (cell->face(f)->at_boundary())
429 if (std::find(par.neumann_ids.begin(),
430 par.neumann_ids.end(),
431 cell->face(f)->boundary_id()) !=
432 par.neumann_ids.end())
434 fe_face_values.reinit(cell, f);
435 for (
unsigned int q = 0;
436 q < fe_face_values.n_quadrature_points;
439 double neumann_value = 0;
440 for (
int d = 0;
d < spacedim; ++
d)
442 par.Neumann_bc.value(
443 fe_face_values.quadrature_point(q),
d) *
444 fe_face_values.normal_vector(q)[
d];
445 neumann_value /= spacedim;
446 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
448 cell_rhs(i) += -neumann_value *
449 fe_face_values.shape_value(i, q) *
450 fe_face_values.JxW(q);
455 cell->get_dof_indices(local_dof_indices);
456 constraints.distribute_local_to_global(cell_matrix,
460 system_rhs.block(0));
468template <
int dim,
int spacedim>
470CoupledElasticityProblem<dim, spacedim>::assemble_coupling_sparsity(
474 "Setup dofs: Assemble Coupling sparsity");
476 IndexSet relevant(inclusions.n_dofs());
478 std::vector<types::global_dof_index> dof_indices(fe->n_dofs_per_cell());
479 std::vector<types::global_dof_index> inclusion_dof_indices;
481 auto particle = inclusions.inclusions_as_particles.begin();
482 while (particle != inclusions.inclusions_as_particles.end())
484 const auto &cell = particle->get_surrounding_cell();
487 dh_cell->get_dof_indices(dof_indices);
489 inclusions.inclusions_as_particles.particles_in_cell(cell);
490 Assert(pic.begin() == particle, ExcInternalError());
491 std::set<types::global_dof_index> inclusion_dof_indices_set;
492 for (
const auto &p : pic)
494 const auto ids = inclusions.get_dof_indices(p.get_id());
495 inclusion_dof_indices_set.insert(ids.begin(), ids.end());
497 inclusion_dof_indices.resize(0);
498 inclusion_dof_indices.insert(inclusion_dof_indices.begin(),
499 inclusion_dof_indices_set.begin(),
500 inclusion_dof_indices_set.end());
501 constraints.add_entries_local_to_global(dof_indices,
502 inclusion_constraints,
503 inclusion_dof_indices,
505 relevant.add_indices(inclusion_dof_indices.begin(),
506 inclusion_dof_indices.end());
507 particle = pic.end();
514template <
int dim,
int spacedim>
516CoupledElasticityProblem<dim, spacedim>::assemble_coupling()
523 std::vector<types::global_dof_index> fe_dof_indices(fe->n_dofs_per_cell());
524 std::vector<types::global_dof_index> inclusion_dof_indices(
525 inclusions.n_dofs_per_inclusion());
528 inclusions.n_dofs_per_inclusion());
531 inclusions.n_dofs_per_inclusion());
535 auto particle = inclusions.inclusions_as_particles.begin();
536 while (particle != inclusions.inclusions_as_particles.end())
538 const auto &cell = particle->get_surrounding_cell();
541 dh_cell->get_dof_indices(fe_dof_indices);
543 inclusions.inclusions_as_particles.particles_in_cell(cell);
544 Assert(pic.begin() == particle, ExcInternalError());
546 auto p = pic.begin();
547 auto next_p = pic.begin();
548 while (p != pic.end())
550 const auto inclusion_id = inclusions.get_inclusion_id(p->get_id());
551 inclusion_dof_indices = inclusions.get_dof_indices(p->get_id());
552 local_coupling_matrix = 0;
553 local_inclusion_matrix = 0;
557 std::vector<Point<spacedim>> ref_q_points;
558 for (; next_p != pic.end() &&
559 inclusions.get_inclusion_id(next_p->get_id()) == inclusion_id;
561 ref_q_points.push_back(next_p->get_reference_location());
567 for (
unsigned int q = 0; q < ref_q_points.size(); ++q)
569 const auto id = p->get_id();
570 const auto &inclusion_fe_values = inclusions.get_fe_values(
id);
571 const auto &real_q = p->get_location();
573 inclusions.get_JxW(
id);
576 for (
unsigned int j = 0; j < inclusions.n_dofs_per_inclusion();
579 for (
unsigned int i = 0; i < fe->n_dofs_per_cell(); ++i)
582 fe->system_to_component_index(i).first;
583 if (comp_i == inclusions.get_component(j))
585 local_coupling_matrix(i, j) +=
586 (fev.shape_value(i, q)) * inclusion_fe_values[j] *
590 if (inclusions.data_file !=
"")
592 if (inclusions.inclusions_data[inclusion_id].size() > j)
595 inclusion_fe_values[j] * inclusion_fe_values[j] *
596 inclusions.get_rotated_inclusion_data(
600 inclusions.get_radius(inclusion_id) * ds;
601 if (par.initial_time != par.final_time)
602 temp *= inclusions.inclusions_rhs.value(
603 real_q, inclusions.get_component(j));
604 local_rhs(j) += temp;
609 local_rhs(j) += inclusion_fe_values[j] *
610 inclusions.inclusions_rhs.value(
611 real_q, inclusions.get_component(j)) /
612 inclusions.get_radius(inclusion_id) * ds;
614 local_inclusion_matrix(j, j) +=
615 (inclusion_fe_values[j] * inclusion_fe_values[j] * ds);
620 Assert(p == next_p, ExcInternalError());
622 constraints.distribute_local_to_global(local_coupling_matrix,
624 inclusion_constraints,
625 inclusion_dof_indices,
627 inclusion_constraints.distribute_local_to_global(
628 local_rhs, inclusion_dof_indices, system_rhs.block(1));
633 particle = pic.end();
641template <
int dim,
int spacedim>
643CoupledElasticityProblem<dim, spacedim>::reassemble_coupling_rhs()
647 system_rhs.block(1) = 0;
649 std::vector<types::global_dof_index> fe_dof_indices(fe->n_dofs_per_cell());
650 std::vector<types::global_dof_index> inclusion_dof_indices(
651 inclusions.n_dofs_per_inclusion());
655 auto particle = inclusions.inclusions_as_particles.begin();
656 while (particle != inclusions.inclusions_as_particles.end())
658 const auto &cell = particle->get_surrounding_cell();
661 dh_cell->get_dof_indices(fe_dof_indices);
663 inclusions.inclusions_as_particles.particles_in_cell(cell);
664 Assert(pic.begin() == particle, ExcInternalError());
666 auto p = pic.begin();
667 auto next_p = pic.begin();
668 while (p != pic.end())
670 const auto inclusion_id = inclusions.get_inclusion_id(p->get_id());
671 inclusion_dof_indices = inclusions.get_dof_indices(p->get_id());
675 std::vector<Point<spacedim>> ref_q_points;
676 for (; next_p != pic.end() &&
677 inclusions.get_inclusion_id(next_p->get_id()) == inclusion_id;
679 ref_q_points.push_back(next_p->get_reference_location());
685 for (
unsigned int q = 0; q < ref_q_points.size(); ++q)
687 const auto id = p->get_id();
688 const auto &inclusion_fe_values = inclusions.get_fe_values(
id);
689 const auto &real_q = p->get_location();
691 inclusions.get_JxW(
id);
694 for (
unsigned int j = 0; j < inclusions.n_dofs_per_inclusion();
697 if (inclusions.data_file !=
"")
699 if (inclusions.inclusions_data[inclusion_id].size() > j)
702 inclusion_fe_values[j] * inclusion_fe_values[j] *
703 inclusions.get_rotated_inclusion_data(
707 inclusions.get_radius(inclusion_id) * ds;
708 if (par.initial_time != par.final_time)
709 temp *= inclusions.inclusions_rhs.value(
710 real_q, inclusions.get_component(j));
711 local_rhs(j) += temp;
716 local_rhs(j) += inclusion_fe_values[j] *
717 inclusions.inclusions_rhs.value(
718 real_q, inclusions.get_component(j)) /
719 inclusions.get_radius(inclusion_id) * ds;
725 Assert(p == next_p, ExcInternalError());
727 inclusion_constraints.distribute_local_to_global(
728 local_rhs, inclusion_dof_indices, system_rhs.block(1));
730 particle = pic.end();
737template <
int dim,
int spacedim>
739CoupledElasticityProblem<dim, spacedim>::solve()
742 LA::MPI::PreconditionAMG prec_A;
747 data.symmetric_operator =
true;
750 std::vector<std::vector<bool>> constant_modes;
753 dh, fe->component_mask(displacement_components), constant_modes);
754 data.constant_modes = constant_modes;
756 prec_A.initialize(stiffness_matrix,
data);
770 auto &u = solution.block(0);
771 auto &lambda = solution.block(1);
773 const auto &f = system_rhs.block(0);
774 auto &g = system_rhs.block(1);
778 if (inclusions.n_dofs() == 0)
796 const auto S = B * invA * Bt;
806 auto S_inv_prec = B * invA * Bt + M;
814 pcout <<
" f norm: " << f.l2_norm() <<
", g norm: " << g.l2_norm()
820 lambda = invS * (B * invA * f - g);
821 pcout <<
" Solved for lambda in " << par.outer_control.last_step()
822 <<
" iterations." << std::endl;
825 u = invA * (f - Bt * lambda);
826 pcout <<
" u norm: " << u.l2_norm()
827 <<
", lambda norm: " << lambda.l2_norm() << std::endl;
832 pcout <<
" Solved for u in " << par.inner_control.last_step()
833 <<
" iterations." << std::endl;
834 constraints.distribute(u);
835 inclusion_constraints.distribute(lambda);
836 locally_relevant_solution = solution;
839template <
int dim,
int spacedim>
841CoupledElasticityProblem<dim, spacedim>::refine_and_transfer_around_inclusions()
849 locally_relevant_solution.block(0),
854 auto particle = inclusions.inclusions_as_particles.begin();
855 while (particle != inclusions.inclusions_as_particles.end())
857 const auto &cell = particle->get_surrounding_cell();
859 inclusions.inclusions_as_particles.particles_in_cell(cell);
860 Assert(pic.begin() == particle, ExcInternalError());
862 cell->set_refine_flag();
863 cell->set_material_id(material_id);
868 for (
auto vertex : cell->vertex_indices())
870 for (
const auto &neigh_i :
875 if (!neigh_i->refine_flag_set())
877 neigh_i->set_refine_flag();
878 neigh_i->set_material_id(material_id);
879 for (
auto vertey : neigh_i->vertex_indices())
880 for (
const auto &neigh_j :
886 neigh_j->set_refine_flag();
887 neigh_j->set_material_id(material_id);
893 particle = pic.end();
895 execute_actual_refine_and_transfer();
897 for (
unsigned int ref_cycle = 0; ref_cycle < par.n_refinement_cycles - 1;
902 if (cell->material_id() == material_id)
903 cell->set_refine_flag();
905 execute_actual_refine_and_transfer();
909template <
int dim,
int spacedim>
911CoupledElasticityProblem<dim, spacedim>::refine_and_transfer()
919 locally_relevant_solution.block(0),
921 if (par.refinement_strategy ==
"fixed_fraction")
924 tria, error_per_cell, par.refinement_fraction, par.coarsening_fraction);
926 else if (par.refinement_strategy ==
"fixed_number")
931 par.refinement_fraction,
932 par.coarsening_fraction,
935 else if (par.refinement_strategy ==
"global")
937 cell->set_refine_flag();
939 execute_actual_refine_and_transfer();
941template <
int dim,
int spacedim>
943CoupledElasticityProblem<dim, spacedim>::execute_actual_refine_and_transfer()
948 inclusions.inclusions_as_particles.prepare_for_coarsening_and_refinement();
949 transfer.prepare_for_coarsening_and_refinement(
950 locally_relevant_solution.block(0));
952 inclusions.inclusions_as_particles.unpack_after_coarsening_and_refinement();
954 transfer.interpolate(solution.block(0));
955 constraints.distribute(solution.block(0));
956 locally_relevant_solution.block(0) = solution.block(0);
961template <
int dim,
int spacedim>
963CoupledElasticityProblem<dim, spacedim>::output_solution()
const
965 std::vector<std::string> solution_names(spacedim,
"displacement");
966 std::vector<std::string> exact_solution_names(spacedim,
"exact_displacement");
969 auto exact_vec(solution.block(0));
972 auto exact_vec_locally_relevant(locally_relevant_solution.block(0));
973 exact_vec_locally_relevant = exact_vec;
975 std::vector<DataComponentInterpretation::DataComponentInterpretation>
976 data_component_interpretation(
984 data_component_interpretation);
987 exact_solution_names,
989 data_component_interpretation);
992 for (
unsigned int i = 0; i < subdomain.size(); ++i)
996 const std::string filename =
997 par.output_name +
"_" + std::to_string(cycle) +
".vtu";
1020template <
int dim,
int spacedim>
1022CoupledElasticityProblem<dim, spacedim>::output_results()
const
1025 static std::vector<std::pair<double, std::string>> cycles_and_solutions;
1026 static std::vector<std::pair<double, std::string>> cycles_and_particles;
1028 if (cycles_and_solutions.size() == cycle)
1030 cycles_and_solutions.push_back({(double)cycle, output_solution()});
1031 std::ofstream pvd_solutions(par.output_directory +
"/" + par.output_name +
1037 const std::string particles_filename =
1038 par.output_name +
"_particles.vtu";
1040 inclusions.output_particles(par.output_directory +
"/" +
1041 particles_filename);
1042 cycles_and_particles.push_back({(double)cycle, particles_filename});
1044 std::ofstream pvd_particles(par.output_directory +
"/" +
1045 par.output_name +
"_particles.pvd");
1051template <
int dim,
int spacedim>
1053CoupledElasticityProblem<dim, spacedim>::print_parameters()
const
1056 pcout <<
"Running CoupledElasticityProblem<"
1060 pcout <<
"Running CoupledElasticityProblem<"
1064 par.prm.print_parameters(par.output_directory +
"/" +
"used_parameters_" +
1065 std::to_string(dim) + std::to_string(spacedim) +
1070template <
int dim,
int spacedim>
1072CoupledElasticityProblem<dim, spacedim>::check_boundary_ids()
1074 for (
const auto id : par.dirichlet_ids)
1076 for (
const auto Nid : par.neumann_ids)
1079 ExcNotImplemented(
"incoherent boundary conditions."));
1080 for (
const auto noid : par.normal_flux_ids)
1083 ExcNotImplemented(
"incoherent boundary conditions."));
1268template <
int dim,
int spacedim>
1270CoupledElasticityProblem<dim, spacedim>::compute_internal_and_boundary_stress(
1271 bool openfilefirsttime)
const
1275 "Postprocessing: Computing internal and boundary stresses");
1277 std::map<types::boundary_id, Tensor<1, spacedim>> boundary_stress;
1280 std::vector<double> u_dot_n(spacedim * spacedim);
1283 std::vector<double> perimeter;
1284 for (
auto id : all_ids)
1288 boundary_stress[id] = 0.0;
1289 perimeter.push_back(0.0);
1291 double internal_area = 0.;
1297 *face_quadrature_formula,
1304 const unsigned int dofs_per_cell = fe->n_dofs_per_cell();
1305 const unsigned int n_q_points = quadrature->size();
1306 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1310 for (
unsigned int ix = 0; ix < spacedim; ++ix)
1315 std::vector<Tensor<2, spacedim>> displacement_gradient(
1316 face_quadrature_formula->size());
1317 std::vector<double> displacement_divergence(face_quadrature_formula->size());
1318 std::vector<Tensor<1, spacedim>> displacement_values(
1319 face_quadrature_formula->size());
1321 for (
const auto &cell : dh.active_cell_iterators())
1323 if (cell->is_locally_owned())
1325 if constexpr (spacedim == 2)
1327 cell->get_dof_indices(local_dof_indices);
1328 fe_values.reinit(cell);
1329 for (
unsigned int q = 0; q < n_q_points; ++q)
1331 internal_area += fe_values.JxW(q);
1332 for (
unsigned int k = 0; k < dofs_per_cell; ++k)
1335 fe_values[displacement].symmetric_gradient(k, q);
1336 div_phi_u = fe_values[displacement].divergence(k, q);
1338 (2 * par.Lame_mu * grad_phi_u +
1339 par.Lame_lambda * div_phi_u *
identity) *
1340 locally_relevant_solution.block(
1341 0)[local_dof_indices[k]] *
1343 average_displacement +=
1344 fe_values[displacement].value(k, q) *
1345 locally_relevant_solution.block(
1346 0)[local_dof_indices[k]] *
1352 for (
unsigned int f = 0; f < GeometryInfo<spacedim>::faces_per_cell;
1356 if (cell->face(f)->at_boundary())
1358 auto boundary_index = cell->face(f)->boundary_id();
1359 fe_face_values.reinit(cell, f);
1361 fe_face_values[displacement].get_function_gradients(
1362 locally_relevant_solution.block(0), displacement_gradient);
1363 fe_face_values[displacement].get_function_values(
1364 locally_relevant_solution.block(0), displacement_values);
1365 fe_face_values[displacement].get_function_divergences(
1366 locally_relevant_solution.block(0), displacement_divergence);
1368 for (
unsigned int q = 0; q < fe_face_values.n_quadrature_points;
1371 perimeter[boundary_index] += fe_face_values.JxW(q);
1373 boundary_stress[boundary_index] +=
1374 (2 * par.Lame_mu * displacement_gradient[q] +
1375 par.Lame_lambda * displacement_divergence[q] *
1377 fe_face_values.JxW(q) * fe_face_values.normal_vector(q);
1378 u_dot_n[boundary_index] +=
1379 (displacement_values[q] *
1380 fe_face_values.normal_vector(q)) *
1381 fe_face_values.JxW(q);
1387 if constexpr (spacedim == 2)
1390 average_displacement =
1394 internal_stress /= internal_area;
1395 average_displacement /= internal_area;
1397 for (
auto id : all_ids)
1399 boundary_stress[id] =
1402 boundary_stress[id] /= perimeter[id];
1407 const std::string filename(par.output_directory +
"/forces.txt");
1408 std::ofstream forces_file;
1409 if (openfilefirsttime)
1411 forces_file.open(filename);
1412 if constexpr (spacedim == 2)
1415 <<
"cycle area perimeter meanInternalStressxx meanInternalStressxy meanInternalStressyx meanInternalStressyy avg_u_x avg_u_y";
1416 for (
auto id : all_ids)
1417 forces_file <<
" boundaryStressX_" <<
id <<
" boundaryStressY_"
1418 <<
id <<
" uDotN_" << id;
1419 forces_file << std::endl;
1423 forces_file <<
"cycle perimeter";
1424 for (
auto id : all_ids)
1425 forces_file <<
" sigmanX_" <<
id <<
" sigmanY_"
1426 <<
" sigmanZ_" <<
id <<
" uDotN_" << id;
1427 forces_file << std::endl;
1431 forces_file.open(filename, std::ios_base::app);
1433 if constexpr (spacedim == 2)
1435 forces_file << cycle <<
" " << internal_area <<
" ";
1436 for (
auto id : all_ids)
1437 forces_file << perimeter[id] <<
" ";
1438 forces_file << internal_stress <<
" " << average_displacement <<
" ";
1439 for (
auto id : all_ids)
1440 forces_file << boundary_stress[id] <<
" " << u_dot_n[id] <<
" ";
1441 forces_file << std::endl;
1445 forces_file << cycle <<
" ";
1446 for (
auto id : all_ids)
1447 forces_file << perimeter[id] <<
" ";
1448 for (
auto id : all_ids)
1449 forces_file << boundary_stress[id] <<
" " << u_dot_n[id] <<
" ";
1450 forces_file << std::endl;
1452 forces_file.close();
1458template <
int dim,
int spacedim>
1461CoupledElasticityProblem<dim, spacedim>::compute_coupling_pressure()
1464 if (inclusions.n_inclusions() > 0 &&
1465 inclusions.get_offset_coefficients() == 1 &&
1466 inclusions.get_n_coefficients() >= 2)
1468 const auto locally_owned_vessels =
1470 mpi_communicator, inclusions.get_n_vessels());
1474 const auto locally_owned_inclusions =
1476 mpi_communicator, inclusions.n_inclusions());
1480 coupling_pressure.reinit(locally_owned_vessels, mpi_communicator);
1481 auto &pressure = coupling_pressure;
1487 pressure_at_inc = 0;
1489 const auto &lambda_to_pressure = locally_relevant_solution.block(1);
1495 locally_owned_vessels, mpi_communicator);
1496 inclusions_to_divide_by = 0;
1498 const auto used_number_modes = inclusions.get_n_coefficients();
1500 const auto local_lambda = lambda_to_pressure.locally_owned_elements();
1501 if constexpr (spacedim == 3)
1503 unsigned int previous_inclusion_number =
1505 auto tensorR = inclusions.get_rotation(0);
1506 for (
const auto &ll : local_lambda)
1508 const unsigned inclusion_number = (
unsigned int)
floor(
1509 ll / (inclusions.get_n_coefficients() * spacedim));
1511 auto lii = ll - inclusion_number *
1512 inclusions.get_n_coefficients() * spacedim;
1513 const unsigned mode_number = (
unsigned int)
floor(lii / spacedim);
1514 const unsigned coor_number = lii % spacedim;
1516 if (previous_inclusion_number != inclusion_number)
1517 tensorR = inclusions.get_rotation(inclusion_number);
1519 if (mode_number == 0 || mode_number == 1)
1522 pressure[inclusions.get_vesselID(inclusion_number)] +=
1523 lambda_to_pressure[ll] * tensorR[coor_number][mode_number] /
1528 pressure_at_inc[inclusion_number] +=
1529 lambda_to_pressure[ll] * tensorR[coor_number][mode_number] /
1532 previous_inclusion_number = inclusion_number;
1539 for (
auto ll : local_lambda)
1541 const unsigned inclusion_number = (
unsigned int)
floor(
1542 ll / (inclusions.get_n_coefficients() * spacedim));
1544 auto lii = ll - inclusion_number *
1545 (inclusions.get_n_coefficients() * spacedim);
1546 if (lii == 0 || lii == 3)
1549 pressure[inclusions.get_vesselID(inclusion_number)] +=
1550 lambda_to_pressure[ll] / used_number_modes;
1553 pressure_at_inc = pressure;
1554 pressure.print(std::cout);
1555 local_lambda.print(std::cout);
1558 coupling_pressure_at_inclusions = pressure_at_inc;
1560 output_coupling_pressure(cycle == 1 ?
true :
false);
1564template <
int dim,
int spacedim>
1567CoupledElasticityProblem<dim, spacedim>::output_coupling_pressure(
1568 bool openfilefirsttime)
const
1571 if (inclusions.n_inclusions() > 0 &&
1572 inclusions.get_offset_coefficients() == 1 &&
1573 inclusions.get_n_coefficients() >= 2)
1575 const auto &pressure = coupling_pressure;
1579 const std::string filename(par.output_directory +
1580 "/externalPressure.txt");
1581 std::ofstream pressure_file;
1582 if (openfilefirsttime)
1583 pressure_file.open(filename);
1585 pressure_file.open(filename, std::ios_base::app);
1587 for (
unsigned int in = 0; in < pressure.size(); ++in)
1588 pressure_file << in <<
" " << pressure[in] << std::endl;
1590 pressure_file.close();
1594 if (par.initial_time == par.final_time)
1596# ifdef DEAL_II_WITH_HDF5
1597 const std::string FILE_NAME(par.output_directory +
1598 "/externalPressure.h5");
1600 auto accessMode = HDF5::File::FileAccessMode::create;
1601 if (!openfilefirsttime)
1602 accessMode = HDF5::File::FileAccessMode::open;
1604 HDF5::File file_h5(FILE_NAME, accessMode, mpi_communicator);
1605 const std::string DATASET_NAME(
"externalPressure_" +
1606 std::to_string(cycle));
1609 file_h5.create_dataset<
double>(DATASET_NAME,
1610 {inclusions.get_n_vessels()});
1612 std::vector<double> data_to_write;
1614 data_to_write.reserve(pressure.locally_owned_size());
1616 const auto locally_owned_vessels =
1618 mpi_communicator, inclusions.get_n_vessels());
1620 for (
const auto &el : locally_owned_vessels)
1623 data_to_write.emplace_back(pressure[el]);
1625 if (pressure.locally_owned_size() > 0)
1628 hsize_t los = pressure.locally_owned_size();
1629 int ierr = MPI_Exscan(&los,
1632 MPI_UNSIGNED_LONG_LONG,
1637 std::vector<hsize_t> offset = {prefix, 1};
1638 std::vector<hsize_t> count = {pressure.locally_owned_size(), 1};
1652 <<
"output_pressure file for time dependent simulation not implemented"
1670template <
int dim,
int spacedim>
1671std::vector<std::vector<double>>
1672CoupledElasticityProblem<dim, spacedim>::split_pressure_over_inclusions(
1673 std::vector<int> number_of_cells_per_vessel,
1676 Assert(number_of_cells_per_vessel.size() == inclusions.get_n_vessels(),
1677 ExcInternalError());
1679 std::vector<std::vector<double>> split_pressure;
1680 unsigned starting_inclusion = 0;
1682 for (
unsigned int vessel = 0; vessel < number_of_cells_per_vessel.size();
1685 auto N2 = number_of_cells_per_vessel[vessel];
1686 auto N1 = inclusions.get_inclusions_in_vessel(vessel);
1688 std::vector<double> new_vector;
1693 coupling_pressure_at_inclusions);
1695 new_vector.push_back(pressure_of_inc_in_vessel[starting_inclusion]);
1697 for (
auto cell = 1; cell < N2 - 1; ++cell)
1699 auto X = cell / (N2 - 1) * (N1 - 1);
1703 new_vector.push_back(
1704 (1 -
w) * pressure_of_inc_in_vessel[starting_inclusion + j] +
1705 (
w)*pressure_of_inc_in_vessel[starting_inclusion + j + 1]);
1707 new_vector.push_back(
1708 pressure_of_inc_in_vessel[starting_inclusion + N1 - 1]);
1709 starting_inclusion += N1;
1710 split_pressure.push_back(new_vector);
1713 return split_pressure;
1717template <
int dim,
int spacedim>
1719CoupledElasticityProblem<dim, spacedim>::run()
1721 if (par.initial_time == par.final_time)
1726 check_boundary_ids();
1729 inclusions.setup_inclusions_particles(tria);
1732 for (cycle = 0; cycle < par.n_refinement_cycles; ++cycle)
1736 assemble_elasticity_system();
1738 assemble_coupling();
1740 if (par.output_results)
1744 if constexpr (spacedim == 2)
1747 par.convergence_table.error_from_exact(
1749 locally_relevant_solution.block(0),
1754 par.convergence_table.error_from_exact(
1755 dh, locally_relevant_solution.block(0), par.bc);
1756 par.convergence_table.output_table(pcout.get_stream());
1758 if constexpr (spacedim == 2)
1761 compute_coupling_pressure();
1762 output_coupling_pressure(cycle == 0 ?
true :
false);
1765 if (cycle != par.n_refinement_cycles - 1)
1766 refine_and_transfer();
1769 compute_coupling_pressure();
1770 output_coupling_pressure(
true);
1772 if (par.domain_type ==
"generate")
1773 compute_internal_and_boundary_stress(
true);
1778 pcout <<
"time dependent simulation, refinement not implemented"
1783 check_boundary_ids();
1787 inclusions.setup_inclusions_particles(tria);
1790 assemble_elasticity_system();
1791 for (current_time = par.initial_time; current_time < par.final_time;
1792 current_time += par.dt, ++cycle)
1794 pcout <<
"Time: " << current_time << std::endl;
1796 inclusions.inclusions_rhs.set_time(current_time);
1797 par.Neumann_bc.set_time(current_time);
1798 assemble_coupling();
1801 if (par.output_results)
1804 compute_coupling_pressure();
1805 output_coupling_pressure(cycle == 0 ?
true :
false);
1807 if (par.domain_type ==
"generate")
1808 compute_internal_and_boundary_stress(cycle == 0 ?
true :
false);
1813template <
int dim,
int spacedim>
1815CoupledElasticityProblem<dim, spacedim>::run_timestep0()
1820 check_boundary_ids();
1823 inclusions.setup_inclusions_particles(tria);
1830template <
int dim,
int spacedim>
1832CoupledElasticityProblem<dim, spacedim>::run_timestep()
1836 if (par.refinement_strategy ==
"inclusions")
1838 refine_and_transfer_around_inclusions();
1839 std::cout <<
"refining around inclusions" << std::endl;
1841 assemble_elasticity_system();
1842 assemble_coupling();
1847 for (
unsigned int ref_cycle = 0; ref_cycle < par.n_refinement_cycles;
1850 assemble_elasticity_system();
1852 assemble_coupling();
1854 if (ref_cycle != par.n_refinement_cycles - 1)
1855 refine_and_transfer();
1861 reassemble_coupling_rhs();
1866 if (par.output_results)
1869 coupling_pressure.clear();
1870 coupling_pressure_at_inclusions.clear();
1875 compute_internal_and_boundary_stress(cycle == 0 ?
true :
false);
1879template <
int dim,
int spacedim>
1881CoupledElasticityProblem<dim, spacedim>::update_inclusions_data(
1882 std::vector<double> new_data)
1884 inclusions.update_inclusions_data(new_data);
1887template <
int dim,
int spacedim>
1889CoupledElasticityProblem<dim, spacedim>::update_inclusions_data(
1890 std::vector<double> new_data,
1891 std::vector<int> cells_per_vessel)
1893 Assert(cells_per_vessel.size() == inclusions.get_n_vessels(),
1894 ExcInternalError());
1895 std::vector<std::vector<double>> full_vector;
1896 unsigned int starting_point = 0;
1897 for (
auto &N1 : cells_per_vessel)
1899 std::vector<double> vessel_vector;
1900 for (
auto j = 0; j < N1; ++j)
1903 vessel_vector.push_back(new_data[starting_point + j]);
1905 starting_point += N1;
1907 full_vector.push_back(vessel_vector);
1909 inclusions.update_inclusions_data(full_vector);
1913template class CoupledElasticityProblemParameters<2>;
1914template class CoupledElasticityProblemParameters<2, 3>;
1915template class CoupledElasticityProblemParameters<3>;
1917template class CoupledElasticityProblem<2>;
1918template class CoupledElasticityProblem<2, 3>;
1919template class CoupledElasticityProblem<3>;
void write_vtu_in_parallel(const std::string &filename, const MPI_Comm comm) const
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
void add_data_vector(const VectorType &data, const std::vector< std::string > &names, const DataVectorType type=type_automatic, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretation={})
virtual void build_patches(const unsigned int n_subdivisions=0)
void attach_triangulation(Triangulation< dim, spacedim > &tria)
void read_msh(std::istream &in)
void read(std::istream &in, Format format=Default)
void write_hyperslab(const Container &data, const std::vector< hsize_t > &offset, const std::vector< hsize_t > &count)
static void estimate(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim - 1 > &quadrature, const std::map< types::boundary_id, const Function< spacedim, Number > * > &neumann_bc, const ReadVector< Number > &solution, Vector< float > &error, const ComponentMask &component_mask={}, const Function< spacedim > *coefficients=nullptr, const unsigned int n_threads=numbers::invalid_unsigned_int, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id, const types::material_id material_id=numbers::invalid_material_id, const Strategy strategy=cell_diameter_over_24)
virtual types::subdomain_id locally_owned_subdomain() const
unsigned int n_active_cells() const
void refine_global(const unsigned int times=1)
bool prepare_coarsening_and_refinement()
virtual void execute_coarsening_and_refinement()
virtual std::vector< types::boundary_id > get_boundary_ids() const
void read_grid_and_cad_files(const std::string &grid_file_name, const std::string &ids_and_cad_file_names, Triangulation< dim, spacedim > &tria)
IteratorRange< active_cell_iterator > active_cell_iterators() const
#define Assert(cond, exc)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
#define AssertThrow(cond, exc)
LinearOperator< Range, Domain, Payload > linear_operator(const OperatorExemplar &, const Matrix &)
LinearOperator< Domain, Range, Payload > transpose_operator(const LinearOperator< Range, Domain, Payload > &op)
LinearOperator< Domain, Range, Payload > inverse_operator(const LinearOperator< Range, Domain, Payload > &op, Solver &solver, const Preconditioner &preconditioner)
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
void compute_nonzero_normal_flux_constraints(const DoFHandler< dim, spacedim > &dof_handler, const unsigned int first_vector_component, const std::set< types::boundary_id > &boundary_ids, const std::map< types::boundary_id, const Function< spacedim, double > * > &function_map, AffineConstraints< double > &constraints, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()), const bool use_manifold_for_normal=true)
void set_manifold(const types::manifold_id number, const Manifold< dim, spacedim > &manifold_object)
IndexSet complete_index_set(const IndexSet::size_type N)
std::vector< index_type > data
component_is_part_of_vector
void write_pvd_record(std::ostream &out, const std::vector< std::pair< double, std::string > > ×_and_names)
Expression floor(const Expression &x)
void generate_from_name_and_arguments(Triangulation< dim, spacedim > &tria, const std::string &grid_generator_function_name, const std::string &grid_generator_function_arguments)
void cheese(Triangulation< dim, spacedim > &tria, const std::vector< unsigned int > &holes)
void hyper_ball(Triangulation< dim, spacedim > &tria, const Point< spacedim > ¢er={}, const double radius=1., const bool attach_spherical_manifold_on_boundary_cells=false)
void cell_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, const ArrayView< const std::vector< double > > &velocity, const double factor=1.)
std::tuple< unsigned int, unsigned int, unsigned int > count_elements(const TopoDS_Shape &shape)
TopoDS_Shape read_STEP(const std::string &filename, const double scale_factor=1e-3)
TopoDS_Shape read_IGES(const std::string &filename, const double scale_factor=1e-3)
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
IndexSet create_evenly_distributed_partitioning(const MPI_Comm comm, const types::global_dof_index total_size)
std::vector< T > gather(const MPI_Comm comm, const T &object_to_send, const unsigned int root_process=0)
std::string dim_string(const int dim, const int spacedim)
constexpr unsigned int invalid_unsigned_int
void refine_and_coarsen_fixed_fraction(::Triangulation< dim, spacedim > &tria, const ::Vector< Number > &criteria, const double top_fraction_of_error, const double bottom_fraction_of_error, const VectorTools::NormType norm_type=VectorTools::L1_norm)
void refine_and_coarsen_fixed_number(::Triangulation< dim, spacedim > &tria, const ::Vector< Number > &criteria, const double top_fraction_of_cells, const double bottom_fraction_of_cells, const types::global_cell_index max_n_cells=std::numeric_limits< types::global_cell_index >::max())
::SolutionTransfer< dim, VectorType, spacedim > SolutionTransfer
std_cxx20::type_identity< T > identity