33 group_svert(pmesh.group_svert),
34 group_sedge(pmesh.group_sedge),
35 group_stria(pmesh.group_stria),
36 group_squad(pmesh.group_squad),
38 glob_offset_sequence(-1),
80 if (pmesh.
Nodes && copy_nodes)
108 : glob_elem_offset(-1)
109 , glob_offset_sequence(-1)
121 partitioning.
MakeRef(
const_cast<int *
>(partitioning_), mesh.
GetNE(),
132 for (
int i = 0; i < mesh.
GetNE(); i++)
171 mesh.
GetNE(), mt,
true);
181 Table *edge_element = NULL;
184 activeBdrElem, edge_element);
239 int nsedges =
FindSharedEdges(mesh, partitioning, edge_element, groups);
246 int ngroups = groups.
Size()-1, nstris, nsquads;
253 face_group, vert_global_local);
269 "invalid NURBS mesh");
295 int element_counter = 0;
296 for (
int i = 0; i < mesh.
GetNE(); i++)
298 if (partitioning[i] ==
MyRank)
301 mesh.
GetNodes()->FESpace()->GetElementVDofs(i, gvdofs);
302 mesh.
GetNodes()->GetSubVector(gvdofs, lnodes);
318 const int* partitioning,
322 vert_global_local = -1;
324 int vert_counter = 0;
325 for (
int i = 0; i < mesh.
GetNE(); i++)
327 if (partitioning[i] ==
MyRank)
331 for (
int j = 0; j < vert.
Size(); j++)
333 if (vert_global_local[vert[j]] < 0)
335 vert_global_local[vert[j]] = vert_counter++;
343 for (
int i = 0; i < vert_global_local.
Size(); i++)
345 if (vert_global_local[i] >= 0)
347 vert_global_local[i] = vert_counter++;
353 for (
int i = 0; i < vert_global_local.
Size(); i++)
355 if (vert_global_local[i] >= 0)
368 const int nelems = std::count_if(partitioning,
369 partitioning + mesh.
GetNE(), [
this](
int i) { return i == MyRank;});
376 int element_counter = 0;
377 for (
int i = 0; i < mesh.
GetNE(); i++)
379 if (partitioning[i] ==
MyRank)
383 int nv =
elements[element_counter]->GetNVertices();
384 for (
int j = 0; j < nv; j++)
386 v[j] = vert_global_local[v[j]];
392 return element_counter;
398 Table*& edge_element)
404 activeBdrElem =
false;
409 for (
int i = 0; i < mesh.
GetNBE(); i++)
411 int face, o, el1, el2;
414 if (partitioning[(o % 2 == 0 || el2 < 0) ? el1 : el2] ==
MyRank)
419 activeBdrElem[i] =
true;
424 int bdrelem_counter = 0;
426 for (
int i = 0; i < mesh.
GetNBE(); i++)
428 int face, o, el1, el2;
431 if (partitioning[(o % 2 == 0 || el2 < 0) ? el1 : el2] ==
MyRank)
435 int nv =
boundary[bdrelem_counter]->GetNVertices();
436 for (
int j = 0; j < nv; j++)
438 v[j] = vert_global_local[v[j]];
446 edge_element =
new Table;
449 for (
int i = 0; i < mesh.
GetNBE(); i++)
452 int el1 = edge_element->
GetRow(edge)[0];
453 if (partitioning[el1] ==
MyRank)
458 activeBdrElem[i] =
true;
463 int bdrelem_counter = 0;
465 for (
int i = 0; i < mesh.
GetNBE(); i++)
468 int el1 = edge_element->
GetRow(edge)[0];
469 if (partitioning[el1] ==
MyRank)
473 int nv =
boundary[bdrelem_counter]->GetNVertices();
474 for (
int j = 0; j < nv; j++)
476 v[j] = vert_global_local[v[j]];
484 for (
int i = 0; i < mesh.
GetNBE(); i++)
486 int vert = mesh.
boundary[i]->GetVertices()[0];
489 if (partitioning[el1] ==
MyRank)
495 int bdrelem_counter = 0;
497 for (
int i = 0; i < mesh.
GetNBE(); i++)
499 int vert = mesh.
boundary[i]->GetVertices()[0];
502 if (partitioning[el1] ==
MyRank)
506 v[0] = vert_global_local[v[0]];
523 for (
int i = 0; i < face_group.
Size(); i++)
530 el[0] = partitioning[el[0]];
531 el[1] = partitioning[el[1]];
536 face_group[i] = groups.
Insert(group) - 1;
543 Table*& edge_element,
549 int sedge_counter = 0;
552 edge_element =
new Table;
563 for (
int i = 0; i < edge_element->
Size(); i++)
565 int me = 0, others = 0;
566 for (
int j = edge_element->
GetI()[i]; j < edge_element->
GetI()[i+1]; j++)
568 int k = edge_element->
GetJ()[j];
569 int rank = partitioning[k];
570 edge_element->
GetJ()[j] = rank;
589 edge_element->
GetRow(i)[0] = -1;
593 return sedge_counter;
602 int svert_counter = 0;
603 for (
int i = 0; i < vert_element->
Size(); i++)
605 int me = 0, others = 0;
606 for (
int j = vert_element->
GetI()[i]; j < vert_element->
GetI()[i+1]; j++)
608 vert_element->
GetJ()[j] = partitioning[vert_element->
GetJ()[j]];
623 vert_element->
GetI()[i] = groups.
Insert(group) - 1;
627 vert_element->
GetI()[i] = -1;
630 return svert_counter;
635 int &nstria,
int &nsquad)
641 for (
int i = 0; i < face_group.
Size(); i++)
643 if (face_group[i] >= 0)
660 for (
int i = 0; i < face_group.
Size(); i++)
662 if (face_group[i] >= 0)
683 for (
int i = 0; i < edge_element.
Size(); i++)
685 if (edge_element.
GetRow(i)[0] >= 0)
693 int sedge_counter = 0;
694 for (
int i = 0; i < edge_element.
Size(); i++)
696 if (edge_element.
GetRow(i)[0] >= 0)
709 for (
int i = 0; i < vert_element.
Size(); i++)
711 if (vert_element.
GetI()[i] >= 0)
719 int svert_counter = 0;
720 for (
int i = 0; i < vert_element.
Size(); i++)
722 if (vert_element.
GetI()[i] >= 0)
732 const Mesh& mesh,
const int *partitioning,
741 if (
Dim < 3) {
return; }
743 int stria_counter = 0;
744 int squad_counter = 0;
745 for (
int i = 0; i < face_group.
Size(); i++)
747 if (face_group[i] < 0) {
continue; }
757 for (
int j = 0; j < 3; j++)
759 v[j] = vert_global_local[v[j]];
761 const int lface = (*faces_tbl)(v[0], v[1], v[2]);
777 if (
MyRank == partitioning[gl_el2])
779 std::swap(v[0], v[1]);
791 for (
int j = 0; j < 4; j++)
793 v[j] = vert_global_local[v[j]];
796 (*faces_tbl)(v[0], v[1], v[2], v[3]);
802 MFEM_ABORT(
"unknown face type: " << face->
GetType());
810 const Table* edge_element)
822 int sedge_counter = 0;
823 for (
int i = 0; i < edge_element->
Size(); i++)
825 if (edge_element->
GetRow(i)[0] >= 0)
831 new Segment(vert_global_local[vert[0]],
832 vert_global_local[vert[1]], 1);
834 sedge_ledge[sedge_counter] = v_to_v(vert_global_local[vert[0]],
835 vert_global_local[vert[1]]);
837 MFEM_VERIFY(
sedge_ledge[sedge_counter] >= 0,
"Error in v_to_v.");
852 int svert_counter = 0;
853 for (
int i = 0; i < vert_element->
Size(); i++)
855 if (vert_element->
GetI()[i] >= 0)
857 svert_lvert[svert_counter++] = vert_global_local[i];
865 : MyComm(pncmesh.MyComm)
866 , NRanks(pncmesh.NRanks)
867 , MyRank(pncmesh.MyRank)
868 , glob_elem_offset(-1)
869 , glob_offset_sequence(-1)
894 MPI_Allreduce(&loc_meshgen, &
meshgen, 1, MPI_INT, MPI_BOR,
MyComm);
908 const int l_edge = v_to_v(v[0], v[1]);
909 MFEM_ASSERT(l_edge >= 0,
"invalid shared edge");
920 for (
int st = 0; st < nst; st++)
934 bool fix_orientation)
935 : glob_elem_offset(-1)
936 , glob_offset_sequence(-1)
946 Load(input, generate_edges, refine, fix_orientation);
950 bool fix_orientation)
957 Loader(input, generate_edges,
"mfem_serial_mesh_end");
969 MFEM_ASSERT(
pncmesh,
"internal error");
992 MFEM_VERIFY(ident ==
"communication_groups",
993 "input stream is not a parallel MFEM mesh");
1001 input >> ident >> num_sverts;
1002 MFEM_VERIFY(ident ==
"total_shared_vertices",
"invalid mesh file");
1011 input >> ident >> num_sedges;
1012 MFEM_VERIFY(ident ==
"total_shared_edges",
"invalid mesh file");
1026 input >> ident >> num_sface;
1027 MFEM_VERIFY(ident ==
"total_shared_faces",
"invalid mesh file");
1040 int svert_counter = 0, sedge_counter = 0;
1047 input >> ident >> g;
1050 mfem::err <<
"ParMesh::ParMesh : expecting group " << gr
1051 <<
", read group " << g << endl;
1057 input >> ident >> nv;
1058 MFEM_VERIFY(ident ==
"shared_vertices",
"invalid mesh file");
1059 nv += svert_counter;
1061 "incorrect number of total_shared_vertices");
1063 for ( ; svert_counter < nv; svert_counter++)
1072 input >> ident >> ne;
1073 MFEM_VERIFY(ident ==
"shared_edges",
"invalid mesh file");
1074 ne += sedge_counter;
1076 "incorrect number of total_shared_edges");
1078 for ( ; sedge_counter < ne; sedge_counter++)
1081 input >> v[0] >> v[1];
1088 input >> ident >> nf;
1089 for (
int i = 0; i < nf; i++)
1098 for (
int ii = 0; ii < 3; ii++) { input >> v[ii]; }
1103 for (
int ii = 0; ii < 4; ii++) { input >> v[ii]; }
1106 MFEM_ABORT(
"invalid shared face geometry: " << geom);
1117 "incorrect number of total_shared_faces");
1152 ref_factors = ref_factor;
1231 for (
int j = 0; j < orig_n_verts; j++)
1238 const int orig_n_edges = orig_mesh.
GroupNEdges(gr);
1239 if (orig_n_edges > 0)
1244 const int *c2h_map = rfec.
GetDofMap(geom, ref_factor);
1246 for (
int e = 0; e < orig_n_edges; e++)
1251 for (
int j = 2; j < rdofs.
Size(); j++)
1259 for (
int k = 0; k < nvert; k++)
1262 v[k] = rdofs[c2h_map[cid]];
1278 const int *c2h_map = rfec.
GetDofMap(geom, ref_factor);
1280 for (
int f = 0;
f < orig_nt;
f++)
1285 for (
int j = rdofs.
Size()-num_int_verts; j < rdofs.
Size(); j++)
1294 for (
int k = 0; k < 2; k++)
1296 v[k] = rdofs[c2h_map[RG.
RefEdges[j+k]]];
1305 for (
int k = 0; k < nvert; k++)
1308 v[k] = rdofs[c2h_map[cid]];
1322 const int *c2h_map = rfec.
GetDofMap(geom, ref_factor);
1324 for (
int f = 0;
f < orig_nq;
f++)
1329 for (
int j = rdofs.
Size()-num_int_verts; j < rdofs.
Size(); j++)
1338 for (
int k = 0; k < 2; k++)
1340 v[k] = rdofs[c2h_map[RG.
RefEdges[j+k]]];
1349 for (
int k = 0; k < nvert; k++)
1352 v[k] = rdofs[c2h_map[cid]];
1399 for (
int iv=0; iv<orig_mesh.
GetNV(); ++iv)
1410 for (
int gr = 1; gr < mesh.
GetNGroups(); gr++)
1436 constexpr int ntris = 2, nv_tri = 3, nv_quad = 4;
1439 for (
int gr = 1; gr < mesh.
GetNGroups(); gr++)
1443 for (
int j = 0; j < orig_n_verts; j++)
1450 const int orig_n_edges = orig_mesh.
GroupNEdges(gr);
1451 for (
int e = 0; e < orig_n_edges; e++)
1463 for (
int e = 0; e < orig_nt; e++)
1470 for (
int iv=0; iv<nv_tri; ++iv) { v2[iv] = v[iv]; }
1477 static const int trimap[12] =
1483 static const int diagmap[4] = { 0, 2, 1, 3 };
1484 for (
int f = 0;
f < orig_nq; ++
f)
1491 for (
int iv=0; iv<nv_quad; ++iv) { vg[iv] = vglobal[v[iv]]; }
1492 int iv_min = std::min_element(vg, vg+nv_quad) - vg;
1493 int isplit = (iv_min == 0 || iv_min == 2) ? 0 : 1;
1497 v_diag[0] = v[diagmap[0 + isplit*2]];
1498 v_diag[1] = v[diagmap[1 + isplit*2]];
1501 for (
int itri=0; itri<ntris; ++itri)
1505 for (
int iv=0; iv<nv_tri; ++iv)
1507 v2[iv] = v[trimap[itri + isplit*2 + iv*ntris*2]];
1520 if (orig_mesh.
GetNodes() !=
nullptr)
1530 const int meshgen_save =
meshgen;
1560 int max_attr = attr.
Size() ? attr.
Max() : 1 ;
1561 int glb_max_attr = -1;
1562 MPI_Allreduce(&max_attr, &glb_max_attr, 1, MPI_INT, MPI_MAX,
MyComm);
1566 bool *attr_marker =
new bool[glb_max_attr];
1567 bool *glb_attr_marker =
new bool[glb_max_attr];
1568 for (
int i = 0; i < glb_max_attr; i++)
1570 attr_marker[i] =
false;
1572 for (
int i = 0; i < attr.
Size(); i++)
1574 attr_marker[attr[i] - 1] =
true;
1576 MPI_Allreduce(attr_marker, glb_attr_marker, glb_max_attr,
1577 MFEM_MPI_CXX_BOOL, MPI_LOR,
MyComm);
1578 delete [] attr_marker;
1583 for (
int i = 0; i < glb_max_attr; i++)
1585 if (glb_attr_marker[i])
1590 delete [] glb_attr_marker;
1598 if (bdr_attrs_changed)
1603 MFEM_WARNING(
"Non-positive boundary element attributes found!");
1607 if (elem_attrs_changed)
1612 MFEM_WARNING(
"Non-positive element attributes found!");
1620 int maxNumOfBdrElements;
1621 MPI_Allreduce(
const_cast<int*
>(&
NumOfBdrElements), &maxNumOfBdrElements, 1,
1622 MPI_INT, MPI_MAX,
MyComm);
1623 return (maxNumOfBdrElements > 0);
1631 o = (v[0] < v[1]) ? (+1) : (-1);
1640 "Expecting a triangular face.");
1651 "Expecting a quadrilateral face.");
1661 gr_sedge.
GetI()[0] = 0;
1670 gr_sedge.
GetJ()[k] =k;
1685 gr_svert.
GetI()[0] = 0;
1694 gr_svert.
GetJ()[k] = k;
1709 gr_squad.
GetI()[0] = 0;
1718 gr_squad.
GetJ()[k] = k;
1733 gr_stria.
GetI()[0] = 0;
1742 gr_stria.
GetJ()[k] = k;
1768 sedge_ord[k] = order[v_to_v(v[0], v[1])];
1771 sedge_comm.
Bcast<
int>(sedge_ord, 1);
1773 for (
int k = 0, gr = 1; gr <
GetNGroups(); gr++)
1776 if (n == 0) {
continue; }
1778 for (
int j = 0; j < n; j++)
1780 sedge_ord_map[j].one = sedge_ord[k+j];
1781 sedge_ord_map[j].two = j;
1784 for (
int j = 0; j < n; j++)
1787 const int *v =
shared_edges[sedge_from]->GetVertices();
1788 sedge_ord[k+j] = order[v_to_v(v[0], v[1])];
1790 std::sort(&sedge_ord[k], &sedge_ord[k] + n);
1791 for (
int j = 0; j < n; j++)
1795 order[v_to_v(v[0], v[1])] = sedge_ord[k+j];
1809 ilen_len[j].one = order[j];
1810 ilen_len[j].two =
GetLength(i, it.Column());
1817 for (
int i = 1; i < order.
Size(); i++)
1819 d_max = std::max(d_max, ilen_len[i-1].two-ilen_len[i].two);
1833 mfem::out <<
"glob_d_max = " << glob_d_max << endl;
1845 elements[i]->MarkEdge(v_to_v, order);
1853 boundary[i]->MarkEdge(v_to_v, order);
1872 if ((m = v_to_v(v[0], v[1])) != -1 && middle[m] != -1)
1889 face_stack.
Append(face_t(fv[0], fv[1], fv[2]));
1890 for (
unsigned bit = 0; face_stack.
Size() > 0; bit++)
1892 if (bit == 8*
sizeof(
unsigned))
1898 const face_t &
f = face_stack.
Last();
1899 int mid = v_to_v.
FindId(
f.one,
f.two);
1909 face_stack.
Append(face_t(
f.three,
f.one, mid));
1910 face_t &r = face_stack[face_stack.
Size()-2];
1911 r = face_t(r.two, r.three, mid);
1923 bool need_refinement = 0;
1924 face_stack.
Append(face_t(v[0], v[1], v[2]));
1925 for (
unsigned bit = 0, code = codes[pos++]; face_stack.
Size() > 0; bit++)
1927 if (bit == 8*
sizeof(
unsigned))
1929 code = codes[pos++];
1933 if ((code & (1 << bit)) == 0) { face_stack.
DeleteLast();
continue; }
1935 const face_t &
f = face_stack.
Last();
1936 int mid = v_to_v.
FindId(
f.one,
f.two);
1939 mid = v_to_v.
GetId(
f.one,
f.two);
1940 int ind[2] = {
f.one,
f.two };
1943 need_refinement = 1;
1946 face_stack.
Append(face_t(
f.three,
f.one, mid));
1947 face_t &r = face_stack[face_stack.
Size()-2];
1948 r = face_t(r.two, r.three, mid);
1950 return need_refinement;
1956 if (HYPRE_AssumedPartitionCheck())
1959 MPI_Scan(loc_sizes, temp.
GetData(), N, HYPRE_MPI_BIG_INT, MPI_SUM,
MyComm);
1960 for (
int i = 0; i < N; i++)
1963 (*offsets[i])[0] = temp[i] - loc_sizes[i];
1964 (*offsets[i])[1] = temp[i];
1967 for (
int i = 0; i < N; i++)
1969 (*offsets[i])[2] = temp[i];
1971 MFEM_VERIFY((*offsets[i])[0] >= 0 && (*offsets[i])[1] >= 0,
1972 "overflow in offsets");
1978 MPI_Allgather(loc_sizes, N, HYPRE_MPI_BIG_INT, temp.
GetData(), N,
1979 HYPRE_MPI_BIG_INT,
MyComm);
1980 for (
int i = 0; i < N; i++)
1985 for (
int j = 0; j <
NRanks; j++)
1987 offs[j+1] = offs[j] + temp[i+N*j];
1991 "overflow in offsets");
2020 space_dim = (space_dim == -1) ?
spaceDim : space_dim;
2067 *new_nodes = *
Nodes;
2098 bool del_tables =
false;
2125 gr_sface =
new Table;
2160 if (del_tables) {
delete gr_sface; }
2171 int num_face_nbrs = 0;
2174 if (gr_sface->
RowSize(g-1) > 0)
2182 if (num_face_nbrs == 0)
2192 for (
int g = 1, counter = 0; g <
GetNGroups(); g++)
2194 if (gr_sface->
RowSize(g-1) > 0)
2199 int lproc = (nbs[0]) ? nbs[0] : nbs[1];
2201 rank_group[counter].two = g;
2208 for (
int fn = 0; fn < num_face_nbrs; fn++)
2214 MPI_Request *requests =
new MPI_Request[2*num_face_nbrs];
2215 MPI_Request *send_requests = requests;
2216 MPI_Request *recv_requests = requests + num_face_nbrs;
2217 MPI_Status *statuses =
new MPI_Status[num_face_nbrs];
2219 int *nbr_data =
new int[6*num_face_nbrs];
2220 int *nbr_send_data = nbr_data;
2221 int *nbr_recv_data = nbr_data + 3*num_face_nbrs;
2230 Table send_face_nbr_elemdata, send_face_nbr_facedata;
2234 send_face_nbr_elemdata.
MakeI(num_face_nbrs);
2235 send_face_nbr_facedata.
MakeI(num_face_nbrs);
2236 for (
int fn = 0; fn < num_face_nbrs; fn++)
2239 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
2240 int *sface = gr_sface->
GetRow(nbr_group-1);
2241 for (
int i = 0; i < num_sfaces; i++)
2243 int lface = s2l_face[sface[i]];
2245 if (el_marker[el] != fn)
2250 const int nv =
elements[el]->GetNVertices();
2251 const int *v =
elements[el]->GetVertices();
2252 for (
int j = 0; j < nv; j++)
2253 if (vertex_marker[v[j]] != fn)
2255 vertex_marker[v[j]] = fn;
2259 const int nf =
elements[el]->GetNFaces();
2268 nbr_send_data[3*fn+2] = send_face_nbr_elemdata.
GetI()[fn];
2273 MPI_Isend(&nbr_send_data[3*fn], 3, MPI_INT, nbr_rank, tag,
MyComm,
2274 &send_requests[fn]);
2275 MPI_Irecv(&nbr_recv_data[3*fn], 3, MPI_INT, nbr_rank, tag,
MyComm,
2276 &recv_requests[fn]);
2280 send_face_nbr_elemdata.
MakeJ();
2281 send_face_nbr_facedata.
MakeJ();
2285 for (
int fn = 0; fn < num_face_nbrs; fn++)
2288 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
2289 int *sface = gr_sface->
GetRow(nbr_group-1);
2290 for (
int i = 0; i < num_sfaces; i++)
2292 const int sf = sface[i];
2293 int lface = s2l_face[sf];
2295 if (el_marker[el] != fn)
2300 const int nv =
elements[el]->GetNVertices();
2301 const int *v =
elements[el]->GetVertices();
2302 for (
int j = 0; j < nv; j++)
2303 if (vertex_marker[v[j]] != fn)
2305 vertex_marker[v[j]] = fn;
2316 const int nf =
elements[el]->GetNFaces();
2327 const int *lf_v =
faces[lface]->GetVertices();
2347 for (
int fn = 0; fn < num_face_nbrs; fn++)
2353 int *elemdata = send_face_nbr_elemdata.
GetRow(fn);
2354 int num_sfaces = send_face_nbr_facedata.
RowSize(fn)/2;
2355 int *facedata = send_face_nbr_facedata.
GetRow(fn);
2357 for (
int i = 0; i < num_verts; i++)
2359 vertex_marker[verts[i]] = i;
2362 for (
int el = 0; el < num_elems; el++)
2364 const int nv =
elements[elems[el]]->GetNVertices();
2367 for (
int j = 0; j < nv; j++)
2369 elemdata[j] = vertex_marker[elemdata[j]];
2371 elemdata += nv + nf;
2373 el_marker[elems[el]] = el;
2376 for (
int i = 0; i < num_sfaces; i++)
2378 facedata[2*i] = el_marker[facedata[2*i]];
2382 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
2385 Table recv_face_nbr_elemdata;
2390 recv_face_nbr_elemdata.
MakeI(num_face_nbrs);
2393 for (
int fn = 0; fn < num_face_nbrs; fn++)
2401 recv_face_nbr_elemdata.
MakeJ();
2403 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2406 for (
int fn = 0; fn < num_face_nbrs; fn++)
2411 MPI_Isend(send_face_nbr_elemdata.
GetRow(fn),
2412 send_face_nbr_elemdata.
RowSize(fn),
2413 MPI_INT, nbr_rank, tag,
MyComm, &send_requests[fn]);
2415 MPI_Irecv(recv_face_nbr_elemdata.
GetRow(fn),
2416 recv_face_nbr_elemdata.
RowSize(fn),
2417 MPI_INT, nbr_rank, tag,
MyComm, &recv_requests[fn]);
2426 MPI_Waitany(num_face_nbrs, recv_requests, &fn, statuses);
2428 if (fn == MPI_UNDEFINED)
2436 int *recv_elemdata = recv_face_nbr_elemdata.
GetRow(fn);
2438 for (
int i = 0; i < num_elems; i++)
2444 for (
int j = 0; j < nv; j++)
2446 recv_elemdata[j] += vert_off;
2449 recv_elemdata += nv;
2454 for (
int j = 0; j < nf; j++)
2456 fn_ori[j] = recv_elemdata[j];
2458 recv_elemdata += nf;
2465 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2468 recv_face_nbr_facedata.
SetSize(
2470 for (
int fn = 0; fn < num_face_nbrs; fn++)
2475 MPI_Isend(send_face_nbr_facedata.
GetRow(fn),
2476 send_face_nbr_facedata.
RowSize(fn),
2477 MPI_INT, nbr_rank, tag,
MyComm, &send_requests[fn]);
2480 MPI_Irecv(&recv_face_nbr_facedata[send_face_nbr_facedata.
GetI()[fn]],
2481 send_face_nbr_facedata.
RowSize(fn),
2482 MPI_INT, nbr_rank, tag,
MyComm, &recv_requests[fn]);
2489 MPI_Waitany(num_face_nbrs, recv_requests, &fn, statuses);
2491 if (fn == MPI_UNDEFINED)
2498 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
2499 int *sface = gr_sface->
GetRow(nbr_group-1);
2501 &recv_face_nbr_facedata[send_face_nbr_facedata.
GetI()[fn]];
2503 for (
int i = 0; i < num_sfaces; i++)
2505 const int sf = sface[i];
2506 int lface = s2l_face[sf];
2508 face_info.
Elem2No = -1 - (facedata[2*i] + elem_off);
2509 int info = facedata[2*i+1];
2517 int nbr_ori = info%64, nbr_v[4];
2518 const int *lf_v =
faces[lface]->GetVertices();
2525 for (
int j = 0; j < 3; j++)
2527 nbr_v[perm[j]] = sf_v[j];
2537 for (
int j = 0; j < 4; j++)
2539 nbr_v[perm[j]] = sf_v[j];
2545 info = 64*(info/64) + nbr_ori;
2551 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2568 else if (
Nodes == NULL)
2578 if (!num_face_nbrs) {
return; }
2580 MPI_Request *requests =
new MPI_Request[2*num_face_nbrs];
2581 MPI_Request *send_requests = requests;
2582 MPI_Request *recv_requests = requests + num_face_nbrs;
2583 MPI_Status *statuses =
new MPI_Status[num_face_nbrs];
2587 for (
int i = 0; i < send_vertices.
Size(); i++)
2593 for (
int fn = 0; fn < num_face_nbrs; fn++)
2608 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
2609 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2617 MFEM_VERIFY(pNodes != NULL,
"Nodes are not ParGridFunction!");
2632 for (
int j = 0; j < 4; j++)
2635 sfaces_tbl->
Push(v[fv[0]], v[fv[1]], v[fv[2]]);
2641 for (
int j = 0; j < 2; j++)
2644 sfaces_tbl->
Push(v[fv[0]], v[fv[1]], v[fv[2]]);
2646 for (
int j = 2; j < 5; j++)
2649 sfaces_tbl->
Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
2655 for (
int j = 0; j < 1; j++)
2658 sfaces_tbl->
Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
2660 for (
int j = 1; j < 5; j++)
2663 sfaces_tbl->
Push(v[fv[0]], v[fv[1]], v[fv[2]]);
2671 for (
int j = 0; j < 6; j++)
2674 sfaces_tbl->
Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
2679 MFEM_ABORT(
"Unexpected type of Element.");
2688 const std::unique_ptr<STable3D> &faces,
2689 const std::unique_ptr<STable3D> &shared_faces,
2690 int elem,
int start,
int end,
const int fverts[][N])
2692 for (
int i = start; i < end; ++i)
2695 const auto fv = fverts[i];
2697 const Vert3 elem_fv(elem_vertices[fv[0]], elem_vertices[fv[1]],
2698 elem_vertices[fv[2]]);
2701 const int lf =
faces->Index(elem_fv.
v[0], elem_fv.
v[1], elem_fv.
v[2]);
2705 const int sf = lf < 0 ? shared_faces->Index(elem_fv.
v[0], elem_fv.
v[1],
2710 const int face_to_add = lf < 0 ? (sf >= 0 ? sf +
NumOfFaces : -1) : lf;
2712 MFEM_ASSERT(sf >= 0 ||
2713 lf >= 0,
"Face must be from a local or a face neighbor element");
2730 auto add_quad_faces = [&
faces, &shared_faces, &v,
this]
2731 (
int elem,
int start,
int end,
const int fverts[][4])
2733 for (
int i = start; i < end; ++i)
2735 const int *
const fv = fverts[i];
2739 if (max < v[fv[1]]) { max = v[fv[1]], k = 1; }
2740 if (max < v[fv[2]]) { max = v[fv[2]], k = 2; }
2741 if (max < v[fv[3]]) { k = 3; }
2743 int v0 = -1, v1 = -1, v2 = -1;
2747 v0 = v[fv[1]]; v1 = v[fv[2]]; v2 = v[fv[3]];
2750 v0 = v[fv[0]]; v1 = v[fv[2]]; v2 = v[fv[3]];
2753 v0 = v[fv[0]]; v1 = v[fv[1]]; v2 = v[fv[3]];
2756 v0 = v[fv[0]]; v1 = v[fv[1]]; v2 = v[fv[2]];
2759 int lf =
faces->Index(v0, v1, v2);
2762 lf = shared_faces->Index(v0, v1, v2);
2800 MFEM_ABORT(
"Unexpected type of Element.");
2812 int nbr_lproc = (nbs[0]) ? nbs[0] : nbs[1];
2827 int el_nbr = i -
GetNE();
2834 MFEM_ABORT(
"ParMesh::GetFaceNbrElementFaces(...) : "
2835 "face_nbr_el_to_face not generated correctly.");
2844 MFEM_ABORT(
"ParMesh::GetFaceNbrElementFaces(...) : "
2845 "face_nbr_el_ori not generated correctly.");
2880 for (
int i = 0; i < s2l_face->
Size(); i++)
2895 for (
int i = 0; i < s2l_face->
Size(); i++)
2897 int lface = (*s2l_face)[i];
2898 int nbr_elem_idx = -1 -
faces_info[lface].Elem2No;
2927 const bool fill2 = mask & 10;
2965 MFEM_VERIFY(face_info.
Elem2Inf >= 0,
"The face must be shared.");
2983 FElTr.
Elem1 = &ElTr1;
2990 Elem2NbrNo = -1 - face_info.
Elem2No;
2997 FElTr.
Elem2 = &ElTr2;
3034 if (is_ghost || fill2)
3057 mfem::out <<
"\nInternal error: face id = " << FaceNo
3058 <<
", dist = " << dist <<
", rank = " <<
MyRank <<
'\n';
3060 MFEM_ABORT(
"internal error");
3083 "Mesh requires nodal Finite Element.");
3094 FElTr.
SetFE(face_el);
3124 for (
int j = 0; j < nv; j++)
3144 for (
int j = 0; j < n; j++)
3154 MFEM_ABORT(
"Nodes are not ParGridFunction!");
3177 MFEM_ASSERT(
Dim > 1,
"");
3196 MFEM_ASSERT(
Dim > 1,
"");
3199 return sface < csize
3201 : shared.
slaves[sface - csize].index;
3214void Rotate3Indirect(
int &
a,
int &
b,
int &c,
3217 if (order[
a] < order[
b])
3219 if (order[
a] > order[c])
3226 if (order[
b] < order[c])
3247 Table *old_elem_vert = NULL;
3270 svert_comm.
Bcast(svert_master_index);
3283 for (
int i = 0; i <
vertices.Size(); i++)
3285 int s = lvert_svert[i];
3288 glob_vert_order[i] =
3289 (std::int64_t(svert_master_rank[s]) << 32) + svert_master_index[s];
3293 glob_vert_order[i] = (std::int64_t(
MyRank) << 32) + i;
3305 int *v =
elements[i]->GetVertices();
3307 Rotate3Indirect(v[0], v[1], v[2], glob_vert_order);
3309 if (glob_vert_order[v[0]] < glob_vert_order[v[3]])
3311 Rotate3Indirect(v[1], v[2], v[3], glob_vert_order);
3325 int *v =
boundary[i]->GetVertices();
3327 Rotate3Indirect(v[0], v[1], v[2], glob_vert_order);
3331 const bool check_consistency =
true;
3332 if (check_consistency)
3339 for (
int i = 0; i < stria_flag.
Size(); i++)
3342 if (glob_vert_order[v[0]] < glob_vert_order[v[1]])
3344 stria_flag[i] = (glob_vert_order[v[0]] < glob_vert_order[v[2]]) ? 0 : 2;
3348 stria_flag[i] = (glob_vert_order[v[1]] < glob_vert_order[v[2]]) ? 1 : 2;
3353 stria_comm.
Bcast(stria_master_flag);
3354 for (
int i = 0; i < stria_flag.
Size(); i++)
3357 MFEM_VERIFY(stria_flag[i] == stria_master_flag[i],
3358 "inconsistent vertex ordering found, shared triangle "
3360 << v[0] <<
", " << v[1] <<
", " << v[2] <<
"), "
3361 <<
"local flag: " << stria_flag[i]
3362 <<
", master flag: " << stria_master_flag[i]);
3371 Rotate3Indirect(v[0], v[1], v[2], glob_vert_order);
3387 delete old_elem_vert;
3400 MFEM_ABORT(
"Local and nonconforming refinements cannot be mixed.");
3409 int uniform_refinement = 0;
3413 uniform_refinement = 1;
3424 for (
int i = 0; i < marked_el.
Size(); i++)
3430 for (
int i = 0; i < marked_el.
Size(); i++)
3439 for (
int i = 0; i < marked_el.
Size(); i++)
3456 int need_refinement;
3457 int max_faces_in_group = 0;
3463 face_splittings[i].
Reserve(faces_in_group);
3464 if (faces_in_group > max_faces_in_group)
3466 max_faces_in_group = faces_in_group;
3472 MPI_Request *requests =
new MPI_Request[
GetNGroups()-1];
3475#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3476 int ref_loops_all = 0, ref_loops_par = 0;
3480 need_refinement = 0;
3483 if (
elements[i]->NeedRefinement(v_to_v))
3485 need_refinement = 1;
3489#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3493 if (uniform_refinement)
3500 if (need_refinement == 0)
3502#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3506 const int tag = 293;
3515 if (faces_in_group == 0) {
continue; }
3517 face_splittings[i].
SetSize(0);
3518 for (
int j = 0; j < faces_in_group; j++)
3521 face_splittings[i]);
3525 MPI_Isend(face_splittings[i], face_splittings[i].Size(),
3526 MPI_UNSIGNED, neighbor, tag,
MyComm,
3527 &requests[req_count++]);
3535 if (faces_in_group == 0) {
continue; }
3539 MPI_Probe(neighbor, tag,
MyComm, &status);
3541 MPI_Get_count(&status, MPI_UNSIGNED, &count);
3543 MPI_Recv(iBuf, count, MPI_UNSIGNED, neighbor, tag,
MyComm,
3546 for (
int j = 0, pos = 0; j < faces_in_group; j++)
3553 int nr = need_refinement;
3554 MPI_Allreduce(&nr, &need_refinement, 1, MPI_INT, MPI_LOR,
MyComm);
3556 MPI_Waitall(req_count, requests, MPI_STATUSES_IGNORE);
3559 while (need_refinement == 1);
3561#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3563 int i = ref_loops_all;
3564 MPI_Reduce(&i, &ref_loops_all, 1, MPI_INT, MPI_MAX, 0,
MyComm);
3567 mfem::out <<
"\n\nParMesh::LocalRefinement : max. ref_loops_all = "
3568 << ref_loops_all <<
", ref_loops_par = " << ref_loops_par
3576 delete [] face_splittings;
3581 need_refinement = 0;
3584 if (
boundary[i]->NeedRefinement(v_to_v))
3586 need_refinement = 1;
3591 while (need_refinement == 1);
3596 " (NumOfBdrElements != boundary.Size())");
3623 int uniform_refinement = 0;
3627 uniform_refinement = 1;
3636 int *edge1 =
new int[nedges];
3637 int *edge2 =
new int[nedges];
3638 int *middle =
new int[nedges];
3640 for (
int i = 0; i < nedges; i++)
3642 edge1[i] = edge2[i] = middle[i] = -1;
3647 int *v =
elements[i]->GetVertices();
3648 for (
int j = 0; j < 3; j++)
3650 int ind = v_to_v(v[j], v[(j+1)%3]);
3651 (edge1[ind] == -1) ? (edge1[ind] = i) : (edge2[ind] = i);
3656 for (
int i = 0; i < marked_el.
Size(); i++)
3662 int need_refinement;
3663 int edges_in_group, max_edges_in_group = 0;
3665 int **edge_splittings =
new int*[
GetNGroups()-1];
3669 edge_splittings[i] =
new int[edges_in_group];
3670 if (edges_in_group > max_edges_in_group)
3672 max_edges_in_group = edges_in_group;
3675 int neighbor, *iBuf =
new int[max_edges_in_group];
3679 MPI_Request request;
3684#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3685 int ref_loops_all = 0, ref_loops_par = 0;
3689 need_refinement = 0;
3690 for (
int i = 0; i < nedges; i++)
3692 if (middle[i] != -1 && edge1[i] != -1)
3694 need_refinement = 1;
3698#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3702 if (uniform_refinement)
3709 if (need_refinement == 0)
3711#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3720 edges_in_group = group_edges.
Size();
3722 if (edges_in_group != 0)
3724 for (
int j = 0; j < edges_in_group; j++)
3726 edge_splittings[i][j] =
3739 MPI_Isend(edge_splittings[i], edges_in_group, MPI_INT,
3740 neighbor, 0,
MyComm, &request);
3748 edges_in_group = group_edges.
Size();
3749 if (edges_in_group != 0)
3760 MPI_Recv(iBuf, edges_in_group, MPI_INT, neighbor,
3761 MPI_ANY_TAG,
MyComm, &status);
3763 for (
int j = 0; j < edges_in_group; j++)
3765 if (iBuf[j] == 1 && edge_splittings[i][j] == 0)
3768 int ii = v_to_v(v[0], v[1]);
3769#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3770 if (middle[ii] != -1)
3772 mfem_error(
"ParMesh::LocalRefinement (triangles) : "
3776 need_refinement = 1;
3788 int nr = need_refinement;
3789 MPI_Allreduce(&nr, &need_refinement, 1, MPI_INT, MPI_LOR,
MyComm);
3792 while (need_refinement == 1);
3794#ifdef MFEM_DEBUG_PARMESH_LOCALREF
3796 int i = ref_loops_all;
3797 MPI_Reduce(&i, &ref_loops_all, 1, MPI_INT, MPI_MAX, 0,
MyComm);
3800 mfem::out <<
"\n\nParMesh::LocalRefinement : max. ref_loops_all = "
3801 << ref_loops_all <<
", ref_loops_par = " << ref_loops_par
3809 delete [] edge_splittings[i];
3811 delete [] edge_splittings;
3816 int v1[2], v2[2],
bisect, temp;
3818 for (
int i = 0; i < temp; i++)
3820 int *v =
boundary[i]->GetVertices();
3821 bisect = v_to_v(v[0], v[1]);
3822 if (middle[
bisect] != -1)
3827 v1[0] = v[0]; v1[1] = middle[
bisect];
3828 v2[0] = middle[
bisect]; v2[1] = v[1];
3835 mfem_error(
"Only bisection of segment is implemented for bdr"
3868 for (
int j = 0; j < marked_el.
Size(); j++)
3870 int i = marked_el[j];
3873 int new_v = cnv + j, new_e = cne + j;
3882 static real_t seg_children[3*2] = { 0.0,1.0, 0.0,0.5, 0.5,1.0 };
3884 UseExternalData(seg_children, 1, 2, 3);
3901 std::set<int> &conflicts)
const
3903 MFEM_VERIFY(
pncmesh,
"AnisotropicConflict should be called only for NCMesh");
3912 MFEM_ABORT(
"NURBS meshes are not supported. Please project the "
3913 "NURBS to Nodes first with SetCurvature().");
3918 MFEM_ABORT(
"Can't convert conforming ParMesh to nonconforming ParMesh "
3919 "(you need to initialize the ParMesh from a nonconforming "
3966 real_t threshold,
int nc_limit,
int op)
3968 MFEM_VERIFY(
pncmesh,
"Only supported for non-conforming meshes.");
3969 MFEM_VERIFY(!
NURBSext,
"Derefinement of NURBS meshes is not supported. "
3970 "Project the NURBS to Nodes first.");
3983 for (
int i = 0; i < dt.
Size(); i++)
3985 if (nc_limit > 0 && !level_ok[i]) {
continue; }
3990 if (error < threshold) { derefs.
Append(i); }
3994 if (!glob_size) {
return false; }
4041 MFEM_ABORT(
"Load balancing is currently not supported for conforming"
4049 != NULL,
"internal error");
4083 MFEM_ASSERT(
Dim == 2 &&
meshgen == 1,
"internal error");
4093 int *I_group_svert, *J_group_svert;
4094 int *I_group_sedge, *J_group_sedge;
4099 I_group_svert[0] = I_group_svert[1] = 0;
4100 I_group_sedge[0] = I_group_sedge[1] = 0;
4107 for (
int group = 0; group <
GetNGroups()-1; group++)
4117 const int ind = middle[v_to_v(v[0], v[1])];
4123 const int attr =
shared_edges[group_edges[i]]->GetAttribute();
4130 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
4131 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
4134 J = J_group_svert+I_group_svert[group];
4135 for (
int i = 0; i < group_verts.
Size(); i++)
4137 J[i] = group_verts[i];
4139 J = J_group_sedge+I_group_sedge[group];
4140 for (
int i = 0; i < group_edges.
Size(); i++)
4142 J[i] = group_edges[i];
4156 MFEM_ASSERT(
Dim == 3 &&
meshgen == 1,
"internal error");
4158 Array<int> group_verts, group_edges, group_trias;
4177 I_group_svert[0] = 0;
4178 I_group_sedge[0] = 0;
4179 I_group_stria[0] = 0;
4181 for (
int group = 0; group <
GetNGroups()-1; group++)
4192 int ind = v_to_v.
FindId(v[0], v[1]);
4193 if (ind == -1) {
continue; }
4196 const int attr =
shared_edges[group_edges[i]]->GetAttribute();
4206 ind = v_to_v.
FindId(v[0], ind);
4214 ind = v_to_v.
FindId(v[0], v[1]);
4235 while (sedge_stack.
Size() > 0);
4242 int ind = v_to_v.
FindId(v[0], v[1]);
4243 if (ind == -1) {
continue; }
4246 const int edge_attr = 1;
4255 v[1] = v[0]; v[0] = v[2]; v[2] = ind;
4256 ind = v_to_v.
FindId(v[0], v[1]);
4264 ind = v_to_v.
FindId(v[0], v[1]);
4282 v = sface_stack[sface_stack.
Size()-2].v;
4284 v[0] = v[1]; v[1] = v[2]; v[2] = ind;
4287 while (sface_stack.
Size() > 0);
4293 ind = v_to_v.
FindId(v[0], v[1]);
4314 while (sedge_stack.
Size() > 0);
4317 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
4318 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
4319 I_group_stria[group+1] = I_group_stria[group] + group_trias.
Size();
4321 J_group_svert.
Append(group_verts);
4322 J_group_sedge.
Append(group_edges);
4323 J_group_stria.
Append(group_trias);
4340 int *I_group_svert, *J_group_svert;
4341 int *I_group_sedge, *J_group_sedge;
4346 I_group_svert[0] = 0;
4347 I_group_sedge[0] = 0;
4354 for (
int group = 0; group <
GetNGroups()-1; group++)
4368 const int attr =
shared_edges[sedges[i]]->GetAttribute();
4374 I_group_svert[group+1] = I_group_svert[group] + sverts.
Size();
4375 I_group_sedge[group+1] = I_group_sedge[group] + sedges.
Size();
4377 sverts.
CopyTo(J_group_svert + I_group_svert[group]);
4378 sedges.
CopyTo(J_group_sedge + I_group_sedge[group]);
4394 Array<int> group_verts, group_edges, group_trias, group_quads;
4396 int *I_group_svert, *J_group_svert;
4397 int *I_group_sedge, *J_group_sedge;
4398 int *I_group_stria, *J_group_stria;
4399 int *I_group_squad, *J_group_squad;
4406 I_group_svert[0] = 0;
4407 I_group_sedge[0] = 0;
4408 I_group_stria[0] = 0;
4409 I_group_squad[0] = 0;
4421 const int oface = old_nv + old_nedges;
4423 for (
int group = 0; group <
GetNGroups()-1; group++)
4435 const int ind = old_nv + old_v_to_v(v[0], v[1]);
4439 const int attr =
shared_edges[group_edges[i]]->GetAttribute();
4449 const int stria = group_trias[i];
4452 m[0] = old_nv + old_v_to_v(v[0], v[1]);
4453 m[1] = old_nv + old_v_to_v(v[1], v[2]);
4454 m[2] = old_nv + old_v_to_v(v[2], v[0]);
4455 const int edge_attr = 1;
4470 v[1] = m[0]; v[2] = m[2];
4471 group_trias.
Append(nst+0);
4472 group_trias.
Append(nst+1);
4473 group_trias.
Append(nst+2);
4481 const int squad = group_quads[i];
4483 const int olf = old_faces(v[0], v[1], v[2], v[3]);
4485 m[0] = oface + (f2qf ? (*f2qf)[olf] : olf);
4489 m[1] = old_nv + old_v_to_v(v[0], v[1]);
4490 m[2] = old_nv + old_v_to_v(v[1], v[2]);
4491 m[3] = old_nv + old_v_to_v(v[2], v[3]);
4492 m[4] = old_nv + old_v_to_v(v[3], v[0]);
4493 const int edge_attr = 1;
4510 v[1] = m[1]; v[2] = m[0]; v[3] = m[4];
4511 group_quads.
Append(nsq+0);
4512 group_quads.
Append(nsq+1);
4513 group_quads.
Append(nsq+2);
4517 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
4518 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
4519 I_group_stria[group+1] = I_group_stria[group] + group_trias.
Size();
4520 I_group_squad[group+1] = I_group_squad[group] + group_quads.
Size();
4522 group_verts.
CopyTo(J_group_svert + I_group_svert[group]);
4523 group_edges.
CopyTo(J_group_sedge + I_group_sedge[group]);
4524 group_trias.
CopyTo(J_group_stria + I_group_stria[group]);
4525 group_quads.
CopyTo(J_group_squad + I_group_squad[group]);
4544 const bool update_nodes =
false;
4569 auto faces_tbl = std::unique_ptr<STable3D>(
GetFacesTable());
4574 const bool update_nodes =
false;
4583 f2qf.
Size() ? &f2qf : NULL);
4592 mfem::out <<
"\nParMesh::NURBSUniformRefinement : Not supported yet!\n";
4600 mfem::out <<
"\nParMesh::NURBSUniformRefinement : Not supported yet!\n";
4608 mfem::out <<
"\nRefineNURBSWithKVFactors : Not supported yet!\n";
4614 MFEM_ASSERT(
Dim ==
spaceDim,
"2D manifolds not supported");
4620 os <<
"NETGEN_Neutral_Format\n";
4625 for (j = 0; j <
Dim; j++)
4639 for (j = 0; j < nv; j++)
4641 os <<
" " << ind[j]+1;
4654 for (j = 0; j < nv; j++)
4656 os <<
" " << ind[j]+1;
4667 for (j = 0; j < 3; j++)
4669 os <<
' ' << ind[j]+1;
4683 <<
" 0 0 0 0 0 0 0\n"
4684 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
4686 <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
4687 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
4688 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
4694 <<
" " <<
vertices[i](2) <<
" 0.0\n";
4702 os << i+1 <<
" " <<
elements[i]->GetAttribute();
4703 for (j = 0; j < nv; j++)
4705 os <<
" " << ind[j]+1;
4716 for (j = 0; j < nv; j++)
4718 os <<
" " << ind[j]+1;
4720 os <<
" 1.0 1.0 1.0 1.0\n";
4731 for (j = 0; j < 4; j++)
4733 os <<
' ' << ind[j]+1;
4735 os <<
" 1.0 1.0 1.0 1.0\n";
4744 os <<
"areamesh2\n\n";
4751 attr =
boundary[i]->GetAttribute();
4754 for (j = 0; j < v.
Size(); j++)
4756 os << v[j] + 1 <<
" ";
4766 for (j = 0; j < v.
Size(); j++)
4768 os << v[j] + 1 <<
" ";
4777 attr =
elements[i]->GetAttribute();
4793 for (j = 0; j < v.
Size(); j++)
4795 os << v[j] + 1 <<
" ";
4804 for (j = 0; j <
Dim; j++)
4829 int shared_bdr_attr;
4846 s2l_face = &nc_shared_faces;
4853 for (
int i = 0; i < sfaces.
conforming.Size(); i++)
4858 for (
int i = 0; i < sfaces.
masters.Size(); i++)
4864 for (
int i = 0; i < sfaces.
slaves.Size(); i++)
4875 os << (!set_names ?
"MFEM mesh v1.0\n" :
"MFEM mesh v1.3\n");
4877 if (!comments.empty()) { os <<
'\n' << comments <<
'\n'; }
4881 "\n#\n# MFEM Geometry Types (see fem/geom.hpp):\n#\n"
4886 "# TETRAHEDRON = 4\n"
4891 os <<
"\ndimension\n" <<
Dim
4900 os <<
"\nattribute_sets\n";
4907 num_bdr_elems += s2l_face->
Size();
4909 os <<
"\nboundary\n" << num_bdr_elems <<
'\n';
4923 shared_bdr_attr =
MyRank + 1;
4925 for (
int i = 0; i < s2l_face->
Size(); i++)
4928 faces[(*s2l_face)[i]]->SetAttribute(shared_bdr_attr);
4935 os <<
"\nbdr_attribute_sets\n";
4962 os <<
"\nmfem_mesh_end" << endl;
4968 ostringstream fname_with_suffix;
4969 fname_with_suffix << fname <<
"." << setfill(
'0') << setw(6) <<
MyRank;
4970 ofstream ofs(fname_with_suffix.str().c_str());
4971 ofs.precision(precision);
4975#ifdef MFEM_USE_ADIOS2
4988 for (
int i = 0; i < nv; i++)
4996 int i, j, k,
p, nv_ne[2], &nv = nv_ne[0], &ne = nv_ne[1], vc;
5004 os <<
"MFEM mesh v1.0\n";
5006 if (!comments.empty()) { os <<
'\n' << comments <<
'\n'; }
5010 "\n#\n# MFEM Geometry Types (see fem/geom.hpp):\n#\n"
5015 "# TETRAHEDRON = 4\n"
5020 os <<
"\ndimension\n" <<
Dim;
5024 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5027 os <<
"\n\nelements\n" << ne <<
'\n';
5031 os << 1 <<
' ' <<
elements[i]->GetGeometryType();
5035 for (j = 0; j < nv; j++)
5044 MPI_Recv(nv_ne, 2, MPI_INT,
p, 444,
MyComm, &status);
5048 MPI_Recv(&ints[0], ne, MPI_INT,
p, 445,
MyComm, &status);
5050 for (i = 0; i < ne; )
5053 os <<
p+1 <<
' ' << ints[i];
5056 for (j = 0; j < k; j++)
5058 os <<
' ' << vc + ints[i++];
5071 ne += 1 +
elements[i]->GetNVertices();
5074 MPI_Send(nv_ne, 2, MPI_INT, 0, 444,
MyComm);
5082 MFEM_ASSERT(ints.
Size() == ne,
"");
5085 MPI_Send(&ints[0], ne, MPI_INT, 0, 445,
MyComm);
5098 ne += list.
conforming.Size() + list.masters.Size() + list.slaves.Size();
5110 dump_element(
boundary[i], ints); ne++;
5148 MFEM_ABORT(
"invalid dimension: " <<
Dim);
5155 for (i = 0; i < list.conforming.Size(); i++)
5157 int index = list.conforming[i].index;
5160 for (i = 0; i < list.masters.Size(); i++)
5162 int index = list.masters[i].index;
5165 for (i = 0; i < list.slaves.Size(); i++)
5167 int index = list.slaves[i].index;
5172 MPI_Reduce(&ne, &k, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5175 os <<
"\nboundary\n" << k <<
'\n';
5181 MPI_Recv(nv_ne, 2, MPI_INT,
p, 446,
MyComm, &status);
5193 for (i = 0; i < ne; )
5196 os <<
p+1 <<
' ' << ints[i];
5199 for (j = 0; j < k; j++)
5201 os <<
' ' << vc + ints[i++];
5212 MPI_Send(nv_ne, 2, MPI_INT, 0, 446,
MyComm);
5220 MPI_Reduce(
const_cast<int*
>(&
NumOfVertices), &nv, 1, MPI_INT, MPI_SUM, 0,
5224 os <<
"\nvertices\n" << nv <<
'\n';
5242 MPI_Recv(&nv, 1, MPI_INT,
p, 448,
MyComm, &status);
5249 for (i = 0; i < nv; i++)
5302 mfem_error(
"ParMesh::PrintAsOne : Nodes have no parallel info!");
5314 serialmesh.
Printer(os,
"", comments);
5323 MFEM_ABORT(
"Nonconforming meshes and NURBS meshes are not yet supported.");
5332 MFEM_VERIFY(
int(ne_glob_l) == ne_glob_l,
5333 "overflow in the number of elements!");
5334 int ne_glob = (save_rank ==
MyRank) ?
int(ne_glob_l) : 0;
5337 long long nvertices_glob_l = 0;
5338 MPI_Reduce(&nvertices, &nvertices_glob_l, 1, MPI_LONG_LONG, MPI_SUM,
5340 int nvertices_glob = int(nvertices_glob_l);
5341 MFEM_VERIFY(nvertices_glob == nvertices_glob_l,
5342 "overflow in the number of vertices!");
5345 long long nbe_glob_l = 0;
5346 MPI_Reduce(&nbe, &nbe_glob_l, 1, MPI_LONG_LONG, MPI_SUM, save_rank,
MyComm);
5347 int nbe_glob = int(nbe_glob_l);
5348 MFEM_VERIFY(nbe_glob == nbe_glob_l,
5349 "overflow in the number of boundary elements!");
5366 const int attr =
elements[e]->GetAttribute();
5367 const int geom_type =
elements[e]->GetGeometryType();
5369 for (
int j = 0; j < dofs.
Size(); j++)
5381 if (
p == save_rank) {
continue; }
5382 MPI_Recv(&n_send_recv, 1, MPI_INT,
p, 444,
MyComm, &status);
5386 MPI_Recv(&ints[0], n_send_recv, MPI_INT,
p, 445,
MyComm, &status);
5388 for (
int i = 0; i < n_send_recv; )
5390 int attr = ints[i++];
5391 int geom_type = ints[i++];
5404 n_send_recv += 2 +
elements[e]->GetNVertices();
5406 MPI_Send(&n_send_recv, 1, MPI_INT, save_rank, 444,
MyComm);
5411 const int attr =
elements[e]->GetAttribute();
5412 const int geom_type =
elements[e]->GetGeometryType();
5416 for (
int j = 0; j < dofs.
Size(); j++)
5423 MPI_Send(&ints[0], n_send_recv, MPI_INT, save_rank, 445,
MyComm);
5432 const int attr =
boundary[e]->GetAttribute();
5433 const int geom_type =
boundary[e]->GetGeometryType();
5435 for (
int j = 0; j < dofs.
Size(); j++)
5447 if (
p == save_rank) {
continue; }
5448 MPI_Recv(&n_send_recv, 1, MPI_INT,
p, 446,
MyComm, &status);
5452 MPI_Recv(&ints[0], n_send_recv, MPI_INT,
p, 447,
MyComm, &status);
5454 for (
int i = 0; i < n_send_recv; )
5456 int attr = ints[i++];
5457 int geom_type = ints[i++];
5472 MPI_Send(&n_send_recv, 1, MPI_INT, save_rank, 446,
MyComm);
5477 const int attr =
boundary[e]->GetAttribute();
5478 const int geom_type =
boundary[e]->GetGeometryType();
5482 for (
int j = 0; j < dofs.
Size(); j++)
5489 MPI_Send(&ints[0], n_send_recv, MPI_INT, save_rank, 447,
MyComm);
5495 for (
int v = 0; v < nvertices_glob; v++)
5516 serialmesh.
GetNodes()->MakeOwner(fec_serial);
5532 serialmesh.
GetNodes()->SetSubVector(dofs, nodeloc);
5538 for (
int i = 0; i < ints.
Size(); i++)
5544 vdata_serial[d] = vdata[d];
5552 if (
p == save_rank) {
continue; }
5553 MPI_Recv(&n_send_recv, 1, MPI_INT,
p, 448,
MyComm, &status);
5560 for (
int i = 0; i < n_send_recv; )
5565 serialmesh.
GetNodes()->SetSubVector(dofs, &vert[i]);
5571 for (
int j = 0; j < ints_serial.
Size(); j++)
5576 vdata_serial[d] = vert[i++];
5599 MPI_Send(&n_send_recv, 1, MPI_INT, save_rank, 448,
MyComm);
5607 for (
int j = 0; j < nodeloc.
Size(); j++)
5615 for (
int i = 0; i < ints.
Size(); i++)
5642 ofs.precision(precision);
5649 MFEM_ASSERT(
Dim ==
spaceDim,
"2D Manifolds not supported.");
5652 int i, j, k, nv, ne,
p;
5660 os <<
"NETGEN_Neutral_Format\n";
5663 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5667 for (j = 0; j <
Dim; j++)
5675 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
5679 for (i = 0; i < nv; i++)
5681 for (j = 0; j <
Dim; j++)
5683 os <<
" " << vert[
Dim*i+j];
5691 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5698 for (j = 0; j < nv; j++)
5700 os <<
" " << ind[j]+1;
5707 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
5708 MPI_Recv(&ne, 1, MPI_INT,
p, 446,
MyComm, &status);
5710 MPI_Recv(&ints[0], 4*ne, MPI_INT,
p, 447,
MyComm, &status);
5711 for (i = 0; i < ne; i++)
5714 for (j = 0; j < 4; j++)
5716 os <<
" " << k+ints[i*4+j]+1;
5724 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5732 for (j = 0; j < nv; j++)
5734 os <<
" " << ind[j]+1;
5745 for (j = 0; j < 3; j++)
5747 os <<
' ' << ind[j]+1;
5755 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
5756 MPI_Recv(&ne, 1, MPI_INT,
p, 446,
MyComm, &status);
5758 MPI_Recv(&ints[0], 3*ne, MPI_INT,
p, 447,
MyComm, &status);
5759 for (i = 0; i < ne; i++)
5762 for (j = 0; j < 3; j++)
5764 os <<
' ' << k+ints[i*3+j]+1;
5774 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5778 for (j = 0; j <
Dim; j++)
5786 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5793 for (j = 0; j < 4; j++)
5801 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5804 MPI_Send(&ne, 1, MPI_INT, 0, 446,
MyComm);
5809 for (j = 0; j < 3; j++)
5814 for ( ; i < ne; i++)
5817 for (j = 0; j < 3; j++)
5822 MPI_Send(&ints[0], 3*ne, MPI_INT, 0, 447,
MyComm);
5828 int i, j, k, nv, ne,
p;
5834 int TG_nv, TG_ne, TG_nbe;
5841 MPI_Reduce(&nv, &TG_nbe, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5844 <<
"1 " << TG_nv <<
" " << TG_ne <<
" 0 0 0 0 0 0 0\n"
5845 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
5846 <<
"0 0 " << TG_nbe <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
5847 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
5848 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
5855 <<
" " <<
vertices[i](2) <<
" 0.0\n";
5859 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
5863 for (i = 0; i < nv; i++)
5865 os << i+1 <<
" 0.0 " << vert[
Dim*i] <<
" " << vert[
Dim*i+1]
5866 <<
" " << vert[
Dim*i+2] <<
" 0.0\n";
5876 os << i+1 <<
" " << 1;
5877 for (j = 0; j < nv; j++)
5879 os <<
" " << ind[j]+1;
5886 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
5887 MPI_Recv(&ne, 1, MPI_INT,
p, 446,
MyComm, &status);
5889 MPI_Recv(&ints[0], 8*ne, MPI_INT,
p, 447,
MyComm, &status);
5890 for (i = 0; i < ne; i++)
5892 os << i+1 <<
" " <<
p+1;
5893 for (j = 0; j < 8; j++)
5895 os <<
" " << k+ints[i*8+j]+1;
5910 for (j = 0; j < nv; j++)
5912 os <<
" " << ind[j]+1;
5914 os <<
" 1.0 1.0 1.0 1.0\n";
5924 for (j = 0; j < 4; j++)
5926 os <<
' ' << ind[j]+1;
5928 os <<
" 1.0 1.0 1.0 1.0\n";
5933 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
5934 MPI_Recv(&ne, 1, MPI_INT,
p, 446,
MyComm, &status);
5936 MPI_Recv(&ints[0], 4*ne, MPI_INT,
p, 447,
MyComm, &status);
5937 for (i = 0; i < ne; i++)
5940 for (j = 0; j < 4; j++)
5942 os <<
" " << k+ints[i*4+j]+1;
5944 os <<
" 1.0 1.0 1.0 1.0\n";
5954 MPI_Reduce(&nv, &TG_nbe, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5959 for (j = 0; j <
Dim; j++)
5972 for (j = 0; j < 8; j++)
5981 MPI_Send(&ne, 1, MPI_INT, 0, 446,
MyComm);
5986 for (j = 0; j < 4; j++)
5991 for ( ; i < ne; i++)
5994 for (j = 0; j < 4; j++)
5999 MPI_Send(&ints[0], 4*ne, MPI_INT, 0, 447,
MyComm);
6005 int i, j, k, attr, nv, ne,
p;
6013 os <<
"areamesh2\n\n";
6017 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
6022 attr =
boundary[i]->GetAttribute();
6025 for (j = 0; j < v.
Size(); j++)
6027 os << v[j] + 1 <<
" ";
6037 for (j = 0; j < v.
Size(); j++)
6039 os << v[j] + 1 <<
" ";
6046 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
6047 MPI_Recv(&ne, 1, MPI_INT,
p, 446,
MyComm, &status);
6049 MPI_Recv(&ints[0], 2*ne, MPI_INT,
p, 447,
MyComm, &status);
6050 for (i = 0; i < ne; i++)
6053 for (j = 0; j < 2; j++)
6055 os <<
" " << k+ints[i*2+j]+1;
6064 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
6070 os << 1 <<
" " << 3 <<
" ";
6071 for (j = 0; j < v.
Size(); j++)
6073 os << v[j] + 1 <<
" ";
6080 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
6081 MPI_Recv(&ne, 1, MPI_INT,
p, 446,
MyComm, &status);
6083 MPI_Recv(&ints[0], 3*ne, MPI_INT,
p, 447,
MyComm, &status);
6084 for (i = 0; i < ne; i++)
6086 os <<
p+1 <<
" " << 3;
6087 for (j = 0; j < 3; j++)
6089 os <<
" " << k+ints[i*3+j]+1;
6098 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
6102 for (j = 0; j <
Dim; j++)
6110 MPI_Recv(&nv, 1, MPI_INT,
p, 444,
MyComm, &status);
6114 for (i = 0; i < nv; i++)
6116 for (j = 0; j <
Dim; j++)
6118 os <<
" " << vert[
Dim*i+j];
6128 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
6131 MPI_Send(&ne, 1, MPI_INT, 0, 446,
MyComm);
6136 for (j = 0; j < 2; j++)
6141 for ( ; i < ne; i++)
6144 for (j = 0; j < 2; j++)
6149 MPI_Send(&ints[0], 2*ne, MPI_INT, 0, 447,
MyComm);
6152 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
6159 for (j = 0; j < 3; j++)
6167 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
6171 for (j = 0; j <
Dim; j++)
6204 real_t h_min, h_max, kappa_min, kappa_max;
6222 real_t h_min, h_max, kappa_min, kappa_max, h,
kappa;
6226 os <<
"Parallel Mesh Stats:" <<
'\n';
6238 kappa_min = kappa_max =
kappa;
6242 if (h < h_min) { h_min = h; }
6243 if (h > h_max) { h_max = h; }
6244 if (
kappa < kappa_min) { kappa_min =
kappa; }
6245 if (
kappa > kappa_max) { kappa_max =
kappa; }
6249 real_t gh_min, gh_max, gk_min, gk_max;
6262 long long mindata[5], maxdata[5], sumdata[5];
6281 MPI_Reduce(ldata, mindata, 5, MPI_LONG_LONG, MPI_MIN, 0,
MyComm);
6282 MPI_Reduce(ldata, sumdata, 5, MPI_LONG_LONG, MPI_SUM, 0,
MyComm);
6283 MPI_Reduce(ldata, maxdata, 5, MPI_LONG_LONG, MPI_MAX, 0,
MyComm);
6289 << setw(12) <<
"minimum"
6290 << setw(12) <<
"average"
6291 << setw(12) <<
"maximum"
6292 << setw(12) <<
"total" <<
'\n';
6294 << setw(12) << mindata[0]
6295 << setw(12) << sumdata[0]/
NRanks
6296 << setw(12) << maxdata[0]
6297 << setw(12) << sumdata[0] <<
'\n';
6299 << setw(12) << mindata[1]
6300 << setw(12) << sumdata[1]/
NRanks
6301 << setw(12) << maxdata[1]
6302 << setw(12) << sumdata[1] <<
'\n';
6306 << setw(12) << mindata[2]
6307 << setw(12) << sumdata[2]/
NRanks
6308 << setw(12) << maxdata[2]
6309 << setw(12) << sumdata[2] <<
'\n';
6312 << setw(12) << mindata[3]
6313 << setw(12) << sumdata[3]/
NRanks
6314 << setw(12) << maxdata[3]
6315 << setw(12) << sumdata[3] <<
'\n';
6317 << setw(12) << mindata[4]
6318 << setw(12) << sumdata[4]/
NRanks
6319 << setw(12) << maxdata[4] <<
'\n';
6322 << setw(12) <<
"minimum"
6323 << setw(12) <<
"maximum" <<
'\n';
6325 << setw(12) << gh_min
6326 << setw(12) << gh_max <<
'\n';
6328 << setw(12) << gk_min
6329 << setw(12) << gk_max <<
'\n';
6336 long long local = value, global;
6337 MPI_Allreduce(&local, &global, 1, MPI_LONG_LONG, MPI_SUM,
MyComm);
6346 Print(os, comments);
6360 Printer(os,
"mfem_serial_mesh_end", comments);
6368 os <<
"total_shared_edges " <<
shared_edges.Size() <<
'\n';
6374 os <<
"\n# group 0 has no shared entities\n";
6380 os <<
"\n# group " << gr <<
"\nshared_vertices " << nv <<
'\n';
6381 for (
int i = 0; i < nv; i++)
6390 os <<
"\nshared_edges " << ne <<
'\n';
6391 for (
int i = 0; i < ne; i++)
6394 os << v[0] <<
' ' << v[1] <<
'\n';
6403 os <<
"\nshared_faces " << nt+nq <<
'\n';
6404 for (
int i = 0; i < nt; i++)
6408 for (
int j = 0; j < 3; j++) { os <<
' ' << v[j]; }
6411 for (
int i = 0; i < nq; i++)
6415 for (
int j = 0; j < 4; j++) { os <<
' ' << v[j]; }
6422 os <<
"\nmfem_mesh_end" << endl;
6427 bool high_order_output,
6428 int compression_level,
6431 int pad_digits_rank = 6;
6434 std::string::size_type pos = pathname.find_last_of(
'/');
6436 = (pos == std::string::npos) ? pathname : pathname.substr(pos+1);
6440 std::string pvtu_name = pathname +
"/" + fname +
".pvtu";
6441 std::ofstream os(pvtu_name);
6444 std::string data_format = (format ==
VTKFormat::ASCII) ?
"ascii" :
"binary";
6446 os <<
"<?xml version=\"1.0\"?>\n";
6447 os <<
"<VTKFile type=\"PUnstructuredGrid\"";
6448 os <<
" version =\"2.2\" byte_order=\"" <<
VTKByteOrder() <<
"\">\n";
6449 os <<
"<PUnstructuredGrid GhostLevel=\"0\">\n";
6451 os <<
"<PPoints>\n";
6452 os <<
"\t<PDataArray type=\"" << data_type <<
"\" ";
6453 os <<
" Name=\"Points\" NumberOfComponents=\"3\""
6454 <<
" format=\"" << data_format <<
"\"/>\n";
6455 os <<
"</PPoints>\n";
6458 os <<
"\t<PDataArray type=\"Int32\" ";
6459 os <<
" Name=\"connectivity\" NumberOfComponents=\"1\""
6460 <<
" format=\"" << data_format <<
"\"/>\n";
6461 os <<
"\t<PDataArray type=\"Int32\" ";
6462 os <<
" Name=\"offsets\" NumberOfComponents=\"1\""
6463 <<
" format=\"" << data_format <<
"\"/>\n";
6464 os <<
"\t<PDataArray type=\"UInt8\" ";
6465 os <<
" Name=\"types\" NumberOfComponents=\"1\""
6466 <<
" format=\"" << data_format <<
"\"/>\n";
6467 os <<
"</PCells>\n";
6469 os <<
"<PCellData>\n";
6470 os <<
"\t<PDataArray type=\"Int32\" Name=\"" <<
"attribute"
6471 <<
"\" NumberOfComponents=\"1\""
6472 <<
" format=\"" << data_format <<
"\"/>\n";
6473 os <<
"</PCellData>\n";
6475 for (
int ii=0; ii<
NRanks; ii++)
6477 std::string piece = fname +
".proc"
6479 os <<
"<Piece Source=\"" << piece <<
"\"/>\n";
6482 os <<
"</PUnstructuredGrid>\n";
6483 os <<
"</VTKFile>\n";
6487 std::string vtu_fname = pathname +
"/" + fname +
".proc"
6489 Mesh::PrintVTU(vtu_fname, format, high_order_output, compression_level,
6497 const int npts = point_mat.
Width();
6498 if (npts == 0) {
return 0; }
6500 const bool no_warn =
false;
6507 Array<int> my_point_rank(npts), glob_point_rank(npts);
6508 for (
int k = 0; k < npts; k++)
6510 my_point_rank[k] = (elem_id[k] == -1) ?
NRanks :
MyRank;
6513 MPI_Allreduce(my_point_rank.GetData(), glob_point_rank.
GetData(), npts,
6514 MPI_INT, MPI_MIN,
MyComm);
6517 for (
int k = 0; k < npts; k++)
6519 if (glob_point_rank[k] ==
NRanks) { elem_id[k] = -1; }
6523 if (glob_point_rank[k] !=
MyRank) { elem_id[k] = -2; }
6526 if (warn && pts_found != npts &&
MyRank == 0)
6528 MFEM_WARNING((npts-pts_found) <<
" points were not found");
6533static void PrintVertex(
const Vertex &v,
int space_dim, ostream &os)
6536 for (
int d = 1; d < space_dim; d++)
6544 stringstream out_name;
6545 out_name << fname_prefix <<
'_' << setw(5) << setfill(
'0') <<
MyRank
6546 <<
".shared_entities";
6547 ofstream os(out_name.str().c_str());
6555 os <<
"total_shared_edges " <<
shared_edges.Size() <<
'\n';
6566 os <<
"\n# group " << gr <<
"\n\nshared_vertices " << nv <<
'\n';
6567 for (
int i = 0; i < nv; i++)
6579 os <<
"\nshared_edges " << ne <<
'\n';
6580 for (
int i = 0; i < ne; i++)
6596 os <<
"\nshared_faces " << nt+nq <<
'\n';
6597 for (
int i = 0; i < nt; i++)
6602 for (
int j = 0; j < 3; j++) { os <<
' ' << v[j]; }
6605 for (
int j = 0; j < 3; j++)
6608 (j < 2) ? os <<
" | " : os <<
'\n';
6611 for (
int i = 0; i < nq; i++)
6616 for (
int j = 0; j < 4; j++) { os <<
' ' << v[j]; }
6619 for (
int j = 0; j < 4; j++)
6622 (j < 3) ? os <<
" | " : os <<
'\n';
6638 for (
int i=0; i<
GetNV(); ++i)
6663 const int ldof = (dofs[0] >= 0) ? dofs[0] : -1 - dofs[0];
6691 const int ldof = (dofs[0] >= 0) ? dofs[0] : -1 - dofs[0];
6704 for (
int i=0; i<
GetNE(); ++i)
6721 MFEM_VERIFY(bdr_marker.
Size() >= max_bdr_attr,
6722 "bdr_marker must be at least bdr_attriburtes.Max() in length");
6727 Array<bool> interior_bdr(max_bdr_attr); interior_bdr =
false;
6728 Array<bool> exterior_bdr(max_bdr_attr); exterior_bdr =
false;
6732 for (
int be = 0; be <
boundary.Size(); be++)
6734 const int bea =
boundary[be]->GetAttribute();
6736 if (bdr_marker[bea-1] != 0)
6740 if (ext_face_marker[
f] > 0)
6742 exterior_bdr[bea-1] =
true;
6746 interior_bdr[bea-1] =
true;
6755 MFEM_MPI_CXX_BOOL, MPI_LOR,
MyComm);
6757 MFEM_MPI_CXX_BOOL, MPI_LOR,
MyComm);
6761 for (
int b = 0;
b < max_bdr_attr;
b++)
6763 if (bdr_marker[
b] != 0 && glb_interior_bdr[
b])
6765 if (!excl || !glb_exterior_bdr[
b])
6777 MFEM_VERIFY(bdr_marker.
Size() >= max_bdr_attr,
6778 "bdr_marker must be at least bdr_attriburtes.Max() in length");
6783 Array<bool> interior_bdr(max_bdr_attr); interior_bdr =
false;
6784 Array<bool> exterior_bdr(max_bdr_attr); exterior_bdr =
false;
6788 for (
int be = 0; be <
boundary.Size(); be++)
6790 const int bea =
boundary[be]->GetAttribute();
6794 if (ext_face_marker[
f] > 0)
6796 exterior_bdr[bea-1] =
true;
6800 interior_bdr[bea-1] =
true;
6808 MFEM_MPI_CXX_BOOL, MPI_LOR,
MyComm);
6810 MFEM_MPI_CXX_BOOL, MPI_LOR,
MyComm);
6814 for (
int b = 0;
b < max_bdr_attr;
b++)
6816 if (bdr_marker[
b] == 0 && glb_exterior_bdr[
b])
6818 if (!excl || !glb_interior_bdr[
b])
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void LoseData()
NULL-ifies the data.
int Size() const
Return the logical size of the array.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
void DeleteAll()
Delete the whole array.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
T * GetData()
Returns the data.
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
void CopyTo(U *dest)
STL-like copyTo dest from begin to end.
void DeleteLast()
Delete the last entry of the array.
T & Last()
Return the last element in the array.
bool SetsExist() const
Return true if any named sets are currently defined.
void Print(std::ostream &out=mfem::out, int width=-1) const
Print the contents of the container to an output stream.
void Copy(AttributeSets ©) const
Create a copy of the internal data to the provided copy.
@ GaussLobatto
Closed type.
int NumberOfEntries() const
static int create_directory(const std::string &dir_name, const Mesh *mesh, int myid)
Data type dense matrix using column-major storage.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
real_t CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
Abstract data type element.
virtual MFEM_DEPRECATED int GetNFaces(int &nFaceVertices) const =0
Geometry::Type GetGeometryType() const
virtual Element * Duplicate(Mesh *m) const =0
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
void SetAttribute(const int attr)
Set element's attribute.
virtual Type GetType() const =0
Returns element's type.
Type
Constants for the classes derived from Element.
int GetAttribute() const
Return element's attribute.
virtual int GetNVertices() const =0
virtual void SetVertices(const Array< int > &v)=0
Set the indices defining the vertices.
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name.
virtual const char * Name() const
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
void GetVertexDofs(int i, Array< int > &dofs) const
Returns the indices of the degrees of freedom for the specified vertices.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indices of degrees of freedom for the i'th element. The returned indices are offsets into an ...
virtual const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement in the FiniteElementCollection associated with i'th element in t...
Ordering::Type GetOrdering() const
Return the ordering method.
int GetEdgeDofs(int edge, Array< int > &dofs, int variant=0) const
Returns the indices of the degrees of freedom for the specified edge, including the DOFs for the vert...
const FiniteElement * GetTraceElement(int i, Geometry::Type geom_type) const
Return the trace element from element 'i' to the given 'geom_type'.
const FiniteElementCollection * FEColl() const
int GetVDim() const
Returns the vector dimension of the finite element space.
Abstract class for all finite elements.
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
static const int NumVerts[NumGeom]
const IntegrationRule * GetVertices(int GeomType) const
Return an IntegrationRule consisting of all vertices of the given Geometry::Type, GeomType.
FiniteElementCollection * OwnFEC()
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
void MakeOwner(FiniteElementCollection *fec_)
Make the GridFunction the owner of fec_owned and fes.
virtual void GetElementDofValues(int el, Vector &dof_vals) const
FiniteElementSpace * FESpace()
void GetVectorValues(int i, const IntegrationRule &ir, DenseMatrix &vals, DenseMatrix &tr) const
Communicator performing operations within groups defined by a GroupTopology with arbitrary-size data ...
Table & GroupLDofTable()
Fill-in the returned Table reference to initialize the GroupCommunicator then call Finalize().
void Bcast(T *ldata, int layout) const
Broadcast within each group where the master is the root.
void Finalize()
Allocate internal buffers after the GroupLDofTable is defined.
int GetNeighborRank(int i) const
Return the MPI rank of neighbor 'i'.
bool IAmMaster(int g) const
Return true if I am master for group 'g'.
void Swap(GroupTopology &other)
Swap the internal data with another GroupTopology object.
void Save(std::ostream &out) const
Save the data in a stream.
const int * GetGroup(int g) const
Return a pointer to a list of neighbors for a given group. Neighbor 0 is the local processor.
int GetGroupSize(int g) const
Get the number of processors in a group.
void Load(std::istream &in)
Load the data from a stream.
int GetGroupMasterRank(int g) const
Return the rank of the group master for group 'g'.
void Create(ListOfIntegerSets &groups, int mpitag)
Set up the group topology given the list of sets of shared entities.
int GetNumNeighbors() const
Return the number of neighbors including the local processor.
Arbitrary order H1-conforming (continuous) finite elements.
int DofForGeometry(Geometry::Type GeomType) const override
const int * GetDofMap(Geometry::Type GeomType) const
Get the Cartesian to local H1 dof map.
int GetId(int p1, int p2)
Get the "id" of the item whose parents are p1, p2, this "id" corresponding to the index of the item i...
int FindId(int p1, int p2) const
Find the "id" of an item whose parents are p1, p2. Return -1 if it does not exist.
void Recreate(const int n, const int *p)
Create an integer set from C-array 'p' of 'n' integers. Overwrites any existing set data.
Class for an integration rule - an Array of IntegrationPoint.
int GetNPoints() const
Returns the number of the points in the integration rule.
Arbitrary order "L2-conforming" discontinuous finite elements.
int Insert(const IntegerSet &s)
Check to see if set 's' is in the list. If not append it to the end of the list. Returns the index of...
int Size() const
Return the number of integer sets in the list.
Class used by MFEM to store pointers to host and/or device memory.
int CheckElementOrientation(bool fix_it=true)
Check (and optionally attempt to fix) the orientation of the elements.
void GetEdgeOrdering(const DSTable &v_to_v, Array< int > &order)
void GetLocalFaceTransformation(int face_type, int elem_type, IsoparametricTransformation &Transf, int info) const
A helper method that constructs a transformation from the reference space of a face to the reference ...
void SetVerticesFromNodes(const GridFunction *nodes)
Helper to set vertex coordinates given a high-order curvature function.
int GetElementToEdgeTable(Table &)
Element * NewElement(int geom)
IsoparametricTransformation Transformation2
int GetNEdges() const
Return the number of edges.
void GetBdrElementFace(int i, int *f, int *o) const
static void PrintElement(const Element *el, std::ostream &os)
Array< FaceInfo > faces_info
CoarseFineTransformations CoarseFineTr
void GetElementJacobian(int i, DenseMatrix &J, const IntegrationPoint *ip=NULL)
int AddBdrElement(Element *elem)
virtual FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void RedRefinement(int i, const DSTable &v_to_v, int *edge1, int *edge2, int *middle)
NURBSExtension * NURBSext
Optional NURBS mesh extension.
virtual void GetExteriorFaceMarker(Array< int > &face_marker) const
Populate a marker array identifying exterior faces.
static FiniteElement * GetTransformationFEforElementType(Element::Type)
Return FiniteElement for reference element of the specified type.
static int GetQuadOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Element::Type GetElementType(int i) const
Returns the type of element i.
void BdrBisection(int i, const HashTable< Hashed2 > &)
Bisect a boundary triangle: boundary element with index i is bisected.
Element::Type GetBdrElementType(int i) const
Returns the type of boundary element i.
const Table & ElementToEdgeTable() const
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
Geometry::Type GetFaceGeometry(int i) const
Return the Geometry::Type associated with face i.
void MakeHigherOrderSimplicial_(const Mesh &orig_mesh, const Array< int > &parent_elements)
Helper function for constructing higher order nodes from a mesh transformed into simplices....
int GetAttribute(int i) const
Return the attribute of element i.
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
void UniformRefinement3D_base(Array< int > *f2qf=NULL, DSTable *v_to_v_p=NULL, bool update_nodes=true)
Array< NCFaceInfo > nc_faces_info
Array< int > MakeSimplicial_(const Mesh &orig_mesh, int *vglobal)
Internal helper user in MakeSimplicial (and ParMesh::MakeSimplicial). Optional return is used in asse...
void MakeRefined_(Mesh &orig_mesh, const Array< int > &ref_factors, int ref_type)
Internal function used in Mesh::MakeRefined.
real_t GetLength(int i, int j) const
Return the length of the segment from node i to node j.
const FiniteElementSpace * GetNodalFESpace() const
void Loader(std::istream &input, int generate_edges=0, std::string parse_tag="")
void GenerateNCFaceInfo()
void ApplyLocalSlaveTransformation(FaceElementTransformations &FT, const FaceInfo &fi, bool is_ghost) const
real_t AggregateError(const Array< real_t > &elem_error, const int *fine, int nfine, int op)
Derefinement helper.
void DoNodeReorder(DSTable *old_v_to_v, Table *old_elem_vert)
bool Nonconforming() const
AttributeSets bdr_attribute_sets
Named sets of boundary element attributes.
int GetBdrElementFaceIndex(int be_idx) const
Return the local face (codimension-1) index for the given boundary element index.
void GetVertices(Vector &vert_coord) const
void InitFromNCMesh(const NCMesh &ncmesh)
Initialize vertices/elements/boundary/tables from a nonconforming mesh.
virtual int GetNFbyType(FaceType type) const
Returns the number of faces according to the requested type, does not count master nonconforming face...
const Element * GetElement(int i) const
Return pointer to the i'th element object.
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.
ElementTransformation * GetFaceTransformation(int FaceNo)
Returns a pointer to the transformation defining the given face element.
void FinalizeTopology(bool generate_bdr=true)
Finalize the construction of the secondary topology (connectivity) data of a Mesh.
virtual void Print(std::ostream &os=mfem::out, const std::string &comments="") const
Print the mesh to the given stream using the default MFEM mesh format.
void PrepareNodeReorder(DSTable **old_v_to_v, Table **old_elem_vert)
int AddVertex(real_t x, real_t y=0.0, real_t z=0.0)
int GetNE() const
Returns number of elements.
const Element * GetFace(int i) const
Return pointer to the i'th face element object.
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
Returns the minimum and maximum corners of the mesh bounding box.
int Dimension() const
Dimension of the reference space used within the elements.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
void GreenRefinement(int i, const DSTable &v_to_v, int *edge1, int *edge2, int *middle)
void UpdateNodes()
Update the nodes of a curved mesh after the topological part of a Mesh::Operation,...
real_t GetElementSize(int i, int type=0)
Get the size of the i-th element relative to the perfect reference element.
int AddElement(Element *elem)
void GetElementTransformation(int i, IsoparametricTransformation *ElTr) const
Builds the transformation defining the i-th element in ElTr. ElTr must be allocated in advance and wi...
STable3D * GetElementToFaceTable(int ret_ftbl=0)
void GetFaceElements(int Face, int *Elem1, int *Elem2) const
void Printer(std::ostream &os=mfem::out, std::string section_delimiter="", const std::string &comments="") const
If NURBS mesh, write NURBS format. If NCMesh, write mfem v1.1 format. If section_delimiter is empty,...
IsoparametricTransformation Transformation
void GetElementFaces(int i, Array< int > &faces, Array< int > &ori) const
Return the indices and the orientations of all faces of element i.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
void GetCharacteristics(real_t &h_min, real_t &h_max, real_t &kappa_min, real_t &kappa_max, Vector *Vh=NULL, Vector *Vk=NULL)
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
virtual void SetAttributes(bool elem_attrs_changed=true, bool bdr_face_attrs_changed=true)
Determine the sets of unique attribute values in domain if elem_attrs_changed and boundary elements i...
void GetNodes(Vector &node_coord) const
AttributeSets attribute_sets
Named sets of element attributes.
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 PrintVTU(std::ostream &os, int ref=1, VTKFormat format=VTKFormat::ASCII, bool high_order_output=false, int compression_level=0, bool bdr_elements=false)
Element::Type GetFaceElementType(int Face) const
int CheckBdrElementOrientation(bool fix_it=true)
Check the orientation of the boundary elements.
void AverageVertices(const int *indexes, int n, int result)
Averages the vertices with given indexes and saves the result in vertices[result].
void Swap(Mesh &other, bool non_geometry)
void Bisection(int i, const DSTable &, int *, int *, int *)
Bisect a triangle: element with index i is bisected.
void UniformRefinement2D_base(bool update_nodes=true)
virtual void SetNodalFESpace(FiniteElementSpace *nfes)
int GetNBE() const
Returns number of boundary elements.
long long GetGlobalNE() const
Return the total (global) number of elements.
virtual void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
virtual int FindPoints(DenseMatrix &point_mat, Array< int > &elem_ids, Array< IntegrationPoint > &ips, bool warn=true, InverseElementTransformation *inv_trans=NULL)
Find the ids of the elements that contain the given points, and their corresponding reference coordin...
bool IsSlaveFace(const FaceInfo &fi) const
void FreeElement(Element *E)
Array< Element * > boundary
NCMesh * ncmesh
Optional nonconforming mesh extension.
void NewNodes(GridFunction &nodes, bool make_owner=false)
Replace the internal node GridFunction with the given GridFunction.
GridFunction * GetNodes()
Return a pointer to the internal node GridFunction (may be NULL).
STable3D * GetFacesTable()
void SetMeshGen()
Determine the mesh generator bitmask meshgen, see MeshGenerator().
FaceElementTransformations FaceElemTr
void GetVertexToVertexTable(DSTable &) const
Geometry::Type GetElementBaseGeometry(int i) const
Table * GetVertexToElementTable()
void InitRefinementTransforms()
int * GeneratePartitioning(int nparts, int part_method=1)
Array< Element * > elements
Array< int > attributes
A list of all unique element attributes used by the Mesh.
const real_t * GetVertex(int i) const
Return pointer to vertex i's coordinates.
void OnMeshUpdated(Mesh *mesh)
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
const Table & GetDerefinementTable()
Arbitrary order H(curl)-conforming Nedelec finite elements.
Class for standard nodal finite elements.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Abstract parallel finite element space.
void GetSharedTriangleDofs(int group, int fi, Array< int > &dofs) const
void GetSharedEdgeDofs(int group, int ei, Array< int > &dofs) const
int GetTrueVSize() const override
Return the number of local vector true dofs.
const FiniteElement * GetFaceNbrFE(int i, int ndofs=0) const
void GetFaceNbrElementVDofs(int i, Array< int > &vdofs, DofTransformation &doftrans) const
int GetFaceDofs(int i, Array< int > &dofs, int variant=0) const override
void GetSharedQuadrilateralDofs(int group, int fi, Array< int > &dofs) const
void GetElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetElementDofs(), but with a user-provided DofTransformation object.
HYPRE_BigInt GetGlobalTDofNumber(int ldof) const
Returns the global tdof number of the given local degree of freedom.
void GetBdrElementDofs(int i, Array< int > &dofs, DofTransformation &doftrans) const override
The same as GetBdrElementDofs(), but with a user-provided DofTransformation object.
Class for parallel grid function.
void ExchangeFaceNbrData()
ParFiniteElementSpace * ParFESpace() const
void SaveAsOne(const char *fname, int precision=16) const
Class for parallel meshes.
Mesh GetSerialMesh(int save_rank) const
void GetCharacteristics(real_t &h_min, real_t &h_max, real_t &kappa_min, real_t &kappa_max)
void NonconformingRefinement(const Array< Refinement > &refinements, int nc_limit=0) override
This function is not public anymore. Use GeneralRefinement instead.
int GroupNQuadrilaterals(int group) const
ElementTransformation * GetFaceNbrElementTransformation(int FaceNo)
Returns a pointer to the transformation defining the i-th face neighbor.
void GetFaceSplittings(const int *fv, const HashTable< Hashed2 > &v_to_v, Array< unsigned > &codes)
Append codes identifying how the given face has been split to codes.
Table send_face_nbr_elements
Array< int > face_nbr_vertices_offset
void BuildVertexGroup(int ngroups, const Table &vert_element)
void NURBSUniformRefinement(int rf=2, real_t tol=1.0e-12) override
Refine NURBS mesh, with an optional refinement factor.
void SetAttributes(bool elem_attrs_changed=true, bool bdr_attrs_changed=true) override
Determine the sets of unique attribute values in domain if elem_attrs_changed and boundary elements i...
void PrintXG(std::ostream &out=mfem::out) const override
Array< Element * > shared_edges
int GetEdgeSplittings(Element *edge, const DSTable &v_to_v, int *middle)
Return a number(0-1) identifying how the given edge has been split.
void RefineGroups(const DSTable &v_to_v, int *middle)
Update the groups after triangle refinement.
void ParPrint(std::ostream &out, const std::string &comments="") const
void GetSharedTriCommunicator(int ordering, GroupCommunicator &stria_comm) const
Get the shared face triangles GroupCommunicator.
bool NonconformingDerefinement(Array< real_t > &elem_error, real_t threshold, int nc_limit=0, int op=1) override
NC version of GeneralDerefinement.
int GetNSharedFaces() const
Return the number of shared faces (3D), edges (2D), vertices (1D)
void SaveAsOne(const std::string &fname, int precision=16) const
void ExchangeFaceNbrData()
void BuildEdgeGroup(int ngroups, const Table &edge_element)
Table group_svert
Shared objects in each group.
MFEM_DEPRECATED void ReorientTetMesh() override
See the remarks for the serial version in mesh.hpp.
int GroupVertex(int group, int i) const
Accessors for entities within a shared group structure.
void UniformRefinement2D() override
Refine a mixed 2D mesh uniformly.
bool WantSkipSharedMaster(const NCMesh::Master &master) const
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31) override
void BuildSharedVertMapping(int nvert, const Table *vert_element, const Array< int > &vert_global_local)
long long GetGlobalElementNum(int local_element_num) const
Map a local element number to a global element number.
bool AnisotropicConflict(const Array< Refinement > &refinements, std::set< int > &conflicts) const
Return true if the input array of refinements to be performed would result in conflicting anisotropic...
Table * GetFaceToAllElementTable() const
void GetGlobalElementIndices(Array< HYPRE_BigInt > &gi) const
AMR meshes are supported.
void AddTriFaces(const Array< int > &v, const std::unique_ptr< STable3D > &faces, const std::unique_ptr< STable3D > &shared_faces, int elem, int start, int end, const int fverts[][N])
Helper function for adding triangle face neighbor element to face table entries. Have to use a templa...
void FindSharedFaces(const Mesh &mesh, const int *partition, Array< int > &face_group, ListOfIntegerSets &groups)
long long glob_elem_offset
void GetSharedEdgeCommunicator(int ordering, GroupCommunicator &sedge_comm) const
Get the shared edges GroupCommunicator.
void PrintInfo(std::ostream &out=mfem::out) override
Print various parallel mesh stats.
int GetNFbyType(FaceType type) const override
Returns the number of local faces according to the requested type, does not count master non-conformi...
void GetGlobalVertexIndices(Array< HYPRE_BigInt > &gi) const
AMR meshes are not supported.
bool HasBoundaryElements() const override
Checks if any rank in the mesh has boundary elements.
void LocalRefinement(const Array< int > &marked_el, int type=3) override
This function is not public anymore. Use GeneralRefinement instead.
void GetFaceNbrElementFaces(int i, Array< int > &faces, Array< int > &orientation) const
void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1) override
Set the curvature of the mesh nodes using the given polynomial degree.
long glob_offset_sequence
int GetLocalElementNum(long long global_element_num) const
void MarkExternalBoundaries(Array< int > &bdr_marker, bool excl=true) const override
Mark boundary attributes of external boundaries.
int FindPoints(DenseMatrix &point_mat, Array< int > &elem_ids, Array< IntegrationPoint > &ips, bool warn=true, InverseElementTransformation *inv_trans=NULL) override
Find the ids of the elements that contain the given points, and their corresponding reference coordin...
void GetSharedQuadCommunicator(int ordering, GroupCommunicator &squad_comm) const
Get the shared face quadrilaterals GroupCommunicator.
void BuildFaceNbrElementToFaceTable()
void MakeRefined_(ParMesh &orig_mesh, int ref_factor, int ref_type)
Internal function used in ParMesh::MakeRefined (and related constructor)
void GetGlobalFaceIndices(Array< HYPRE_BigInt > &gi) const
AMR meshes are not supported.
Array< Vertex > face_nbr_vertices
void UniformRefineGroups2D(int old_nv)
void GetGlobalEdgeIndices(Array< HYPRE_BigInt > &gi) const
AMR meshes are not supported.
void ExchangeFaceNbrNodes()
void SetNodalFESpace(FiniteElementSpace *nfes) override
void UniformRefinement3D() override
Refine a mixed 3D mesh uniformly.
void PrintVTU(std::string pathname, VTKFormat format=VTKFormat::ASCII, bool high_order_output=false, int compression_level=0, bool bdr_elements=false) override
long long ReduceInt(int value) const override
Utility function: sum integers from all processors (Allreduce).
Table send_face_nbr_vertices
ParMesh()
Default constructor. Create an empty ParMesh.
void GetExteriorFaceMarker(Array< int > &face_marker) const override
Populate a marker array identifying exterior faces.
int BuildLocalElements(const Mesh &global_mesh, const int *partitioning, const Array< int > &vert_global_local)
Fills out partitioned Mesh::elements.
bool DecodeFaceSplittings(HashTable< Hashed2 > &v_to_v, const int *v, const Array< unsigned > &codes, int &pos)
static ParMesh MakeSimplicial(ParMesh &orig_mesh)
Array< Vert4 > shared_quads
void LoadSharedEntities(std::istream &input)
void Finalize(bool refine=false, bool fix_orientation=false) override
Finalize the construction of a general Mesh.
void BuildFaceGroup(int ngroups, const Mesh &mesh, const Array< int > &face_group, int &nstria, int &nsquad)
void BuildSharedEdgeElems(int nedges, Mesh &mesh, const Array< int > &vert_global_local, const Table *edge_element)
Array< int > svert_lvert
Shared to local index mapping.
Array< Element * > face_nbr_elements
FaceElementTransformations * GetSharedFaceTransformationsByLocalIndex(int FaceNo, bool fill2=true)
Get the FaceElementTransformations for the given shared face (edge 2D) using the face index FaceNo....
void PrintSharedEntities(const std::string &fname_prefix) const
Debugging method.
int GroupNTriangles(int group) const
void GetSharedVertexCommunicator(int ordering, GroupCommunicator &svert_comm) const
Get the shared vertices GroupCommunicator.
int GetSharedFace(int sface) const
Return the local face index for the given shared face.
void EnsureParNodes()
If the mesh is curved, make sure 'Nodes' is ParGridFunction.
int GroupNEdges(int group) const
void BuildSharedFaceElems(int ntri_faces, int nquad_faces, const Mesh &mesh, const int *partitioning, const STable3D *faces_tbl, const Array< int > &face_group, const Array< int > &vert_global_local)
void GenerateOffsets(int N, HYPRE_BigInt loc_sizes[], Array< HYPRE_BigInt > *offsets[]) const
void MarkTetMeshForRefinement(const DSTable &v_to_v) override
Array< int > face_nbr_group
Array< int > face_nbr_elements_offset
ParMesh & operator=(ParMesh &&mesh)
Move assignment operator.
void Load(std::istream &input, int generate_edges=0, int refine=1, bool fix_orientation=true) override
Parallel version of Mesh::Load().
int GetNFaceNeighbors() const
void UniformRefineGroups3D(int old_nv, int old_nedges, const DSTable &old_v_to_v, const STable3D &old_faces, Array< int > *f2qf)
void GetGhostFaceTransformation(FaceElementTransformations &FElTr, Element::Type face_type, Geometry::Type face_geom) const
void RebalanceImpl(const Array< int > *partition)
int FindSharedEdges(const Mesh &mesh, const int *partition, Table *&edge_element, ListOfIntegerSets &groups)
void PrintAsOneXG(std::ostream &out=mfem::out)
Old mesh format (Netgen/Truegrid) version of 'PrintAsOne'.
std::unique_ptr< Table > face_nbr_el_to_face
Array< Vert3 > shared_trias
void GroupQuadrilateral(int group, int i, int &face, int &o) const
void Save(const std::string &fname, int precision=16) const override
void DistributeAttributes(Array< int > &attr)
Ensure that bdr_attributes and attributes agree across processors.
STable3D * GetSharedFacesTable()
static ParMesh MakeRefined(ParMesh &orig_mesh, int ref_factor, int ref_type)
Create a uniformly refined (by any factor) version of orig_mesh.
real_t GetFaceNbrElementSize(int i, int type=0)
void UnmarkInternalBoundaries(Array< int > &bdr_marker, bool excl=true) const override
Unmark boundary attributes of internal boundaries.
std::unique_ptr< Table > face_nbr_el_ori
orientations for each face (from nbr processor)
int GetFaceNbrRank(int fn) const
int FindSharedVertices(const int *partition, Table *vertex_element, ListOfIntegerSets &groups)
void GroupTriangle(int group, int i, int &face, int &o) const
FaceElementTransformations * GetSharedFaceTransformations(int sf, bool fill2=true)
Get the FaceElementTransformations for the given shared face (edge 2D) using the shared face index sf...
void PrintAsSerial(std::ostream &out=mfem::out, const std::string &comments="") const
int BuildLocalBoundary(const Mesh &global_mesh, const int *partitioning, const Array< int > &vert_global_local, Array< bool > &activeBdrElem, Table *&edge_element)
Fills out partitioned Mesh::boundary.
int BuildLocalVertices(const Mesh &global_mesh, const int *partitioning, Array< int > &vert_global_local)
Fills out partitioned Mesh::vertices.
void ComputeGlobalElementOffset() const
void GetBoundingBox(Vector &p_min, Vector &p_max, int ref=2)
void PrintAsOne(std::ostream &out=mfem::out, const std::string &comments="") const
void Print(std::ostream &out=mfem::out, const std::string &comments="") const override
void RefineNURBSWithKVFactors(int rf, const std::string &kvf) override
void Swap(ParMesh &other)
void GroupEdge(int group, int i, int &edge, int &o) const
int GroupNVertices(int group) const
A parallel extension of the NCMesh class.
bool AnisotropicConflict(const Array< Refinement > &refinements, std::set< int > &conflicts)
bool IsGhost(int entity, int index) const
Return true if the specified vertex/edge/face is a ghost.
void GetFaceNeighbors(class ParMesh &pmesh)
void LimitNCLevel(int max_nc_level) override
Parallel version of NCMesh::LimitNCLevel.
void Refine(const Array< Refinement > &refinements) override
void GetConformingSharedStructures(class ParMesh &pmesh)
void Derefine(const Array< int > &derefs) override
void Rebalance(const Array< int > *custom_partition=NULL)
void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level) override
const NCList & GetSharedList(int entity)
Helper to get shared vertices/edges/faces ('entity' == 0/1/2 resp.).
const NCList & GetSharedEdges()
const NCList & GetSharedFaces()
int InitialPartition(int index) const
Helper to get the partitioning when the serial mesh gets split initially.
void SynchronizeDerefinementData(Array< Type > &elem_data, const Table &deref_table)
Parallel version of NURBSExtension.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Symmetric 3D Table stored as an array of rows each of which has a stack of column,...
int Push(int r, int c, int f)
Check to see if this entry is in the table and add it to the table if it is not there....
int Push4(int r, int c, int f, int t)
Check to see if this entry is in the table and add it to the table if it is not there....
Data type line segment element.
void GetVertices(Array< int > &v) const override
Get the indices defining the vertices.
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
void AddConnections(int r, const int *c, int nc)
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void AddConnection(int r, int c)
void SetIJ(int *newI, int *newJ, int newsize=-1)
Replace the I and J arrays with the given newI and newJ arrays.
int Size() const
Returns the number of TYPE I elements.
int Size_of_connections() const
Returns the number of connections in the table.
void AddColumnsInRow(int r, int ncol)
void AddAColumnInRow(int r)
void SetDims(int rows, int nnz)
Set the rows and the number of all connections for the table.
Data type tetrahedron element.
int GetRefinementFlag() const
void GetMarkedFace(const int face, int *fv) const
void MarkEdge(DenseMatrix &pmat)
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
int index(int i, int j, int nx, int ny)
void mfem_error(const char *msg)
GeometryRefiner GlobGeometryRefiner
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
void ShiftRight(int &a, int &b, int &c)
void Swap(T &a, T &b)
Swap objects of type T. The operation is performed using the most specialized swap function from the ...
std::string to_padded_string(int i, int digits)
Convert an integer to a 0-padded string with the given number of digits.
VTKFormat
Data array format for VTK and VTU files.
@ ASCII
Data arrays will be written in ASCII format.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
const T & AsConst(const T &a)
Utility function similar to std::as_const in c++17.
double bisect(ElementTransformation &Tr, Coefficient *LvlSet)
const char * VTKByteOrder()
Determine the byte order and return either "BigEndian" or "LittleEndian".
void SortPairs(Pair< A, B > *pairs, int size)
Sort an array of Pairs with respect to the first element.
MemoryType
Memory types supported by MFEM.
@ HOST
Host memory; using new[] and delete[].
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void skip_comment_lines(std::istream &is, const char comment_char)
Check if the stream starts with comment_char. If so skip it.
real_t p(const Vector &x, real_t t)
Defines the position of a fine element within a coarse element.
static const int FaceVert[NumFaces][MaxFaceVert]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int Orient[NumOrient][NumVert]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int Orient[NumOrient][NumVert]
Helper struct to convert a C++ type to an MPI type.
This structure stores the low level information necessary to interpret the configuration of elements ...
int slaves_end
slave faces
Lists all edges/faces in the nonconforming mesh.
Array< MeshId > conforming
All MeshIds corresponding to conformal faces.
Array< Slave > slaves
All MeshIds corresponding to slave faces.
Array< Master > masters
All MeshIds corresponding to master faces.
std::array< int, NCMesh::MaxFaceNodes > nodes