17#include <unordered_set>
40 const Array<int> &attributes) : parent_(parent), from_(from),
41 attributes_(attributes)
57 std::tie(parent_vertex_ids_,
65 std::tie(parent_vertex_ids_,
71 parent_to_submesh_vertex_ids_ = -1;
72 for (
int i = 0; i < parent_vertex_ids_.
Size(); i++)
74 parent_to_submesh_vertex_ids_[parent_vertex_ids_[i]] = i;
77 parent_to_submesh_element_ids_.
SetSize(from == From::Boundary ? parent.
GetNBE()
79 parent_to_submesh_element_ids_ = -1;
80 for (
int i = 0; i < parent_element_ids_.
Size(); i++)
82 parent_to_submesh_element_ids_[parent_element_ids_[i]] = i;
100 parent_to_submesh_vertex_ids_ = -1;
101 for (
int i = 0; i < parent_vertex_ids_.
Size(); i++)
107 parent_vertex_ids_[i] = parent_vertex;
108 parent_to_submesh_vertex_ids_[parent_vertex] = i;
115 DSTable v2v(parent_.
GetNV());
123 int parent_edge_id = v2v(parent_vertex_ids_[lv[0]],
124 parent_vertex_ids_[lv[1]]);
125 parent_edge_ids_.
Append(parent_edge_id);
129 parent_to_submesh_edge_ids_ = -1;
130 for (
int i = 0; i < parent_edge_ids_.
Size(); i++)
132 parent_to_submesh_edge_ids_[parent_edge_ids_[i]] = i;
138 parent_element_ids_);
141 parent_to_submesh_face_ids_ = -1;
142 for (
int i = 0; i < parent_face_ids_.
Size(); i++)
144 parent_to_submesh_face_ids_[parent_face_ids_[i]] = i;
153 Array<int> sub_par_vert(sub_vert.Size());
154 for (
int j = 0; j < sub_vert.Size(); j++)
156 sub_par_vert[j] = parent_vertex_ids_[sub_vert[j]];
162 if (par_vert.Size() == 3)
181 Array<int> sub_par_vert(sub_vert.Size());
182 for (
int j = 0; j < sub_vert.Size(); j++)
184 sub_par_vert[j] = parent_vertex_ids_[sub_vert[j]];
201 if (par_vert.Size() == 3)
214 ListOfIntegerSets groups;
217 group.Recreate(1, &
MyRank);
218 groups.Insert(group);
224 FindSharedVerticesRanks(rhvtx);
225 AppendSharedVerticesGroups(groups, rhvtx);
228 FindSharedEdgesRanks(rhe);
229 AppendSharedEdgesGroups(groups, rhe);
234 FindSharedFacesRanks(rht, rhq);
235 AppendSharedFacesGroups(groups, rht, rhq);
242 int ngroups = groups.Size()-1;
244 int nsverts, nsedges, nstrias, nsquads;
245 BuildVertexGroup(ngroups, rhvtx, nsverts);
246 BuildEdgeGroup(ngroups, rhe, nsedges);
249 BuildFaceGroup(ngroups, rht, nstrias, rhq, nsquads);
262 BuildSharedVerticesMapping(nsverts, rhvtx);
263 BuildSharedEdgesMapping(nsedges, rhe);
266 BuildSharedFacesMapping(nstrias, rht, nsquads, rhq);
273 ? FindGhostBoundaryElementAttributes()
274 : std::unordered_map<int,int> {});
278 if (!el_to_edge) { el_to_edge =
new Table; }
279 NumOfEdges = GetElementToEdgeTable(*el_to_edge);
283 GetElementToFaceTable();
289 const GridFunction *parent_nodes = parent_.GetNodes();
292 const FiniteElementSpace *parent_fes = parent_nodes->FESpace();
295 parent_fes->FEColl()->GetOrder(),
296 parent_fes->IsDGSpace(),
298 parent_fes->GetOrdering());
300 const ParGridFunction* pn =
dynamic_cast<const ParGridFunction*
>
301 (parent_.GetNodes());
303 "Internal error. Object is supposed to be ParGridFunction.");
305 ParGridFunction* n =
dynamic_cast<ParGridFunction*
>
308 "Internal error. Object is supposed to be ParGridFunction.");
316void ParSubMesh::FindSharedVerticesRanks(Array<int> &rhvtx)
319 GroupCommunicator svert_comm(parent_.gtopo);
320 parent_.GetSharedVertexCommunicator(svert_comm);
322 int nsvtx = svert_comm.GroupLDofTable().Size_of_connections();
324 rhvtx.SetSize(nsvtx);
329 for (
int g = 1, sv = 0; g < parent_.GetNGroups(); g++)
331 const int group_sz = parent_.gtopo.GetGroupSize(g);
332 MFEM_VERIFY((
unsigned int)group_sz <= 8*
sizeof(
int),
333 "Group size too large. Groups with more than 32 ranks are not supported, yet.");
334 const int* group_lproc = parent_.gtopo.GetGroup(g);
336 const int* my_group_id_ptr = std::find(group_lproc, group_lproc+group_sz, 0);
337 MFEM_ASSERT(my_group_id_ptr != group_lproc+group_sz,
"internal error");
339 const int my_group_id = my_group_id_ptr-group_lproc;
341 for (
int gv = 0; gv < parent_.GroupNVertices(g); gv++, sv++)
343 int plvtx = parent_.GroupVertex(g, gv);
344 int submesh_vertex_id = parent_to_submesh_vertex_ids_[plvtx];
345 if (submesh_vertex_id != -1)
347 rhvtx[sv] |= 1 << my_group_id;
354 svert_comm.Reduce(rhvtx, GroupCommunicator::Sum);
355 svert_comm.Bcast<
int>(rhvtx, 0);
358void ParSubMesh::FindSharedEdgesRanks(Array<int> &rhe)
361 GroupCommunicator sedge_comm(parent_.gtopo);
362 parent_.GetSharedEdgeCommunicator(sedge_comm);
364 int nsedges = sedge_comm.GroupLDofTable().Size_of_connections();
367 rhe.SetSize(nsedges);
372 for (
int g = 1, se = 0; g < parent_.GetNGroups(); g++)
374 const int group_sz = parent_.gtopo.GetGroupSize(g);
375 MFEM_VERIFY((
unsigned int)group_sz <= 8*
sizeof(
int),
376 "Group size too large. Groups with more than 32 ranks are not supported, yet.");
377 const int* group_lproc = parent_.gtopo.GetGroup(g);
379 const int* my_group_id_ptr = std::find(group_lproc, group_lproc+group_sz, 0);
380 MFEM_ASSERT(my_group_id_ptr != group_lproc+group_sz,
"internal error");
383 const int my_group_id = my_group_id_ptr-group_lproc;
385 for (
int ge = 0; ge < parent_.GroupNEdges(g); ge++, se++)
387 int ple = parent_.GroupEdge(g, ge);
388 int submesh_edge_id = parent_to_submesh_edge_ids_[ple];
389 if (submesh_edge_id != -1)
391 rhe[se] |= 1 << my_group_id;
398 sedge_comm.Reduce(rhe, GroupCommunicator::Sum);
399 sedge_comm.Bcast<
int>(rhe, 0);
402void ParSubMesh::FindSharedFacesRanks(Array<int>& rht, Array<int> &rhq)
404 GroupCommunicator stria_comm(parent_.gtopo);
405 parent_.GetSharedTriCommunicator(stria_comm);
406 int nstria = stria_comm.GroupLDofTable().Size_of_connections();
410 for (
int g = 1, st = 0; g < parent_.GetNGroups(); g++)
412 MFEM_ASSERT(parent_.gtopo.GetGroupSize(g) == 2
413 || parent_.GroupNTriangles(g) == 0,
414 parent_.gtopo.GetGroupSize(g) <<
' ' << parent_.GroupNTriangles(g));
415 for (
int gt = 0; gt < parent_.GroupNTriangles(g); gt++, st++)
418 int plt = parent_.GroupTriangle(g, gt);
419 int submesh_face_id = parent_to_submesh_face_ids_[plt];
420 if (submesh_face_id != -1)
428 stria_comm.Reduce(rht, GroupCommunicator::Sum);
429 stria_comm.Bcast<
int>(rht, 0);
431 GroupCommunicator squad_comm(parent_.gtopo);
432 parent_.GetSharedQuadCommunicator(squad_comm);
433 int nsquad = squad_comm.GroupLDofTable().Size_of_connections();
437 for (
int g = 1,
sq = 0; g < parent_.GetNGroups(); g++)
439 MFEM_ASSERT(parent_.gtopo.GetGroupSize(g) == 2
440 || parent_.GroupNQuadrilaterals(g) == 0,
441 parent_.gtopo.GetGroupSize(g) <<
' ' << parent_.GroupNQuadrilaterals(g));
442 for (
int gq = 0; gq < parent_.GroupNQuadrilaterals(g); gq++,
sq++)
445 int plq = parent_.GroupQuadrilateral(g, gq);
446 int submesh_face_id = parent_to_submesh_face_ids_[plq];
447 if (submesh_face_id != -1)
455 squad_comm.Reduce(rhq, GroupCommunicator::Sum);
456 squad_comm.Bcast<
int>(rhq, 0);
460void ParSubMesh::AppendSharedVerticesGroups(ListOfIntegerSets &groups,
466 for (
int g = 1, sv = 0; g < parent_.GetNGroups(); g++)
468 const int group_sz = parent_.gtopo.GetGroupSize(g);
469 MFEM_VERIFY((
unsigned int)group_sz <= 8*
sizeof(
int),
470 "Group size too large. Groups with more than 32 ranks are not supported, yet.");
471 const int* group_lproc = parent_.gtopo.GetGroup(g);
473 const int* my_group_id_ptr = std::find(group_lproc, group_lproc+group_sz, 0);
474 MFEM_ASSERT(my_group_id_ptr != group_lproc+group_sz,
"internal error");
476 const int my_group_id = my_group_id_ptr-group_lproc;
478 for (
int gv = 0; gv < parent_.GroupNVertices(g); gv++, sv++)
481 int plvtx = parent_.GroupVertex(g, gv);
482 int submesh_vtx = parent_to_submesh_vertex_ids_[plvtx];
485 if (submesh_vtx == -1)
490 else if (rhvtx[sv] & ~(1 << my_group_id))
493 MFEM_ASSERT(rhvtx[sv] & (1 << my_group_id),
"error again");
496 Array<int> &ranks = group;
498 for (
int i = 0; i < group_sz; i++)
500 if ((rhvtx[sv] >> i) & 1)
502 ranks.Append(parent_.gtopo.GetNeighborRank(group_lproc[i]));
505 MFEM_ASSERT(ranks.Size() >= 2,
"internal error");
507 rhvtx[sv] = groups.Insert(group) - 1;
518void ParSubMesh::AppendSharedEdgesGroups(ListOfIntegerSets &groups,
523 for (
int g = 1, se = 0; g < parent_.GetNGroups(); g++)
525 const int group_sz = parent_.gtopo.GetGroupSize(g);
526 MFEM_VERIFY((
unsigned int)group_sz <= 8*
sizeof(
int),
527 "Group size too large. Groups with more than 32 ranks are not supported, yet.");
528 const int* group_lproc = parent_.gtopo.GetGroup(g);
530 const int* my_group_id_ptr = std::find(group_lproc, group_lproc+group_sz, 0);
531 MFEM_ASSERT(my_group_id_ptr != group_lproc+group_sz,
"internal error");
533 const int my_group_id = my_group_id_ptr-group_lproc;
535 for (
int ge = 0; ge < parent_.GroupNEdges(g); ge++, se++)
537 int ple = parent_.GroupEdge(g, ge);
538 int submesh_edge = parent_to_submesh_edge_ids_[ple];
541 if (submesh_edge == -1)
546 else if (rhe[se] & ~(1 << my_group_id))
551 Array<int> &ranks = group;
553 for (
int i = 0; i < group_sz; i++)
555 if ((rhe[se] >> i) & 1)
557 ranks.Append(parent_.gtopo.GetNeighborRank(group_lproc[i]));
560 MFEM_ASSERT(ranks.Size() >= 2,
"internal error");
562 rhe[se] = groups.Insert(group) - 1;
573void ParSubMesh::AppendSharedFacesGroups(ListOfIntegerSets &groups,
574 Array<int>& rht, Array<int> &rhq)
576 IntegerSet quad_group;
578 for (
int g = 1,
sq = 0; g < parent_.GetNGroups(); g++)
580 const int* group_lproc = parent_.gtopo.GetGroup(g);
581 for (
int gq = 0; gq < parent_.GroupNQuadrilaterals(g); gq++,
sq++)
583 const int group_sz = parent_.gtopo.GetGroupSize(g);
584 MFEM_ASSERT(group_sz == 2,
"internal error");
586 int plq = parent_.GroupQuadrilateral(g, gq);
587 int submesh_face_id = parent_to_submesh_face_ids_[plq];
590 if (submesh_face_id == -1)
595 else if (rhq[
sq] == group_sz)
601 Array<int> &ranks = quad_group;
603 ranks.Append(parent_.gtopo.GetNeighborRank(group_lproc[0]));
604 ranks.Append(parent_.gtopo.GetNeighborRank(group_lproc[1]));
606 rhq[
sq] = groups.Insert(quad_group) - 1;
616 IntegerSet tria_group;
618 for (
int g = 1, st = 0; g < parent_.GetNGroups(); g++)
620 const int* group_lproc = parent_.gtopo.GetGroup(g);
621 for (
int gt = 0; gt < parent_.GroupNTriangles(g); gt++, st++)
623 const int group_sz = parent_.gtopo.GetGroupSize(g);
624 MFEM_ASSERT(group_sz == 2,
"internal error");
626 int plt = parent_.GroupTriangle(g, gt);
627 int submesh_face_id = parent_to_submesh_face_ids_[plt];
630 if (submesh_face_id == -1)
635 else if (rht[st] == group_sz)
641 Array<int> &ranks = tria_group;
643 ranks.Append(parent_.gtopo.GetNeighborRank(group_lproc[0]));
644 ranks.Append(parent_.gtopo.GetNeighborRank(group_lproc[1]));
646 rht[st] = groups.Insert(tria_group) - 1;
659 group.
MakeI(ngroups);
660 for (
int i = 0; i < rh.
Size(); i++)
670 for (
int i = 0; i < rh.
Size(); i++)
680void ParSubMesh::BuildVertexGroup(
int ngroups,
const Array<int>& rhvtx,
683 BuildGroup(group_svert, ngroups, rhvtx, nsverts);
686void ParSubMesh::BuildEdgeGroup(
int ngroups,
const Array<int>& rhe,
689 BuildGroup(group_sedge, ngroups, rhe, nsedges);
692void ParSubMesh::BuildFaceGroup(
int ngroups,
const Array<int>& rht,
693 int& nstrias,
const Array<int>& rhq,
int& nsquads)
695 BuildGroup(group_squad, ngroups, rhq, nsquads);
696 BuildGroup(group_stria, ngroups, rht, nstrias);
699void ParSubMesh::BuildSharedVerticesMapping(
const int nsverts,
700 const Array<int>& rhvtx)
702 svert_lvert.Reserve(nsverts);
704 for (
int g = 1, sv = 0; g < parent_.GetNGroups(); g++)
706 for (
int gv = 0; gv < parent_.GroupNVertices(g); gv++, sv++)
709 int plvtx = parent_.GroupVertex(g, gv);
710 int submesh_vtx_id = parent_to_submesh_vertex_ids_[plvtx];
711 if ((submesh_vtx_id == -1) || (rhvtx[sv] == -1))
717 svert_lvert.Append(submesh_vtx_id);
723void ParSubMesh::BuildSharedEdgesMapping(
const int sedges_ct,
724 const Array<int>& rhe)
726 shared_edges.Reserve(sedges_ct);
727 sedge_ledge.Reserve(sedges_ct);
729 for (
int g = 1, se = 0; g < parent_.GetNGroups(); g++)
731 for (
int ge = 0; ge < parent_.GroupNEdges(g); ge++, se++)
734 parent_.GroupEdge(g, ge, ple, o);
735 int submesh_edge_id = parent_to_submesh_edge_ids_[ple];
736 if ((submesh_edge_id == -1) || rhe[se] == -1)
743 parent_.GetEdgeVertices(ple, vert);
745 int v0 = parent_to_submesh_vertex_ids_[vert[(1-o)/2]];
746 int v1 = parent_to_submesh_vertex_ids_[vert[(1+o)/2]];
750 shared_edges.Append(
new Segment(v0, v1, 1));
751 sedge_ledge.Append(submesh_edge_id);
757void ParSubMesh::BuildSharedFacesMapping(
const int nstrias,
758 const Array<int>& rht,
759 const int nsquads,
const Array<int>& rhq)
761 shared_trias.Reserve(nstrias);
762 shared_quads.Reserve(nsquads);
763 sface_lface.Reserve(nstrias + nsquads);
767 for (
int g = 1, st = 0; g < parent_.GetNGroups(); g++)
769 for (
int gt = 0; gt < parent_.GroupNTriangles(g); gt++, st++)
772 parent_.GroupTriangle(g, gt, plt, o);
773 int submesh_face_id = parent_to_submesh_face_ids_[plt];
774 if ((submesh_face_id == -1) || rht[st] == -1)
782 GetFaceVertices(submesh_face_id, vert);
805 shared_trias.Append(Vert3(v0, v1, v2));
806 sface_lface.Append(submesh_face_id);
811 for (
int g = 1,
sq = 0; g < parent_.GetNGroups(); g++)
813 for (
int gq = 0; gq < parent_.GroupNQuadrilaterals(g); gq++,
sq++)
816 parent_.GroupQuadrilateral(g, gq, plq, o);
817 int submesh_face_id = parent_to_submesh_face_ids_[plq];
818 if ((submesh_face_id == -1) || rhq[
sq] == -1)
825 GetFaceVertices(submesh_face_id, vert);
854 shared_quads.Append(Vert4(v0, v1, v2, v3));
855 sface_lface.Append(submesh_face_id);
861std::unordered_map<int, int>
862ParSubMesh::FindGhostBoundaryElementAttributes()
const
866 std::unordered_map<int,int> lface_boundary_attribute;
867 const auto &face_to_be = parent_.GetFaceToBdrElMap();
870 GroupCommunicator squad_comm(parent_.gtopo);
871 parent_.GetSharedQuadCommunicator(squad_comm);
872 int nsquad = squad_comm.GroupLDofTable().Size_of_connections();
874 GroupCommunicator stria_comm(parent_.gtopo);
875 parent_.GetSharedTriCommunicator(stria_comm);
876 int nstria = stria_comm.GroupLDofTable().Size_of_connections();
878 Array<int> stba(nstria), sqba(nsquad);
879 Array<int> parent_ltface(nstria), parent_lqface(nsquad);
881 parent_ltface = -1; parent_lqface = -1;
882 for (
int g = 1, st = 0; g < parent_.GetNGroups(); g++)
884 for (
int gt = 0; gt < parent_.GroupNTriangles(g); gt++, st++)
887 int plt = parent_.GroupTriangle(g, gt);
888 auto pbe = face_to_be[plt];
891 stba[st] = parent_.GetBdrAttribute(pbe);
893 parent_ltface[st] = plt;
896 for (
int g = 1,
sq = 0; g < parent_.GetNGroups(); g++)
898 for (
int gq = 0; gq < parent_.GroupNQuadrilaterals(g); gq++,
sq++)
901 int plq = parent_.GroupQuadrilateral(g, gq);
902 auto pbe = face_to_be[plq];
905 sqba[
sq] = parent_.GetBdrAttribute(pbe);
907 parent_lqface[
sq] = plq;
911 auto pre_stba = stba;
912 auto pre_sqba = sqba;
914 stria_comm.Reduce(stba, GroupCommunicator::Sum);
915 stria_comm.Bcast<
int>(stba, 0);
916 squad_comm.Reduce(sqba, GroupCommunicator::Sum);
917 squad_comm.Bcast<
int>(sqba, 0);
920 Array<int> fail_indices;
921 fail_indices.Reserve(stba.Size());
922 for (
int i = 0; i < stba.Size(); i++)
923 if (pre_stba[i] != 0 && pre_stba[i] != stba[i])
925 fail_indices.Append(i);
927 MFEM_ASSERT(fail_indices.Size() == 0, [&]()
929 std::stringstream msg;
930 msg <<
"More than one rank found attribute on shared tri face: ";
931 for (auto x : fail_indices)
940 Array<int> fail_indices;
941 fail_indices.Reserve(sqba.Size());
942 for (
int i = 0; i < sqba.Size(); i++)
943 if (pre_sqba[i] != 0 && pre_sqba[i] != sqba[i])
945 fail_indices.Append(i);
947 MFEM_ASSERT(fail_indices.Size() == 0, [&]()
949 std::stringstream msg;
950 msg <<
"More than one rank found attribute on shared quad face: ";
951 for (auto x : fail_indices)
961 if (x > 0) { ++nghost; }
964 if (x > 0) { ++nghost; }
966 lface_boundary_attribute.reserve(nghost);
967 for (
int i = 0; i < stba.Size(); i++)
970 MFEM_ASSERT(parent_ltface[i] > -1, i);
971 lface_boundary_attribute[parent_ltface[i]] = stba[i];
973 for (
int i = 0; i < sqba.Size(); i++)
976 MFEM_ASSERT(parent_lqface[i] > -1, i);
977 lface_boundary_attribute[parent_lqface[i]] = sqba[i];
982 GroupCommunicator sedge_comm(parent_.gtopo);
983 parent_.GetSharedEdgeCommunicator(sedge_comm);
984 int nsedge = sedge_comm.GroupLDofTable().Size_of_connections();
986 Array<int> seba(nsedge), parent_ledge(nsedge);
987 seba = 0; parent_ledge = -1;
988 for (
int g = 1, se = 0; g < parent_.GetNGroups(); g++)
990 for (
int ge = 0; ge < parent_.GroupNEdges(g); ge++, se++)
993 int ple = parent_.GroupEdge(g, ge);
994 auto pbe = face_to_be[ple];
997 seba[se] = parent_.GetBdrAttribute(pbe);
999 parent_ledge[se] = ple;
1004 auto pre_seba = seba;
1006 sedge_comm.Reduce(seba, GroupCommunicator::Sum);
1007 sedge_comm.Bcast<
int>(seba, 0);
1010 Array<int> fail_indices;
1011 fail_indices.Reserve(seba.Size());
1012 for (
int i = 0; i < seba.Size(); i++)
1013 if (pre_seba[i] != 0 && pre_seba[i] != seba[i])
1015 fail_indices.Append(i);
1017 MFEM_ASSERT(fail_indices.Size() == 0, [&]()
1019 std::stringstream msg;
1020 msg <<
"More than one rank found attribute on shared edge: ";
1021 for (auto x : fail_indices)
1031 if (x > 0) { ++nghost; }
1033 lface_boundary_attribute.reserve(nghost);
1034 for (
int i = 0; i < seba.Size(); i++)
1037 MFEM_ASSERT(parent_ledge[i] > -1, i);
1038 lface_boundary_attribute[parent_ledge[i]] = seba[i];
1043 GroupCommunicator svert_comm(parent_.gtopo);
1044 parent_.GetSharedVertexCommunicator(svert_comm);
1045 int nsvtx = svert_comm.GroupLDofTable().Size_of_connections();
1047 Array<int> svba(nsvtx), parent_lvtx(nsvtx);
1048 svba = 0; parent_lvtx = -1;
1049 for (
int g = 1, sv = 0; g < parent_.GetNGroups(); g++)
1051 for (
int gv = 0; gv < parent_.GroupNVertices(g); gv++, sv++)
1054 int plv = parent_.GroupVertex(g, gv);
1055 auto pbe = face_to_be[plv];
1058 svba[sv] = parent_.GetBdrAttribute(pbe);
1060 parent_lvtx[sv] = plv;
1065 auto pre_svba = svba;
1067 svert_comm.Reduce(svba, GroupCommunicator::Sum);
1068 svert_comm.Bcast<
int>(svba, 0);
1071 Array<int> fail_indices;
1072 fail_indices.Reserve(svba.Size());
1073 for (
int i = 0; i < svba.Size(); i++)
1074 if (pre_svba[i] != 0 && pre_svba[i] != svba[i])
1076 fail_indices.Append(i);
1078 MFEM_ASSERT(fail_indices.Size() == 0, [&]()
1080 std::stringstream msg;
1081 msg <<
"More than one rank found attribute on shared vertex: ";
1082 for (auto x : fail_indices)
1092 if (x > 0) { ++nghost; }
1094 lface_boundary_attribute.reserve(nghost);
1095 for (
int i = 0; i < svba.Size(); i++)
1098 MFEM_ASSERT(parent_lvtx[i] > -1, i);
1099 lface_boundary_attribute[parent_lvtx[i]] = svba[i];
1102 return lface_boundary_attribute;
1108 CreateTransferMap(src, dst).Transfer(src, dst);
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void SetComm(MPI_Comm comm)
Set the MPI communicator to 'comm'.
void Create(ListOfIntegerSets &groups, int mpitag)
Set up the group topology given the list of sets of shared entities.
int GetNEdges() const
Return the number of edges.
void GetBdrElementFace(int i, int *f, int *o) const
void InitMesh(int Dim_, int spaceDim_, int NVert, int NElem, int NBdrElem)
Begin construction of a mesh.
static int GetQuadOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
void GetBdrElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of boundary element i.
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
void GenerateNCFaceInfo()
bool Nonconforming() const
Return a bool indicating whether this mesh is nonconforming.
static int ComposeQuadOrientations(int ori_a_b, int ori_b_c)
void InitFromNCMesh(const NCMesh &ncmesh)
Initialize vertices/elements/boundary/tables from a nonconforming mesh.
static int GetTriOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
int GetNFaces() const
Return the number of faces in a 3D mesh.
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
int GetNE() const
Returns number of elements.
int Dimension() const
Dimension of the reference space used within the elements.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
static int ComposeTriOrientations(int ori_a_b, int ori_b_c)
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
void GetFaceVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of face i.
int GetNBE() const
Returns number of boundary elements.
NCMesh * ncmesh
Optional nonconforming mesh extension.
void GetVertexToVertexTable(DSTable &) const
Array< int > attributes
A list of all unique element attributes used by the Mesh.
void OnMeshUpdated(Mesh *mesh)
int GetNodeVertex(int node)
Given a node index, return the vertex index associated.
Array< int > vertex_nodeId
vertex-index to node-id map, see UpdateVertices
Class for parallel grid function.
Class for parallel meshes.
void ExchangeFaceNbrData()
void SetAttributes() override
Determine the sets of unique attribute values in domain and boundary elements.
Array< int > parent_node_ids_
Subdomain representation of a topological parent in another ParMesh.
static ParSubMesh CreateFromDomain(const ParMesh &parent, const Array< int > &domain_attributes)
Create a domain ParSubMesh from its parent.
friend class ParNCSubMesh
static ParSubMesh CreateFromBoundary(const ParMesh &parent, const Array< int > &boundary_attributes)
Create a surface ParSubMesh from its parent.
ParTransferMap represents a mapping of degrees of freedom from a source ParGridFunction to a destinat...
From
Indicator from which part of the parent Mesh the SubMesh is created.
void AddConnection(int r, int c)
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
void AddAColumnInRow(int r)
std::tuple< Array< int >, Array< int > > AddElementsToMesh(const Mesh &parent, Mesh &mesh, const Array< int > &attributes, bool from_boundary)
Given a Mesh parent and another Mesh mesh using the list of attributes in attributes,...
Array< int > BuildFaceMap(const Mesh &pm, const Mesh &sm, const Array< int > &parent_element_ids)
Given two meshes that have a parent to SubMesh relationship create a face map, using a SubMesh to par...
void AddBoundaryElements(SubMeshT &mesh, const std::unordered_map< int, int > &lface_to_boundary_attribute)
Add boundary elements to the SubMesh.
void BuildGroup(Table &group, int ngroups, const Array< int > &rh, int &ns)
std::function< real_t(const Vector &)> f(real_t mass_coeff)