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"
29 ParMesh::ParMesh(
const ParMesh &pmesh,
bool copy_nodes)
31 group_svert(pmesh.group_svert),
32 group_sedge(pmesh.group_sedge),
33 group_sface(pmesh.group_sface),
65 MFEM_VERIFY(pmesh.
pncmesh == NULL,
66 "copy of parallel non-conforming meshes is not implemented");
71 if (pmesh.
Nodes && copy_nodes)
103 int* partition =
new int[mesh.
GetNE()];
104 for (
int i = 0; i < mesh.
GetNE(); i++)
143 partitioning = partitioning_;
155 int vert_counter, element_counter, bdrelem_counter;
158 vert_global_local = -1;
162 for (i = 0; i < mesh.
GetNE(); i++)
163 if (partitioning[i] ==
MyRank)
167 for (j = 0; j < vert.
Size(); j++)
168 if (vert_global_local[vert[j]] < 0)
170 vert_global_local[vert[j]] = vert_counter++;
179 for (i = vert_counter = 0; i < vert_global_local.
Size(); i++)
180 if (vert_global_local[i] >= 0)
182 vert_global_local[i] = vert_counter++;
186 for (i = 0; i < vert_global_local.Size(); i++)
187 if (vert_global_local[i] >= 0)
198 for (i = 0; i < mesh.
GetNE(); i++)
199 if (partitioning[i] ==
MyRank)
202 int *v =
elements[element_counter]->GetVertices();
203 int nv =
elements[element_counter]->GetNVertices();
204 for (j = 0; j < nv; j++)
206 v[j] = vert_global_local[v[j]];
211 Table *edge_element = NULL;
215 activeBdrElem =
false;
221 for (i = 0; i < mesh.
GetNBE(); i++)
223 int face, o, el1, el2;
226 if (partitioning[(o % 2 == 0 || el2 < 0) ? el1 : el2] ==
MyRank)
231 activeBdrElem[i] =
true;
238 for (i = 0; i < mesh.
GetNBE(); i++)
240 int face, o, el1, el2;
243 if (partitioning[(o % 2 == 0 || el2 < 0) ? el1 : el2] ==
MyRank)
246 int *v =
boundary[bdrelem_counter]->GetVertices();
247 int nv =
boundary[bdrelem_counter]->GetNVertices();
248 for (j = 0; j < nv; j++)
250 v[j] = vert_global_local[v[j]];
258 edge_element =
new Table;
262 for (i = 0; i < mesh.
GetNBE(); i++)
265 int el1 = edge_element->
GetRow(edge)[0];
266 if (partitioning[el1] ==
MyRank)
271 activeBdrElem[i] =
true;
278 for (i = 0; i < mesh.
GetNBE(); i++)
281 int el1 = edge_element->
GetRow(edge)[0];
282 if (partitioning[el1] ==
MyRank)
285 int *v =
boundary[bdrelem_counter]->GetVertices();
286 int nv =
boundary[bdrelem_counter]->GetNVertices();
287 for (j = 0; j < nv; j++)
289 v[j] = vert_global_local[v[j]];
298 for (i = 0; i < mesh.
GetNBE(); i++)
300 int vert = mesh.
boundary[i]->GetVertices()[0];
303 if (partitioning[el1] ==
MyRank)
311 for (i = 0; i < mesh.
GetNBE(); i++)
313 int vert = mesh.
boundary[i]->GetVertices()[0];
316 if (partitioning[el1] ==
MyRank)
319 int *v =
boundary[bdrelem_counter]->GetVertices();
320 v[0] = vert_global_local[v[0]];
366 "(Dim < 3 && mesh.GetNFaces() != 0) is true!" << endl;
371 int sface_counter = 0;
373 for (i = 0; i < face_group.Size(); i++)
380 el[0] = partitioning[el[0]];
381 el[1] = partitioning[el[1]];
386 face_group[i] = groups.
Insert(group) - 1;
393 int sedge_counter = 0;
396 edge_element =
new Table;
406 for (i = 0; i < edge_element->
Size(); i++)
408 int me = 0, others = 0;
409 for (j = edge_element->
GetI()[i]; j < edge_element->
GetI()[i+1]; j++)
411 edge_element->
GetJ()[j] = partitioning[edge_element->
GetJ()[j]];
430 edge_element->
GetRow(i)[0] = -1;
435 int svert_counter = 0;
438 for (i = 0; i < vert_element->
Size(); i++)
440 int me = 0, others = 0;
441 for (j = vert_element->
GetI()[i]; j < vert_element->
GetI()[i+1]; j++)
443 vert_element->
GetJ()[j] = partitioning[vert_element->
GetJ()[j]];
458 vert_element->
GetI()[i] = groups.
Insert(group) - 1;
462 vert_element->
GetI()[i] = -1;
469 for (i = 0; i < face_group.Size(); i++)
471 if (face_group[i] >= 0)
480 for (i = 0; i < face_group.Size(); i++)
482 if (face_group[i] >= 0)
493 for (i = 0; i < edge_element->
Size(); i++)
495 if (edge_element->
GetRow(i)[0] >= 0)
504 for (i = 0; i < edge_element->
Size(); i++)
506 if (edge_element->
GetRow(i)[0] >= 0)
517 for (i = 0; i < vert_element->
Size(); i++)
519 if (vert_element->
GetI()[i] >= 0)
528 for (i = 0; i < vert_element->
Size(); i++)
530 if (vert_element->
GetI()[i] >= 0)
545 for (i = 0; i < face_group.Size(); i++)
547 if (face_group[i] >= 0)
552 for (j = 0; j < nv; j++)
554 v[j] = vert_global_local[v[j]];
559 sface_lface[sface_counter] = (*faces_tbl)(v[0], v[1], v[2]);
573 if (
MyRank == partitioning[gl_el2])
575 std::swap(v[0], v[1]);
582 (*faces_tbl)(v[0], v[1], v[2], v[3]);
601 for (i = 0; i < edge_element->
Size(); i++)
603 if (edge_element->
GetRow(i)[0] >= 0)
608 new Segment(vert_global_local[vert[0]],
609 vert_global_local[vert[1]], 1);
612 v_to_v(vert_global_local[vert[0]],
613 vert_global_local[vert[1]])) < 0)
616 <<
"ERROR in v_to_v\n\n" << endl;
631 for (i = 0; i < vert_element->
Size(); i++)
633 if (vert_element->
GetI()[i] >= 0)
635 svert_lvert[svert_counter++] = vert_global_local[i];
648 "invalid NURBS mesh");
668 Nodes->MakeOwner(nfec);
675 for (i = 0; i < mesh.
GetNE(); i++)
676 if (partitioning[i] ==
MyRank)
679 mesh.
GetNodes()->FESpace()->GetElementVDofs(i, gvdofs);
680 mesh.
GetNodes()->GetSubVector(gvdofs, lnodes);
686 if (partitioning_ == NULL)
688 delete [] partitioning;
696 : MyComm(pncmesh.MyComm)
697 , NRanks(pncmesh.NRanks)
698 , MyRank(pncmesh.MyRank)
724 Loader(input, gen_edges,
"mfem_serial_mesh_end");
730 MFEM_VERIFY(ident ==
"communication_groups",
731 "input stream is not a parallel MFEM mesh");
741 input >> ident >> num_sverts;
750 input >> ident >> num_sedges;
766 input >> ident >> num_sfaces;
781 int svert_counter = 0, sedge_counter = 0, sface_counter = 0;
788 mfem::err <<
"ParMesh::ParMesh : expecting group " << gr
789 <<
", read group " << g << endl;
795 input >> ident >> nv;
798 "incorrect number of total_shared_vertices");
800 for ( ; svert_counter < nv; svert_counter++)
809 input >> ident >> ne;
812 "incorrect number of total_shared_edges");
814 for ( ; sedge_counter < ne; sedge_counter++)
817 input >> v[0] >> v[1];
819 sedge_ledge[sedge_counter] = (*v_to_v)(v[0], v[1]);
825 input >> ident >> nf;
828 "incorrect number of total_shared_faces");
830 for ( ; sface_counter < nf; sface_counter++)
839 sface_lface[sface_counter] = (*faces_tbl)(v[0], v[1], v[2]);
843 (*faces_tbl)(v[0], v[1], v[2], v[3]);
852 const bool refine =
true;
853 const bool fix_orientation =
false;
864 :
Mesh(orig_mesh, ref_factor, ref_type),
865 MyComm(orig_mesh->GetComm()),
866 NRanks(orig_mesh->GetNRanks()),
867 MyRank(orig_mesh->GetMyRank()),
868 gtopo(orig_mesh->gtopo),
869 have_face_nbr_data(false),
895 for (
int fi = 0; fi < orig_nf; fi++)
897 const int orig_l_face = orig_mesh->
sface_lface[orig_sf[fi]];
928 for (
int j = 0; j < orig_n_verts; j++)
935 const int orig_n_edges = orig_mesh->
GroupNEdges(gr);
939 for (
int e = 0; e < orig_n_edges; e++)
944 for (
int j = 2; j < rdofs.
Size(); j++)
948 const int *c2h_map = rfec.
GetDofMap(geom);
953 for (
int k = 0; k < nvert; k++)
956 v[k] = rdofs[c2h_map[cid]];
965 for (
int f = 0; f < orig_nf; f++)
967 const int orig_l_face = orig_mesh->
sface_lface[orig_sf[f]];
977 for (
int j = rdofs.
Size()-num_int_verts; j < rdofs.
Size(); j++)
981 const int *c2h_map = rfec.
GetDofMap(geom);
987 for (
int k = 0; k < 2; k++)
989 v[k] = rdofs[c2h_map[RG.
RefEdges[j+k]]];
998 for (
int k = 0; k < nvert; k++)
1001 v[k] = rdofs[c2h_map[cid]];
1019 const int l_edge = v_to_v(v[0], v[1]);
1020 MFEM_ASSERT(l_edge >= 0,
"invalid shared edge");
1036 l_face = (*faces_tbl)(v[0], v[1], v[2]);
1039 l_face = (*faces_tbl)(v[0], v[1], v[2], v[3]);
1042 MFEM_ABORT(
"invalid face geometry");
1045 MFEM_ASSERT(l_face >= 0,
"invalid shared face");
1057 o = (v[0] < v[1]) ? (+1) : (-1);
1088 gr_sedge.
GetI()[0] = 0;
1107 sedge_comm.
Bcast<
int>(sedge_ord, 1);
1109 for (
int k = 0, gr = 1; gr <
GetNGroups(); gr++)
1112 if (n == 0) {
continue; }
1113 sedge_ord_map.SetSize(n);
1114 for (
int j = 0; j < n; j++)
1116 sedge_ord_map[j].one = sedge_ord[k+j];
1117 sedge_ord_map[j].two = j;
1119 SortPairs<int, int>(sedge_ord_map, n);
1120 for (
int j = 0; j < n; j++)
1125 std::sort(&sedge_ord[k], &sedge_ord[k] + n);
1126 for (
int j = 0; j < n; j++)
1143 ilen_len[j].one = order[j];
1144 ilen_len[j].two =
GetLength(i, it.Column());
1148 SortPairs<int, double>(ilen_len, order.
Size());
1151 for (
int i = 1; i < order.
Size(); i++)
1153 d_max = std::max(d_max, ilen_len[i-1].two-ilen_len[i].two);
1163 MPI_Reduce(&d_max, &glob_d_max, 1, MPI_DOUBLE, MPI_MAX, 0,
MyComm);
1166 mfem::out <<
"glob_d_max = " << glob_d_max << endl;
1178 elements[i]->MarkEdge(v_to_v, order);
1186 boundary[i]->MarkEdge(v_to_v, order);
1208 if ((m = v_to_v(v[0], v[1])) != -1 && middle[m] != -1)
1229 int number_of_splittings = 0;
1232 if ((m = v_to_v(v[0], v[1])) != -1 && middle[m] != -1)
1234 number_of_splittings++;
1235 if ((m = v_to_v(v[1], v[2])) != -1 && middle[m] != -1)
1238 number_of_splittings++;
1240 if ((m = v_to_v(v[2], v[0])) != -1 && middle[m] != -1)
1242 number_of_splittings++;
1245 switch (number_of_splittings)
1250 number_of_splittings++;
1254 number_of_splittings++;
1259 return number_of_splittings;
1265 if (HYPRE_AssumedPartitionCheck())
1268 MPI_Scan(loc_sizes, temp.
GetData(), N, HYPRE_MPI_INT, MPI_SUM,
MyComm);
1269 for (
int i = 0; i < N; i++)
1272 (*offsets[i])[0] = temp[i] - loc_sizes[i];
1273 (*offsets[i])[1] = temp[i];
1276 for (
int i = 0; i < N; i++)
1278 (*offsets[i])[2] = temp[i];
1280 MFEM_VERIFY((*offsets[i])[0] >= 0 && (*offsets[i])[1] >= 0,
1281 "overflow in offsets");
1287 MPI_Allgather(loc_sizes, N, HYPRE_MPI_INT, temp.
GetData(), N,
1289 for (
int i = 0; i < N; i++)
1294 for (
int j = 0; j <
NRanks; j++)
1296 offs[j+1] = offs[j] + temp[i+N*j];
1300 "overflow in offsets");
1322 for (
int j = 0; j < nv; j++)
1341 for (
int j = 0; j < n; j++)
1343 pointmat(k,j) = (pNodes->
FaceNbrData())(vdofs[n*k+j]);
1351 MFEM_ABORT(
"Nodes are not ParGridFunction!");
1413 int num_face_nbrs = 0;
1415 if (gr_sface->
RowSize(g-1) > 0)
1422 if (num_face_nbrs == 0)
1432 for (
int g = 1, counter = 0; g <
GetNGroups(); g++)
1433 if (gr_sface->
RowSize(g-1) > 0)
1437 mfem_error(
"ParMesh::ExchangeFaceNbrData() : "
1438 "group size is not 2!");
1441 int lproc = (nbs[0]) ? nbs[0] : nbs[1];
1443 rank_group[counter].two = g;
1447 SortPairs<int, int>(rank_group, rank_group.
Size());
1449 for (
int fn = 0; fn < num_face_nbrs; fn++)
1455 MPI_Request *requests =
new MPI_Request[2*num_face_nbrs];
1456 MPI_Request *send_requests = requests;
1457 MPI_Request *recv_requests = requests + num_face_nbrs;
1458 MPI_Status *statuses =
new MPI_Status[num_face_nbrs];
1460 int *nbr_data =
new int[6*num_face_nbrs];
1461 int *nbr_send_data = nbr_data;
1462 int *nbr_recv_data = nbr_data + 3*num_face_nbrs;
1469 Table send_face_nbr_elemdata, send_face_nbr_facedata;
1473 send_face_nbr_elemdata.
MakeI(num_face_nbrs);
1474 send_face_nbr_facedata.
MakeI(num_face_nbrs);
1475 for (
int fn = 0; fn < num_face_nbrs; fn++)
1478 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
1479 int *sface = gr_sface->
GetRow(nbr_group-1);
1480 for (
int i = 0; i < num_sfaces; i++)
1482 int lface = s2l_face[sface[i]];
1484 if (el_marker[el] != fn)
1489 const int nv =
elements[el]->GetNVertices();
1490 const int *v =
elements[el]->GetVertices();
1491 for (
int j = 0; j < nv; j++)
1492 if (vertex_marker[v[j]] != fn)
1494 vertex_marker[v[j]] = fn;
1505 nbr_send_data[3*fn+2] = send_face_nbr_elemdata.
GetI()[fn];
1510 MPI_Isend(&nbr_send_data[3*fn], 3, MPI_INT, nbr_rank, tag,
MyComm,
1511 &send_requests[fn]);
1512 MPI_Irecv(&nbr_recv_data[3*fn], 3, MPI_INT, nbr_rank, tag,
MyComm,
1513 &recv_requests[fn]);
1517 send_face_nbr_elemdata.
MakeJ();
1518 send_face_nbr_facedata.
MakeJ();
1521 for (
int fn = 0; fn < num_face_nbrs; fn++)
1524 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
1525 int *sface = gr_sface->
GetRow(nbr_group-1);
1526 for (
int i = 0; i < num_sfaces; i++)
1528 int lface = s2l_face[sface[i]];
1530 if (el_marker[el] != fn)
1535 const int nv =
elements[el]->GetNVertices();
1536 const int *v =
elements[el]->GetVertices();
1537 for (
int j = 0; j < nv; j++)
1538 if (vertex_marker[v[j]] != fn)
1540 vertex_marker[v[j]] = fn;
1556 const int *sf_v =
shared_faces[sface[i]]->GetVertices();
1577 for (
int fn = 0; fn < num_face_nbrs; fn++)
1583 int *elemdata = send_face_nbr_elemdata.
GetRow(fn);
1584 int num_sfaces = send_face_nbr_facedata.
RowSize(fn)/2;
1585 int *facedata = send_face_nbr_facedata.
GetRow(fn);
1587 for (
int i = 0; i < num_verts; i++)
1589 vertex_marker[verts[i]] = i;
1592 for (
int el = 0; el < num_elems; el++)
1594 const int nv =
elements[el]->GetNVertices();
1596 for (
int j = 0; j < nv; j++)
1598 elemdata[j] = vertex_marker[elemdata[j]];
1602 el_marker[elems[el]] = el;
1605 for (
int i = 0; i < num_sfaces; i++)
1607 facedata[2*i] = el_marker[facedata[2*i]];
1611 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
1614 Table recv_face_nbr_elemdata;
1619 recv_face_nbr_elemdata.
MakeI(num_face_nbrs);
1622 for (
int fn = 0; fn < num_face_nbrs; fn++)
1630 recv_face_nbr_elemdata.
MakeJ();
1632 MPI_Waitall(num_face_nbrs, send_requests, statuses);
1635 for (
int fn = 0; fn < num_face_nbrs; fn++)
1640 MPI_Isend(send_face_nbr_elemdata.
GetRow(fn),
1641 send_face_nbr_elemdata.
RowSize(fn),
1642 MPI_INT, nbr_rank, tag,
MyComm, &send_requests[fn]);
1644 MPI_Irecv(recv_face_nbr_elemdata.
GetRow(fn),
1645 recv_face_nbr_elemdata.
RowSize(fn),
1646 MPI_INT, nbr_rank, tag,
MyComm, &recv_requests[fn]);
1654 MPI_Waitany(num_face_nbrs, recv_requests, &fn, statuses);
1656 if (fn == MPI_UNDEFINED)
1664 int *recv_elemdata = recv_face_nbr_elemdata.
GetRow(fn);
1666 for (
int i = 0; i < num_elems; i++)
1672 for (
int j = 0; j < nv; j++)
1674 recv_elemdata[j] += vert_off;
1677 recv_elemdata += nv;
1682 MPI_Waitall(num_face_nbrs, send_requests, statuses);
1685 recv_face_nbr_facedata.
SetSize(
1687 for (
int fn = 0; fn < num_face_nbrs; fn++)
1692 MPI_Isend(send_face_nbr_facedata.
GetRow(fn),
1693 send_face_nbr_facedata.
RowSize(fn),
1694 MPI_INT, nbr_rank, tag,
MyComm, &send_requests[fn]);
1697 MPI_Irecv(&recv_face_nbr_facedata[send_face_nbr_facedata.
GetI()[fn]],
1698 send_face_nbr_facedata.
RowSize(fn),
1699 MPI_INT, nbr_rank, tag,
MyComm, &recv_requests[fn]);
1706 MPI_Waitany(num_face_nbrs, recv_requests, &fn, statuses);
1708 if (fn == MPI_UNDEFINED)
1715 int num_sfaces = gr_sface->
RowSize(nbr_group-1);
1716 int *sface = gr_sface->
GetRow(nbr_group-1);
1718 &recv_face_nbr_facedata[send_face_nbr_facedata.
GetI()[fn]];
1720 for (
int i = 0; i < num_sfaces; i++)
1722 int lface = s2l_face[sface[i]];
1724 face_info.
Elem2No = -1 - (facedata[2*i] + elem_off);
1725 int info = facedata[2*i+1];
1733 int nbr_ori = info%64, nbr_v[4];
1735 const int *sf_v =
shared_faces[sface[i]]->GetVertices();
1741 for (
int j = 0; j < 3; j++)
1743 nbr_v[perm[j]] = sf_v[j];
1752 for (
int j = 0; j < 4; j++)
1754 nbr_v[perm[j]] = sf_v[j];
1760 info = 64*(info/64) + nbr_ori;
1766 MPI_Waitall(num_face_nbrs, send_requests, statuses);
1787 else if (
Nodes == NULL)
1797 MPI_Request *requests =
new MPI_Request[2*num_face_nbrs];
1798 MPI_Request *send_requests = requests;
1799 MPI_Request *recv_requests = requests + num_face_nbrs;
1800 MPI_Status *statuses =
new MPI_Status[num_face_nbrs];
1804 for (
int i = 0; i < send_vertices.Size(); i++)
1810 for (
int fn = 0; fn < num_face_nbrs; fn++)
1817 MPI_DOUBLE, nbr_rank, tag,
MyComm, &send_requests[fn]);
1822 MPI_DOUBLE, nbr_rank, tag, MyComm, &recv_requests[fn]);
1825 MPI_Waitall(num_face_nbrs, recv_requests, statuses);
1826 MPI_Waitall(num_face_nbrs, send_requests, statuses);
1834 MFEM_VERIFY(pNodes != NULL,
"Nodes are not ParGridFunction!");
1845 int nbr_lproc = (nbs[0]) ? nbs[0] : nbs[1];
1887 for (
int i = 0; i < s2l_face->
Size(); i++)
1902 for (
int i = 0; i < s2l_face->
Size(); i++)
1904 int lface = (*s2l_face)[i];
1905 int nbr_elem_idx = -1 -
faces_info[lface].Elem2No;
1929 #if 0 // TODO: handle the case of non-interpolatory Nodes
1957 int local_face = is_ghost ? nc_info->
MasterFace : FaceNo;
2006 if (is_ghost || fill2)
2015 std::swap(pm(0,0), pm(0,1));
2016 std::swap(pm(1,0), pm(1,1));
2043 MFEM_ASSERT(
Dim > 1,
"");
2062 MFEM_ASSERT(
Dim > 1,
"");
2065 return sface < csize
2067 : shared.
slaves[sface - csize].index;
2121 MFEM_ABORT(
"Local and nonconforming refinements cannot be mixed.");
2130 int uniform_refinement = 0;
2134 uniform_refinement = 1;
2149 for (i = 0; i < marked_el.
Size(); i++)
2151 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
2155 for (i = 0; i < marked_el.
Size(); i++)
2157 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
2160 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
2164 for (i = 0; i < marked_el.
Size(); i++)
2166 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
2169 Bisection(j, v_to_v, NULL, NULL, middle);
2171 Bisection(j, v_to_v, NULL, NULL, middle);
2173 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
2175 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
2181 int need_refinement;
2182 int refined_edge[5][3] =
2190 int faces_in_group, max_faces_in_group = 0;
2192 int **face_splittings =
new int*[
GetNGroups()-1];
2196 face_splittings[i] =
new int[faces_in_group];
2197 if (faces_in_group > max_faces_in_group)
2199 max_faces_in_group = faces_in_group;
2202 int neighbor, *iBuf =
new int[max_faces_in_group];
2206 MPI_Request request;
2209 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2210 int ref_loops_all = 0, ref_loops_par = 0;
2214 need_refinement = 0;
2217 if (
elements[i]->NeedRefinement(v_to_v, middle))
2219 need_refinement = 1;
2220 Bisection(i, v_to_v, NULL, NULL, middle);
2223 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2227 if (uniform_refinement)
2234 if (need_refinement == 0)
2236 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2240 const int tag = 293;
2246 faces_in_group = group_faces.
Size();
2248 if (faces_in_group == 0) {
continue; }
2250 for (j = 0; j < faces_in_group; j++)
2252 face_splittings[i][j] =
2258 MPI_Isend(face_splittings[i], faces_in_group, MPI_INT,
2259 neighbor, tag,
MyComm, &request);
2266 faces_in_group = group_faces.
Size();
2267 if (faces_in_group == 0) {
continue; }
2271 MPI_Recv(iBuf, faces_in_group, MPI_INT, neighbor,
2274 for (j = 0; j < faces_in_group; j++)
2276 if (iBuf[j] == face_splittings[i][j]) {
continue; }
2279 for (
int k = 0; k < 3; k++)
2281 if (refined_edge[iBuf[j]][k] != 1 ||
2282 refined_edge[face_splittings[i][j]][k] != 0)
2285 int ind[2] = { v[k], v[(k+1)%3] };
2286 int ii = v_to_v(ind[0], ind[1]);
2287 if (middle[ii] == -1)
2289 need_refinement = 1;
2298 i = need_refinement;
2299 MPI_Allreduce(&i, &need_refinement, 1, MPI_INT, MPI_LOR,
MyComm);
2302 while (need_refinement == 1);
2304 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2306 MPI_Reduce(&i, &ref_loops_all, 1, MPI_INT, MPI_MAX, 0,
MyComm);
2309 mfem::out <<
"\n\nParMesh::LocalRefinement : max. ref_loops_all = "
2310 << ref_loops_all <<
", ref_loops_par = " << ref_loops_par
2318 delete [] face_splittings[i];
2320 delete [] face_splittings;
2326 need_refinement = 0;
2329 if (
boundary[i]->NeedRefinement(v_to_v, middle))
2331 need_refinement = 1;
2336 while (need_refinement == 1);
2341 " (NumOfBdrElements != boundary.Size())");
2355 int refinement_edges[2], type, flag;
2380 int uniform_refinement = 0;
2384 uniform_refinement = 1;
2393 int *edge1 =
new int[nedges];
2394 int *edge2 =
new int[nedges];
2395 int *middle =
new int[nedges];
2397 for (i = 0; i < nedges; i++)
2399 edge1[i] = edge2[i] = middle[i] = -1;
2404 int *v =
elements[i]->GetVertices();
2405 for (j = 0; j < 3; j++)
2407 int ind = v_to_v(v[j], v[(j+1)%3]);
2408 (edge1[ind] == -1) ? (edge1[ind] = i) : (edge2[ind] = i);
2413 for (i = 0; i < marked_el.
Size(); i++)
2419 int need_refinement;
2420 int edges_in_group, max_edges_in_group = 0;
2422 int **edge_splittings =
new int*[
GetNGroups()-1];
2426 edge_splittings[i] =
new int[edges_in_group];
2427 if (edges_in_group > max_edges_in_group)
2429 max_edges_in_group = edges_in_group;
2432 int neighbor, *iBuf =
new int[max_edges_in_group];
2436 MPI_Request request;
2441 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2442 int ref_loops_all = 0, ref_loops_par = 0;
2446 need_refinement = 0;
2447 for (i = 0; i < nedges; i++)
2448 if (middle[i] != -1 && edge1[i] != -1)
2450 need_refinement = 1;
2453 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2457 if (uniform_refinement)
2464 if (need_refinement == 0)
2466 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2475 edges_in_group = group_edges.
Size();
2477 if (edges_in_group != 0)
2479 for (j = 0; j < edges_in_group; j++)
2481 edge_splittings[i][j] =
2494 MPI_Isend(edge_splittings[i], edges_in_group, MPI_INT,
2495 neighbor, 0,
MyComm, &request);
2503 edges_in_group = group_edges.
Size();
2504 if (edges_in_group != 0)
2515 MPI_Recv(iBuf, edges_in_group, MPI_INT, neighbor,
2516 MPI_ANY_TAG,
MyComm, &status);
2518 for (j = 0; j < edges_in_group; j++)
2519 if (iBuf[j] == 1 && edge_splittings[i][j] == 0)
2522 int ii = v_to_v(v[0], v[1]);
2523 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2524 if (middle[ii] != -1)
2525 mfem_error(
"ParMesh::LocalRefinement (triangles) : "
2528 need_refinement = 1;
2530 for (
int c = 0; c < 2; c++)
2539 i = need_refinement;
2540 MPI_Allreduce(&i, &need_refinement, 1, MPI_INT, MPI_LOR,
MyComm);
2543 while (need_refinement == 1);
2545 #ifdef MFEM_DEBUG_PARMESH_LOCALREF
2547 MPI_Reduce(&i, &ref_loops_all, 1, MPI_INT, MPI_MAX, 0,
MyComm);
2550 mfem::out <<
"\n\nParMesh::LocalRefinement : max. ref_loops_all = "
2551 << ref_loops_all <<
", ref_loops_par = " << ref_loops_par
2558 delete [] edge_splittings[i];
2560 delete [] edge_splittings;
2565 int v1[2], v2[2], bisect, temp;
2567 for (i = 0; i < temp; i++)
2569 int *v =
boundary[i]->GetVertices();
2570 bisect = v_to_v(v[0], v[1]);
2571 if (middle[bisect] != -1)
2576 v1[0] = v[0]; v1[1] = middle[bisect];
2577 v2[0] = middle[bisect]; v2[1] = v[1];
2583 mfem_error(
"Only bisection of segment is implemented for bdr"
2615 for (j = 0; j < marked_el.
Size(); j++)
2620 int new_v = cnv + j, new_e = cne + j;
2629 static double seg_children[3*2] = { 0.0,1.0, 0.0,0.5, 0.5,1.0 };
2651 MFEM_ABORT(
"ParMesh::NonconformingRefinement: NURBS meshes are not "
2652 "supported. Project the NURBS to Nodes first.");
2657 MFEM_ABORT(
"Can't convert conforming ParMesh to nonconforming ParMesh "
2658 "(you need to initialize the ParMesh from a nonconforming "
2682 Swap(*pmesh2,
false);
2699 double threshold,
int nc_limit,
int op)
2712 for (
int i = 0; i < dt.
Size(); i++)
2714 if (nc_limit > 0 && !level_ok[i]) {
continue; }
2716 const int* fine = dt.
GetRow(i);
2720 for (
int j = 0; j < size; j++)
2722 MFEM_VERIFY(fine[j] < elem_error.
Size(),
"");
2724 double err_fine = elem_error[fine[j]];
2727 case 0: error = std::min(error, err_fine);
break;
2728 case 1: error += err_fine;
break;
2729 case 2: error = std::max(error, err_fine);
break;
2733 if (error < threshold) { derefs.
Append(i); }
2750 MFEM_ABORT(
"Load balancing is currently not supported for conforming"
2764 Swap(*pmesh2,
false);
2781 int i, attr, newv[3], ind, f_ind, *v;
2784 Array<int> group_verts, group_edges, group_faces;
2792 int *I_group_svert, *J_group_svert;
2793 int *I_group_sedge, *J_group_sedge;
2794 int *I_group_sface, *J_group_sface;
2804 I_group_sface = NULL;
2807 I_group_svert[0] = I_group_svert[1] = 0;
2808 I_group_sedge[0] = I_group_sedge[1] = 0;
2811 I_group_sface[0] = I_group_sface[1] = 0;
2828 J_group_sface = NULL;
2832 J_group_svert = J_group_sedge = J_group_sface = NULL;
2835 for (group = 0; group <
GetNGroups()-1; group++)
2846 ind = middle[v_to_v(v[0], v[1])];
2863 ind = middle[v_to_v(v[0], v[1])];
2871 f_ind = group_faces.
Size();
2874 newv[0] = v[2]; newv[1] = v[0]; newv[2] = ind;
2879 ind = middle[v_to_v(v[0], v[1])];
2888 newv[0] = v[2]; newv[1] = v[0]; newv[2] = ind;
2894 ind = middle[v_to_v(v[0], v[1])];
2903 newv[0] = v[2]; newv[1] = v[0]; newv[2] = ind;
2909 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
2910 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
2913 I_group_sface[group+1] = I_group_sface[group] + group_faces.
Size();
2917 J = J_group_svert+I_group_svert[group];
2918 for (i = 0; i < group_verts.
Size(); i++)
2920 J[i] = group_verts[i];
2922 J = J_group_sedge+I_group_sedge[group];
2923 for (i = 0; i < group_edges.
Size(); i++)
2925 J[i] = group_edges[i];
2929 J = J_group_sface+I_group_sface[group];
2930 for (i = 0; i < group_faces.
Size(); i++)
2932 J[i] = group_faces[i];
2982 int i, attr, ind, *v;
2987 int *I_group_svert, *J_group_svert;
2988 int *I_group_sedge, *J_group_sedge;
2993 I_group_svert[0] = I_group_svert[1] = 0;
2994 I_group_sedge[0] = I_group_sedge[1] = 0;
3001 for (group = 0; group <
GetNGroups()-1; group++)
3021 I_group_svert[group+1] = I_group_svert[group] + sverts.
Size();
3022 I_group_sedge[group+1] = I_group_sedge[group] + sedges.
Size();
3025 J = J_group_svert+I_group_svert[group];
3026 for (i = 0; i < sverts.
Size(); i++)
3030 J = J_group_sedge+I_group_sedge[group];
3031 for (i = 0; i < sedges.
Size(); i++)
3074 int i, attr, newv[4], ind, m[5];
3078 Array<int> group_verts, group_edges, group_faces;
3080 int *I_group_svert, *J_group_svert;
3081 int *I_group_sedge, *J_group_sedge;
3082 int *I_group_sface, *J_group_sface;
3089 I_group_svert[0] = I_group_svert[1] = 0;
3090 I_group_sedge[0] = I_group_sedge[1] = 0;
3091 I_group_sface[0] = I_group_sface[1] = 0;
3097 I_group_svert[0] = 0;
3098 I_group_sedge[0] = 0;
3099 I_group_sface[0] = 0;
3110 for (group = 0; group <
GetNGroups()-1; group++)
3121 ind = oedge + v_to_v(v[0], v[1]);
3128 newv[0] = v[0]; newv[1] = ind;
3136 m[0] = oface+(*faces_tbl)(v[0], v[1], v[2], v[3]);
3141 m[1] = oedge + v_to_v(v[0], v[1]);
3142 m[2] = oedge + v_to_v(v[1], v[2]);
3143 m[3] = oedge + v_to_v(v[2], v[3]);
3144 m[4] = oedge + v_to_v(v[3], v[0]);
3154 newv[0] = v[0]; newv[1] = m[1]; newv[2] = m[0]; newv[3] = m[4];
3164 I_group_svert[group+1] = I_group_svert[group] + group_verts.
Size();
3165 I_group_sedge[group+1] = I_group_sedge[group] + group_edges.
Size();
3166 I_group_sface[group+1] = I_group_sface[group] + group_faces.
Size();
3169 J = J_group_svert+I_group_svert[group];
3170 for (i = 0; i < group_verts.
Size(); i++)
3172 J[i] = group_verts[i];
3174 J = J_group_sedge+I_group_sedge[group];
3175 for (i = 0; i < group_edges.
Size(); i++)
3177 J[i] = group_edges[i];
3179 J = J_group_sface+I_group_sface[group];
3180 for (i = 0; i < group_faces.
Size(); i++)
3182 J[i] = group_faces[i];
3200 sface_lface[i] = (*faces_tbl)(v[0], v[1], v[2], v[3]);
3216 mfem::out <<
"\nParMesh::NURBSUniformRefinement : Not supported yet!\n";
3222 MFEM_ASSERT(
Dim ==
spaceDim,
"2D manifolds not supported");
3228 out <<
"NETGEN_Neutral_Format\n";
3233 for (j = 0; j <
Dim; j++)
3246 out <<
elements[i]->GetAttribute();
3247 for (j = 0; j < nv; j++)
3249 out <<
" " << ind[j]+1;
3261 out <<
boundary[i]->GetAttribute();
3262 for (j = 0; j < nv; j++)
3264 out <<
" " << ind[j]+1;
3274 for (j = 0; j < nv; j++)
3276 out <<
" " << ind[j]+1;
3289 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
3291 <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
3292 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
3293 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
3298 <<
" " <<
vertices[i](2) <<
" 0.0\n";
3305 out << i+1 <<
" " <<
elements[i]->GetAttribute();
3306 for (j = 0; j < nv; j++)
3308 out <<
" " << ind[j]+1;
3318 out <<
boundary[i]->GetAttribute();
3319 for (j = 0; j < nv; j++)
3321 out <<
" " << ind[j]+1;
3323 out <<
" 1.0 1.0 1.0 1.0\n";
3332 for (j = 0; j < nv; j++)
3334 out <<
" " << ind[j]+1;
3336 out <<
" 1.0 1.0 1.0 1.0\n";
3345 out <<
"areamesh2\n\n";
3352 attr =
boundary[i]->GetAttribute();
3355 for (j = 0; j < v.
Size(); j++)
3357 out << v[j] + 1 <<
" ";
3367 for (j = 0; j < v.
Size(); j++)
3369 out << v[j] + 1 <<
" ";
3378 attr =
elements[i]->GetAttribute();
3394 for (j = 0; j < v.
Size(); j++)
3396 out << v[j] + 1 <<
" ";
3405 for (j = 0; j <
Dim; j++)
3430 bool print_shared =
true;
3431 int i, j, shared_bdr_attr;
3448 s2l_face = &nc_shared_faces;
3455 for (
unsigned i = 0; i < sfaces.
conforming.size(); i++)
3458 if (index < nfaces) { nc_shared_faces.
Append(index); }
3460 for (
unsigned i = 0; i < sfaces.
masters.size(); i++)
3463 int index = sfaces.
masters[i].index;
3464 if (index < nfaces) { nc_shared_faces.
Append(index); }
3466 for (
unsigned i = 0; i < sfaces.
slaves.size(); i++)
3468 int index = sfaces.
slaves[i].index;
3469 if (index < nfaces) { nc_shared_faces.
Append(index); }
3474 out <<
"MFEM mesh v1.0\n";
3478 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
3483 "# TETRAHEDRON = 4\n"
3487 out <<
"\ndimension\n" <<
Dim
3495 if (print_shared &&
Dim > 1)
3497 num_bdr_elems += s2l_face->
Size();
3499 out <<
"\nboundary\n" << num_bdr_elems <<
'\n';
3505 if (print_shared &&
Dim > 1)
3513 shared_bdr_attr =
MyRank + 1;
3515 for (i = 0; i < s2l_face->
Size(); i++)
3518 faces[(*s2l_face)[i]]->SetAttribute(shared_bdr_attr);
3550 for (
int i = 0; i < nv; i++)
3558 int i, j, k, p, nv_ne[2], &nv = nv_ne[0], &ne = nv_ne[1], vc;
3566 out <<
"MFEM mesh v1.0\n";
3570 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
3575 "# TETRAHEDRON = 4\n"
3579 out <<
"\ndimension\n" <<
Dim;
3583 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3586 out <<
"\n\nelements\n" << ne <<
'\n';
3590 out << 1 <<
' ' <<
elements[i]->GetGeometryType();
3594 for (j = 0; j < nv; j++)
3601 for (p = 1; p <
NRanks; p++)
3603 MPI_Recv(nv_ne, 2, MPI_INT, p, 444,
MyComm, &status);
3607 MPI_Recv(&ints[0], ne, MPI_INT, p, 445,
MyComm, &status);
3609 for (i = 0; i < ne; )
3612 out << p+1 <<
' ' << ints[i];
3615 for (j = 0; j < k; j++)
3617 out <<
' ' << vc + ints[i++];
3630 ne += 1 +
elements[i]->GetNVertices();
3633 MPI_Send(nv_ne, 2, MPI_INT, 0, 444,
MyComm);
3641 MFEM_ASSERT(ints.
Size() == ne,
"");
3644 MPI_Send(&ints[0], ne, MPI_INT, 0, 445,
MyComm);
3667 dump_element(
boundary[i], ints); ne++;
3672 for (i = 0; i < shared.
Size(); i++)
3674 dump_element(shared[i], ints); ne++;
3681 for (i = 0; i < (int) list.
conforming.size(); i++)
3684 if (index < nfaces) { dump_element(
faces[index], ints); ne++; }
3686 for (i = 0; i < (int) list.
masters.size(); i++)
3688 int index = list.
masters[i].index;
3689 if (index < nfaces) { dump_element(
faces[index], ints); ne++; }
3691 for (i = 0; i < (int) list.
slaves.size(); i++)
3693 int index = list.
slaves[i].index;
3694 if (index < nfaces) { dump_element(
faces[index], ints); ne++; }
3698 MPI_Reduce(&ne, &k, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3701 out <<
"\nboundary\n" << k <<
'\n';
3703 for (p = 0; p <
NRanks; p++)
3707 MPI_Recv(nv_ne, 2, MPI_INT, p, 446,
MyComm, &status);
3711 MPI_Recv(ints.
GetData(), ne, MPI_INT, p, 447,
MyComm, &status);
3719 for (i = 0; i < ne; )
3722 out << p+1 <<
' ' << ints[i];
3725 for (j = 0; j < k; j++)
3727 out <<
' ' << vc + ints[i++];
3738 MPI_Send(nv_ne, 2, MPI_INT, 0, 446,
MyComm);
3749 out <<
"\nvertices\n" << nv <<
'\n';
3765 for (p = 1; p <
NRanks; p++)
3767 MPI_Recv(&nv, 1, MPI_INT, p, 448,
MyComm, &status);
3771 MPI_Recv(&vert[0], nv*spaceDim, MPI_DOUBLE, p, 449,
MyComm, &status);
3773 for (i = 0; i < nv; i++)
3778 out <<
' ' << vert[i*spaceDim+j];
3793 vert[i*spaceDim+j] =
vertices[i](j);
3798 MPI_Send(&vert[0], NumOfVertices*spaceDim, MPI_DOUBLE, 0, 449,
MyComm);
3825 mfem_error(
"ParMesh::PrintAsOne : Nodes have no parallel info!");
3833 MFEM_ASSERT(
Dim ==
spaceDim,
"2D Manifolds not supported.");
3836 int i, j, k, nv, ne, p;
3844 out <<
"NETGEN_Neutral_Format\n";
3847 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3851 for (j = 0; j <
Dim; j++)
3857 for (p = 1; p <
NRanks; p++)
3859 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
3861 MPI_Recv(&vert[0],
Dim*nv, MPI_DOUBLE, p, 445,
MyComm, &status);
3862 for (i = 0; i < nv; i++)
3864 for (j = 0; j <
Dim; j++)
3866 out <<
" " << vert[Dim*i+j];
3874 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3881 for (j = 0; j < nv; j++)
3883 out <<
" " << ind[j]+1;
3888 for (p = 1; p <
NRanks; p++)
3890 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
3891 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
3893 MPI_Recv(&ints[0], 4*ne, MPI_INT, p, 447,
MyComm, &status);
3894 for (i = 0; i < ne; i++)
3897 for (j = 0; j < 4; j++)
3899 out <<
" " << k+ints[i*4+j]+1;
3907 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3915 for (j = 0; j < nv; j++)
3917 out <<
" " << ind[j]+1;
3927 for (j = 0; j < nv; j++)
3929 out <<
" " << ind[j]+1;
3934 for (p = 1; p <
NRanks; p++)
3936 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
3937 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
3939 MPI_Recv(&ints[0], 3*ne, MPI_INT, p, 447,
MyComm, &status);
3940 for (i = 0; i < ne; i++)
3943 for (j = 0; j < 3; j++)
3945 out <<
" " << k+ints[i*3+j]+1;
3955 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3959 for (j = 0; j <
Dim; j++)
3963 MPI_Send(&vert[0], Dim*NumOfVertices, MPI_DOUBLE,
3967 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3968 MPI_Send(&NumOfVertices, 1, MPI_INT, 0, 444,
MyComm);
3974 for (j = 0; j < 4; j++)
3979 MPI_Send(&ints[0], 4*NumOfElements, MPI_INT, 0, 447,
MyComm);
3982 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
3983 MPI_Send(&NumOfVertices, 1, MPI_INT, 0, 444,
MyComm);
3985 MPI_Send(&ne, 1, MPI_INT, 0, 446,
MyComm);
3990 for (j = 0; j < 3; j++)
3995 for ( ; i < ne; i++)
3998 for (j = 0; j < 3; j++)
4003 MPI_Send(&ints[0], 3*ne, MPI_INT, 0, 447,
MyComm);
4009 int i, j, k, nv, ne, p;
4015 int TG_nv, TG_ne, TG_nbe;
4022 MPI_Reduce(&nv, &TG_nbe, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4025 <<
"1 " << TG_nv <<
" " << TG_ne <<
" 0 0 0 0 0 0 0\n"
4026 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
4027 <<
"0 0 " << TG_nbe <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
4028 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
4029 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
4035 <<
" " <<
vertices[i](2) <<
" 0.0\n";
4036 for (p = 1; p <
NRanks; p++)
4038 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
4040 MPI_Recv(&vert[0],
Dim*nv, MPI_DOUBLE, p, 445,
MyComm, &status);
4041 for (i = 0; i < nv; i++)
4042 out << i+1 <<
" 0.0 " << vert[
Dim*i] <<
" " << vert[
Dim*i+1]
4043 <<
" " << vert[
Dim*i+2] <<
" 0.0\n";
4052 out << i+1 <<
" " << 1;
4053 for (j = 0; j < nv; j++)
4055 out <<
" " << ind[j]+1;
4060 for (p = 1; p <
NRanks; p++)
4062 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
4063 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
4065 MPI_Recv(&ints[0], 8*ne, MPI_INT, p, 447,
MyComm, &status);
4066 for (i = 0; i < ne; i++)
4068 out << i+1 <<
" " << p+1;
4069 for (j = 0; j < 8; j++)
4071 out <<
" " << k+ints[i*8+j]+1;
4086 for (j = 0; j < nv; j++)
4088 out <<
" " << ind[j]+1;
4090 out <<
" 1.0 1.0 1.0 1.0\n";
4098 for (j = 0; j < nv; j++)
4100 out <<
" " << ind[j]+1;
4102 out <<
" 1.0 1.0 1.0 1.0\n";
4105 for (p = 1; p <
NRanks; p++)
4107 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
4108 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
4110 MPI_Recv(&ints[0], 4*ne, MPI_INT, p, 447,
MyComm, &status);
4111 for (i = 0; i < ne; i++)
4114 for (j = 0; j < 4; j++)
4116 out <<
" " << k+ints[i*4+j]+1;
4118 out <<
" 1.0 1.0 1.0 1.0\n";
4128 MPI_Reduce(&nv, &TG_nbe, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4133 for (j = 0; j <
Dim; j++)
4137 MPI_Send(&vert[0], Dim*NumOfVertices, MPI_DOUBLE, 0, 445,
MyComm);
4139 MPI_Send(&NumOfVertices, 1, MPI_INT, 0, 444,
MyComm);
4145 for (j = 0; j < 8; j++)
4150 MPI_Send(&ints[0], 8*NumOfElements, MPI_INT, 0, 447,
MyComm);
4152 MPI_Send(&NumOfVertices, 1, MPI_INT, 0, 444,
MyComm);
4154 MPI_Send(&ne, 1, MPI_INT, 0, 446,
MyComm);
4159 for (j = 0; j < 4; j++)
4164 for ( ; i < ne; i++)
4167 for (j = 0; j < 4; j++)
4172 MPI_Send(&ints[0], 4*ne, MPI_INT, 0, 447,
MyComm);
4178 int i, j, k, attr, nv, ne, p;
4187 out <<
"areamesh2\n\n";
4191 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4196 attr =
boundary[i]->GetAttribute();
4199 for (j = 0; j < v.
Size(); j++)
4201 out << v[j] + 1 <<
" ";
4211 for (j = 0; j < v.
Size(); j++)
4213 out << v[j] + 1 <<
" ";
4218 for (p = 1; p <
NRanks; p++)
4220 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
4221 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
4223 MPI_Recv(&ints[0], 2*ne, MPI_INT, p, 447,
MyComm, &status);
4224 for (i = 0; i < ne; i++)
4227 for (j = 0; j < 2; j++)
4229 out <<
" " << k+ints[i*2+j]+1;
4238 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4244 out << 1 <<
" " << 3 <<
" ";
4245 for (j = 0; j < v.
Size(); j++)
4247 out << v[j] + 1 <<
" ";
4252 for (p = 1; p <
NRanks; p++)
4254 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
4255 MPI_Recv(&ne, 1, MPI_INT, p, 446,
MyComm, &status);
4257 MPI_Recv(&ints[0], 3*ne, MPI_INT, p, 447,
MyComm, &status);
4258 for (i = 0; i < ne; i++)
4260 out << p+1 <<
" " << 3;
4261 for (j = 0; j < 3; j++)
4263 out <<
" " << k+ints[i*3+j]+1;
4272 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4276 for (j = 0; j <
Dim; j++)
4282 for (p = 1; p <
NRanks; p++)
4284 MPI_Recv(&nv, 1, MPI_INT, p, 444,
MyComm, &status);
4286 MPI_Recv(&vert[0],
Dim*nv, MPI_DOUBLE, p, 445,
MyComm, &status);
4287 for (i = 0; i < nv; i++)
4289 for (j = 0; j <
Dim; j++)
4291 out <<
" " << vert[Dim*i+j];
4301 MPI_Reduce(&nv, &ne, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4304 MPI_Send(&ne, 1, MPI_INT, 0, 446,
MyComm);
4309 for (j = 0; j < 2; j++)
4314 for ( ; i < ne; i++)
4317 for (j = 0; j < 2; j++)
4322 MPI_Send(&ints[0], 2*ne, MPI_INT, 0, 447,
MyComm);
4325 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4332 for (j = 0; j < 3; j++)
4337 MPI_Send(&ints[0], 3*NumOfElements, MPI_INT, 0, 447,
MyComm);
4340 MPI_Reduce(&ne, &nv, 1, MPI_INT, MPI_SUM, 0,
MyComm);
4344 for (j = 0; j <
Dim; j++)
4348 MPI_Send(&vert[0], Dim*NumOfVertices, MPI_DOUBLE,
4366 MPI_Allreduce(p_min.
GetData(), gp_min, sdim, MPI_DOUBLE, MPI_MIN,
MyComm);
4367 MPI_Allreduce(p_max.
GetData(), gp_max, sdim, MPI_DOUBLE, MPI_MAX,
MyComm);
4371 double &gk_min,
double &gk_max)
4373 double h_min, h_max, kappa_min, kappa_max;
4377 MPI_Allreduce(&h_min, &gh_min, 1, MPI_DOUBLE, MPI_MIN,
MyComm);
4378 MPI_Allreduce(&h_max, &gh_max, 1, MPI_DOUBLE, MPI_MAX,
MyComm);
4379 MPI_Allreduce(&kappa_min, &gk_min, 1, MPI_DOUBLE, MPI_MIN,
MyComm);
4380 MPI_Allreduce(&kappa_max, &gk_max, 1, MPI_DOUBLE, MPI_MAX,
MyComm);
4387 double h_min, h_max, kappa_min, kappa_max, h,
kappa;
4391 out <<
"Parallel Mesh Stats:" <<
'\n';
4397 h = pow(fabs(J.
Det()), 1.0/
double(
Dim));
4402 kappa_min = kappa_max =
kappa;
4406 if (h < h_min) { h_min = h; }
4407 if (h > h_max) { h_max = h; }
4408 if (kappa < kappa_min) { kappa_min =
kappa; }
4409 if (kappa > kappa_max) { kappa_max =
kappa; }
4413 double gh_min, gh_max, gk_min, gk_max;
4414 MPI_Reduce(&h_min, &gh_min, 1, MPI_DOUBLE, MPI_MIN, 0,
MyComm);
4415 MPI_Reduce(&h_max, &gh_max, 1, MPI_DOUBLE, MPI_MAX, 0,
MyComm);
4416 MPI_Reduce(&kappa_min, &gk_min, 1, MPI_DOUBLE, MPI_MIN, 0,
MyComm);
4417 MPI_Reduce(&kappa_max, &gk_max, 1, MPI_DOUBLE, MPI_MAX, 0,
MyComm);
4420 long mindata[5], maxdata[5], sumdata[5];
4436 MPI_Reduce(ldata, mindata, 5, MPI_LONG, MPI_MIN, 0,
MyComm);
4437 MPI_Reduce(ldata, sumdata, 5, MPI_LONG, MPI_SUM, 0,
MyComm);
4438 MPI_Reduce(ldata, maxdata, 5, MPI_LONG, MPI_MAX, 0,
MyComm);
4444 << setw(12) <<
"minimum"
4445 << setw(12) <<
"average"
4446 << setw(12) <<
"maximum"
4447 << setw(12) <<
"total" <<
'\n';
4449 << setw(12) << mindata[0]
4450 << setw(12) << sumdata[0]/
NRanks
4451 << setw(12) << maxdata[0]
4452 << setw(12) << sumdata[0] <<
'\n';
4454 << setw(12) << mindata[1]
4455 << setw(12) << sumdata[1]/
NRanks
4456 << setw(12) << maxdata[1]
4457 << setw(12) << sumdata[1] <<
'\n';
4460 << setw(12) << mindata[2]
4461 << setw(12) << sumdata[2]/
NRanks
4462 << setw(12) << maxdata[2]
4463 << setw(12) << sumdata[2] <<
'\n';
4465 << setw(12) << mindata[3]
4466 << setw(12) << sumdata[3]/
NRanks
4467 << setw(12) << maxdata[3]
4468 << setw(12) << sumdata[3] <<
'\n';
4469 out <<
" neighbors "
4470 << setw(12) << mindata[4]
4471 << setw(12) << sumdata[4]/
NRanks
4472 << setw(12) << maxdata[4] <<
'\n';
4475 << setw(12) <<
"minimum"
4476 << setw(12) <<
"maximum" <<
'\n';
4478 << setw(12) << gh_min
4479 << setw(12) << gh_max <<
'\n';
4481 << setw(12) << gk_min
4482 << setw(12) << gk_max <<
'\n';
4489 long local = value, global;
4490 MPI_Allreduce(&local, &global, 1, MPI_LONG, MPI_SUM,
MyComm);
4506 Printer(out,
"mfem_serial_mesh_end");
4514 out <<
"total_shared_edges " <<
shared_edges.Size() <<
'\n';
4518 out <<
"total_shared_faces " <<
shared_faces.Size() <<
'\n';
4525 out <<
"\n#group " << gr <<
"\nshared_vertices " << nv <<
'\n';
4526 for (
int i = 0; i < nv; i++)
4535 out <<
"\nshared_edges " << ne <<
'\n';
4536 for (
int i = 0; i < ne; i++)
4539 out << v[0] <<
' ' << v[1] <<
'\n';
4546 out <<
"\nshared_faces " << nf <<
'\n';
4547 for (
int i = 0; i < nf; i++)
4555 out <<
"\nmfem_mesh_end" << endl;
4562 const int npts = point_mat.
Width();
4563 if (npts == 0) {
return 0; }
4565 const bool no_warn =
false;
4572 Array<int> my_point_rank(npts), glob_point_rank(npts);
4573 for (
int k = 0; k < npts; k++)
4575 my_point_rank[k] = (elem_id[k] == -1) ?
NRanks :
MyRank;
4578 MPI_Allreduce(my_point_rank.GetData(), glob_point_rank.
GetData(), npts,
4579 MPI_INT, MPI_MIN,
MyComm);
4582 for (
int k = 0; k < npts; k++)
4584 if (glob_point_rank[k] ==
NRanks) { elem_id[k] = -1; }
4588 if (glob_point_rank[k] !=
MyRank) { elem_id[k] = -2; }
4591 if (warn && pts_found != npts &&
MyRank == 0)
4593 MFEM_WARNING((npts-pts_found) <<
" points were not found");
int GetNPoints() const
Returns the number of the points in the integration rule.
Abstract class for Finite Elements.
int GetNFaceNeighbors() const
void PrintAsOneXG(std::ostream &out=mfem::out)
Old mesh format (Netgen/Truegrid) version of 'PrintAsOne'.
void Create(ListOfIntegerSets &groups, int mpitag)
void Loader(std::istream &input, int generate_edges=0, std::string parse_tag="")
Ordering::Type GetOrdering() const
Return the ordering method.
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
int Size() const
Logical size of the array.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
void Recreate(const int n, const int *p)
Class for an integration rule - an Array of IntegrationPoint.
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
Class for grid function - Vector with associated FE space.
void Bcast(T *ldata, int layout) const
Broadcast within each group where the master is the root.
void UseExternalData(double *ext_data, int i, int j, int k)
void FreeElement(Element *E)
void DerefineMesh(const Array< int > &derefinements)
Derefine elements once a list of derefinements is known.
void ExchangeFaceNbrData()
virtual void Update(bool want_transform=true)
int CheckElementOrientation(bool fix_it=true)
Check the orientation of the elements.
void SetSize(int dim, int connections_per_row)
Set the size and the number of connections for the table.
virtual Element * Duplicate(Mesh *m) const =0
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
void AddColumnsInRow(int r, int ncol)
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
void GetFaceElements(int Face, int *Elem1, int *Elem2)
Array< Element * > boundary
int * GeneratePartitioning(int nparts, int part_method=1)
CoarseFineTransformations CoarseFineTr
virtual void ReorientTetMesh()
See the remarks for the serial version in mesh.hpp.
void SetSize(int s)
Resize the vector to size s.
int GetNBE() const
Returns number of boundary elements.
IsoparametricTransformation Transformation
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void GetCharacteristics(double &h_min, double &h_max, double &kappa_min, double &kappa_max, Vector *Vh=NULL, Vector *Vk=NULL)
int GetFaceGeometryType(int Face) const
void MakeOwner(FiniteElementCollection *_fec)
Make the GridFunction the owner of 'fec' and 'fes'.
Array< Element * > face_nbr_elements
void GetFaceNeighbors(class ParMesh &pmesh)
Lists all edges/faces in the nonconforming mesh.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
int GetGroupSize(int g) const
int GetNSharedFaces() const
Return the number of shared faces (3D), edges (2D), vertices (1D)
void GetBoundingBox(Vector &min, Vector &max, int ref=2)
void SetDims(int rows, int nnz)
const int * GetGroup(int g) const
void Copy(Array ©) const
Create a copy of the current array.
RefinedGeometry * Refine(int Geom, int Times, int ETimes=1)
T * GetData()
Returns the data.
void SaveAsOne(std::ostream &out=mfem::out)
Merge the local grid functions.
virtual void LocalRefinement(const Array< int > &marked_el, int type=3)
This function is not public anymore. Use GeneralRefinement instead.
Data type dense matrix using column-major storage.
ElementTransformation * GetGhostFaceTransformation(FaceElementTransformations *FETr, int face_type, int face_geom)
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
const FiniteElement * GetTraceElement(int i, int geom_type) const
Return the trace element from element 'i' to the given 'geom_type'.
int GetBdrElementEdgeIndex(int i) const
void GetCharacteristics(double &h_min, double &h_max, double &kappa_min, double &kappa_max)
int GetNE() const
Returns number of elements.
void SynchronizeDerefinementData(Array< Type > &elem_data, const Table &deref_table)
const Element * GetFace(int i) const
virtual void SetVertices(const int *ind)
Set the indices the element according to the input.
virtual void OnMeshUpdated(Mesh *mesh)
Abstract parallel finite element space.
Array< int > face_nbr_vertices_offset
std::vector< MeshId > conforming
Array< int > face_nbr_group
static int GetQuadOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Data type quadrilateral element.
void GetVertices(Vector &vert_coord) const
int GetFaceElementType(int Face) const
double * GetData() const
Return a pointer to the beginning of the Vector data.
virtual void MarkTetMeshForRefinement(DSTable &v_to_v)
int Size_of_connections() const
const IntegrationRule * GetVertices(int GeomType)
Return an IntegrationRule consisting of all vertices of the given Geometry::Type, GeomType...
const NCList & GetSharedEdges()
void GetVertexToVertexTable(DSTable &) const
void RedRefinement(int i, const DSTable &v_to_v, int *edge1, int *edge2, int *middle)
void skip_comment_lines(std::istream &is, const char comment_char)
int GetGeometryType() const
void DeleteAll()
Delete whole array.
void AddConnections(int r, const int *c, int nc)
void InitRefinementTransforms()
IsoparametricTransformation FaceTransformation
const NCList & GetSharedList(int entity)
Helper to get shared vertices/edges/faces ('entity' == 0/1/2 resp.).
Array< NCFaceInfo > nc_faces_info
bool IAmMaster(int g) const
bool WantSkipSharedMaster(const NCMesh::Master &master) const
A parallel extension of the NCMesh class.
void GetSharedEdgeDofs(int group, int ei, Array< int > &dofs) const
Element * NewElement(int geom)
FaceElementTransformations FaceElemTr
int GroupVertex(int group, int i)
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
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...
void GetFaceNbrElementVDofs(int i, Array< int > &vdofs) const
void ExchangeFaceNbrData()
virtual void Save(std::ostream &out) const
Save the GridFunction to an output stream.
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
void GetElementJacobian(int i, DenseMatrix &J)
void Rebalance()
Load balance the mesh. NC meshes only.
void GetVertexDofs(int i, Array< int > &dofs) const
bool Nonconforming() const
Communicator performing operations within groups defined by a GroupTopology with arbitrary-size data ...
const FiniteElement * GetFaceNbrFE(int i) const
void GetSharedFaceDofs(int group, int fi, Array< int > &dofs) const
Array< int > face_nbr_elements_offset
void GetEdgeOrdering(DSTable &v_to_v, Array< int > &order)
void GetBoundingBox(Vector &p_min, Vector &p_max, int ref=2)
const Table & GetDerefinementTable()
Array< Element * > shared_edges
int Append(const T &el)
Append element to array, resize if necessary.
virtual void NonconformingRefinement(const Array< Refinement > &refinements, int nc_limit=0)
This function is not public anymore. Use GeneralRefinement instead.
int GetSharedFace(int sface) const
Return the local face index for the given shared face.
int GetNumNeighbors() const
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void PrintAsOne(std::ostream &out=mfem::out)
void Finalize()
Allocate internal buffers after the GroupLDofTable is defined.
void GetFaceTransformation(int i, IsoparametricTransformation *FTr)
Returns the transformation defining the given face element in a user-defined variable.
void CreateRefinementFlag(int refinement_edges[2], int type, int flag=0)
std::vector< Master > masters
static const int NumVerts[NumGeom]
static FiniteElement * GetTransformationFEforElementType(int)
void AddConnection(int r, int c)
STable3D * GetElementToFaceTable(int ret_ftbl=0)
FaceElementTransformations * GetSharedFaceTransformations(int sf, bool fill2=true)
static void Rotate3(int &, int &, int &)
int MeshGenerator()
Get the mesh generator/type.
Table send_face_nbr_vertices
int GetFaceSplittings(Element *face, const DSTable &v_to_v, int *middle)
Return a number(0-4) identifying how the given face has been split.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
int InitialPartition(int index) const
Helper to get the partitioning when the serial mesh gets split initially.
const int * GetDofMap(int GeomType) const
Get the Cartesian to local H1 dof map.
const IntegrationRule & GetNodes() const
int Insert(IntegerSet &s)
virtual void Print(std::ostream &out=mfem::out) const
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
GeometryRefiner GlobGeometryRefiner
Array< Element * > shared_faces
int GetAttribute() const
Return element's attribute.
int GetElementToEdgeTable(Table &, Array< int > &)
Data type triangle element.
int GetElementType(int i) const
Returns the type of element i.
const Element * GetElement(int i) const
int GroupNVertices(int group)
virtual void QuadUniformRefinement()
Refine quadrilateral mesh.
void GetLocalFaceTransformation(int face_type, int elem_type, IsoparametricTransformation &Transf, int info)
A helper method that constructs a transformation from the reference space of a face to the reference ...
IsoparametricTransformation Transformation2
int GetVDim() const
Returns vector dimension.
int Size() const
Returns the number of TYPE I elements.
FiniteElementSpace * FESpace()
virtual void ReorientTetMesh()
virtual void HexUniformRefinement()
Refine a hexahedral mesh.
int slaves_end
slave faces
Data type tetrahedron element.
int CheckBdrElementOrientation(bool fix_it=true)
Check the orientation of the boundary elements.
int SpaceDimension() const
void GetBdrElementFace(int i, int *, int *) const
Return the index and the orientation of the face of bdr element i. (3D)
void Save(std::ostream &out) const
Save the data in a stream.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void RefineGroups(const DSTable &v_to_v, int *middle)
Update the groups after tet refinement.
virtual bool NonconformingDerefinement(Array< double > &elem_error, double threshold, int nc_limit=0, int op=1)
NC version of GeneralDerefinement.
Array< Vertex > face_nbr_vertices
std::vector< Slave > slaves
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
int GetDof() const
Returns the number of degrees of freedom in the finite element.
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void ApplyLocalSlaveTransformation(IsoparametricTransformation &transf, const FaceInfo &fi)
static void PrintElement(const Element *, std::ostream &)
int GetNeighborRank(int i) const
void AddAColumnInRow(int r)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
virtual long ReduceInt(int value) const
Utility function: sum integers from all processors (Allreduce).
bool IsSlaveFace(const FaceInfo &fi) const
virtual void QuadUniformRefinement()
Refine quadrilateral mesh.
virtual void HexUniformRefinement()
Refine hexahedral mesh.
void Swap(Mesh &other, bool non_geometry=false)
Table & GroupLDofTable()
Fill-in the returned Table reference to initialize the GroupCommunicator then call Finalize()...
Array< Element * > elements
double GetLength(int i, int j) const
Return the length of the segment from node i to node j.
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
int GetElementBaseGeometry(int i=0) const
static FiniteElementCollection * New(const char *name)
Factory method: return a newly allocated FiniteElementCollection according to the given name...
void GetFaceNbrElementTransformation(int i, IsoparametricTransformation *ElTr)
NURBSExtension * NURBSext
Optional NURBS mesh extension.
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
virtual const char * Name() const
virtual void Refine(const Array< Refinement > &refinements)
Element * ReadElementWithoutAttr(std::istream &)
void GroupFace(int group, int i, int &face, int &o)
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
void ExchangeFaceNbrNodes()
void Finalize(bool refine=false, bool fix_orientation=false)
Finalize the construction of a general Mesh.
static const int Orient[NumOrient][NumVert]
void SetIJ(int *newI, int *newJ, int newsize=-1)
Table group_svert
Shared objects in each group.
int GroupNFaces(int group)
virtual int DofForGeometry(int GeomType) const
bool IsGhost(int entity, int index) const
Return true if the specified vertex/edge/face is a ghost.
double CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
void GetVectorValues(ElementTransformation &T, const IntegrationRule &ir, DenseMatrix &vals) const
Array< FaceInfo > faces_info
virtual int GetNVertices() const =0
void SetAttribute(const int attr)
Set element's attribute.
STable3D * GetFacesTable()
NCMesh * ncmesh
Optional non-conforming mesh extension.
static void PrintElementWithoutAttr(const Element *, std::ostream &)
virtual void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level)
int GetEdgeSplittings(Element *edge, const DSTable &v_to_v, int *middle)
Return a number(0-1) identifying how the given edge has been split.
int GetNEdges() const
Return the number of edges.
virtual void PrintXG(std::ostream &out=mfem::out) const
void GetMarkedFace(const int face, int *fv)
void GroupEdge(int group, int i, int &edge, int &o)
int GetNFaces() const
Return the number of faces in a 3D 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...
const FiniteElementCollection * FEColl() const
void GetNodes(Vector &node_coord) const
int GetFaceBaseGeometry(int i) const
void AverageVertices(int *indexes, int n, int result)
void GenerateOffsets(int N, HYPRE_Int loc_sizes[], Array< HYPRE_Int > *offsets[]) const
int NumberOfEntries() const
static int GetTriOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Arbitrary order H1-conforming (continuous) finite elements.
Array< int > svert_lvert
Shared to local index mapping.
const NCList & GetSharedFaces()
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
void ParseRefinementFlag(int refinement_edges[2], int &type, int &flag)
Class for parallel grid function.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Table send_face_nbr_elements
virtual void PrintInfo(std::ostream &out=mfem::out)
Print various parallel mesh stats.
Table * GetFaceToAllElementTable() const
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void InitFromNCMesh(const NCMesh &ncmesh)
Initialize vertices/elements/boundary/tables from a nonconforming mesh.
void Bisection(int i, const DSTable &, int *, int *, int *)
void ParPrint(std::ostream &out) const
Save the mesh in a parallel mesh format.
Class for parallel meshes.
Abstract data type element.
int GetAttribute(int i) const
Return the attribute of element i.
int GetFaceNbrRank(int fn) const
const Table & ElementToEdgeTable() const
Data type line segment element.
void GenerateNCFaceInfo()
void GetElementVertices(int i, Array< int > &v) const
Returns the indices of the vertices of element i.
virtual void LimitNCLevel(int max_nc_level)
Parallel version of NCMesh::LimitNCLevel.
Array< int > attributes
A list of all unique element attributes used by the Mesh.
Table * GetVertexToElementTable()
The returned Table must be destroyed by the caller.
const Element * GetBdrElement(int i) const
static const int Orient[NumOrient][NumVert]
void Load(std::istream &in)
Load the data from a stream.
virtual int GetType() const =0
Returns element's type.
void UpdateNodes()
Update the nodes of a curved mesh after refinement.
Defines the position of a fine element within a coarse element.
int GroupNEdges(int group)
void GreenRefinement(int i, const DSTable &v_to_v, int *edge1, int *edge2, int *middle)
void Printer(std::ostream &out=mfem::out, std::string section_delimiter="") const
ParFiniteElementSpace * ParFESpace() const
virtual void NURBSUniformRefinement()
Refine NURBS mesh.