12 #include "../config/config.hpp"
17 #include "../fem/fem.hpp"
18 #include "../general/sets.hpp"
19 #include "../general/sort_pairs.hpp"
20 #include "../general/text.hpp"
21 #include "../general/globals.hpp"
31 ParMesh::ParMesh(
const ParMesh &pmesh,
bool copy_nodes)
33 group_svert(pmesh.group_svert),
34 group_sedge(pmesh.group_sedge),
35 group_stria(pmesh.group_stria),
36 group_squad(pmesh.group_squad),
37 face_nbr_el_to_face(NULL),
39 glob_offset_sequence(-1),
81 if (pmesh.
Nodes && copy_nodes)
109 : face_nbr_el_to_face(NULL)
110 , glob_elem_offset(-1)
111 , glob_offset_sequence(-1)
114 int *partitioning = NULL;
125 partitioning = partitioning_;
130 partitioning =
new int[mesh.
GetNE()];
131 for (
int i = 0; i < mesh.
GetNE(); i++)
161 partitioning = partitioning_;
175 Table *edge_element = NULL;
178 activeBdrElem, edge_element);
216 int nsedges =
FindSharedEdges(mesh, partitioning, edge_element, groups);
223 int ngroups = groups.
Size()-1, nstris, nsquads;
230 face_group, vert_global_local);
249 "invalid NURBS mesh");
269 Nodes->MakeOwner(nfec);
275 int element_counter = 0;
276 for (
int i = 0; i < mesh.
GetNE(); i++)
278 if (partitioning[i] ==
MyRank)
281 mesh.
GetNodes()->FESpace()->GetElementVDofs(i, gvdofs);
282 mesh.
GetNodes()->GetSubVector(gvdofs, lnodes);
293 if (partitioning != partitioning_)
295 delete [] partitioning;
303 const int* partitioning,
307 vert_global_local = -1;
309 int vert_counter = 0;
310 for (
int i = 0; i < mesh.
GetNE(); i++)
312 if (partitioning[i] ==
MyRank)
316 for (
int j = 0; j < vert.
Size(); j++)
318 if (vert_global_local[vert[j]] < 0)
320 vert_global_local[vert[j]] = vert_counter++;
328 for (
int i = 0; i < vert_global_local.
Size(); i++)
330 if (vert_global_local[i] >= 0)
332 vert_global_local[i] = vert_counter++;
338 for (
int i = 0; i < vert_global_local.
Size(); i++)
340 if (vert_global_local[i] >= 0)
354 for (
int i = 0; i < mesh.
GetNE(); i++)
356 if (partitioning[i] ==
MyRank) { nelems++; }
364 int element_counter = 0;
365 for (
int i = 0; i < mesh.
GetNE(); i++)
367 if (partitioning[i] ==
MyRank)
370 int *v =
elements[element_counter]->GetVertices();
371 int nv =
elements[element_counter]->GetNVertices();
372 for (
int j = 0; j < nv; j++)
374 v[j] = vert_global_local[v[j]];
380 return element_counter;
386 Table*& edge_element)
393 activeBdrElem =
false;
398 for (
int i = 0; i < mesh.
GetNBE(); i++)
400 int face, o, el1, el2;
403 if (partitioning[(o % 2 == 0 || el2 < 0) ? el1 : el2] ==
MyRank)
408 activeBdrElem[i] =
true;
413 int bdrelem_counter = 0;
415 for (
int i = 0; i < mesh.
GetNBE(); i++)
417 int face, o, el1, el2;
420 if (partitioning[(o % 2 == 0 || el2 < 0) ? el1 : el2] ==
MyRank)
423 int *v =
boundary[bdrelem_counter]->GetVertices();
424 int nv =
boundary[bdrelem_counter]->GetNVertices();
425 for (
int j = 0; j < nv; j++)
427 v[j] = vert_global_local[v[j]];
435 edge_element =
new Table;
438 for (
int i = 0; i < mesh.
GetNBE(); i++)
441 int el1 = edge_element->
GetRow(edge)[0];
442 if (partitioning[el1] ==
MyRank)
447 activeBdrElem[i] =
true;
452 int bdrelem_counter = 0;
454 for (
int i = 0; i < mesh.
GetNBE(); i++)
457 int el1 = edge_element->
GetRow(edge)[0];
458 if (partitioning[el1] ==
MyRank)
461 int *v =
boundary[bdrelem_counter]->GetVertices();
462 int nv =
boundary[bdrelem_counter]->GetNVertices();
463 for (
int j = 0; j < nv; j++)
465 v[j] = vert_global_local[v[j]];
473 for (
int i = 0; i < mesh.
GetNBE(); i++)
475 int vert = mesh.
boundary[i]->GetVertices()[0];
478 if (partitioning[el1] ==
MyRank)
484 int bdrelem_counter = 0;
486 for (
int i = 0; i < mesh.
GetNBE(); i++)
488 int vert = mesh.
boundary[i]->GetVertices()[0];
491 if (partitioning[el1] ==
MyRank)
494 int *v =
boundary[bdrelem_counter]->GetVertices();
495 v[0] = vert_global_local[v[0]];
512 for (
int i = 0; i < face_group.
Size(); i++)
519 el[0] = partitioning[el[0]];
520 el[1] = partitioning[el[1]];
525 face_group[i] = groups.
Insert(group) - 1;
532 Table*& edge_element,
538 int sedge_counter = 0;
541 edge_element =
new Table;
552 for (
int i = 0; i < edge_element->
Size(); i++)
554 int me = 0, others = 0;
555 for (
int j = edge_element->
GetI()[i]; j < edge_element->
GetI()[i+1]; j++)
557 int k = edge_element->
GetJ()[j];
558 int rank = partitioning[k];
559 edge_element->
GetJ()[j] = rank;
578 edge_element->
GetRow(i)[0] = -1;
582 return sedge_counter;
591 int svert_counter = 0;
592 for (
int i = 0; i < vert_element->
Size(); i++)
594 int me = 0, others = 0;
595 for (
int j = vert_element->
GetI()[i]; j < vert_element->
GetI()[i+1]; j++)
597 vert_element->
GetJ()[j] = partitioning[vert_element->
GetJ()[j]];
612 vert_element->
GetI()[i] = groups.
Insert(group) - 1;
616 vert_element->
GetI()[i] = -1;
619 return svert_counter;
624 int &nstria,
int &nsquad)
630 for (
int i = 0; i < face_group.
Size(); i++)
632 if (face_group[i] >= 0)
649 for (
int i = 0; i < face_group.
Size(); i++)
651 if (face_group[i] >= 0)
672 for (
int i = 0; i < edge_element.
Size(); i++)
674 if (edge_element.
GetRow(i)[0] >= 0)
682 int sedge_counter = 0;
683 for (
int i = 0; i < edge_element.
Size(); i++)
685 if (edge_element.
GetRow(i)[0] >= 0)
698 for (
int i = 0; i < vert_element.
Size(); i++)
700 if (vert_element.
GetI()[i] >= 0)
708 int svert_counter = 0;
709 for (
int i = 0; i < vert_element.
Size(); i++)
711 if (vert_element.
GetI()[i] >= 0)
721 const Mesh& mesh,
int *partitioning,
730 if (
Dim < 3) {
return; }
732 int stria_counter = 0;
733 int squad_counter = 0;
734 for (
int i = 0; i < face_group.
Size(); i++)
736 if (face_group[i] < 0) {
continue; }
746 for (
int j = 0; j < 3; j++)
748 v[j] = vert_global_local[v[j]];
750 const int lface = (*faces_tbl)(v[0], v[1], v[2]);
766 if (
MyRank == partitioning[gl_el2])
768 std::swap(v[0], v[1]);
780 for (
int j = 0; j < 4; j++)
782 v[j] = vert_global_local[v[j]];
785 (*faces_tbl)(v[0], v[1], v[2], v[3]);
791 MFEM_ABORT(
"unknown face type: " << face->
GetType());
799 const Table* edge_element)
811 int sedge_counter = 0;
812 for (
int i = 0; i < edge_element->
Size(); i++)
814 if (edge_element->
GetRow(i)[0] >= 0)
820 new Segment(vert_global_local[vert[0]],
821 vert_global_local[vert[1]], 1);
823 sedge_ledge[sedge_counter] = v_to_v(vert_global_local[vert[0]],
824 vert_global_local[vert[1]]);
826 MFEM_VERIFY(
sedge_ledge[sedge_counter] >= 0,
"Error in v_to_v.");
841 int svert_counter = 0;
842 for (
int i = 0; i < vert_element->
Size(); i++)
844 if (vert_element->
GetI()[i] >= 0)
846 svert_lvert[svert_counter++] = vert_global_local[i];
854 : MyComm(pncmesh.MyComm)
855 , NRanks(pncmesh.NRanks)
856 , MyRank(pncmesh.MyRank)
857 , face_nbr_el_to_face(NULL)
858 , glob_elem_offset(-1)
859 , glob_offset_sequence(-1)
884 MPI_Allreduce(&loc_meshgen, &
meshgen, 1, MPI_INT, MPI_BOR,
MyComm);
898 const int l_edge = v_to_v(v[0], v[1]);
899 MFEM_ASSERT(l_edge >= 0,
"invalid shared edge");
910 for (
int st = 0; st < nst; st++)
925 : face_nbr_el_to_face(NULL)
926 , glob_elem_offset(-1)
927 , glob_offset_sequence(-1)
937 const int gen_edges = 1;
939 Load(input, gen_edges, refine,
true);
943 bool fix_orientation)
950 Loader(input, generate_edges,
"mfem_serial_mesh_end");
962 MFEM_ASSERT(
pncmesh,
"internal error");
985 MFEM_VERIFY(ident ==
"communication_groups",
986 "input stream is not a parallel MFEM mesh");
994 input >> ident >> num_sverts;
995 MFEM_VERIFY(ident ==
"total_shared_vertices",
"invalid mesh file");
1004 input >> ident >> num_sedges;
1005 MFEM_VERIFY(ident ==
"total_shared_edges",
"invalid mesh file");
1019 input >> ident >> num_sface;
1020 MFEM_VERIFY(ident ==
"total_shared_faces",
"invalid mesh file");
1033 int svert_counter = 0, sedge_counter = 0;
1040 input >> ident >> g;
1043 mfem::err <<
"ParMesh::ParMesh : expecting group " << gr
1044 <<
", read group " << g << endl;
1050 input >> ident >> nv;
1051 MFEM_VERIFY(ident ==
"shared_vertices",
"invalid mesh file");
1052 nv += svert_counter;
1054 "incorrect number of total_shared_vertices");
1056 for ( ; svert_counter < nv; svert_counter++)
1065 input >> ident >> ne;
1066 MFEM_VERIFY(ident ==
"shared_edges",
"invalid mesh file");
1067 ne += sedge_counter;
1069 "incorrect number of total_shared_edges");
1071 for ( ; sedge_counter < ne; sedge_counter++)
1074 input >> v[0] >> v[1];
1081 input >> ident >> nf;
1082 for (
int i = 0; i < nf; i++)
1091 for (
int ii = 0; ii < 3; ii++) { input >> v[ii]; }
1096 for (
int ii = 0; ii < 4; ii++) { input >> v[ii]; }
1099 MFEM_ABORT(
"invalid shared face geometry: " << geom);
1110 "incorrect number of total_shared_faces");
1145 ref_factors = ref_factor;
1224 for (
int j = 0; j < orig_n_verts; j++)
1231 const int orig_n_edges = orig_mesh.
GroupNEdges(gr);
1232 if (orig_n_edges > 0)
1237 const int *c2h_map = rfec.
GetDofMap(geom, ref_factor);
1239 for (
int e = 0; e < orig_n_edges; e++)
1244 for (
int j = 2; j < rdofs.
Size(); j++)
1252 for (
int k = 0; k < nvert; k++)
1255 v[k] = rdofs[c2h_map[cid]];
1271 const int *c2h_map = rfec.
GetDofMap(geom, ref_factor);
1273 for (
int f = 0;
f < orig_nt;
f++)
1278 for (
int j = rdofs.
Size()-num_int_verts; j < rdofs.
Size(); j++)
1287 for (
int k = 0; k < 2; k++)
1289 v[k] = rdofs[c2h_map[RG.
RefEdges[j+k]]];
1298 for (
int k = 0; k < nvert; k++)
1301 v[k] = rdofs[c2h_map[cid]];
1315 const int *c2h_map = rfec.
GetDofMap(geom, ref_factor);
1317 for (
int f = 0;
f < orig_nq;
f++)
1322 for (
int j = rdofs.
Size()-num_int_verts; j < rdofs.
Size(); j++)
1331 for (
int k = 0; k < 2; k++)
1333 v[k] = rdofs[c2h_map[RG.
RefEdges[j+k]]];
1342 for (
int k = 0; k < nvert; k++)
1345 v[k] = rdofs[c2h_map[cid]];
1392 for (
int iv=0; iv<orig_mesh.
GetNV(); ++iv)
1394 vglobal[iv] = fes.GetGlobalTDofNumber(iv);
1403 for (
int gr = 1; gr < mesh.
GetNGroups(); gr++)
1429 constexpr
int ntris = 2, nv_tri = 3, nv_quad = 4;
1432 for (
int gr = 1; gr < mesh.
GetNGroups(); gr++)
1436 for (
int j = 0; j < orig_n_verts; j++)
1438 fes.GetVertexDofs(orig_mesh.
GroupVertex(gr, j), dofs);
1443 const int orig_n_edges = orig_mesh.
GroupNEdges(gr);
1444 for (
int e = 0; e < orig_n_edges; e++)
1456 for (
int e = 0; e < orig_nt; e++)
1463 for (
int iv=0; iv<nv_tri; ++iv) { v2[iv] = v[iv]; }
1470 static const int trimap[12] =
1476 static const int diagmap[4] = { 0, 2, 1, 3 };
1477 for (
int f = 0;
f < orig_nq; ++
f)
1484 for (
int iv=0; iv<nv_quad; ++iv) { vg[iv] = vglobal[v[iv]]; }
1485 int iv_min = std::min_element(vg, vg+nv_quad) - vg;
1486 int isplit = (iv_min == 0 || iv_min == 2) ? 0 : 1;
1490 v_diag[0] = v[diagmap[0 + isplit*2]];
1491 v_diag[1] = v[diagmap[1 + isplit*2]];
1494 for (
int itri=0; itri<ntris; ++itri)
1498 for (
int iv=0; iv<nv_tri; ++iv)
1500 v2[iv] = v[trimap[itri + isplit*2 + iv*ntris*2]];
1518 const int meshgen_save =
meshgen;
1547 int max_attr = attr.
Size() ? attr.
Max() : 1 ;
1548 int glb_max_attr = -1;
1549 MPI_Allreduce(&max_attr, &glb_max_attr, 1, MPI_INT, MPI_MAX,
MyComm);
1553 bool *attr_marker =
new bool[glb_max_attr];
1554 bool *glb_attr_marker =
new bool[glb_max_attr];
1555 for (
int i = 0; i < glb_max_attr; i++)
1557 attr_marker[i] =
false;
1559 for (
int i = 0; i < attr.
Size(); i++)
1561 attr_marker[attr[i] - 1] =
true;
1563 MPI_Allreduce(attr_marker, glb_attr_marker, glb_max_attr,
1564 MPI_C_BOOL, MPI_LOR,
MyComm);
1565 delete [] attr_marker;
1570 for (
int i = 0; i < glb_max_attr; i++)
1572 if (glb_attr_marker[i])
1577 delete [] glb_attr_marker;
1588 MFEM_WARNING(
"Non-positive boundary element attributes found!");
1594 MFEM_WARNING(
"Non-positive element attributes found!");
1601 int maxNumOfBdrElements;
1603 MPI_INT, MPI_MAX,
MyComm);
1604 return (maxNumOfBdrElements > 0);
1612 o = (v[0] < v[1]) ? (+1) : (-1);
1621 "Expecting a triangular face.");
1632 "Expecting a quadrilateral face.");
1642 gr_sedge.
GetI()[0] = 0;
1651 gr_sedge.
GetJ()[k] =k;
1666 gr_svert.
GetI()[0] = 0;
1675 gr_svert.
GetJ()[k] = k;
1690 gr_squad.
GetI()[0] = 0;
1699 gr_squad.
GetJ()[k] = k;
1714 gr_stria.
GetI()[0] = 0;
1723 gr_stria.
GetJ()[k] = k;
1749 sedge_ord[k] = order[v_to_v(v[0], v[1])];
1752 sedge_comm.
Bcast<
int>(sedge_ord, 1);
1754 for (
int k = 0, gr = 1; gr <
GetNGroups(); gr++)
1757 if (n == 0) {
continue; }
1758 sedge_ord_map.SetSize(n);
1759 for (
int j = 0; j < n; j++)
1761 sedge_ord_map[j].one = sedge_ord[k+j];
1762 sedge_ord_map[j].two = j;
1764 SortPairs<int, int>(sedge_ord_map, n);
1765 for (
int j = 0; j < n; j++)
1768 const int *v =
shared_edges[sedge_from]->GetVertices();
1769 sedge_ord[k+j] = order[v_to_v(v[0], v[1])];
1771 std::sort(&sedge_ord[k], &sedge_ord[k] + n);
1772 for (
int j = 0; j < n; j++)
1776 order[v_to_v(v[0], v[1])] = sedge_ord[k+j];
1790 ilen_len[j].one = order[j];
1791 ilen_len[j].two =
GetLength(i, it.Column());
1795 SortPairs<int, double>(ilen_len, order.
Size());
1798 for (
int i = 1; i < order.
Size(); i++)
1800 d_max = std::max(d_max, ilen_len[i-1].two-ilen_len[i].two);
1810 MPI_Reduce(&d_max, &glob_d_max, 1, MPI_DOUBLE, MPI_MAX, 0,
MyComm);
1813 mfem::out <<
"glob_d_max = " << glob_d_max << endl;
1825 elements[i]->MarkEdge(v_to_v, order);
1833 boundary[i]->MarkEdge(v_to_v, order);
1852 if ((m = v_to_v(v[0], v[1])) != -1 && middle[m] != -1)
1869 face_stack.
Append(face_t(fv[0], fv[1], fv[2]));
1870 for (
unsigned bit = 0; face_stack.
Size() > 0; bit++)
1872 if (bit == 8*
sizeof(
unsigned))
1878 const face_t &
f = face_stack.
Last();
1879 int mid = v_to_v.
FindId(f.one, f.two);
1889 face_stack.
Append(face_t(f.three, f.one, mid));
1890 face_t &r = face_stack[face_stack.
Size()-2];
1891 r = face_t(r.two, r.three, mid);
1903 bool need_refinement = 0;
1904 face_stack.
Append(face_t(v[0], v[1], v[2]));
1905 for (
unsigned bit = 0, code = codes[pos++]; face_stack.
Size() > 0; bit++)
1907 if (bit == 8*
sizeof(
unsigned))
1909 code = codes[pos++];
1913 if ((code & (1 << bit)) == 0) { face_stack.
DeleteLast();
continue; }
1915 const face_t &
f = face_stack.
Last();
1916 int mid = v_to_v.
FindId(f.one, f.two);
1919 mid = v_to_v.
GetId(f.one, f.two);
1920 int ind[2] = { f.one, f.two };
1923 need_refinement = 1;
1926 face_stack.
Append(face_t(f.three, f.one, mid));
1927 face_t &r = face_stack[face_stack.
Size()-2];
1928 r = face_t(r.two, r.three, mid);
1930 return need_refinement;
1936 if (HYPRE_AssumedPartitionCheck())
1939 MPI_Scan(loc_sizes, temp.
GetData(), N, HYPRE_MPI_BIG_INT, MPI_SUM,
MyComm);
1940 for (
int i = 0; i < N; i++)
1943 (*offsets[i])[0] = temp[i] - loc_sizes[i];
1944 (*offsets[i])[1] = temp[i];
1947 for (
int i = 0; i < N; i++)
1949 (*offsets[i])[2] = temp[i];
1951 MFEM_VERIFY((*offsets[i])[0] >= 0 && (*offsets[i])[1] >= 0,
1952 "overflow in offsets");
1958 MPI_Allgather(loc_sizes, N, HYPRE_MPI_BIG_INT, temp.
GetData(), N,
1959 HYPRE_MPI_BIG_INT,
MyComm);
1960 for (
int i = 0; i < N; i++)
1965 for (
int j = 0; j <
NRanks; j++)
1967 offs[j+1] = offs[j] + temp[i+N*j];
1971 "overflow in offsets");
1996 for (
int j = 0; j < nv; j++)
2015 for (
int j = 0; j < n; j++)
2017 pointmat(k,j) = (pNodes->
FaceNbrData())(vdofs[n*k+j]);
2025 MFEM_ABORT(
"Nodes are not ParGridFunction!");
2058 space_dim = (space_dim == -1) ?
spaceDim : space_dim;
2103 *new_nodes = *
Nodes;
2136 bool del_tables =
false;
2163 gr_sface =
new Table;
2198 if (del_tables) {
delete gr_sface; }
2209 int num_face_nbrs = 0;
2212 if (gr_sface->
RowSize(g-1) > 0)
2220 if (num_face_nbrs == 0)
2230 for (
int g = 1, counter = 0; g <
GetNGroups(); g++)
2232 if (gr_sface->
RowSize(g-1) > 0)
2237 int lproc = (nbs[0]) ? nbs[0] : nbs[1];
2239 rank_group[counter].two = g;
2244 SortPairs<int, int>(rank_group, rank_group.
Size());
2246 for (
int fn = 0; fn < num_face_nbrs; fn++)
2252 MPI_Request *requests =
new MPI_Request[2*num_face_nbrs];
2253 MPI_Request *send_requests = requests;
2254 MPI_Request *recv_requests = requests + num_face_nbrs;
2255 MPI_Status *statuses =
new MPI_Status[num_face_nbrs];
2257 int *nbr_data =
new int[6*num_face_nbrs];
2258 int *nbr_send_data = nbr_data;
2259 int *nbr_recv_data = nbr_data + 3*num_face_nbrs;
2268 Table send_face_nbr_elemdata, send_face_nbr_facedata;
2272 send_face_nbr_elemdata.
MakeI(num_face_nbrs);
2273 send_face_nbr_facedata.
MakeI(num_face_nbrs);
2274 for (
int fn = 0; fn < num_face_nbrs; fn++)
2277 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
2278 int *sface = gr_sface->
GetRow(nbr_group-1);
2279 for (
int i = 0; i < num_sfaces; i++)
2281 int lface = s2l_face[sface[i]];
2283 if (el_marker[el] != fn)
2288 const int nv =
elements[el]->GetNVertices();
2289 const int *v =
elements[el]->GetVertices();
2290 for (
int j = 0; j < nv; j++)
2291 if (vertex_marker[v[j]] != fn)
2293 vertex_marker[v[j]] = fn;
2297 const int nf =
elements[el]->GetNFaces();
2306 nbr_send_data[3*fn+2] = send_face_nbr_elemdata.
GetI()[fn];
2311 MPI_Isend(&nbr_send_data[3*fn], 3, MPI_INT, nbr_rank, tag,
MyComm,
2312 &send_requests[fn]);
2313 MPI_Irecv(&nbr_recv_data[3*fn], 3, MPI_INT, nbr_rank, tag,
MyComm,
2314 &recv_requests[fn]);
2318 send_face_nbr_elemdata.
MakeJ();
2319 send_face_nbr_facedata.
MakeJ();
2323 for (
int fn = 0; fn < num_face_nbrs; fn++)
2326 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
2327 int *sface = gr_sface->
GetRow(nbr_group-1);
2328 for (
int i = 0; i < num_sfaces; i++)
2330 const int sf = sface[i];
2331 int lface = s2l_face[sf];
2333 if (el_marker[el] != fn)
2338 const int nv =
elements[el]->GetNVertices();
2339 const int *v =
elements[el]->GetVertices();
2340 for (
int j = 0; j < nv; j++)
2341 if (vertex_marker[v[j]] != fn)
2343 vertex_marker[v[j]] = fn;
2354 const int nf =
elements[el]->GetNFaces();
2365 const int *lf_v =
faces[lface]->GetVertices();
2385 for (
int fn = 0; fn < num_face_nbrs; fn++)
2391 int *elemdata = send_face_nbr_elemdata.
GetRow(fn);
2392 int num_sfaces = send_face_nbr_facedata.
RowSize(fn)/2;
2393 int *facedata = send_face_nbr_facedata.
GetRow(fn);
2395 for (
int i = 0; i < num_verts; i++)
2397 vertex_marker[verts[i]] = i;
2400 for (
int el = 0; el < num_elems; el++)
2402 const int nv =
elements[elems[el]]->GetNVertices();
2405 for (
int j = 0; j < nv; j++)
2407 elemdata[j] = vertex_marker[elemdata[j]];
2409 elemdata += nv + nf;
2411 el_marker[elems[el]] = el;
2414 for (
int i = 0; i < num_sfaces; i++)
2416 facedata[2*i] = el_marker[facedata[2*i]];
2420 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
2423 Table recv_face_nbr_elemdata;
2428 recv_face_nbr_elemdata.
MakeI(num_face_nbrs);
2431 for (
int fn = 0; fn < num_face_nbrs; fn++)
2439 recv_face_nbr_elemdata.
MakeJ();
2441 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2444 for (
int fn = 0; fn < num_face_nbrs; fn++)
2449 MPI_Isend(send_face_nbr_elemdata.
GetRow(fn),
2450 send_face_nbr_elemdata.
RowSize(fn),
2451 MPI_INT, nbr_rank, tag,
MyComm, &send_requests[fn]);
2453 MPI_Irecv(recv_face_nbr_elemdata.
GetRow(fn),
2454 recv_face_nbr_elemdata.
RowSize(fn),
2455 MPI_INT, nbr_rank, tag,
MyComm, &recv_requests[fn]);
2465 MPI_Waitany(num_face_nbrs, recv_requests, &fn, statuses);
2467 if (fn == MPI_UNDEFINED)
2475 int *recv_elemdata = recv_face_nbr_elemdata.
GetRow(fn);
2477 for (
int i = 0; i < num_elems; i++)
2483 for (
int j = 0; j < nv; j++)
2485 recv_elemdata[j] += vert_off;
2488 recv_elemdata += nv;
2493 for (
int j = 0; j < nf; j++)
2495 fn_ori[j] = recv_elemdata[j];
2497 recv_elemdata += nf;
2504 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2507 recv_face_nbr_facedata.
SetSize(
2509 for (
int fn = 0; fn < num_face_nbrs; fn++)
2514 MPI_Isend(send_face_nbr_facedata.
GetRow(fn),
2515 send_face_nbr_facedata.
RowSize(fn),
2516 MPI_INT, nbr_rank, tag,
MyComm, &send_requests[fn]);
2519 MPI_Irecv(&recv_face_nbr_facedata[send_face_nbr_facedata.
GetI()[fn]],
2520 send_face_nbr_facedata.
RowSize(fn),
2521 MPI_INT, nbr_rank, tag,
MyComm, &recv_requests[fn]);
2528 MPI_Waitany(num_face_nbrs, recv_requests, &fn, statuses);
2530 if (fn == MPI_UNDEFINED)
2537 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
2538 int *sface = gr_sface->
GetRow(nbr_group-1);
2540 &recv_face_nbr_facedata[send_face_nbr_facedata.
GetI()[fn]];
2542 for (
int i = 0; i < num_sfaces; i++)
2544 const int sf = sface[i];
2545 int lface = s2l_face[sf];
2547 face_info.
Elem2No = -1 - (facedata[2*i] + elem_off);
2548 int info = facedata[2*i+1];
2556 int nbr_ori = info%64, nbr_v[4];
2557 const int *lf_v =
faces[lface]->GetVertices();
2564 for (
int j = 0; j < 3; j++)
2566 nbr_v[perm[j]] = sf_v[j];
2576 for (
int j = 0; j < 4; j++)
2578 nbr_v[perm[j]] = sf_v[j];
2584 info = 64*(info/64) + nbr_ori;
2590 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2607 else if (
Nodes == NULL)
2617 if (!num_face_nbrs) {
return; }
2619 MPI_Request *requests =
new MPI_Request[2*num_face_nbrs];
2620 MPI_Request *send_requests = requests;
2621 MPI_Request *recv_requests = requests + num_face_nbrs;
2622 MPI_Status *statuses =
new MPI_Status[num_face_nbrs];
2626 for (
int i = 0; i < send_vertices.Size(); i++)
2632 for (
int fn = 0; fn < num_face_nbrs; fn++)
2639 MPI_DOUBLE, nbr_rank, tag,
MyComm, &send_requests[fn]);
2644 MPI_DOUBLE, nbr_rank, tag, MyComm, &recv_requests[fn]);
2647 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
2648 MPI_Waitall(num_face_nbrs, send_requests, statuses);
2656 MFEM_VERIFY(pNodes != NULL,
"Nodes are not ParGridFunction!");
2671 for (
int j = 0; j < 4; j++)
2674 sfaces_tbl->
Push(v[fv[0]], v[fv[1]], v[fv[2]]);
2680 for (
int j = 0; j < 2; j++)
2683 sfaces_tbl->
Push(v[fv[0]], v[fv[1]], v[fv[2]]);
2685 for (
int j = 2; j < 5; j++)
2688 sfaces_tbl->
Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
2696 for (
int j = 0; j < 6; j++)
2699 sfaces_tbl->
Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
2704 MFEM_ABORT(
"Unexpected type of Element.");
2728 for (
int j = 0; j < 4; j++)
2731 int lf = faces_tbl->
Index(v[fv[0]], v[fv[1]], v[fv[2]]);
2734 lf = sfaces_tbl->
Index(v[fv[0]], v[fv[1]], v[fv[2]]);
2746 for (
int j = 0; j < 2; j++)
2749 int lf = faces_tbl->
Index(v[fv[0]], v[fv[1]], v[fv[2]]);
2752 lf = sfaces_tbl->
Index(v[fv[0]], v[fv[1]], v[fv[2]]);
2760 for (
int j = 2; j < 5; j++)
2766 if (max < v[fv[1]]) { max = v[fv[1]], k = 1; }
2767 if (max < v[fv[2]]) { max = v[fv[2]], k = 2; }
2768 if (max < v[fv[3]]) { k = 3; }
2770 int v0 = -1, v1 = -1, v2 = -1;
2774 v0 = v[fv[1]]; v1 = v[fv[2]]; v2 = v[fv[3]];
2777 v0 = v[fv[0]]; v1 = v[fv[2]]; v2 = v[fv[3]];
2780 v0 = v[fv[0]]; v1 = v[fv[1]]; v2 = v[fv[3]];
2783 v0 = v[fv[0]]; v1 = v[fv[1]]; v2 = v[fv[2]];
2786 int lf = faces_tbl->
Index(v0, v1, v2);
2789 lf = sfaces_tbl->
Index(v0, v1, v2);
2803 for (
int j = 0; j < 6; j++)
2809 if (max < v[fv[1]]) { max = v[fv[1]], k = 1; }
2810 if (max < v[fv[2]]) { max = v[fv[2]], k = 2; }
2811 if (max < v[fv[3]]) { k = 3; }
2813 int v0 = -1, v1 = -1, v2 = -1;
2817 v0 = v[fv[1]]; v1 = v[fv[2]]; v2 = v[fv[3]];
2820 v0 = v[fv[0]]; v1 = v[fv[2]]; v2 = v[fv[3]];
2823 v0 = v[fv[0]]; v1 = v[fv[1]]; v2 = v[fv[3]];
2826 v0 = v[fv[0]]; v1 = v[fv[1]]; v2 = v[fv[2]];
2829 int lf = faces_tbl->
Index(v0, v1, v2);
2832 lf = sfaces_tbl->
Index(v0, v1, v2);
2843 MFEM_ABORT(
"Unexpected type of Element.");
2863 int nbr_lproc = (nbs[0]) ? nbs[0] : nbs[1];
2878 int el_nbr = i -
GetNE();
2885 MFEM_ABORT(
"ParMesh::GetFaceNbrElementFaces(...) : "
2886 "face_nbr_el_to_face not generated.");
2900 MFEM_ABORT(
"ParMesh::GetFaceNbrElementFaces(...) : "
2901 "face_nbr_el_to_face not generated.");
2936 for (
int i = 0; i < s2l_face->
Size(); i++)
2951 for (
int i = 0; i < s2l_face->
Size(); i++)
2953 int lface = (*s2l_face)[i];
2954 int nbr_elem_idx = -1 -
faces_info[lface].Elem2No;
2979 MFEM_VERIFY(dynamic_cast<const NodalFiniteElement*>(face_el),
2980 "Mesh requires nodal Finite Element.");
2982 #if 0 // TODO: handle the case of non-interpolatory Nodes
2991 FETr->
SetFE(face_el);
3005 const bool fill2 = mask & 10;
3022 MFEM_VERIFY(face_info.
Elem2Inf >= 0,
"The face must be shared.");
3035 int local_face = is_ghost ? nc_info->
MasterFace : FaceNo;
3049 Elem2NbrNo = -1 - face_info.
Elem2No;
3093 if (is_ghost || fill2)
3116 mfem::out <<
"\nInternal error: face id = " << FaceNo
3117 <<
", dist = " << dist <<
", rank = " <<
MyRank <<
'\n';
3119 MFEM_ABORT(
"internal error");
3140 MFEM_ASSERT(
Dim > 1,
"");
3159 MFEM_ASSERT(
Dim > 1,
"");
3162 return sface < csize
3164 : shared.
slaves[sface - csize].index;
3177 void Rotate3Indirect(
int &
a,
int &
b,
int &c,
3180 if (order[a] < order[b])
3182 if (order[a] > order[c])
3189 if (order[b] < order[c])
3210 Table *old_elem_vert = NULL;
3234 svert_comm.
Bcast(svert_master_index);
3248 for (
int i = 0; i <
vertices.Size(); i++)
3250 int s = lvert_svert[i];
3253 glob_vert_order[i] =
3254 (std::int64_t(svert_master_rank[s]) << 32) + svert_master_index[s];
3258 glob_vert_order[i] = (std::int64_t(
MyRank) << 32) + i;
3270 int *v =
elements[i]->GetVertices();
3272 Rotate3Indirect(v[0], v[1], v[2], glob_vert_order);
3274 if (glob_vert_order[v[0]] < glob_vert_order[v[3]])
3276 Rotate3Indirect(v[1], v[2], v[3], glob_vert_order);
3290 int *v =
boundary[i]->GetVertices();
3292 Rotate3Indirect(v[0], v[1], v[2], glob_vert_order);
3296 const bool check_consistency =
true;
3297 if (check_consistency)
3306 gr_stria.
GetI()[0] = 0;
3318 for (
int i = 0; i < stria_flag.Size(); i++)
3321 if (glob_vert_order[v[0]] < glob_vert_order[v[1]])
3323 stria_flag[i] = (glob_vert_order[v[0]] < glob_vert_order[v[2]]) ? 0 : 2;
3327 stria_flag[i] = (glob_vert_order[v[1]] < glob_vert_order[v[2]]) ? 1 : 2;
3332 stria_comm.
Bcast(stria_master_flag);
3333 for (
int i = 0; i < stria_flag.Size(); i++)
3336 MFEM_VERIFY(stria_flag[i] == stria_master_flag[i],
3337 "inconsistent vertex ordering found, shared triangle "
3339 << v[0] <<
", " << v[1] <<
", " << v[2] <<
"), "
3340 <<
"local flag: " << stria_flag[i]
3341 <<
", master flag: " << stria_master_flag[i]);
3350 Rotate3Indirect(v[0], v[1], v[2], glob_vert_order);
3366 delete old_elem_vert;
3379 MFEM_ABORT(
"Local and nonconforming refinements cannot be mixed.");
3388 int uniform_refinement = 0;
3392 uniform_refinement = 1;
3403 for (
int i = 0; i < marked_el.
Size(); i++)
3409 for (
int i = 0; i < marked_el.
Size(); i++)
3418 for (
int i = 0; i < marked_el.
Size(); i++)
3435 int need_refinement;
3436 int max_faces_in_group = 0;
3442 face_splittings[i].
Reserve(faces_in_group);
3443 if (faces_in_group > max_faces_in_group)
3445 max_faces_in_group = faces_in_group;
3451 MPI_Request *requests =
new MPI_Request[
GetNGroups()-1];
3454 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3455 int ref_loops_all = 0, ref_loops_par = 0;
3459 need_refinement = 0;
3462 if (
elements[i]->NeedRefinement(v_to_v))
3464 need_refinement = 1;
3468 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3472 if (uniform_refinement)
3479 if (need_refinement == 0)
3481 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3485 const int tag = 293;
3494 if (faces_in_group == 0) {
continue; }
3496 face_splittings[i].
SetSize(0);
3497 for (
int j = 0; j < faces_in_group; j++)
3500 face_splittings[i]);
3504 MPI_Isend(face_splittings[i], face_splittings[i].Size(),
3505 MPI_UNSIGNED, neighbor, tag,
MyComm,
3506 &requests[req_count++]);
3514 if (faces_in_group == 0) {
continue; }
3518 MPI_Probe(neighbor, tag,
MyComm, &status);
3520 MPI_Get_count(&status, MPI_UNSIGNED, &count);
3522 MPI_Recv(iBuf, count, MPI_UNSIGNED, neighbor, tag,
MyComm,
3525 for (
int j = 0, pos = 0; j < faces_in_group; j++)
3532 int nr = need_refinement;
3533 MPI_Allreduce(&nr, &need_refinement, 1, MPI_INT, MPI_LOR,
MyComm);
3535 MPI_Waitall(req_count, requests, MPI_STATUSES_IGNORE);
3538 while (need_refinement == 1);
3540 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3542 int i = ref_loops_all;
3543 MPI_Reduce(&i, &ref_loops_all, 1, MPI_INT, MPI_MAX, 0,
MyComm);
3546 mfem::out <<
"\n\nParMesh::LocalRefinement : max. ref_loops_all = "
3547 << ref_loops_all <<
", ref_loops_par = " << ref_loops_par
3555 delete [] face_splittings;
3560 need_refinement = 0;
3563 if (
boundary[i]->NeedRefinement(v_to_v))
3565 need_refinement = 1;
3570 while (need_refinement == 1);
3575 " (NumOfBdrElements != boundary.Size())");
3602 int uniform_refinement = 0;
3606 uniform_refinement = 1;
3615 int *edge1 =
new int[nedges];
3616 int *edge2 =
new int[nedges];
3617 int *middle =
new int[nedges];
3619 for (
int i = 0; i < nedges; i++)
3621 edge1[i] = edge2[i] = middle[i] = -1;
3626 int *v =
elements[i]->GetVertices();
3627 for (
int j = 0; j < 3; j++)
3629 int ind = v_to_v(v[j], v[(j+1)%3]);
3630 (edge1[ind] == -1) ? (edge1[ind] = i) : (edge2[ind] = i);
3635 for (
int i = 0; i < marked_el.
Size(); i++)
3641 int need_refinement;
3642 int edges_in_group, max_edges_in_group = 0;
3644 int **edge_splittings =
new int*[
GetNGroups()-1];
3648 edge_splittings[i] =
new int[edges_in_group];
3649 if (edges_in_group > max_edges_in_group)
3651 max_edges_in_group = edges_in_group;
3654 int neighbor, *iBuf =
new int[max_edges_in_group];
3658 MPI_Request request;
3663 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3664 int ref_loops_all = 0, ref_loops_par = 0;
3668 need_refinement = 0;
3669 for (
int i = 0; i < nedges; i++)
3671 if (middle[i] != -1 && edge1[i] != -1)
3673 need_refinement = 1;
3677 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3681 if (uniform_refinement)
3688 if (need_refinement == 0)
3690 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3699 edges_in_group = group_edges.
Size();
3701 if (edges_in_group != 0)
3703 for (
int j = 0; j < edges_in_group; j++)
3705 edge_splittings[i][j] =
3718 MPI_Isend(edge_splittings[i], edges_in_group, MPI_INT,
3719 neighbor, 0,
MyComm, &request);
3727 edges_in_group = group_edges.
Size();
3728 if (edges_in_group != 0)
3739 MPI_Recv(iBuf, edges_in_group, MPI_INT, neighbor,
3740 MPI_ANY_TAG,
MyComm, &status);
3742 for (
int j = 0; j < edges_in_group; j++)
3744 if (iBuf[j] == 1 && edge_splittings[i][j] == 0)
3747 int ii = v_to_v(v[0], v[1]);
3748 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3749 if (middle[ii] != -1)
3751 mfem_error(
"ParMesh::LocalRefinement (triangles) : "
3755 need_refinement = 1;
3757 for (
int c = 0; c < 2; c++)
3767 int nr = need_refinement;
3768 MPI_Allreduce(&nr, &need_refinement, 1, MPI_INT, MPI_LOR,
MyComm);
3771 while (need_refinement == 1);
3773 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
3775 int i = ref_loops_all;
3776 MPI_Reduce(&i, &ref_loops_all, 1, MPI_INT, MPI_MAX, 0,
MyComm);
3779 mfem::out <<
"\n\nParMesh::LocalRefinement : max. ref_loops_all = "
3780 << ref_loops_all <<
", ref_loops_par = " << ref_loops_par
3788 delete [] edge_splittings[i];
3790 delete [] edge_splittings;
3795 int v1[2], v2[2], bisect, temp;
3797 for (
int i = 0; i < temp; i++)
3799 int *v =
boundary[i]->GetVertices();
3800 bisect = v_to_v(v[0], v[1]);
3801 if (middle[bisect] != -1)
3806 v1[0] = v[0]; v1[1] = middle[bisect];
3807 v2[0] = middle[bisect]; v2[1] = v[1];
3814 mfem_error(
"Only bisection of segment is implemented for bdr"
3847 for (
int j = 0; j < marked_el.
Size(); j++)
3849 int i = marked_el[j];
3852 int new_v = cnv + j, new_e = cne + j;
3861 static double seg_children[3*2] = { 0.0,1.0, 0.0,0.5, 0.5,1.0 };
3863 UseExternalData(seg_children, 1, 2, 3);
3884 MFEM_ABORT(
"NURBS meshes are not supported. Please project the "
3885 "NURBS to Nodes first with SetCurvature().");
3890 MFEM_ABORT(
"Can't convert conforming ParMesh to nonconforming ParMesh "
3891 "(you need to initialize the ParMesh from a nonconforming "
3932 double threshold,
int nc_limit,
int op)
3934 MFEM_VERIFY(
pncmesh,
"Only supported for non-conforming meshes.");
3935 MFEM_VERIFY(!
NURBSext,
"Derefinement of NURBS meshes is not supported. "
3936 "Project the NURBS to Nodes first.");
3949 for (
int i = 0; i < dt.
Size(); i++)
3951 if (nc_limit > 0 && !level_ok[i]) {
continue; }
3956 if (error < threshold) { derefs.
Append(i); }
3960 if (!glob_size) {
return false; }
4003 MFEM_ABORT(
"Load balancing is currently not supported for conforming"
4010 MFEM_VERIFY(dynamic_cast<ParFiniteElementSpace*>(
Nodes->
FESpace())
4011 != NULL,
"internal error");
4041 MFEM_ASSERT(
Dim == 2 &&
meshgen == 1,
"internal error");
4051 int *I_group_svert, *J_group_svert;
4052 int *I_group_sedge, *J_group_sedge;
4057 I_group_svert[0] = I_group_svert[1] = 0;
4058 I_group_sedge[0] = I_group_sedge[1] = 0;
4065 for (
int group = 0; group <
GetNGroups()-1; group++)
4075 const int ind = middle[v_to_v(v[0], v[1])];
4081 const int attr =
shared_edges[group_edges[i]]->GetAttribute();
4088 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
4089 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
4092 J = J_group_svert+I_group_svert[group];
4093 for (
int i = 0; i < group_verts.
Size(); i++)
4095 J[i] = group_verts[i];
4097 J = J_group_sedge+I_group_sedge[group];
4098 for (
int i = 0; i < group_edges.
Size(); i++)
4100 J[i] = group_edges[i];
4114 MFEM_ASSERT(
Dim == 3 &&
meshgen == 1,
"internal error");
4116 Array<int> group_verts, group_edges, group_trias;
4135 I_group_svert[0] = 0;
4136 I_group_sedge[0] = 0;
4137 I_group_stria[0] = 0;
4139 for (
int group = 0; group <
GetNGroups()-1; group++)
4150 int ind = v_to_v.
FindId(v[0], v[1]);
4151 if (ind == -1) {
continue; }
4154 const int attr =
shared_edges[group_edges[i]]->GetAttribute();
4164 ind = v_to_v.
FindId(v[0], ind);
4172 ind = v_to_v.
FindId(v[0], v[1]);
4193 while (sedge_stack.
Size() > 0);
4200 int ind = v_to_v.
FindId(v[0], v[1]);
4201 if (ind == -1) {
continue; }
4204 const int edge_attr = 1;
4213 v[1] = v[0]; v[0] = v[2]; v[2] = ind;
4214 ind = v_to_v.
FindId(v[0], v[1]);
4222 ind = v_to_v.
FindId(v[0], v[1]);
4240 v = sface_stack[sface_stack.
Size()-2].v;
4242 v[0] = v[1]; v[1] = v[2]; v[2] = ind;
4245 while (sface_stack.
Size() > 0);
4251 ind = v_to_v.
FindId(v[0], v[1]);
4272 while (sedge_stack.
Size() > 0);
4275 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
4276 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
4277 I_group_stria[group+1] = I_group_stria[group] + group_trias.
Size();
4279 J_group_svert.
Append(group_verts);
4280 J_group_sedge.
Append(group_edges);
4281 J_group_stria.
Append(group_trias);
4298 int *I_group_svert, *J_group_svert;
4299 int *I_group_sedge, *J_group_sedge;
4304 I_group_svert[0] = 0;
4305 I_group_sedge[0] = 0;
4312 for (
int group = 0; group <
GetNGroups()-1; group++)
4326 const int attr =
shared_edges[sedges[i]]->GetAttribute();
4332 I_group_svert[group+1] = I_group_svert[group] + sverts.
Size();
4333 I_group_sedge[group+1] = I_group_sedge[group] + sedges.
Size();
4335 sverts.
CopyTo(J_group_svert + I_group_svert[group]);
4336 sedges.
CopyTo(J_group_sedge + I_group_sedge[group]);
4352 Array<int> group_verts, group_edges, group_trias, group_quads;
4354 int *I_group_svert, *J_group_svert;
4355 int *I_group_sedge, *J_group_sedge;
4356 int *I_group_stria, *J_group_stria;
4357 int *I_group_squad, *J_group_squad;
4364 I_group_svert[0] = 0;
4365 I_group_sedge[0] = 0;
4366 I_group_stria[0] = 0;
4367 I_group_squad[0] = 0;
4379 const int oface = old_nv + old_nedges;
4381 for (
int group = 0; group <
GetNGroups()-1; group++)
4393 const int ind = old_nv + old_v_to_v(v[0], v[1]);
4397 const int attr =
shared_edges[group_edges[i]]->GetAttribute();
4407 const int stria = group_trias[i];
4410 m[0] = old_nv + old_v_to_v(v[0], v[1]);
4411 m[1] = old_nv + old_v_to_v(v[1], v[2]);
4412 m[2] = old_nv + old_v_to_v(v[2], v[0]);
4413 const int edge_attr = 1;
4428 v[1] = m[0]; v[2] = m[2];
4429 group_trias.
Append(nst+0);
4430 group_trias.
Append(nst+1);
4431 group_trias.
Append(nst+2);
4439 const int squad = group_quads[i];
4441 const int olf = old_faces(v[0], v[1], v[2], v[3]);
4443 m[0] = oface + (f2qf ? (*f2qf)[olf] : olf);
4447 m[1] = old_nv + old_v_to_v(v[0], v[1]);
4448 m[2] = old_nv + old_v_to_v(v[1], v[2]);
4449 m[3] = old_nv + old_v_to_v(v[2], v[3]);
4450 m[4] = old_nv + old_v_to_v(v[3], v[0]);
4451 const int edge_attr = 1;
4468 v[1] = m[1]; v[2] = m[0]; v[3] = m[4];
4469 group_quads.
Append(nsq+0);
4470 group_quads.
Append(nsq+1);
4471 group_quads.
Append(nsq+2);
4475 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
4476 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
4477 I_group_stria[group+1] = I_group_stria[group] + group_trias.
Size();
4478 I_group_squad[group+1] = I_group_squad[group] + group_quads.
Size();
4480 group_verts.
CopyTo(J_group_svert + I_group_svert[group]);
4481 group_edges.
CopyTo(J_group_sedge + I_group_sedge[group]);
4482 group_trias.
CopyTo(J_group_stria + I_group_stria[group]);
4483 group_quads.
CopyTo(J_group_squad + I_group_squad[group]);
4502 const bool update_nodes =
false;
4532 const bool update_nodes =
false;
4541 f2qf.
Size() ? &f2qf : NULL);
4551 mfem::out <<
"\nParMesh::NURBSUniformRefinement : Not supported yet!\n";
4557 MFEM_ASSERT(
Dim ==
spaceDim,
"2D manifolds not supported");
4563 os <<
"NETGEN_Neutral_Format\n";
4568 for (j = 0; j <
Dim; j++)
4582 for (j = 0; j < nv; j++)
4584 os <<
" " << ind[j]+1;
4597 for (j = 0; j < nv; j++)
4599 os <<
" " << ind[j]+1;
4610 for (j = 0; j < 3; j++)
4612 os <<
' ' << ind[j]+1;
4626 <<
" 0 0 0 0 0 0 0\n"
4627 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
4629 <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
4630 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
4631 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
4637 <<
" " <<
vertices[i](2) <<
" 0.0\n";
4645 os << i+1 <<
" " <<
elements[i]->GetAttribute();
4646 for (j = 0; j < nv; j++)
4648 os <<
" " << ind[j]+1;
4659 for (j = 0; j < nv; j++)
4661 os <<
" " << ind[j]+1;
4663 os <<
" 1.0 1.0 1.0 1.0\n";
4674 for (j = 0; j < 4; j++)
4676 os <<
' ' << ind[j]+1;
4678 os <<
" 1.0 1.0 1.0 1.0\n";
4687 os <<
"areamesh2\n\n";
4694 attr =
boundary[i]->GetAttribute();
4697 for (j = 0; j < v.
Size(); j++)
4699 os << v[j] + 1 <<
" ";
4709 for (j = 0; j < v.
Size(); j++)
4711 os << v[j] + 1 <<
" ";
4720 attr =
elements[i]->GetAttribute();
4736 for (j = 0; j < v.
Size(); j++)
4738 os << v[j] + 1 <<
" ";
4747 for (j = 0; j <
Dim; j++)
4772 int shared_bdr_attr;
4789 s2l_face = &nc_shared_faces;
4796 for (
int i = 0; i < sfaces.
conforming.Size(); i++)
4799 if (index < nfaces) { nc_shared_faces.
Append(index); }
4801 for (
int i = 0; i < sfaces.
masters.Size(); i++)
4805 if (index < nfaces) { nc_shared_faces.
Append(index); }
4807 for (
int i = 0; i < sfaces.
slaves.Size(); i++)
4810 if (index < nfaces) { nc_shared_faces.
Append(index); }
4815 os <<
"MFEM mesh v1.0\n";
4819 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
4824 "# TETRAHEDRON = 4\n"
4829 os <<
"\ndimension\n" <<
Dim
4839 num_bdr_elems += s2l_face->
Size();
4841 os <<
"\nboundary\n" << num_bdr_elems <<
'\n';
4855 shared_bdr_attr =
MyRank + 1;
4857 for (
int i = 0; i < s2l_face->
Size(); i++)
4860 faces[(*s2l_face)[i]]->SetAttribute(shared_bdr_attr);
4888 ostringstream fname_with_suffix;
4889 fname_with_suffix << fname <<
"." << setfill(
'0') << setw(6) <<
MyRank;
4890 ofstream ofs(fname_with_suffix.str().c_str());
4891 ofs.precision(precision);
4895 #ifdef MFEM_USE_ADIOS2
4908 for (
int i = 0; i < nv; i++)
4916 int i, j, k,
p, nv_ne[2], &nv = nv_ne[0], &ne = nv_ne[1], vc;
4924 os <<
"MFEM mesh v1.0\n";
4928 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
4933 "# TETRAHEDRON = 4\n"
4938 os <<
"\ndimension\n" <<
Dim;
4942 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4945 os <<
"\n\nelements\n" << ne <<
'\n';
4949 os << 1 <<
' ' <<
elements[i]->GetGeometryType();
4953 for (j = 0; j < nv; j++)
4960 for (p = 1; p <
NRanks; p++)
4962 MPI_Recv(nv_ne, 2, MPI_INT, p, 444,
MyComm, &status);
4966 MPI_Recv(&ints[0], ne, MPI_INT, p, 445,
MyComm, &status);
4968 for (i = 0; i < ne; )
4971 os << p+1 <<
' ' << ints[i];
4974 for (j = 0; j < k; j++)
4976 os <<
' ' << vc + ints[i++];
4989 ne += 1 +
elements[i]->GetNVertices();
4992 MPI_Send(nv_ne, 2, MPI_INT, 0, 444,
MyComm);
5000 MFEM_ASSERT(ints.
Size() == ne,
"");
5003 MPI_Send(&ints[0], ne, MPI_INT, 0, 445,
MyComm);
5028 dump_element(
boundary[i], ints); ne++;
5066 MFEM_ABORT(
"invalid dimension: " <<
Dim);
5076 if (index < nfaces) { dump_element(
faces[index], ints); ne++; }
5078 for (i = 0; i < list.
masters.Size(); i++)
5081 if (index < nfaces) { dump_element(
faces[index], ints); ne++; }
5083 for (i = 0; i < list.
slaves.Size(); i++)
5086 if (index < nfaces) { dump_element(
faces[index], ints); ne++; }
5090 MPI_Reduce(&ne, &k, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5093 os <<
"\nboundary\n" << k <<
'\n';
5095 for (p = 0; p <
NRanks; p++)
5099 MPI_Recv(nv_ne, 2, MPI_INT, p, 446,
MyComm, &status);
5111 for (i = 0; i < ne; )
5114 os << p+1 <<
' ' << ints[i];
5117 for (j = 0; j < k; j++)
5119 os <<
' ' << vc + ints[i++];
5130 MPI_Send(nv_ne, 2, MPI_INT, 0, 446,
MyComm);
5141 os <<
"\nvertices\n" << nv <<
'\n';
5157 for (p = 1; p <
NRanks; p++)
5159 MPI_Recv(&nv, 1, MPI_INT, p, 448,
MyComm, &status);
5163 MPI_Recv(&vert[0], nv*spaceDim, MPI_DOUBLE, p, 449,
MyComm, &status);
5165 for (i = 0; i < nv; i++)
5170 os <<
' ' << vert[i*spaceDim+j];
5185 vert[i*spaceDim+j] =
vertices[i](j);
5190 MPI_Send(&vert[0], NumOfVertices*spaceDim, MPI_DOUBLE, 0, 449,
MyComm);
5217 mfem_error(
"ParMesh::PrintAsOne : Nodes have no parallel info!");
5238 MFEM_ABORT(
"Nonconforming meshes and NURBS meshes are not yet supported.");
5247 MFEM_VERIFY(
int(ne_glob_l) == ne_glob_l,
5248 "overflow in the number of elements!");
5249 int ne_glob = (save_rank ==
MyRank) ?
int(ne_glob_l) : 0;
5252 long long nvertices_glob_l = 0;
5253 MPI_Reduce(&nvertices, &nvertices_glob_l, 1, MPI_LONG_LONG, MPI_SUM,
5255 int nvertices_glob = int(nvertices_glob_l);
5256 MFEM_VERIFY(nvertices_glob == nvertices_glob_l,
5257 "overflow in the number of vertices!");
5260 long long nbe_glob_l = 0;
5261 MPI_Reduce(&nbe, &nbe_glob_l, 1, MPI_LONG_LONG, MPI_SUM, save_rank,
MyComm);
5262 int nbe_glob = int(nbe_glob_l);
5263 MFEM_VERIFY(nbe_glob == nbe_glob_l,
5264 "overflow in the number of boundary elements!");
5281 const int attr =
elements[e]->GetAttribute();
5282 const int geom_type =
elements[e]->GetGeometryType();
5284 for (
int j = 0; j < dofs.
Size(); j++)
5296 if (
p == save_rank) {
continue; }
5297 MPI_Recv(&n_send_recv, 1, MPI_INT,
p, 444,
MyComm, &status);
5301 MPI_Recv(&ints[0], n_send_recv, MPI_INT,
p, 445,
MyComm, &status);
5303 for (
int i = 0; i < n_send_recv; )
5305 int attr = ints[i++];
5306 int geom_type = ints[i++];
5319 n_send_recv += 2 +
elements[e]->GetNVertices();
5321 MPI_Send(&n_send_recv, 1, MPI_INT, save_rank, 444,
MyComm);
5326 const int attr =
elements[e]->GetAttribute();
5327 const int geom_type =
elements[e]->GetGeometryType();;
5331 for (
int j = 0; j < dofs.
Size(); j++)
5338 MPI_Send(&ints[0], n_send_recv, MPI_INT, save_rank, 445,
MyComm);
5347 const int attr =
boundary[e]->GetAttribute();
5348 const int geom_type =
boundary[e]->GetGeometryType();
5350 for (
int j = 0; j < dofs.
Size(); j++)
5362 if (
p == save_rank) {
continue; }
5363 MPI_Recv(&n_send_recv, 1, MPI_INT,
p, 446,
MyComm, &status);
5367 MPI_Recv(&ints[0], n_send_recv, MPI_INT,
p, 447,
MyComm, &status);
5369 for (
int i = 0; i < n_send_recv; )
5371 int attr = ints[i++];
5372 int geom_type = ints[i++];
5387 MPI_Send(&n_send_recv, 1, MPI_INT, save_rank, 446,
MyComm);
5392 const int attr =
boundary[e]->GetAttribute();
5393 const int geom_type =
boundary[e]->GetGeometryType();
5397 for (
int j = 0; j < dofs.
Size(); j++)
5404 MPI_Send(&ints[0], n_send_recv, MPI_INT, save_rank, 447,
MyComm);
5410 for (
int v = 0; v < nvertices_glob; v++)
5431 serialmesh.
GetNodes()->MakeOwner(fec_serial);
5447 serialmesh.
GetNodes()->SetSubVector(dofs, nodeloc);
5453 for (
int i = 0; i < ints.
Size(); i++)
5455 const double *vdata =
GetVertex(ints[i]);
5456 double *vdata_serial = serialmesh.
GetVertex(ints_serial[i]);
5459 vdata_serial[d] = vdata[d];
5467 if (
p == save_rank) {
continue; }
5468 MPI_Recv(&n_send_recv, 1, MPI_INT,
p, 448,
MyComm, &status);
5472 MPI_Recv(&vert[0], n_send_recv, MPI_DOUBLE,
p, 449,
MyComm, &status);
5474 for (
int i = 0; i < n_send_recv; )
5479 serialmesh.
GetNodes()->SetSubVector(dofs, &vert[i]);
5485 for (
int j = 0; j < ints_serial.
Size(); j++)
5487 double *vdata_serial = serialmesh.
GetVertex(ints_serial[j]);
5490 vdata_serial[d] = vert[i++];
5513 MPI_Send(&n_send_recv, 1, MPI_INT, save_rank, 448,
MyComm);
5521 for (
int j = 0; j < nodeloc.
Size(); j++)
5529 for (
int i = 0; i < ints.
Size(); i++)
5531 const double *vdata =
GetVertex(ints[i]);
5541 MPI_Send(&vert[0], n_send_recv, MPI_DOUBLE, save_rank, 449,
MyComm);
5555 ofs.precision(precision);
5562 MFEM_ASSERT(
Dim ==
spaceDim,
"2D Manifolds not supported.");
5565 int i, j, k, nv, ne,
p;
5573 os <<
"NETGEN_Neutral_Format\n";
5576 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5580 for (j = 0; j <
Dim; j++)
5586 for (p = 1; p <
NRanks; p++)
5588 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
5590 MPI_Recv(&vert[0],
Dim*nv, MPI_DOUBLE, p, 445,
MyComm, &status);
5591 for (i = 0; i < nv; i++)
5593 for (j = 0; j <
Dim; j++)
5595 os <<
" " << vert[Dim*i+j];
5603 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5610 for (j = 0; j < nv; j++)
5612 os <<
" " << ind[j]+1;
5617 for (p = 1; p <
NRanks; p++)
5619 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
5620 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
5622 MPI_Recv(&ints[0], 4*ne, MPI_INT, p, 447,
MyComm, &status);
5623 for (i = 0; i < ne; i++)
5626 for (j = 0; j < 4; j++)
5628 os <<
" " << k+ints[i*4+j]+1;
5636 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5644 for (j = 0; j < nv; j++)
5646 os <<
" " << ind[j]+1;
5657 for (j = 0; j < 3; j++)
5659 os <<
' ' << ind[j]+1;
5665 for (p = 1; p <
NRanks; p++)
5667 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
5668 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
5670 MPI_Recv(&ints[0], 3*ne, MPI_INT, p, 447,
MyComm, &status);
5671 for (i = 0; i < ne; i++)
5674 for (j = 0; j < 3; j++)
5676 os <<
' ' << k+ints[i*3+j]+1;
5686 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5690 for (j = 0; j <
Dim; j++)
5694 MPI_Send(&vert[0], Dim*NumOfVertices, MPI_DOUBLE,
5698 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5699 MPI_Send(&NumOfVertices, 1, MPI_INT, 0, 444,
MyComm);
5705 for (j = 0; j < 4; j++)
5710 MPI_Send(&ints[0], 4*NumOfElements, MPI_INT, 0, 447,
MyComm);
5713 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5714 MPI_Send(&NumOfVertices, 1, MPI_INT, 0, 444,
MyComm);
5716 MPI_Send(&ne, 1, MPI_INT, 0, 446,
MyComm);
5721 for (j = 0; j < 3; j++)
5726 for ( ; i < ne; i++)
5729 for (j = 0; j < 3; j++)
5734 MPI_Send(&ints[0], 3*ne, MPI_INT, 0, 447,
MyComm);
5740 int i, j, k, nv, ne,
p;
5746 int TG_nv, TG_ne, TG_nbe;
5753 MPI_Reduce(&nv, &TG_nbe, 1, MPI_INT, MPI_SUM, 0,
MyComm);
5756 <<
"1 " << TG_nv <<
" " << TG_ne <<
" 0 0 0 0 0 0 0\n"
5757 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
5758 <<
"0 0 " << TG_nbe <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
5759 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
5760 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
5767 <<
" " <<
vertices[i](2) <<
" 0.0\n";
5769 for (p = 1; p <
NRanks; p++)
5771 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
5773 MPI_Recv(&vert[0],
Dim*nv, MPI_DOUBLE, p, 445,
MyComm, &status);
5774 for (i = 0; i < nv; i++)
5776 os << i+1 <<
" 0.0 " << vert[
Dim*i] <<
" " << vert[
Dim*i+1]
5777 <<
" " << vert[
Dim*i+2] <<
" 0.0\n";
5787 os << i+1 <<
" " << 1;
5788 for (j = 0; j < nv; j++)