18 #include "../fem/fem.hpp"
19 #include "../general/sort_pairs.hpp"
20 #include "../general/text.hpp"
21 #include "../general/sets.hpp"
36 PumiMesh::PumiMesh(apf::Mesh2* apf_mesh,
int generate_edges,
int refine,
39 Load(apf_mesh, generate_edges, refine, fix_orientation);
42 Element *PumiMesh::ReadElement(apf::MeshEntity* Ent,
const int geom,
44 const int Attr, apf::Numbering* vert_num)
50 el = NewElement(geom);
55 for (
int i = 0; i < nv; ++i)
57 v[i] = apf::getNumber(vert_num, Verts[i], 0, 0);
66 void PumiMesh::CountBoundaryEntity(apf::Mesh2* apf_mesh,
const int BcDim,
70 apf::MeshIterator* itr = apf_mesh->begin(BcDim);
72 while ((ent=apf_mesh->iterate(itr)))
74 apf::ModelEntity* mdEnt = apf_mesh->toModel(ent);
75 if (apf_mesh->getModelType(mdEnt) == BcDim)
85 MFEM_ABORT(
"no boundary detected!");
89 void PumiMesh::Load(apf::Mesh2* apf_mesh,
int generate_edges,
int refine,
92 int curved = 0, read_gf = 1;
98 apf::Field* apf_field_crd = apf_mesh->getCoordinateField();
99 apf::FieldShape* crd_shape = apf::getShape(apf_field_crd);
100 apf::Numbering* v_num_loc = apf::createNumbering(apf_mesh,
"VertexNumbering",
103 curved = (crd_shape->getOrder() > 1) ? 1 : 0;
106 ReadSCORECMesh(apf_mesh, v_num_loc, curved);
107 mfem::out <<
"After ReadSCORECMesh" << endl;
126 if (curved && read_gf)
130 crd_shape->getOrder());
136 for (
int i = 0; i < spaceDim; i++)
139 Nodes->GetNodalValues(vert_val, i+1);
140 for (
int j = 0; j < NumOfVertices; j++)
142 vertices[j](i) = vert_val(j);
148 apf::destroyNumbering(v_num_loc);
150 Finalize(refine, fix_orientation);
153 void PumiMesh::ReadSCORECMesh(apf::Mesh2* apf_mesh, apf::Numbering* v_num_loc,
159 apf::MeshIterator* itr = apf_mesh->begin(0);
160 apf::MeshEntity* ent;
162 while ((ent = apf_mesh->iterate(itr)))
165 apf::number(v_num_loc, ent, 0, 0, NumOfVertices);
170 Dim = apf_mesh->getDimension();
171 NumOfElements = countOwned(apf_mesh,Dim);
172 elements.SetSize(NumOfElements);
175 itr = apf_mesh->begin(Dim);
177 while ((ent = apf_mesh->iterate(itr)))
181 apf_mesh->getDownward(ent,0,verts);
185 int geom_type = apf_mesh->getType(ent);
186 elements[j] = ReadElement(ent, geom_type, verts, attr, v_num_loc);
195 NumOfBdrElements = 0;
196 CountBoundaryEntity(apf_mesh, BCdim, NumOfBdrElements);
197 boundary.SetSize(NumOfBdrElements);
201 itr = apf_mesh->begin(BCdim);
202 while ((ent = apf_mesh->iterate(itr)))
205 apf::ModelEntity* mdEnt = apf_mesh->toModel(ent);
206 if (apf_mesh->getModelType(mdEnt) == BCdim)
209 apf_mesh->getDownward(ent, 0, verts);
211 int geom_type = apf_mesh->getType(ent);
212 boundary[j] = ReadElement( ent, geom_type, verts, attr, v_num_loc);
219 vertices.SetSize(NumOfVertices);
223 apf::MeshIterator* itr = apf_mesh->begin(0);
226 while ((ent = apf_mesh->iterate(itr)))
228 unsigned int id = apf::getNumber(v_num_loc, ent, 0, 0);
230 apf_mesh->getPoint(ent,0,Crds);
232 for (
int ii=0; ii<spaceDim; ii++)
234 vertices[id](ii) = Crds[ii];
242 Element *ParPumiMesh::ReadElement(apf::MeshEntity* Ent,
const int geom,
244 const int Attr, apf::Numbering* vert_num)
250 el = NewElement(geom);
255 for (
int i = 0; i < nv; ++i)
257 v[i] = apf::getNumber(vert_num, Verts[i], 0, 0);
268 ParPumiMesh::ParPumiMesh(MPI_Comm comm, apf::Mesh2* apf_mesh)
277 MPI_Comm_size(MyComm, &NRanks);
278 MPI_Comm_rank(MyComm, &MyRank);
280 Dim = apf_mesh->getDimension();
284 apf::MeshIterator* itr = apf_mesh->begin(Dim);
285 BaseGeom = apf_mesh->getType(apf_mesh->iterate(itr));
288 itr = apf_mesh->begin(Dim - 1);
289 BaseBdrGeom = apf_mesh->getType(apf_mesh->iterate(itr));
294 apf::FieldShape* v_shape = apf::getConstant(0);
295 apf::Numbering* vLocNum =
296 apf::createNumbering(apf_mesh,
"AuxVertexNumbering", v_shape, 1);
298 itr = apf_mesh->begin(0);
299 apf::MeshEntity* ent;
303 while ((ent = apf_mesh->iterate(itr)))
306 if (apf_mesh->isOwned(ent))
308 apf::number(vLocNum, ent, 0, 0, owned_num++);
310 if (apf_mesh->isShared(ent))
318 apf::GlobalNumbering* VertexNumbering = apf::makeGlobal(vLocNum,
true);
319 apf::synchronize(VertexNumbering);
324 itr = apf_mesh->begin(0);
326 while ((ent = apf_mesh->iterate(itr)))
328 unsigned int id = apf::getNumber(VertexNumbering, ent, 0, 0);
329 thisIds[all_num++] = id;
335 apf::Field* apf_field_crd = apf_mesh->getCoordinateField();
336 apf::FieldShape* crd_shape = apf::getShape(apf_field_crd);
337 apf::Numbering* v_num_loc = apf::createNumbering(apf_mesh,
338 "LocalVertexNumbering",
343 itr = apf_mesh->begin(0);
344 while ((ent = apf_mesh->iterate(itr)))
347 unsigned int id = apf::getNumber(VertexNumbering, ent, 0, 0);
351 apf::number(v_num_loc, ent, 0, 0, ordered_id);
355 if (apf_mesh->isShared(ent))
357 SharedVertIds[shared_num++] = ordered_id;
361 SharedVertIds.
Sort();
362 apf::destroyGlobalNumbering(VertexNumbering);
364 vertices.SetSize(NumOfVertices);
366 itr = apf_mesh->begin(0);
367 while ((ent = apf_mesh->iterate(itr)))
369 unsigned int id = apf::getNumber(v_num_loc, ent, 0, 0);
371 apf_mesh->getPoint(ent,0,Crds);
373 for (
int ii=0; ii<spaceDim; ii++)
375 vertices[id](ii) = Crds[ii];
381 NumOfElements = countOwned(apf_mesh,Dim);
382 elements.SetSize(NumOfElements);
385 itr = apf_mesh->begin(Dim);
387 while ((ent = apf_mesh->iterate(itr)))
391 apf_mesh->getDownward(ent,0,verts);
395 int geom_type = BaseGeom;
396 elements[j] = ReadElement(ent, geom_type, verts, attr, v_num_loc);
402 Table *edge_element = NULL;
406 itr = apf_mesh->begin(BcDim);
407 NumOfBdrElements = 0;
409 while ((ent=apf_mesh->iterate(itr)))
411 apf::ModelEntity* mdEnt = apf_mesh->toModel(ent);
412 if (apf_mesh->getModelType(mdEnt) == BcDim)
419 boundary.
SetSize(NumOfBdrElements);
422 itr = apf_mesh->begin(BcDim);
423 while ((ent = apf_mesh->iterate(itr)))
426 apf::ModelEntity* mdEnt = apf_mesh->toModel(ent);
427 if (apf_mesh->getModelType(mdEnt) == BcDim)
430 apf_mesh->getDownward(ent, 0, verts);
432 int geom_type = BaseBdrGeom;
433 boundary[bdr_ctr] = ReadElement(ent, geom_type, verts, attr,
447 this->FinalizeTopology();
449 STable3D *faces_tbl = (Dim == 3) ? GetFacesTable() : NULL;
458 MFEM_ASSERT(Dim >= 3 || GetNFaces() == 0,
459 "[proc " << MyRank <<
"]: invalid state");
462 int sface_counter = 0;
464 apf::FieldShape* fc_shape =apf::getConstant(2);
465 apf::Numbering* faceNum = apf::createNumbering(apf_mesh,
"FaceNumbering",
471 apf::Numbering* AuxFaceNum =
472 apf::numberOwnedDimension(apf_mesh,
"AuxFaceNumbering", 2);
473 apf::GlobalNumbering* GlobalFaceNum = apf::makeGlobal(AuxFaceNum,
true);
474 apf::synchronize(GlobalFaceNum);
479 itr = apf_mesh->begin(2);
482 while ((ent = apf_mesh->iterate(itr)))
484 unsigned int id = apf::getNumber(GlobalFaceNum, ent, 0, 0);
485 thisFaceIds[all_num++] = id;
486 if (apf_mesh->isShared(ent))
495 SharedFaceIds.
SetSize(shared_num);
497 itr = apf_mesh->begin(2);
498 while ((ent = apf_mesh->iterate(itr)))
501 unsigned int id = apf::getNumber(GlobalFaceNum, ent, 0, 0);
505 apf::number(faceNum, ent, 0, 0, ordered_id);
507 if (apf_mesh->isShared(ent))
509 SharedFaceIds[shared_num++] = ordered_id;
513 SharedFaceIds.
Sort();
514 apf::destroyGlobalNumbering(GlobalFaceNum);
516 itr = apf_mesh->begin(2);
517 while ((ent = apf_mesh->iterate(itr)))
519 int faceId = apf::getNumber(faceNum, ent, 0, 0);
520 face_group[faceId] = -1;
521 if (apf_mesh->isShared(ent))
524 const int thisNumAdjs = 2;
525 int eleRanks[thisNumAdjs];
529 apf_mesh->getResidence(ent, res);
531 for (std::set<int>::iterator itr = res.begin();
532 itr != res.end(); ++itr)
534 eleRanks[kk++] = *itr;
538 face_group[faceId] = groups.
Insert(group) - 1;
546 int sedge_counter = 0;
549 edge_element =
new Table;
556 edge_element->
SetSize(GetNEdges(), 1);
561 apf::Numbering* AuxEdgeNum = apf::numberOwnedDimension(apf_mesh,
563 apf::GlobalNumbering* GlobalEdgeNum = apf::makeGlobal(AuxEdgeNum,
true);
564 apf::synchronize(GlobalEdgeNum);
569 itr = apf_mesh->begin(1);
572 while ((ent = apf_mesh->iterate(itr)))
574 unsigned int id = apf::getNumber(GlobalEdgeNum, ent, 0, 0);
575 thisEdgeIds[all_num++] = id;
576 if (apf_mesh->isShared(ent))
585 apf::FieldShape* ed_shape =apf::getConstant(1);
586 apf::Numbering* edgeNum = apf::createNumbering(apf_mesh,
"EdgeNumbering",
591 itr = apf_mesh->begin(1);
592 while ((ent = apf_mesh->iterate(itr)))
595 unsigned int id = apf::getNumber(GlobalEdgeNum, ent, 0, 0);
599 apf::number(edgeNum, ent, 0, 0, ordered_id);
601 if (apf_mesh->isShared(ent))
603 SharedEdgeIds[shared_num++] = ordered_id;
607 SharedEdgeIds.
Sort();
608 apf::destroyGlobalNumbering(GlobalEdgeNum);
610 itr = apf_mesh->begin(1);
612 while ((ent = apf_mesh->iterate(itr)))
614 int edId = apf::getNumber(edgeNum, ent, 0, 0);
615 edge_element->
GetRow(edId)[0] = -1;
617 if (apf_mesh->isShared(ent))
623 apf_mesh->getResidence(ent, res);
624 int thisNumAdjs = res.size();
629 for (std::set<int>::iterator itr = res.begin();
630 itr != res.end(); itr++)
632 eleRanks[kk++] = *itr;
636 group.
Recreate(thisNumAdjs, eleRanks);
637 edge_element->
GetRow(edId)[0] = groups.
Insert(group) - 1;
645 int svert_counter = 0;
647 vert_element->
SetSize(GetNV(), 1);
649 itr = apf_mesh->begin(0);
650 while ((ent = apf_mesh->iterate(itr)))
652 int vtId = apf::getNumber(v_num_loc, ent, 0, 0);
653 vert_element->
GetRow(vtId)[0] = -1;
655 if (apf_mesh->isShared(ent))
660 apf_mesh->getResidence(ent, res);
661 int thisNumAdjs = res.size();
666 for (std::set<int>::iterator itr = res.begin();
667 itr != res.end(); itr++)
669 eleRanks[kk++] = *itr;
672 group.
Recreate(thisNumAdjs, eleRanks);
673 vert_element->
GetRow(vtId)[0]= groups.
Insert(group) - 1;
679 group_sface.MakeI(groups.
Size()-1);
681 for (i = 0; i < face_group.
Size(); i++)
683 if (face_group[i] >= 0)
685 group_sface.AddAColumnInRow(face_group[i]);
692 for (i = 0; i < face_group.
Size(); i++)
694 if (face_group[i] >= 0)
696 group_sface.AddConnection(face_group[i], sface_counter++);
700 group_sface.ShiftUpI();
703 group_sedge.MakeI(groups.
Size()-1);
705 for (i = 0; i < edge_element->
Size(); i++)
707 if (edge_element->
GetRow(i)[0] >= 0)
709 group_sedge.AddAColumnInRow(edge_element->
GetRow(i)[0]);
716 for (i = 0; i < edge_element->
Size(); i++)
718 if (edge_element->
GetRow(i)[0] >= 0)
720 group_sedge.AddConnection(edge_element->
GetRow(i)[0], sedge_counter++);
724 group_sedge.ShiftUpI();
727 group_svert.MakeI(groups.
Size()-1);
729 for (i = 0; i < vert_element->
Size(); i++)
731 if (vert_element->
GetRow(i)[0] >= 0)
733 group_svert.AddAColumnInRow(vert_element->
GetRow(i)[0]);
740 for (i = 0; i < vert_element->
Size(); i++)
742 if (vert_element->
GetRow(i)[0] >= 0)
744 group_svert.AddConnection(vert_element->
GetRow(i)[0], svert_counter++);
747 group_svert.ShiftUpI();
750 shared_faces.SetSize(sface_counter);
751 sface_lface. SetSize(sface_counter);
756 itr = apf_mesh->begin(2);
757 while ((ent = apf_mesh->iterate(itr)))
759 if (apf_mesh->isShared(ent))
762 int fcId = apf::getNumber(faceNum, ent, 0, 0);
766 apf_mesh->getDownward(ent,0,verts);
767 int geom = BaseBdrGeom;
769 shared_faces[ctr] = ReadElement(ent, geom, verts, attr,
772 int *v = shared_faces[ctr]->GetVertices();
775 case Element::TRIANGLE:
776 sface_lface[ctr] = (*faces_tbl)(v[0], v[1], v[2]);
779 case Element::QUADRILATERAL:
781 (*faces_tbl)(v[0], v[1], v[2], v[3]);
792 shared_edges.SetSize(sedge_counter);
793 sedge_ledge. SetSize(sedge_counter);
797 GetVertexToVertexTable(v_to_v);
800 itr = apf_mesh->begin(1);
801 while ((ent = apf_mesh->iterate(itr)))
803 if (apf_mesh->isShared(ent))
805 int edId = apf::getNumber(edgeNum, ent, 0, 0);
808 apf_mesh->getDownward(ent, 0, verts);
810 id1 = apf::getNumber(v_num_loc, verts[0], 0, 0);
811 id2 = apf::getNumber(v_num_loc, verts[1], 0, 0);
812 if (id1 > id2) { swap(id1,id2); }
814 shared_edges[ctr] =
new Segment(id1, id2, 1);
815 if ((sedge_ledge[ctr] = v_to_v(id1,id2)) < 0)
817 mfem::err <<
"\n\n\n" << MyRank <<
": ParPumiMesh::ParPumiMesh: "
818 <<
"ERROR in v_to_v\n\n" << endl;
831 svert_lvert.
SetSize(svert_counter);
834 itr = apf_mesh->begin(0);
835 while ((ent = apf_mesh->iterate(itr)))
837 if (apf_mesh->isShared(ent))
839 int vt_id = apf::getNumber(v_num_loc, ent, 0, 0);
841 svert_lvert[ctr] = vt_id;
850 gtopo.Create(groups, 822);
853 int curved = (crd_shape->getOrder() > 1) ? 1 : 0;
857 crd_shape->getOrder());
859 Nodes->Vector::Swap(auxNodes);
860 this->edge_vertex = NULL;
863 apf::destroyNumbering(edgeNum);
864 apf::destroyNumbering(faceNum);
869 GridFunctionPumi::GridFunctionPumi(
Mesh* m, apf::Mesh2* PumiM,
870 apf::Numbering* v_num_loc,
871 const int mesh_order)
876 int ordering = Ordering::byVDIM;
878 int data_size = fes->GetVSize();
881 this->SetSize(data_size);
882 double* PumiData = this->GetData();
884 apf::MeshEntity* ent;
885 apf::MeshIterator* itr;
890 int nnodes = All_nodes.
Size();
893 apf::Field* crd_field = PumiM->getCoordinateField();
895 int nc = apf::countComponents(crd_field);
898 while ((ent = PumiM->iterate(itr)))
901 fes->GetElementVDofs(iel, vdofs);
904 apf::MeshElement* mE = apf::createMeshElement(PumiM, ent);
905 apf::Element* elem = apf::createElement(crd_field, mE);
908 for (
int ip = 0; ip < nnodes; ip++)
917 apf::DynamicVector phCrd(nc);
918 apf::getComponents(elem, param, &phCrd[0]);
921 for (
int kk = 0; kk < spDim; ++kk)
923 int dof_ctr = ip + kk * nnodes;
924 PumiData[vdofs[dof_ctr]] = phCrd[kk];
928 apf::destroyElement(elem);
929 apf::destroyMeshElement(mE);
938 void ParPumiMesh::UpdateMesh(
const ParMesh* AdaptedpMesh)
946 for (
int i = 0; i < shared_faces.Size(); i++)
948 FreeElement(shared_faces[i]);
950 for (
int i = 0; i < shared_edges.Size(); i++)
952 FreeElement(shared_edges[i]);
954 shared_faces.DeleteAll();
955 shared_edges.DeleteAll();
959 svert_lvert.DeleteAll();
960 sedge_ledge.DeleteAll();
961 sface_lface.DeleteAll();
967 MFEM_ASSERT(Dim == AdaptedpMesh->
Dim,
"");
968 MFEM_ASSERT(spaceDim == AdaptedpMesh->
spaceDim,
"");
969 MFEM_ASSERT(BaseGeom == AdaptedpMesh->
BaseGeom,
"");
970 MFEM_ASSERT(BaseBdrGeom == AdaptedpMesh->
BaseBdrGeom,
"");
972 NumOfVertices = AdaptedpMesh->
GetNV();
973 NumOfElements = AdaptedpMesh->
GetNE();
974 NumOfBdrElements = AdaptedpMesh->
GetNBE();
978 meshgen = AdaptedpMesh->
meshgen;
982 last_operation = Mesh::NONE;
985 elements.SetSize(NumOfElements);
986 for (
int i = 0; i < NumOfElements; i++)
992 AdaptedpMesh->
vertices.Copy(vertices);
995 boundary.SetSize(NumOfBdrElements);
996 for (
int i = 0; i < NumOfBdrElements; i++)
1020 faces.SetSize(AdaptedpMesh->
faces.Size());
1021 for (
int i = 0; i < faces.Size(); i++)
1024 faces[i] = (face) ? face->
Duplicate(
this) : NULL;
1043 MFEM_VERIFY(AdaptedpMesh->
NURBSext == NULL,
1044 "invalid adapted mesh: it is a NURBS mesh");
1048 MFEM_VERIFY(AdaptedpMesh->
ncmesh == NULL && AdaptedpMesh->
pncmesh == NULL,
1049 "invalid adapted mesh: it is a non-conforming mesh");
1059 MyComm = AdaptedpMesh->
MyComm;
1060 NRanks = AdaptedpMesh->
NRanks;
1061 MyRank = AdaptedpMesh->
MyRank;
1064 shared_edges.SetSize(AdaptedpMesh->
shared_edges.Size());
1065 for (
int i = 0; i < shared_edges.Size(); i++)
1067 shared_edges[i] = AdaptedpMesh->
shared_edges[i]->Duplicate(
this);
1071 shared_faces.SetSize(AdaptedpMesh->
shared_faces.Size());
1072 for (
int i = 0; i < shared_faces.Size(); i++)
1074 shared_faces[i] = AdaptedpMesh->
shared_faces[i]->Duplicate(
this);
1083 have_face_nbr_data =
false;
1087 if (AdaptedpMesh->
Nodes)
1092 FiniteElementCollection::New(fec->
Name());
1097 Nodes->MakeOwner(fec_copy);
1098 *Nodes = *(AdaptedpMesh->
Nodes);
1105 void ParPumiMesh::FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
1108 apf::Field* VelField,
1109 apf::Field* PrField,
1110 apf::Field* VelMagField)
1112 apf::FieldShape* VelFieldShape = getShape(VelField);
1113 int num_nodes = 4 * VelFieldShape->countNodesOn(0) +
1114 6 * VelFieldShape->countNodesOn(1) +
1115 4 * VelFieldShape->countNodesOn(2) +
1116 VelFieldShape->countNodesOn(4);
1121 apf::Vector3 xi_crd(0.,0.,0.);
1128 double pt_crd[3] = {0., 0., 0.};
1130 for (
int kk = 0; kk < 3; kk++)
1133 double pt_crd[3] = {0.,0.,0.};
1138 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
1140 const int nn = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
1141 for (
int ii = 0; ii < 6; ii++)
1143 for (
int jj = 0; jj < nn; jj++)
1145 VelFieldShape->getNodeXi(apf::Mesh::EDGE, jj, xi_crd);
1146 xi_crd[0] = 0.5 * (xi_crd[0] + 1.);
1147 double pt_crd[3] = {0., 0., 0.};
1151 pt_crd[0] = xi_crd[0];
1154 pt_crd[0] = 1. - xi_crd[0];
1155 pt_crd[1] = xi_crd[0];
1158 pt_crd[1] = xi_crd[0];
1161 pt_crd[2] = xi_crd[0];
1164 pt_crd[0] = 1. - xi_crd[0];
1165 pt_crd[2] = xi_crd[0];
1168 pt_crd[1] = 1. - xi_crd[0];
1169 pt_crd[2] = xi_crd[0];
1178 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1180 const int nn = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1181 for (
int ii = 0; ii < 4; ii++)
1183 for (
int jj = 0; jj < nn; jj++)
1185 VelFieldShape->getNodeXi(apf::Mesh::TRIANGLE, jj, xi_crd);
1186 double pt_crd[3] = {0., 0., 0.};
1190 pt_crd[0] = xi_crd[0];
1191 pt_crd[1] = xi_crd[1];
1194 pt_crd[0] = xi_crd[0];
1195 pt_crd[2] = xi_crd[2];
1198 pt_crd[0] = xi_crd[0];
1199 pt_crd[1] = xi_crd[1];
1200 pt_crd[2] = xi_crd[2];
1203 pt_crd[1] = xi_crd[0];
1204 pt_crd[2] = xi_crd[1];
1212 MFEM_ASSERT(ip_cnt == num_nodes,
"");
1215 apf::MeshEntity* ent;
1216 apf::MeshIterator* itr = apf_mesh->begin(3);
1218 while ((ent = apf_mesh->iterate(itr)))
1221 Vector u_vel, v_vel, w_vel;
1222 grid_vel->
GetValues(iel, pumi_nodes, u_vel, 1);
1223 grid_vel->
GetValues(iel, pumi_nodes, v_vel, 2);
1224 grid_vel->
GetValues(iel, pumi_nodes, w_vel, 3);
1227 grid_pr->
GetValues(iel, pumi_nodes, pr, 1);
1231 int num_vts = apf_mesh->getDownward(ent, 0, vtxs);
1232 for (
int kk = 0; kk < num_vts; kk++)
1234 double mag = u_vel[kk] * u_vel[kk] + v_vel[kk] * v_vel[kk] +
1235 w_vel[kk] * w_vel[kk];
1237 apf::setScalar(VelMagField, vtxs[kk], 0, mag);
1239 double vels[3] = {u_vel[kk], v_vel[kk], w_vel[kk]};
1240 apf::setComponents(VelField, vtxs[kk], 0, vels);
1243 apf::setScalar(PrField, vtxs[kk], 0, pr[kk]);
1246 int dofId = num_vts;
1248 apf::EntityShape* es = VelFieldShape->getEntityShape(apf::Mesh::TET);
1250 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
1252 int ndOnEdge = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
1255 apf::Downward edges;
1256 int num_edge = apf_mesh->getDownward(ent, apf::Mesh::EDGE, edges);
1257 for (
int ii = 0 ; ii < num_edge; ++ii)
1259 es->alignSharedNodes(apf_mesh, ent, edges[ii], order);
1260 for (
int jj = 0; jj < ndOnEdge; jj++)
1262 int cnt = dofId + order[jj];
1263 double mag = u_vel[cnt] * u_vel[cnt] +
1264 v_vel[cnt] * v_vel[cnt] +
1265 w_vel[cnt] * w_vel[cnt];
1267 apf::setScalar(VelMagField, edges[ii], jj, mag);
1270 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1271 apf::setComponents(VelField, edges[ii], jj, vels);
1274 apf::setScalar(PrField, edges[ii], jj, pr[cnt]);
1282 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1284 int ndOnFace = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1287 apf::Downward faces;
1288 int num_face = apf_mesh->getDownward(ent, apf::Mesh::TRIANGLE, faces);
1289 for (
int ii = 0; ii < num_face; ii++)
1293 es->alignSharedNodes(apf_mesh, ent, faces[ii], order);
1299 for (
int jj = 0; jj < ndOnFace; jj++)
1301 int cnt = dofId + order[jj];
1302 double mag = u_vel[cnt] * u_vel[cnt] +
1303 v_vel[cnt] * v_vel[cnt] +
1304 w_vel[cnt] * w_vel[cnt];
1306 apf::setScalar(VelMagField, faces[ii], jj, mag);
1309 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1310 apf::setComponents(VelField, faces[ii], jj, vels);
1313 apf::setScalar(PrField, faces[ii], jj, pr[cnt]);
1326 void ParPumiMesh::FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
1328 apf::Field* PrField,
1329 apf::Field* PrMagField)
1331 apf::FieldShape* PrFieldShape = getShape(PrField);
1332 int num_nodes = 4 * PrFieldShape->countNodesOn(0) +
1333 6 * PrFieldShape->countNodesOn(1) +
1334 4 * PrFieldShape->countNodesOn(2) +
1335 PrFieldShape->countNodesOn(4);
1340 apf::Vector3 xi_crd(0.,0.,0.);
1347 double pt_crd[3] = {0., 0., 0.};
1349 for (
int kk = 0; kk < 3; kk++)
1352 double pt_crd[3] = {0.,0.,0.};
1357 if (PrFieldShape->hasNodesIn(apf::Mesh::EDGE))
1359 const int nn = PrFieldShape->countNodesOn(apf::Mesh::EDGE);
1360 for (
int ii = 0; ii < 6; ii++)
1362 for (
int jj = 0; jj < nn; jj++)
1364 PrFieldShape->getNodeXi(apf::Mesh::EDGE, jj, xi_crd);
1365 xi_crd[0] = 0.5 * (xi_crd[0] + 1.);
1366 double pt_crd[3] = {0., 0., 0.};
1370 pt_crd[0] = xi_crd[0];
1373 pt_crd[0] = 1. - xi_crd[0];
1374 pt_crd[1] = xi_crd[0];
1377 pt_crd[1] = xi_crd[0];
1380 pt_crd[2] = xi_crd[0];
1383 pt_crd[0] = 1. - xi_crd[0];
1384 pt_crd[2] = xi_crd[0];
1387 pt_crd[1] = 1. - xi_crd[0];
1388 pt_crd[2] = xi_crd[0];
1397 if (PrFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1399 const int nn = PrFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1400 for (
int ii = 0; ii < 4; ii++)
1402 for (
int jj = 0; jj < nn; jj++)
1404 PrFieldShape->getNodeXi(apf::Mesh::TRIANGLE, jj, xi_crd);
1405 double pt_crd[3] = {0., 0., 0.};
1409 pt_crd[0] = xi_crd[0];
1410 pt_crd[1] = xi_crd[1];
1413 pt_crd[0] = xi_crd[0];
1414 pt_crd[2] = xi_crd[2];
1417 pt_crd[0] = xi_crd[0];
1418 pt_crd[1] = xi_crd[1];
1419 pt_crd[2] = xi_crd[2];
1422 pt_crd[1] = xi_crd[0];
1423 pt_crd[2] = xi_crd[1];
1431 MFEM_ASSERT(ip_cnt == num_nodes,
"");
1434 apf::MeshEntity* ent;
1435 apf::MeshIterator* itr = apf_mesh->begin(3);
1437 while ((ent = apf_mesh->iterate(itr)))
1441 grid_pr->
GetValues(iel, pumi_nodes, pr, 1);
1445 int num_vts = apf_mesh->getDownward(ent, 0, vtxs);
1446 for (
int kk = 0; kk < num_vts; kk++)
1449 (pr[kk] >= 0. ? mag = pr[kk] : mag = -pr[kk]);
1450 apf::setScalar(PrMagField, vtxs[kk], 0, mag);
1453 apf::setScalar(PrField, vtxs[kk], 0, pr[kk]);
1456 int dofId = num_vts;
1458 apf::EntityShape* es = PrFieldShape->getEntityShape(apf::Mesh::TET);
1460 if (PrFieldShape->hasNodesIn(apf::Mesh::EDGE))
1462 int ndOnEdge = PrFieldShape->countNodesOn(apf::Mesh::EDGE);
1465 apf::Downward edges;
1466 int num_edge = apf_mesh->getDownward(ent, apf::Mesh::EDGE, edges);
1467 for (
int ii = 0 ; ii < num_edge; ++ii)
1469 es->alignSharedNodes(apf_mesh, ent, edges[ii], order);
1470 for (
int jj = 0; jj < ndOnEdge; jj++)
1472 int cnt = dofId + order[jj];
1474 (pr[cnt] >= 0. ? mag = pr[cnt] : mag = -pr[cnt]);
1475 apf::setScalar(PrMagField, edges[ii], jj, mag);
1478 apf::setScalar(PrField, edges[ii], jj, pr[cnt]);
1487 if (PrFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1489 int ndOnFace = PrFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1492 apf::Downward faces;
1493 int num_face = apf_mesh->getDownward(ent, apf::Mesh::TRIANGLE, faces);
1494 for (
int ii = 0; ii < num_face; ii++)
1498 es->alignSharedNodes(apf_mesh, ent, faces[ii], order);
1504 for (
int jj = 0; jj < ndOnFace; jj++)
1506 int cnt = dofId + order[jj];
1508 (pr[cnt] >= 0. ? mag = pr[cnt] : mag = -pr[cnt]);
1509 apf::setScalar(PrMagField, faces[ii], jj, mag);
1512 apf::setScalar(PrField, faces[ii], jj, pr[cnt]);
1526 void ParPumiMesh::VectorFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
1528 apf::Field* VelField,
1529 apf::Field* VelMagField)
1531 apf::FieldShape* VelFieldShape = getShape(VelField);
1532 int num_nodes = 4 * VelFieldShape->countNodesOn(0) +
1533 6 * VelFieldShape->countNodesOn(1) +
1534 4 * VelFieldShape->countNodesOn(2) +
1535 VelFieldShape->countNodesOn(4);
1540 apf::Vector3 xi_crd(0.,0.,0.);
1547 double pt_crd[3] = {0., 0., 0.};
1549 for (
int kk = 0; kk < 3; kk++)
1552 double pt_crd[3] = {0.,0.,0.};
1557 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
1559 const int nn = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
1560 for (
int ii = 0; ii < 6; ii++)
1562 for (
int jj = 0; jj < nn; jj++)
1564 VelFieldShape->getNodeXi(apf::Mesh::EDGE, jj, xi_crd);
1565 xi_crd[0] = 0.5 * (xi_crd[0] + 1.);
1566 double pt_crd[3] = {0., 0., 0.};
1570 pt_crd[0] = xi_crd[0];
1573 pt_crd[0] = 1. - xi_crd[0];
1574 pt_crd[1] = xi_crd[0];
1577 pt_crd[1] = xi_crd[0];
1580 pt_crd[2] = xi_crd[0];
1583 pt_crd[0] = 1. - xi_crd[0];
1584 pt_crd[2] = xi_crd[0];
1587 pt_crd[1] = 1. - xi_crd[0];
1588 pt_crd[2] = xi_crd[0];
1597 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1599 const int nn = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1600 for (
int ii = 0; ii < 4; ii++)
1602 for (
int jj = 0; jj < nn; jj++)
1604 VelFieldShape->getNodeXi(apf::Mesh::TRIANGLE, jj, xi_crd);
1605 double pt_crd[3] = {0., 0., 0.};
1609 pt_crd[0] = xi_crd[0];
1610 pt_crd[1] = xi_crd[1];
1613 pt_crd[0] = xi_crd[0];
1614 pt_crd[2] = xi_crd[2];
1617 pt_crd[0] = xi_crd[0];
1618 pt_crd[1] = xi_crd[1];
1619 pt_crd[2] = xi_crd[2];
1622 pt_crd[1] = xi_crd[0];
1623 pt_crd[2] = xi_crd[1];
1631 MFEM_ASSERT(ip_cnt == num_nodes,
"");
1634 apf::MeshEntity* ent;
1635 apf::MeshIterator* itr = apf_mesh->begin(3);
1637 while ((ent = apf_mesh->iterate(itr)))
1640 Vector u_vel, v_vel, w_vel;
1641 grid_vel->
GetValues(iel, pumi_nodes, u_vel, 1);
1642 grid_vel->
GetValues(iel, pumi_nodes, v_vel, 2);
1643 grid_vel->
GetValues(iel, pumi_nodes, w_vel, 3);
1647 int num_vts = apf_mesh->getDownward(ent, 0, vtxs);
1648 for (
int kk = 0; kk < num_vts; kk++)
1650 double mag = u_vel[kk] * u_vel[kk] + v_vel[kk] * v_vel[kk] +
1651 w_vel[kk] * w_vel[kk];
1653 apf::setScalar(VelMagField, vtxs[kk], 0, mag);
1655 double vels[3] = {u_vel[kk], v_vel[kk], w_vel[kk]};
1656 apf::setComponents(VelField, vtxs[kk], 0, vels);
1659 int dofId = num_vts;
1661 apf::EntityShape* es = VelFieldShape->getEntityShape(apf::Mesh::TET);
1663 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
1665 int ndOnEdge = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
1668 apf::Downward edges;
1669 int num_edge = apf_mesh->getDownward(ent, apf::Mesh::EDGE, edges);
1670 for (
int ii = 0 ; ii < num_edge; ++ii)
1672 es->alignSharedNodes(apf_mesh, ent, edges[ii], order);
1673 for (
int jj = 0; jj < ndOnEdge; jj++)
1675 int cnt = dofId + order[jj];
1676 double mag = u_vel[cnt] * u_vel[cnt] +
1677 v_vel[cnt] * v_vel[cnt] +
1678 w_vel[cnt] * w_vel[cnt];
1680 apf::setScalar(VelMagField, edges[ii], jj, mag);
1683 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1684 apf::setComponents(VelField, edges[ii], jj, vels);
1692 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1694 int ndOnFace = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1697 apf::Downward faces;
1698 int num_face = apf_mesh->getDownward(ent, apf::Mesh::TRIANGLE, faces);
1699 for (
int ii = 0; ii < num_face; ii++)
1703 es->alignSharedNodes(apf_mesh, ent, faces[ii], order);
1709 for (
int jj = 0; jj < ndOnFace; jj++)
1711 int cnt = dofId + order[jj];
1712 double mag = u_vel[cnt] * u_vel[cnt] +
1713 v_vel[cnt] * v_vel[cnt] +
1714 w_vel[cnt] * w_vel[cnt];
1716 apf::setScalar(VelMagField, faces[ii], jj, mag);
1719 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1720 apf::setComponents(VelField, faces[ii], jj, vels);
1732 void ParPumiMesh::FieldPUMItoMFEM(apf::Mesh2* apf_mesh,
1733 apf::Field* ScalarField,
1738 v_num_loc = apf_mesh->findNumbering(
"LocalVertexNumbering");
1741 getShape(ScalarField);
1742 apf::MeshEntity* ent;
1743 apf::MeshIterator* itr = apf_mesh->begin(0);
1744 while ((ent = apf_mesh->iterate(itr)))
1746 unsigned int id = apf::getNumber(v_num_loc, ent, 0, 0);
1747 double fieldVal = apf::getScalar(ScalarField, ent, 0);
1749 (Pr->
GetData())[
id] = fieldVal;
1754 getShape(ScalarField);
1760 int nnodes = All_nodes.
Size();
1763 int nc = apf::countComponents(ScalarField);
1765 itr = apf_mesh->begin(3);
1766 while ((ent = apf_mesh->iterate(itr)))
1772 apf::MeshElement* mE = apf::createMeshElement(apf_mesh, ent);
1773 apf::Element* elem = apf::createElement(ScalarField, mE);
1776 for (
int ip = 0; ip < nnodes; ip++)
1785 apf::DynamicVector phCrd(nc);
1786 apf::getComponents(elem, param, &phCrd[0]);
1789 for (
int kk = 0; kk < nc; ++kk)
1791 int dof_ctr = ip + kk * nnodes;
1792 (Pr->
GetData())[vdofs[dof_ctr]] = phCrd[kk];
1796 apf::destroyElement(elem);
1797 apf::destroyMeshElement(mE);
1805 #endif // MFEM_USE_MPI
1806 #endif // MFEM_USE_SCOREC
Abstract class for Finite Elements.
void Set(const double *p, const int dim)
Ordering::Type GetOrdering() const
Return the ordering method.
int Size() const
Logical size of the array.
void Recreate(const int n, const int *p)
Class for an integration rule - an Array of IntegrationPoint.
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
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
int GetNBE() const
Returns number of boundary elements.
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void SetDims(int rows, int nnz)
void Copy(Array ©) const
Create a copy of the current array.
Class for PUMI grid functions.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
int GetNE() const
Returns number of elements.
Abstract parallel finite element space.
double * GetData() const
Return a pointer to the beginning of the Vector data.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Array< Element * > shared_edges
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
const IntegrationRule & GetNodes() const
int Insert(IntegerSet &s)
Array< Element * > shared_faces
const Element * GetElement(int i) const
void Sort()
Sorts the array. This requires operator< to be defined for T.
void GetValues(int i, const IntegrationRule &ir, Vector &vals, int vdim=1) const
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
int GetVDim() const
Returns vector dimension.
int Size() const
Returns the number of TYPE I elements.
FiniteElementSpace * FESpace()
void Copy(GroupTopology ©) const
Copy.
int SpaceDimension() const
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
int GetOrder(int i) const
Returns the order of the i'th finite element.
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
Class for integration point with weight.
Table group_svert
Shared objects in each group.
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i'th element.
Array< FaceInfo > faces_info
virtual int GetNVertices() const =0
void SetAttribute(const int attr)
Set element's attribute.
NCMesh * ncmesh
Optional non-conforming mesh extension.
int GetNEdges() const
Return the number of edges.
int GetNFaces() const
Return the number of faces in a 3D mesh.
const FiniteElementCollection * FEColl() const
Arbitrary order H1-conforming (continuous) finite elements.
Array< int > svert_lvert
Shared to local index mapping.
Class for parallel grid function.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Class for parallel meshes.
Abstract data type element.
Data type line segment element.
void Copy(Table ©) const
Array< int > attributes
A list of all unique element attributes used by the Mesh.
const Element * GetBdrElement(int i) const