20template <
int dim,
int spacedim>
28 Assert(dim == spacedim, ExcNotImplemented(
"Not available with codim > 0"));
29 Assert(dim == 2 || dim == 3, ExcImpossibleInDim(1));
35 "The triangulation must not be empty upon calling this function."));
44template <
int dim,
int spacedim>
49 Assert(cells.size() > 0, ExcMessage(
"No cells to be agglomerated."));
51 if (cells.size() == 1)
57 cells[0]->global_active_cell_index();
63 cells[0]->as_dof_handler_iterator(
agglo_dh);
67 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>
69 slaves.reserve(cells.size() - 1);
71 for (
auto it = ++cells.begin(); it != cells.end(); ++it)
73 slaves.push_back(*it);
80 (*it)->as_dof_handler_iterator(
agglo_dh);
85 Assert(((*it)->subdomain_id() ==
tria->locally_owned_subdomain() ||
103 return {cells[0],
this};
106template <
int dim,
int spacedim>
110 const unsigned int fecollection_size)
112 Assert(cells.size() > 0, ExcMessage(
"No cells to be agglomerated."));
114 if (cells.size() == 1)
120 cells[0]->global_active_cell_index();
126 cells[0]->as_dof_handler_iterator(
agglo_dh);
130 std::vector<typename Triangulation<dim, spacedim>::active_cell_iterator>
132 slaves.reserve(cells.size() - 1);
134 for (
auto it = ++cells.begin(); it != cells.end(); ++it)
136 slaves.push_back(*it);
143 (*it)->as_dof_handler_iterator(
agglo_dh);
144 cell->set_active_fe_index(
149 Assert(((*it)->subdomain_id() ==
tria->locally_owned_subdomain() ||
167 return {cells[0],
this};
172template <
int dim,
int spacedim>
177 Assert(cells.size() > 0, ExcMessage(
"No cells to be agglomerated."));
184 std::vector<std::vector<types::global_cell_index>> connected_components;
189 if (connected_components.size() > 1)
190 std::cout <<
"Disconnected elements. Connected components will be "
191 "computed and agglomerated together."
196 std::vector<typename Triangulation<dim>::active_cell_iterator> agglomerate;
197 for (
const auto &comp : connected_components)
199 agglomerate.reserve(comp.size());
201 agglomerate.push_back(cells[local_idx]);
210template <
int dim,
int spacedim>
225 std::make_unique<FEValues<dim>>(*
mapping,
238template <
int dim,
int spacedim>
269template <
int dim,
int spacedim>
274 unsigned int n_neighbors = 0;
275 for (
const auto &f : cell->face_indices())
277 const auto &neighboring_cell = cell->neighbor(f);
278 if ((cell->face(f)->at_boundary()) ||
279 (neighboring_cell->is_active() &&
290template <
int dim,
int spacedim>
295 tria = &cache_tria->get_triangulation();
296 mapping = &cache_tria->get_mapping();
300 if (
const auto parallel_tria =
dynamic_cast<
301 const dealii::parallel::TriangulationBase<dim, spacedim> *
>(&*
tria))
303 const std::weak_ptr<const Utilities::MPI::Partitioner> cells_partitioner =
304 parallel_tria->global_active_cell_index_partitioner();
306 cells_partitioner.lock()->locally_owned_range(),
communicator);
310 master_slave_relationships.reinit(tria->n_active_cells(), MPI_COMM_SELF);
313 polytope_cache.clear();
318 cache_tria->get_triangulation(), cache_tria->get_mapping());
326template <
int dim,
int spacedim>
332 fe = std::make_unique<FE_DGQ<dim>>(fe_space.
degree);
334 fe = std::make_unique<FE_AggloDGP<dim>>(fe_space.
degree);
336 fe = std::make_unique<FE_SimplexDGP<dim>>(fe_space.
degree);
341 "Currently, this interface supports only DGQ and DGP bases."));
354 std::make_unique<ScratchData>(*
mapping,
369 const bool needs_ghost_info =
372 if (needs_ghost_info)
377 if (needs_ghost_info)
381template <
int dim,
int spacedim>
400 "Hybrid mesh is not implemented for hp::FECollection."));
403 for (
unsigned int i = 0; i < fe_collection_in.
size(); ++i)
405 if (
dynamic_cast<const FESystem<dim> *
>(&fe_collection_in[i]))
408 for (
unsigned int b = 0;
b < fe_collection_in[i].n_base_elements();
412 &fe_collection_in[i].base_element(
b)) ||
414 &fe_collection_in[i].base_element(
b)) ||
416 &fe_collection_in[i].base_element(
b)) ||
418 &fe_collection_in[i].base_element(
b))))
422 "Currently, this interface supports only DGQ and DGP bases."));
428 if (!(
dynamic_cast<const FE_DGQ<dim> *
>(&fe_collection_in[i]) ||
434 "Currently, this interface supports only DGQ and DGP bases."));
436 fe_collection.push_back(fe_collection_in[i]);
440 ExcMessage(
"Invalid FE: must have at least one component."));
445 else if (fe_collection[0].n_components() > 1)
447 std::vector<const FiniteElement<dim, spacedim> *> base_elements;
448 std::vector<unsigned int> multiplicities;
452 multiplicities.push_back(
fe_collection[0].element_multiplicity(
b));
455 for (
const auto *ptr : base_elements)
457 fe_collection.push_back(fe_system_nothing);
464 const bool needs_ghost_info =
467 if (needs_ghost_info)
472 if (needs_ghost_info)
476template <
int dim,
int spacedim>
482 ExcMessage(
"No agglomeration has been performed."));
483 Assert(dim > 1, ExcNotImplemented());
485 std::vector<Point<spacedim>> pts;
486 for (
const auto &cell : polytope)
487 for (
const auto i : cell->vertex_indices())
488 pts.push_back(cell->vertex(i));
495template <
int dim,
int spacedim>
500 ExcMessage(
"No agglomeration has been performed."));
504 "The DoFHandler associated to the agglomeration has not been initialized."
505 "It's likely that you forgot to distribute the DoFs. You may want"
506 "to check if a call to `initialize_hp_structure()` has been done."));
531template <
int dim,
int spacedim>
535 const unsigned int dofs_per_cell =
fe->dofs_per_cell;
538 if (polytope->is_locally_owned())
540 const unsigned int n_faces = polytope->n_faces();
541 for (
unsigned int f = 0; f < n_faces; ++f)
543 if (!polytope->at_boundary(f))
545 const auto &neigh_polytope = polytope->neighbor(f);
546 if (!neigh_polytope->is_locally_owned())
551 const auto ¤t_fe =
reinit(polytope, f);
553 std::vector<Point<spacedim>> qpoints_to_send =
554 current_fe.get_quadrature_points();
556 const std::vector<double> &jxws_to_send =
557 current_fe.get_JxW_values();
559 const std::vector<Tensor<1, spacedim>> &normals_to_send =
560 current_fe.get_normal_vectors();
564 neigh_polytope->subdomain_id();
566 std::pair<CellId, unsigned int> cell_and_face{
579 const unsigned int n_qpoints = qpoints_to_send.size();
583 std::vector<std::vector<double>> values_per_qpoints(
586 std::vector<std::vector<Tensor<1, spacedim>>>
587 gradients_per_qpoints(dofs_per_cell);
589 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
591 values_per_qpoints[i].resize(n_qpoints);
592 gradients_per_qpoints[i].resize(n_qpoints);
593 for (
unsigned int q = 0; q < n_qpoints; ++q)
595 values_per_qpoints[i][q] =
596 current_fe.shape_value(i, q);
597 gradients_per_qpoints[i][q] =
598 current_fe.shape_grad(i, q);
602 local_values[neigh_rank].emplace(cell_and_face,
604 local_gradients[neigh_rank].emplace(
605 cell_and_face, gradients_per_qpoints);
622template <
int dim,
int spacedim>
631 ExcMessage(
"This must be a master cell."));
633 std::vector<Point<dim>> vec_pts;
634 std::vector<double> vec_JxWs;
639 for (
const auto &dummy_cell : cells)
642 auto q_points =
no_values->get_quadrature_points();
643 const auto &JxWs =
no_values->get_JxW_values();
645 std::transform(q_points.begin(),
647 std::back_inserter(vec_pts),
649 std::transform(JxWs.begin(),
651 std::back_inserter(vec_JxWs),
652 [&](
const double w) { return w; });
658 const auto &master_cell_as_dh_iterator =
659 master_cell->as_dof_handler_iterator(agglo_dh);
660 for (
const auto &dummy_cell : cells)
677 master_cell_as_dh_iterator->active_fe_index(),
681 .get_quadrature_points();
685 std::transform(q_points.begin(),
687 std::back_inserter(vec_pts),
689 std::transform(JxWs.begin(),
691 std::back_inserter(vec_JxWs),
692 [&](
const double w) { return w; });
698 std::vector<Point<dim>> unit_points(vec_pts.size());
700 bboxes[master2polygon.at(master_cell->active_cell_index())];
701 unit_points.reserve(vec_pts.size());
703 for (
unsigned int i = 0; i < vec_pts.size(); i++)
704 unit_points[i] = bbox.real_to_unit(vec_pts[i]);
711template <
int dim,
int spacedim>
717 "Triangulation must not be empty upon calling this function."));
719 ExcMessage(
"No agglomeration has been performed."));
729template <
int dim,
int spacedim>
771template <
int dim,
int spacedim>
775 const unsigned int face_index,
777 &agglo_isv_ptr)
const
785template <
int dim,
int spacedim>
789 const unsigned int face_index)
const
805template <
int dim,
int spacedim>
806std::pair<const FEValuesBase<dim, spacedim> &,
811 const unsigned int local_in,
812 const unsigned int local_neigh)
const
820 const auto &neigh_cell =
829 std::pair<const FEValuesBase<dim, spacedim> &,
845 const unsigned int neigh_rank = neigh_polytope->
subdomain_id();
846 const CellId &neigh_id = neigh_polytope->
id();
850 std::vector<Point<spacedim>> &real_qpoints =
851 recv_qpoints.at(neigh_rank).at({neigh_id, local_neigh});
853 const auto &JxWs =
recv_jxws.at(neigh_rank).at({neigh_id, local_neigh});
855 std::vector<Tensor<1, spacedim>> &normals =
856 recv_normals.at(neigh_rank).at({neigh_id, local_neigh});
859 std::vector<Point<spacedim>> final_unit_q_points;
860 std::transform(real_qpoints.begin(),
862 std::back_inserter(final_unit_q_points),
864 return bbox.real_to_unit(p);
886 for (
unsigned int q = 0; q < final_unit_q_points.size(); ++q)
891 final_unit_q_points, JxWs, normals);
894 std::make_unique<NonMatching::FEImmersedSurfaceValues<spacedim>>(
900 std::pair<const FEValuesBase<dim, spacedim> &,
910template <
int dim,
int spacedim>
911template <
typename SparsityPatternType,
typename Number>
914 SparsityPatternType &dsp,
916 const bool keep_constrained_dofs,
920 ExcMessage(
"The agglomeration has not been set up correctly."));
923 "The Sparsity pattern must be empty upon calling this function."));
926 const IndexSet locally_relevant_dofs =
929 if constexpr (std::is_same_v<SparsityPatternType, DynamicSparsityPattern>)
930 dsp.reinit(locally_owned_dofs.
size(),
931 locally_owned_dofs.
size(),
932 locally_relevant_dofs);
933 else if constexpr (std::is_same_v<SparsityPatternType,
942 agglo_dh, dsp, constraints, keep_constrained_dofs, subdomain_id);
948 const unsigned int dofs_per_cell =
agglo_dh.get_fe(0).n_dofs_per_cell();
949 std::vector<types::global_dof_index> current_dof_indices(dofs_per_cell);
950 std::vector<types::global_dof_index> neighbor_dof_indices(dofs_per_cell);
956 if (polytope->is_locally_owned())
958 const unsigned int n_current_faces = polytope->n_faces();
959 polytope->get_dof_indices(current_dof_indices);
960 for (
unsigned int f = 0; f < n_current_faces; ++f)
962 const auto &neigh_polytope = polytope->neighbor(f);
965 neigh_polytope->get_dof_indices(neighbor_dof_indices);
968 neighbor_dof_indices,
970 keep_constrained_dofs,
985 if (polytope->is_locally_owned())
987 const unsigned int current_dofs_per_cell =
988 polytope->get_fe().dofs_per_cell;
989 std::vector<types::global_dof_index> current_dof_indices(
990 current_dofs_per_cell);
992 const unsigned int n_current_faces = polytope->n_faces();
993 polytope->get_dof_indices(current_dof_indices);
994 for (
unsigned int f = 0; f < n_current_faces; ++f)
996 const auto &neigh_polytope = polytope->neighbor(f);
999 const unsigned int neighbor_dofs_per_cell =
1000 neigh_polytope->get_fe().dofs_per_cell;
1001 std::vector<types::global_dof_index> neighbor_dof_indices(
1002 neighbor_dofs_per_cell);
1004 neigh_polytope->get_dof_indices(neighbor_dof_indices);
1006 current_dof_indices,
1007 neighbor_dof_indices,
1009 keep_constrained_dofs,
1019 if constexpr (std::is_same_v<SparsityPatternType,
1026template <
int dim,
int spacedim>
1030 [[maybe_unused]]
const auto parallel_triangulation =
1032 Assert(parallel_triangulation !=
nullptr, ExcInternalError());
1035 std::vector<types::global_dof_index> global_dof_indices(
n_dofs_per_cell);
1037 if (polytope->is_locally_owned())
1039 const CellId &master_cell_id = polytope->id();
1041 const auto polytope_dh = polytope->as_dof_handler_iterator(
agglo_dh);
1042 polytope_dh->get_dof_indices(global_dof_indices);
1045 const auto &agglomerate = polytope->get_agglomerate();
1047 for (
const auto &cell : agglomerate)
1050 for (
const auto &f : cell->face_indices())
1052 if (!cell->at_boundary(f))
1054 const auto &neighbor = cell->neighbor(f);
1055 if (neighbor->is_ghost())
1059 neighbor->subdomain_id();
1064 cell->id(), master_cell_id);
1069 master_cell_id, global_dof_indices);
1072 const auto &bbox =
bboxes[polytope->index()];
1099 template <
int dim,
int spacedim>
1106 const unsigned int face_index,
1112 ExcMessage(
"This cell must be a master one."));
1115 const auto &neigh_polytope = it->
neighbor(face_index);
1117 const CellId polytope_in_id = cell->id();
1125 polytope_out_id = neigh_polytope->id();
1127 polytope_out_id = polytope_in_id;
1130 {polytope_in_id, polytope_out_id});
1132 std::vector<Point<spacedim>> final_unit_q_points;
1133 std::vector<double> final_weights;
1134 std::vector<Tensor<1, dim>> final_normals;
1139 const unsigned int expected_qpoints =
1141 final_unit_q_points.reserve(expected_qpoints);
1142 final_weights.reserve(expected_qpoints);
1143 final_normals.reserve(expected_qpoints);
1146 for (
const auto &[deal_cell, local_face_idx] : common_face)
1150 const auto &q_points =
1153 const auto &normals =
1156 const unsigned int n_qpoints_agglo = q_points.size();
1158 for (
unsigned int q = 0; q < n_qpoints_agglo; ++q)
1160 final_unit_q_points.push_back(
1161 bbox.real_to_unit(q_points[q]));
1162 final_weights.push_back(JxWs[q]);
1163 final_normals.push_back(normals[q]);
1170 unsigned int higher_order_quad_index = cell->active_fe_index();
1173 .agglomeration_face_quad_collection[cell->active_fe_index()]
1177 ->active_fe_index()]
1179 higher_order_quad_index = neigh_polytope->active_fe_index();
1181 const unsigned int expected_qpoints =
1182 common_face.size() *
1186 final_unit_q_points.reserve(expected_qpoints);
1187 final_weights.reserve(expected_qpoints);
1188 final_normals.reserve(expected_qpoints);
1190 for (
const auto &[deal_cell, local_face_idx] : common_face)
1193 deal_cell, local_face_idx, higher_order_quad_index, 0, 0);
1195 const auto &q_points =
1197 .get_quadrature_points();
1201 const auto &normals =
1203 .get_normal_vectors();
1205 const unsigned int n_qpoints_agglo = q_points.size();
1207 for (
unsigned int q = 0; q < n_qpoints_agglo; ++q)
1209 final_unit_q_points.push_back(
1210 bbox.real_to_unit(q_points[q]));
1211 final_weights.push_back(JxWs[q]);
1212 final_normals.push_back(normals[q]);
1219 final_unit_q_points, final_weights, final_normals);
1224 std::make_unique<NonMatching::FEImmersedSurfaceValues<spacedim>>(
1233 std::make_unique<NonMatching::FEImmersedSurfaceValues<spacedim>>(
1240 agglo_isv_ptr->reinit(cell);
1242 return *agglo_isv_ptr;
1261 ->global_active_cell_index()] ==
1263 ExcMessage(
"The present cell with index " +
1264 std::to_string(master_cell->global_active_cell_index()) +
1265 "is not a master one."));
1271 CellId current_polytope_id = master_cell->id();
1274 std::set<types::global_cell_index> visited_polygonal_neighbors;
1276 std::map<unsigned int, CellId> face_to_neigh_id;
1278 std::map<unsigned int, bool> is_face_at_boundary;
1281 std::set<CellId> visited_polygonal_neighbors_id;
1282 unsigned int ghost_counter = 0;
1284 for (
const auto &cell : agglomeration)
1287 cell->active_cell_index();
1289 const CellId cell_id = cell->id();
1291 for (
const auto f : cell->face_indices())
1293 const auto &neighboring_cell = cell->neighbor(f);
1295 const bool valid_neighbor =
1300 if (neighboring_cell->is_locally_owned() &&
1326 neighboring_cell->active_cell_index();
1329 const auto &master_of_neighbor =
1331 neighboring_cell_index);
1333 const auto nof = cell->neighbor_of_neighbor(f);
1339 neighbor_polytope_index =
1341 master_of_neighbor->active_cell_index());
1343 CellId neighbor_polytope_id =
1344 master_of_neighbor->id();
1346 if (visited_polygonal_neighbors.find(
1347 neighbor_polytope_index) ==
1348 std::end(visited_polygonal_neighbors))
1352 const unsigned int n_face =
1354 [current_polytope_index];
1357 current_polytope_index, n_face}] = {
1358 false, master_of_neighbor};
1360 is_face_at_boundary[n_face] =
true;
1363 [current_polytope_index];
1365 visited_polygonal_neighbors.insert(
1366 neighbor_polytope_index);
1371 .find({cell_index, f}) ==
1373 .visited_cell_and_faces))
1377 current_polytope_id, neighbor_polytope_id}]
1378 .emplace_back(cell, f);
1386 .find({neighboring_cell_index, nof}) ==
1388 .visited_cell_and_faces))
1392 neighbor_polytope_id, current_polytope_id}]
1393 .emplace_back(neighboring_cell, nof);
1396 .insert({neighboring_cell_index, nof});
1405 neighbor_polytope_index =
1407 neighboring_cell_index);
1409 CellId neighbor_polytope_id =
1410 neighboring_cell->id();
1412 if (visited_polygonal_neighbors.find(
1413 neighbor_polytope_index) ==
1414 std::end(visited_polygonal_neighbors))
1417 const unsigned int n_face =
1419 [current_polytope_index];
1423 current_polytope_index, n_face}] = {
1424 false, neighboring_cell};
1426 is_face_at_boundary[n_face] =
true;
1429 [current_polytope_index];
1431 visited_polygonal_neighbors.insert(
1432 neighbor_polytope_index);
1438 .find({cell_index, f}) ==
1440 .visited_cell_and_faces))
1444 current_polytope_id, neighbor_polytope_id}]
1445 .emplace_back(cell, f);
1452 .find({neighboring_cell_index, nof}) ==
1454 .visited_cell_and_faces))
1458 neighbor_polytope_id, current_polytope_id}]
1459 .emplace_back(neighboring_cell, nof);
1462 .insert({neighboring_cell_index, nof});
1466 else if (neighboring_cell->is_ghost())
1468 const auto nof = cell->neighbor_of_neighbor(f);
1475 const auto &check_neigh_poly_ids =
1477 neighboring_cell->subdomain_id());
1479 const CellId neighboring_cell_id =
1480 neighboring_cell->id();
1482 const CellId &check_neigh_polytope_id =
1483 check_neigh_poly_ids.at(neighboring_cell_id);
1488 if (visited_polygonal_neighbors_id.find(
1489 check_neigh_polytope_id) ==
1490 std::end(visited_polygonal_neighbors_id))
1493 current_polytope_index,
1495 [current_polytope_index]}] = {
false,
1501 current_polytope_id,
1503 [current_polytope_index]}] =
1504 check_neigh_polytope_id;
1507 const unsigned int n_face =
1509 [current_polytope_index];
1511 face_to_neigh_id[n_face] = check_neigh_polytope_id;
1513 is_face_at_boundary[n_face] =
false;
1518 [current_polytope_index];
1520 visited_polygonal_neighbors_id.insert(
1521 check_neigh_polytope_id);
1531 .find({cell_id, f}) ==
1537 current_polytope_id, check_neigh_polytope_id}]
1538 .emplace_back(cell, f);
1548 .insert({cell_id, f});
1553 .find({neighboring_cell_id, nof}) ==
1559 check_neigh_polytope_id, current_polytope_id}]
1560 .emplace_back(neighboring_cell, nof);
1563 .insert({neighboring_cell_id, nof});
1567 else if (cell->face(f)->at_boundary())
1575 if (visited_polygonal_neighbors.find(
1576 std::numeric_limits<unsigned int>::max()) ==
1577 std::end(visited_polygonal_neighbors))
1582 current_polytope_index,
1584 [current_polytope_index]}] = {
true,
1587 const unsigned int n_face =
1589 [current_polytope_index];
1591 is_face_at_boundary[n_face] =
true;
1594 [current_polytope_index];
1596 visited_polygonal_neighbors.insert(
1597 std::numeric_limits<unsigned int>::max());
1608 current_polytope_id, current_polytope_id}]
1609 .emplace_back(cell, f);
1620 if (ghost_counter > 0)
1622 const auto parallel_triangulation =
dynamic_cast<
1623 const dealii::parallel::TriangulationBase<dim, spacedim> *
>(
1626 const unsigned int n_faces_current_poly =
1632 for (
const unsigned int neigh_rank :
1633 parallel_triangulation->ghost_owners())
1635 handler.
local_n_faces[neigh_rank].emplace(current_polytope_id,
1636 n_faces_current_poly);
1639 current_polytope_id, is_face_at_boundary);
1642 current_polytope_id, face_to_neigh_id);
1660 const bool keep_constrained_dofs,
1667 const bool keep_constrained_dofs,
1675 const bool keep_constrained_dofs,
1682 const bool keep_constrained_dofs,
1690 const bool keep_constrained_dofs,
1697 const bool keep_constrained_dofs,
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternBase &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
const FiniteElement< dim, spacedim > & get_fe(const types::fe_index index=0) const
const unsigned int degree
unsigned int size() const
AgglomerationContainer get_agglomerate() const
bool is_locally_owned() const
const AgglomerationIterator< dim, spacedim > neighbor(const unsigned int f) const
const FiniteElement< dim, spacedim > & get_fe() const
DoFHandler< dim, spacedim >::active_cell_iterator as_dof_handler_iterator(const DoFHandler< dim, spacedim > &dof_handler) const
types::subdomain_id subdomain_id() const
unsigned int n_dofs_per_cell() const noexcept
AgglomerationHandler()=default
std::map< types::subdomain_id, std::map< CellId, unsigned int > > local_n_faces
std::unique_ptr< GridTools::Cache< dim, spacedim > > cached_tria
LinearAlgebra::distributed::Vector< float > master_slave_relationships
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< Tensor< 1, spacedim > > > > local_normals
const FEValues< dim, spacedim > & reinit(const AgglomerationIterator< dim, spacedim > &polytope) const
std::map< types::subdomain_id, std::map< CellId, CellId > > recv_cell_ids_neigh_cell
FE_Nothing< dim, spacedim > dummy_fe
std::unique_ptr< NonMatching::FEImmersedSurfaceValues< spacedim > > agglomerated_isv_bdary
std::unique_ptr< hp::FEValues< dim, spacedim > > hp_no_values
bool is_slave_cell(const CellIterator &cell) const
std::map< types::subdomain_id, std::map< CellId, std::map< unsigned int, bool > > > local_bdary_info
std::unique_ptr< NonMatching::FEImmersedSurfaceValues< spacedim > > agglomerated_isv
std::unique_ptr< ScratchData > standard_scratch
Quadrature< dim > agglomeration_quad
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< double > > > recv_jxws
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< Tensor< 1, spacedim > > > > recv_normals
Quadrature< dim - 1 > agglomeration_face_quad
std::unique_ptr< FEValues< dim, spacedim > > no_values
std::map< types::subdomain_id, std::map< CellId, unsigned int > > recv_n_faces
std::vector< BoundingBox< spacedim > > bboxes
void exchange_interface_values()
std::unique_ptr< hp::FEFaceValues< dim, spacedim > > hp_no_face_values
std::map< types::subdomain_id, std::map< CellId, BoundingBox< dim > > > recv_ghosted_bbox
bool are_cells_agglomerated(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell, const typename Triangulation< dim, spacedim >::active_cell_iterator &other_cell) const
unsigned int n_agglomerations
Quadrature< dim > agglomerated_quadrature(const AgglomerationContainer &cells, const typename Triangulation< dim, spacedim >::active_cell_iterator &master_cell) const
AgglomerationIterator< dim, spacedim > agglomeration_iterator
hp::QCollection< dim - 1 > agglomeration_face_quad_collection
std::map< const typename Triangulation< dim, spacedim >::active_cell_iterator, std::vector< typename Triangulation< dim >::active_face_iterator > > polygon_boundary
ObserverPointer< const Triangulation< dim, spacedim > > tria
std::unordered_map< types::global_cell_index, std::vector< typename Triangulation< dim, spacedim >::active_cell_iterator > > master2slaves
void create_bounding_box(const AgglomerationContainer &polytope)
std::map< types::global_cell_index, types::global_cell_index > master2polygon
typename AgglomerationIterator< dim, spacedim >::AgglomerationContainer AgglomerationContainer
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< Point< spacedim > > > > recv_qpoints
std::pair< const FEValuesBase< dim, spacedim > &, const FEValuesBase< dim, spacedim > & > reinit_interface(const AgglomerationIterator< dim, spacedim > &polytope_in, const AgglomerationIterator< dim, spacedim > &neigh_polytope, const unsigned int local_in, const unsigned int local_outside) const
const MPI_Comm communicator
std::map< types::subdomain_id, std::map< CellId, std::vector< types::global_dof_index > > > recv_ghost_dofs
void setup_connectivity_of_agglomeration()
const Triangulation< dim, spacedim > & get_triangulation() const
void create_agglomeration_sparsity_pattern(SparsityPatternType &sparsity_pattern, const AffineConstraints< Number > &constraints=AffineConstraints< Number >(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
const Mapping< dim > & get_mapping() const
void setup_ghost_polytopes()
std::map< types::global_cell_index, typename Triangulation< dim, spacedim >::active_cell_iterator > master_slave_relationships_iterators
std::vector< typename Triangulation< dim, spacedim >::active_cell_iterator > get_agglomerate(const typename Triangulation< dim, spacedim >::active_cell_iterator &master_cell) const
unsigned int n_agglomerated_faces_per_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell) const
const UpdateFlags internal_agglomeration_face_flags
void distribute_agglomerated_dofs(const FiniteElement< dim > &fe_space)
hp::FECollection< dim, spacedim > dummy_fe_collection
std::vector< types::global_cell_index > number_of_agglomerated_faces
const UpdateFlags internal_agglomeration_flags
std::map< types::subdomain_id, std::map< CellId, std::map< unsigned int, bool > > > recv_bdary_info
void connect_to_tria_signals()
std::unique_ptr< FEFaceValues< dim, spacedim > > no_face_values
const FEValuesBase< dim, spacedim > & reinit_master(const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell, const unsigned int face_number, std::unique_ptr< NonMatching::FEImmersedSurfaceValues< spacedim > > &agglo_isv_ptr) const
std::map< types::subdomain_id, std::map< CellId, std::vector< types::global_dof_index > > > local_ghost_dofs
std::vector< typename Triangulation< dim, spacedim >::active_cell_iterator > master_cells_container
friend class AgglomerationIterator
std::unique_ptr< hp::FECollection< dim, spacedim > > hp_fe_collection
hp::QCollection< dim > agglomeration_quad_collection
bool is_master_cell(const CellIterator &cell) const
IteratorRange< agglomeration_iterator > polytope_iterators() const
void initialize_agglomeration_data(const std::unique_ptr< GridTools::Cache< dim, spacedim > > &cache_tria)
agglomeration_iterator define_agglomerate(const AgglomerationContainer &cells)
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< double > > > local_jxws
void initialize_fe_values(const Quadrature< dim > &cell_quadrature=QGauss< dim >(1), const UpdateFlags &flags=UpdateFlags::update_default, const Quadrature< dim - 1 > &face_quadrature=QGauss< dim - 1 >(1), const UpdateFlags &face_flags=UpdateFlags::update_default)
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< Point< spacedim > > > > local_qpoints
std::unique_ptr< NonMatching::FEImmersedSurfaceValues< spacedim > > agglomerated_isv_neigh
void define_agglomerate_with_check(const AgglomerationContainer &cells)
std::unique_ptr< ScratchData > agglomerated_scratch
UpdateFlags agglomeration_face_flags
hp::FECollection< dim, spacedim > fe_collection
std::map< types::subdomain_id, std::map< CellId, BoundingBox< dim > > > local_ghosted_bbox
DoFHandler< dim, spacedim > agglo_dh
void initialize_hp_structure()
std::unique_ptr< MappingBox< dim > > box_mapping
std::unique_ptr< FiniteElement< dim > > fe
ObserverPointer< const Mapping< dim, spacedim > > mapping
UpdateFlags agglomeration_flags
std::map< types::subdomain_id, std::map< CellId, std::map< unsigned int, CellId > > > recv_ghosted_master_id
std::map< types::subdomain_id, std::map< CellId, CellId > > local_cell_ids_neigh_cell
internal::PolytopeCache< dim, spacedim > polytope_cache
std::map< types::subdomain_id, std::map< CellId, std::map< unsigned int, CellId > > > local_ghosted_master_id
hp::MappingCollection< dim > mapping_collection
static void setup_master_neighbor_connectivity(const typename Triangulation< dim, spacedim >::active_cell_iterator &master_cell, const AgglomerationHandler< dim, spacedim > &handler)
static const FEValuesBase< dim, spacedim > & reinit_master(const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell, const unsigned int face_index, std::unique_ptr< NonMatching::FEImmersedSurfaceValues< spacedim > > &agglo_isv_ptr, const AgglomerationHandler< dim, spacedim > &handler)
unsigned int size() const
#define Assert(cond, exc)
#define AssertThrow(cond, exc)
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)
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
std::map< unsigned int, T > some_to_some(const MPI_Comm comm, const std::map< unsigned int, T > &objects_to_send)
void create_graph_from_agglomerate(const std::vector< typename Triangulation< dim >::active_cell_iterator > &cells, Graph &g)
void compute_connected_components(Graph &g, std::vector< std::vector< types::global_cell_index > > &connected_components)
constexpr types::subdomain_id invalid_subdomain_id
unsigned int subdomain_id
unsigned int global_cell_index