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);
108 mfem::out <<
"After ReadSCORECMesh" << endl;
128 if (curved && read_gf)
132 crd_shape->getOrder());
138 for (
int i = 0; i < spaceDim; i++)
141 Nodes->GetNodalValues(vert_val, i+1);
142 for (
int j = 0; j < NumOfVertices; j++)
144 vertices[j](i) = vert_val(j);
150 apf::destroyNumbering(v_num_loc);
152 Finalize(refine, fix_orientation);
155 void PumiMesh::ReadSCORECMesh(apf::Mesh2* apf_mesh, apf::Numbering* v_num_loc,
161 apf::MeshIterator* itr = apf_mesh->begin(0);
162 apf::MeshEntity* ent;
164 while ((ent = apf_mesh->iterate(itr)))
167 apf::number(v_num_loc, ent, 0, 0, NumOfVertices);
172 Dim = apf_mesh->getDimension();
173 NumOfElements = countOwned(apf_mesh,Dim);
174 elements.SetSize(NumOfElements);
177 itr = apf_mesh->begin(Dim);
179 while ((ent = apf_mesh->iterate(itr)))
183 apf_mesh->getDownward(ent,0,verts);
187 int geom_type = apf_mesh->getType(ent);
188 elements[j] = ReadElement(ent, geom_type, verts, attr, v_num_loc);
197 NumOfBdrElements = 0;
198 CountBoundaryEntity(apf_mesh, BCdim, NumOfBdrElements);
199 boundary.SetSize(NumOfBdrElements);
203 itr = apf_mesh->begin(BCdim);
204 while ((ent = apf_mesh->iterate(itr)))
207 apf::ModelEntity* mdEnt = apf_mesh->toModel(ent);
208 if (apf_mesh->getModelType(mdEnt) == BCdim)
211 apf_mesh->getDownward(ent, 0, verts);
213 int geom_type = apf_mesh->getType(ent);
214 boundary[j] = ReadElement( ent, geom_type, verts, attr, v_num_loc);
221 vertices.SetSize(NumOfVertices);
225 apf::MeshIterator* itr = apf_mesh->begin(0);
228 while ((ent = apf_mesh->iterate(itr)))
230 unsigned int id = apf::getNumber(v_num_loc, ent, 0, 0);
232 apf_mesh->getPoint(ent,0,Crds);
234 for (
int ii=0; ii<spaceDim; ii++)
236 vertices[id](ii) = Crds[ii];
244 Element *ParPumiMesh::ReadElement(apf::MeshEntity* Ent,
const int geom,
246 const int Attr, apf::Numbering* vert_num)
252 el = NewElement(geom);
257 for (
int i = 0; i < nv; ++i)
259 v[i] = apf::getNumber(vert_num, Verts[i], 0, 0);
270 ParPumiMesh::ParPumiMesh(MPI_Comm comm, apf::Mesh2* apf_mesh)
276 MPI_Comm_size(MyComm, &NRanks);
277 MPI_Comm_rank(MyComm, &MyRank);
279 Dim = apf_mesh->getDimension();
282 apf::MeshIterator* itr;
283 apf::MeshEntity* ent;
287 apf::Numbering* vLocNum =
288 apf::numberOwnedDimension(apf_mesh,
"AuxVertexNumbering", 0);
289 apf::GlobalNumbering* VertexNumbering = apf::makeGlobal(vLocNum,
true);
290 apf::synchronize(VertexNumbering);
294 itr = apf_mesh->
begin(0);
295 for (
int i = 0; (ent = apf_mesh->iterate(itr)); i++)
297 long id = apf::getNumber(VertexNumbering, ent, 0, 0);
301 apf::destroyGlobalNumbering(VertexNumbering);
306 for (
int j = 0; j < thisVertIds.Size(); j++)
308 const int i = thisVertIds[j].two;
309 thisVertIds[i].one = j;
313 apf::Field* apf_field_crd = apf_mesh->getCoordinateField();
314 apf::FieldShape* crd_shape = apf::getShape(apf_field_crd);
315 apf::Numbering* v_num_loc = apf::createNumbering(apf_mesh,
316 "LocalVertexNumbering",
320 NumOfVertices = thisVertIds.Size();
321 vertices.SetSize(NumOfVertices);
322 itr = apf_mesh->
begin(0);
323 for (
int i = 0; (ent = apf_mesh->iterate(itr)); i++)
325 const int id = thisVertIds[i].one;
327 apf::number(v_num_loc, ent, 0, 0,
id);
330 apf_mesh->getPoint(ent,0,Crds);
332 for (
int ii=0; ii<spaceDim; ii++)
334 vertices[id](ii) = Crds[ii];
338 thisVertIds.DeleteAll();
341 NumOfElements = countOwned(apf_mesh,Dim);
342 elements.SetSize(NumOfElements);
345 itr = apf_mesh->
begin(Dim);
346 for (
int j = 0; (ent = apf_mesh->iterate(itr)); j++)
350 apf_mesh->getDownward(ent,0,verts);
354 int geom_type = apf_mesh->getType(ent);
355 elements[j] = ReadElement(ent, geom_type, verts, attr, v_num_loc);
362 itr = apf_mesh->
begin(BcDim);
363 NumOfBdrElements = 0;
364 while ((ent=apf_mesh->iterate(itr)))
366 apf::ModelEntity* mdEnt = apf_mesh->toModel(ent);
367 if (apf_mesh->getModelType(mdEnt) == BcDim)
374 boundary.SetSize(NumOfBdrElements);
376 itr = apf_mesh->
begin(BcDim);
377 for (
int bdr_ctr = 0; (ent = apf_mesh->iterate(itr)); )
380 apf::ModelEntity* mdEnt = apf_mesh->toModel(ent);
381 if (apf_mesh->getModelType(mdEnt) == BcDim)
384 apf_mesh->getDownward(ent, 0, verts);
386 int geom_type = apf_mesh->getType(ent);
387 boundary[bdr_ctr++] = ReadElement(ent, geom_type, verts, attr,
400 this->FinalizeTopology();
409 MFEM_ASSERT(Dim >= 3 || GetNFaces() == 0,
410 "[proc " << MyRank <<
"]: invalid state");
422 apf::Numbering* AuxFaceNum =
423 apf::numberOwnedDimension(apf_mesh,
"AuxFaceNumbering", 2);
424 apf::GlobalNumbering* GlobalFaceNum = apf::makeGlobal(AuxFaceNum,
true);
425 apf::synchronize(GlobalFaceNum);
427 itr = apf_mesh->
begin(2);
428 while ((ent = apf_mesh->iterate(itr)))
430 if (apf_mesh->isShared(ent))
432 long id = apf::getNumber(GlobalFaceNum, ent, 0, 0);
438 apf::destroyGlobalNumbering(GlobalFaceNum);
441 for (
int i = 0; i < sfaces.
Size(); i++)
445 const int thisNumAdjs = 2;
446 int eleRanks[thisNumAdjs];
450 apf_mesh->getResidence(ent, res);
452 for (std::set<int>::iterator itr = res.
begin();
453 itr != res.
end(); ++itr)
455 eleRanks[kk++] = *itr;
459 sfaces[i].one = groups.
Insert(group) - 1;
473 apf::Numbering* AuxEdgeNum =
474 apf::numberOwnedDimension(apf_mesh,
"EdgeNumbering", 1);
475 apf::GlobalNumbering* GlobalEdgeNum = apf::makeGlobal(AuxEdgeNum,
true);
476 apf::synchronize(GlobalEdgeNum);
478 itr = apf_mesh->
begin(1);
479 while ((ent = apf_mesh->iterate(itr)))
481 if (apf_mesh->isShared(ent))
483 long id = apf::getNumber(GlobalEdgeNum, ent, 0, 0);
489 apf::destroyGlobalNumbering(GlobalEdgeNum);
493 for (
int i = 0; i < sedges.
Size(); i++)
499 apf_mesh->getResidence(ent, res);
504 for (std::set<int>::iterator itr = res.
begin();
505 itr != res.
end(); itr++)
507 eleRanks[kk++] = *itr;
512 sedges[i].one = groups.
Insert(group) - 1;
521 itr = apf_mesh->
begin(0);
522 while ((ent = apf_mesh->iterate(itr)))
524 if (apf_mesh->isShared(ent))
526 int vtId = apf::getNumber(v_num_loc, ent, 0, 0);
536 for (
int i = 0; i < sverts.
Size(); i++)
542 apf_mesh->getResidence(ent, res);
547 for (std::set<int>::iterator itr = res.
begin();
548 itr != res.
end(); itr++)
550 eleRanks[kk++] = *itr;
554 svert_group[i] = groups.
Insert(group) - 1;
560 group_stria.MakeI(groups.
Size()-1);
561 group_squad.MakeI(groups.
Size()-1);
562 for (
int i = 0; i < sfaces.
Size(); i++)
564 apf::Mesh::Type ftype = apf_mesh->getType(sfaces[i].two);
565 if (ftype == apf::Mesh::TRIANGLE)
567 group_stria.AddAColumnInRow(sfaces[i].one);
569 else if (ftype == apf::Mesh::QUAD)
571 group_squad.AddAColumnInRow(sfaces[i].one);
578 for (
int i = 0; i < sfaces.
Size(); i++)
580 apf::Mesh::Type ftype = apf_mesh->getType(sfaces[i].two);
581 if (ftype == apf::Mesh::TRIANGLE)
583 group_stria.AddConnection(sfaces[i].one, nst++);
585 else if (ftype == apf::Mesh::QUAD)
587 group_squad.AddConnection(sfaces[i].one, i-nst);
590 shared_trias.SetSize(nst);
591 shared_quads.SetSize(sfaces.
Size()-nst);
592 sface_lface.SetSize(sfaces.
Size());
594 group_stria.ShiftUpI();
595 group_squad.ShiftUpI();
598 group_sedge.MakeI(groups.
Size()-1);
599 for (
int i = 0; i < sedges.
Size(); i++)
601 group_sedge.AddAColumnInRow(sedges[i].one);
604 for (
int i = 0; i < sedges.
Size(); i++)
606 group_sedge.AddConnection(sedges[i].one, i);
608 group_sedge.ShiftUpI();
611 group_svert.MakeI(groups.
Size()-1);
612 for (
int i = 0; i < svert_group.
Size(); i++)
614 group_svert.AddAColumnInRow(svert_group[i]);
617 for (
int i = 0; i < svert_group.
Size(); i++)
619 group_svert.AddConnection(svert_group[i], i);
621 group_svert.ShiftUpI();
626 for (
int i = 0; i < sfaces.
Size(); i++)
631 apf_mesh->getDownward(ent,0,verts);
634 apf::Mesh::Type ftype = apf_mesh->getType(ent);
635 if (ftype == apf::Mesh::TRIANGLE)
637 v = shared_trias[nst++].v;
640 else if (ftype == apf::Mesh::QUAD)
642 v = shared_quads[i-nst].v;
645 for (
int j = 0; j < nv; ++j)
647 v[j] = apf::getNumber(v_num_loc, verts[j], 0, 0);
653 shared_edges.SetSize(sedges.
Size());
654 sedge_ledge. SetSize(sedges.
Size());
655 for (
int i = 0; i < sedges.
Size(); i++)
660 apf_mesh->getDownward(ent, 0, verts);
662 id1 = apf::getNumber(v_num_loc, verts[0], 0, 0);
663 id2 = apf::getNumber(v_num_loc, verts[1], 0, 0);
664 if (id1 > id2) { swap(id1,id2); }
666 shared_edges[i] =
new Segment(id1, id2, 1);
670 svert_lvert.SetSize(sverts.
Size());
671 for (
int i = 0; i < sverts.
Size(); i++)
673 svert_lvert[i] = sverts[i].one;
677 gtopo.Create(groups, 822);
683 int curved = (crd_shape->getOrder() > 1) ? 1 : 0;
687 crd_shape->getOrder());
689 Nodes->Vector::Swap(auxNodes);
690 this->edge_vertex = NULL;
697 GridFunctionPumi::GridFunctionPumi(
Mesh* m, apf::Mesh2* PumiM,
698 apf::Numbering* v_num_loc,
699 const int mesh_order)
704 int ordering = Ordering::byVDIM;
706 int data_size = fes->GetVSize();
709 this->SetSize(data_size);
710 double* PumiData = this->GetData();
712 apf::MeshEntity* ent;
713 apf::MeshIterator* itr;
718 int nnodes = All_nodes.
Size();
721 apf::Field* crd_field = PumiM->getCoordinateField();
723 int nc = apf::countComponents(crd_field);
726 while ((ent = PumiM->iterate(itr)))
729 fes->GetElementVDofs(iel, vdofs);
732 apf::MeshElement* mE = apf::createMeshElement(PumiM, ent);
733 apf::Element* elem = apf::createElement(crd_field, mE);
736 for (
int ip = 0; ip < nnodes; ip++)
745 apf::DynamicVector phCrd(nc);
746 apf::getComponents(elem, param, &phCrd[0]);
749 for (
int kk = 0; kk < spDim; ++kk)
751 int dof_ctr = ip + kk * nnodes;
752 PumiData[vdofs[dof_ctr]] = phCrd[kk];
756 apf::destroyElement(elem);
757 apf::destroyMeshElement(mE);
766 void ParPumiMesh::UpdateMesh(
const ParMesh* AdaptedpMesh)
774 for (
int i = 0; i < shared_edges.Size(); i++)
776 FreeElement(shared_edges[i]);
778 shared_quads.DeleteAll();
779 shared_trias.DeleteAll();
780 shared_edges.DeleteAll();
785 svert_lvert.DeleteAll();
786 sedge_ledge.DeleteAll();
787 sface_lface.DeleteAll();
793 MFEM_ASSERT(Dim == AdaptedpMesh->
Dim,
"");
794 MFEM_ASSERT(spaceDim == AdaptedpMesh->
spaceDim,
"");
795 MFEM_ASSERT(meshgen == AdaptedpMesh->
meshgen,
"");
797 NumOfVertices = AdaptedpMesh->
GetNV();
798 NumOfElements = AdaptedpMesh->
GetNE();
799 NumOfBdrElements = AdaptedpMesh->
GetNBE();
803 meshgen = AdaptedpMesh->
meshgen;
807 last_operation = Mesh::NONE;
810 elements.SetSize(NumOfElements);
811 for (
int i = 0; i < NumOfElements; i++)
817 AdaptedpMesh->
vertices.Copy(vertices);
820 boundary.SetSize(NumOfBdrElements);
821 for (
int i = 0; i < NumOfBdrElements; i++)
845 faces.SetSize(AdaptedpMesh->
faces.Size());
846 for (
int i = 0; i < faces.Size(); i++)
849 faces[i] = (face) ? face->
Duplicate(
this) : NULL;
868 MFEM_VERIFY(AdaptedpMesh->
NURBSext == NULL,
869 "invalid adapted mesh: it is a NURBS mesh");
873 MFEM_VERIFY(AdaptedpMesh->
ncmesh == NULL && AdaptedpMesh->
pncmesh == NULL,
874 "invalid adapted mesh: it is a non-conforming mesh");
885 MyComm = AdaptedpMesh->
MyComm;
886 NRanks = AdaptedpMesh->
NRanks;
887 MyRank = AdaptedpMesh->
MyRank;
890 shared_edges.SetSize(AdaptedpMesh->
shared_edges.Size());
891 for (
int i = 0; i < shared_edges.Size(); i++)
893 shared_edges[i] = AdaptedpMesh->
shared_edges[i]->Duplicate(
this);
906 have_face_nbr_data =
false;
910 if (AdaptedpMesh->
Nodes)
915 FiniteElementCollection::New(fec->
Name());
920 Nodes->MakeOwner(fec_copy);
921 *Nodes = *(AdaptedpMesh->
Nodes);
928 void ParPumiMesh::FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
931 apf::Field* VelField,
933 apf::Field* VelMagField)
935 apf::FieldShape* VelFieldShape = getShape(VelField);
936 int num_nodes = 4 * VelFieldShape->countNodesOn(0) +
937 6 * VelFieldShape->countNodesOn(1) +
938 4 * VelFieldShape->countNodesOn(2) +
939 VelFieldShape->countNodesOn(4);
944 apf::Vector3 xi_crd(0.,0.,0.);
951 double pt_crd[3] = {0., 0., 0.};
953 for (
int kk = 0; kk < 3; kk++)
956 double pt_crd[3] = {0.,0.,0.};
961 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
963 const int nn = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
964 for (
int ii = 0; ii < 6; ii++)
966 for (
int jj = 0; jj < nn; jj++)
968 VelFieldShape->getNodeXi(apf::Mesh::EDGE, jj, xi_crd);
969 xi_crd[0] = 0.5 * (xi_crd[0] + 1.);
970 double pt_crd[3] = {0., 0., 0.};
974 pt_crd[0] = xi_crd[0];
977 pt_crd[0] = 1. - xi_crd[0];
978 pt_crd[1] = xi_crd[0];
981 pt_crd[1] = xi_crd[0];
984 pt_crd[2] = xi_crd[0];
987 pt_crd[0] = 1. - xi_crd[0];
988 pt_crd[2] = xi_crd[0];
991 pt_crd[1] = 1. - xi_crd[0];
992 pt_crd[2] = xi_crd[0];
1001 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1003 const int nn = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1004 for (
int ii = 0; ii < 4; ii++)
1006 for (
int jj = 0; jj < nn; jj++)
1008 VelFieldShape->getNodeXi(apf::Mesh::TRIANGLE, jj, xi_crd);
1009 double pt_crd[3] = {0., 0., 0.};
1013 pt_crd[0] = xi_crd[0];
1014 pt_crd[1] = xi_crd[1];
1017 pt_crd[0] = xi_crd[0];
1018 pt_crd[2] = xi_crd[2];
1021 pt_crd[0] = xi_crd[0];
1022 pt_crd[1] = xi_crd[1];
1023 pt_crd[2] = xi_crd[2];
1026 pt_crd[1] = xi_crd[0];
1027 pt_crd[2] = xi_crd[1];
1035 MFEM_ASSERT(ip_cnt == num_nodes,
"");
1038 apf::MeshEntity* ent;
1039 apf::MeshIterator* itr = apf_mesh->begin(3);
1041 while ((ent = apf_mesh->iterate(itr)))
1044 Vector u_vel, v_vel, w_vel;
1045 grid_vel->
GetValues(iel, pumi_nodes, u_vel, 1);
1046 grid_vel->
GetValues(iel, pumi_nodes, v_vel, 2);
1047 grid_vel->
GetValues(iel, pumi_nodes, w_vel, 3);
1050 grid_pr->
GetValues(iel, pumi_nodes, pr, 1);
1054 int num_vts = apf_mesh->getDownward(ent, 0, vtxs);
1055 for (
int kk = 0; kk < num_vts; kk++)
1057 double mag = u_vel[kk] * u_vel[kk] + v_vel[kk] * v_vel[kk] +
1058 w_vel[kk] * w_vel[kk];
1060 apf::setScalar(VelMagField, vtxs[kk], 0, mag);
1062 double vels[3] = {u_vel[kk], v_vel[kk], w_vel[kk]};
1063 apf::setComponents(VelField, vtxs[kk], 0, vels);
1066 apf::setScalar(PrField, vtxs[kk], 0, pr[kk]);
1069 int dofId = num_vts;
1071 apf::EntityShape* es = VelFieldShape->getEntityShape(apf::Mesh::TET);
1073 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
1075 int ndOnEdge = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
1078 apf::Downward edges;
1079 int num_edge = apf_mesh->getDownward(ent, apf::Mesh::EDGE, edges);
1080 for (
int ii = 0 ; ii < num_edge; ++ii)
1082 es->alignSharedNodes(apf_mesh, ent, edges[ii], order);
1083 for (
int jj = 0; jj < ndOnEdge; jj++)
1085 int cnt = dofId + order[jj];
1086 double mag = u_vel[cnt] * u_vel[cnt] +
1087 v_vel[cnt] * v_vel[cnt] +
1088 w_vel[cnt] * w_vel[cnt];
1090 apf::setScalar(VelMagField, edges[ii], jj, mag);
1093 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1094 apf::setComponents(VelField, edges[ii], jj, vels);
1097 apf::setScalar(PrField, edges[ii], jj, pr[cnt]);
1105 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1107 int ndOnFace = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1110 apf::Downward faces;
1111 int num_face = apf_mesh->getDownward(ent, apf::Mesh::TRIANGLE, faces);
1112 for (
int ii = 0; ii < num_face; ii++)
1116 es->alignSharedNodes(apf_mesh, ent, faces[ii], order);
1122 for (
int jj = 0; jj < ndOnFace; jj++)
1124 int cnt = dofId + order[jj];
1125 double mag = u_vel[cnt] * u_vel[cnt] +
1126 v_vel[cnt] * v_vel[cnt] +
1127 w_vel[cnt] * w_vel[cnt];
1129 apf::setScalar(VelMagField, faces[ii], jj, mag);
1132 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1133 apf::setComponents(VelField, faces[ii], jj, vels);
1136 apf::setScalar(PrField, faces[ii], jj, pr[cnt]);
1149 void ParPumiMesh::FieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
1151 apf::Field* PrField,
1152 apf::Field* PrMagField)
1154 apf::FieldShape* PrFieldShape = getShape(PrField);
1155 int num_nodes = 4 * PrFieldShape->countNodesOn(0) +
1156 6 * PrFieldShape->countNodesOn(1) +
1157 4 * PrFieldShape->countNodesOn(2) +
1158 PrFieldShape->countNodesOn(4);
1163 apf::Vector3 xi_crd(0.,0.,0.);
1170 double pt_crd[3] = {0., 0., 0.};
1172 for (
int kk = 0; kk < 3; kk++)
1175 double pt_crd[3] = {0.,0.,0.};
1180 if (PrFieldShape->hasNodesIn(apf::Mesh::EDGE))
1182 const int nn = PrFieldShape->countNodesOn(apf::Mesh::EDGE);
1183 for (
int ii = 0; ii < 6; ii++)
1185 for (
int jj = 0; jj < nn; jj++)
1187 PrFieldShape->getNodeXi(apf::Mesh::EDGE, jj, xi_crd);
1188 xi_crd[0] = 0.5 * (xi_crd[0] + 1.);
1189 double pt_crd[3] = {0., 0., 0.};
1193 pt_crd[0] = xi_crd[0];
1196 pt_crd[0] = 1. - xi_crd[0];
1197 pt_crd[1] = xi_crd[0];
1200 pt_crd[1] = xi_crd[0];
1203 pt_crd[2] = xi_crd[0];
1206 pt_crd[0] = 1. - xi_crd[0];
1207 pt_crd[2] = xi_crd[0];
1210 pt_crd[1] = 1. - xi_crd[0];
1211 pt_crd[2] = xi_crd[0];
1220 if (PrFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1222 const int nn = PrFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1223 for (
int ii = 0; ii < 4; ii++)
1225 for (
int jj = 0; jj < nn; jj++)
1227 PrFieldShape->getNodeXi(apf::Mesh::TRIANGLE, jj, xi_crd);
1228 double pt_crd[3] = {0., 0., 0.};
1232 pt_crd[0] = xi_crd[0];
1233 pt_crd[1] = xi_crd[1];
1236 pt_crd[0] = xi_crd[0];
1237 pt_crd[2] = xi_crd[2];
1240 pt_crd[0] = xi_crd[0];
1241 pt_crd[1] = xi_crd[1];
1242 pt_crd[2] = xi_crd[2];
1245 pt_crd[1] = xi_crd[0];
1246 pt_crd[2] = xi_crd[1];
1254 MFEM_ASSERT(ip_cnt == num_nodes,
"");
1257 apf::MeshEntity* ent;
1258 apf::MeshIterator* itr = apf_mesh->begin(3);
1260 while ((ent = apf_mesh->iterate(itr)))
1264 grid_pr->
GetValues(iel, pumi_nodes, pr, 1);
1268 int num_vts = apf_mesh->getDownward(ent, 0, vtxs);
1269 for (
int kk = 0; kk < num_vts; kk++)
1272 (pr[kk] >= 0. ? mag = pr[kk] : mag = -pr[kk]);
1273 apf::setScalar(PrMagField, vtxs[kk], 0, mag);
1276 apf::setScalar(PrField, vtxs[kk], 0, pr[kk]);
1279 int dofId = num_vts;
1281 apf::EntityShape* es = PrFieldShape->getEntityShape(apf::Mesh::TET);
1283 if (PrFieldShape->hasNodesIn(apf::Mesh::EDGE))
1285 int ndOnEdge = PrFieldShape->countNodesOn(apf::Mesh::EDGE);
1288 apf::Downward edges;
1289 int num_edge = apf_mesh->getDownward(ent, apf::Mesh::EDGE, edges);
1290 for (
int ii = 0 ; ii < num_edge; ++ii)
1292 es->alignSharedNodes(apf_mesh, ent, edges[ii], order);
1293 for (
int jj = 0; jj < ndOnEdge; jj++)
1295 int cnt = dofId + order[jj];
1297 (pr[cnt] >= 0. ? mag = pr[cnt] : mag = -pr[cnt]);
1298 apf::setScalar(PrMagField, edges[ii], jj, mag);
1301 apf::setScalar(PrField, edges[ii], jj, pr[cnt]);
1310 if (PrFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1312 int ndOnFace = PrFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1315 apf::Downward faces;
1316 int num_face = apf_mesh->getDownward(ent, apf::Mesh::TRIANGLE, faces);
1317 for (
int ii = 0; ii < num_face; ii++)
1321 es->alignSharedNodes(apf_mesh, ent, faces[ii], order);
1327 for (
int jj = 0; jj < ndOnFace; jj++)
1329 int cnt = dofId + order[jj];
1331 (pr[cnt] >= 0. ? mag = pr[cnt] : mag = -pr[cnt]);
1332 apf::setScalar(PrMagField, faces[ii], jj, mag);
1335 apf::setScalar(PrField, faces[ii], jj, pr[cnt]);
1349 void ParPumiMesh::VectorFieldMFEMtoPUMI(apf::Mesh2* apf_mesh,
1351 apf::Field* VelField,
1352 apf::Field* VelMagField)
1354 apf::FieldShape* VelFieldShape = getShape(VelField);
1355 int num_nodes = 4 * VelFieldShape->countNodesOn(0) +
1356 6 * VelFieldShape->countNodesOn(1) +
1357 4 * VelFieldShape->countNodesOn(2) +
1358 VelFieldShape->countNodesOn(4);
1363 apf::Vector3 xi_crd(0.,0.,0.);
1370 double pt_crd[3] = {0., 0., 0.};
1372 for (
int kk = 0; kk < 3; kk++)
1375 double pt_crd[3] = {0.,0.,0.};
1380 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
1382 const int nn = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
1383 for (
int ii = 0; ii < 6; ii++)
1385 for (
int jj = 0; jj < nn; jj++)
1387 VelFieldShape->getNodeXi(apf::Mesh::EDGE, jj, xi_crd);
1388 xi_crd[0] = 0.5 * (xi_crd[0] + 1.);
1389 double pt_crd[3] = {0., 0., 0.};
1393 pt_crd[0] = xi_crd[0];
1396 pt_crd[0] = 1. - xi_crd[0];
1397 pt_crd[1] = xi_crd[0];
1400 pt_crd[1] = xi_crd[0];
1403 pt_crd[2] = xi_crd[0];
1406 pt_crd[0] = 1. - xi_crd[0];
1407 pt_crd[2] = xi_crd[0];
1410 pt_crd[1] = 1. - xi_crd[0];
1411 pt_crd[2] = xi_crd[0];
1420 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1422 const int nn = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1423 for (
int ii = 0; ii < 4; ii++)
1425 for (
int jj = 0; jj < nn; jj++)
1427 VelFieldShape->getNodeXi(apf::Mesh::TRIANGLE, jj, xi_crd);
1428 double pt_crd[3] = {0., 0., 0.};
1432 pt_crd[0] = xi_crd[0];
1433 pt_crd[1] = xi_crd[1];
1436 pt_crd[0] = xi_crd[0];
1437 pt_crd[2] = xi_crd[2];
1440 pt_crd[0] = xi_crd[0];
1441 pt_crd[1] = xi_crd[1];
1442 pt_crd[2] = xi_crd[2];
1445 pt_crd[1] = xi_crd[0];
1446 pt_crd[2] = xi_crd[1];
1454 MFEM_ASSERT(ip_cnt == num_nodes,
"");
1457 apf::MeshEntity* ent;
1458 apf::MeshIterator* itr = apf_mesh->begin(3);
1460 while ((ent = apf_mesh->iterate(itr)))
1463 Vector u_vel, v_vel, w_vel;
1464 grid_vel->
GetValues(iel, pumi_nodes, u_vel, 1);
1465 grid_vel->
GetValues(iel, pumi_nodes, v_vel, 2);
1466 grid_vel->
GetValues(iel, pumi_nodes, w_vel, 3);
1470 int num_vts = apf_mesh->getDownward(ent, 0, vtxs);
1471 for (
int kk = 0; kk < num_vts; kk++)
1473 double mag = u_vel[kk] * u_vel[kk] + v_vel[kk] * v_vel[kk] +
1474 w_vel[kk] * w_vel[kk];
1476 apf::setScalar(VelMagField, vtxs[kk], 0, mag);
1478 double vels[3] = {u_vel[kk], v_vel[kk], w_vel[kk]};
1479 apf::setComponents(VelField, vtxs[kk], 0, vels);
1482 int dofId = num_vts;
1484 apf::EntityShape* es = VelFieldShape->getEntityShape(apf::Mesh::TET);
1486 if (VelFieldShape->hasNodesIn(apf::Mesh::EDGE))
1488 int ndOnEdge = VelFieldShape->countNodesOn(apf::Mesh::EDGE);
1491 apf::Downward edges;
1492 int num_edge = apf_mesh->getDownward(ent, apf::Mesh::EDGE, edges);
1493 for (
int ii = 0 ; ii < num_edge; ++ii)
1495 es->alignSharedNodes(apf_mesh, ent, edges[ii], order);
1496 for (
int jj = 0; jj < ndOnEdge; jj++)
1498 int cnt = dofId + order[jj];
1499 double mag = u_vel[cnt] * u_vel[cnt] +
1500 v_vel[cnt] * v_vel[cnt] +
1501 w_vel[cnt] * w_vel[cnt];
1503 apf::setScalar(VelMagField, edges[ii], jj, mag);
1506 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1507 apf::setComponents(VelField, edges[ii], jj, vels);
1515 if (VelFieldShape->hasNodesIn(apf::Mesh::TRIANGLE))
1517 int ndOnFace = VelFieldShape->countNodesOn(apf::Mesh::TRIANGLE);
1520 apf::Downward faces;
1521 int num_face = apf_mesh->getDownward(ent, apf::Mesh::TRIANGLE, faces);
1522 for (
int ii = 0; ii < num_face; ii++)
1526 es->alignSharedNodes(apf_mesh, ent, faces[ii], order);
1532 for (
int jj = 0; jj < ndOnFace; jj++)
1534 int cnt = dofId + order[jj];
1535 double mag = u_vel[cnt] * u_vel[cnt] +
1536 v_vel[cnt] * v_vel[cnt] +
1537 w_vel[cnt] * w_vel[cnt];
1539 apf::setScalar(VelMagField, faces[ii], jj, mag);
1542 double vels[3] = {u_vel[cnt], v_vel[cnt], w_vel[cnt]};
1543 apf::setComponents(VelField, faces[ii], jj, vels);
1555 void ParPumiMesh::FieldPUMItoMFEM(apf::Mesh2* apf_mesh,
1556 apf::Field* ScalarField,
1561 v_num_loc = apf_mesh->findNumbering(
"LocalVertexNumbering");
1564 getShape(ScalarField);
1565 apf::MeshEntity* ent;
1566 apf::MeshIterator* itr = apf_mesh->begin(0);
1567 while ((ent = apf_mesh->iterate(itr)))
1569 unsigned int id = apf::getNumber(v_num_loc, ent, 0, 0);
1570 double fieldVal = apf::getScalar(ScalarField, ent, 0);
1572 (Pr->
GetData())[
id] = fieldVal;
1577 getShape(ScalarField);
1583 int nnodes = All_nodes.
Size();
1586 int nc = apf::countComponents(ScalarField);
1588 itr = apf_mesh->begin(3);
1589 while ((ent = apf_mesh->iterate(itr)))
1595 apf::MeshElement* mE = apf::createMeshElement(apf_mesh, ent);
1596 apf::Element* elem = apf::createElement(ScalarField, mE);
1599 for (
int ip = 0; ip < nnodes; ip++)
1608 apf::DynamicVector phCrd(nc);
1609 apf::getComponents(elem, param, &phCrd[0]);
1612 for (
int kk = 0; kk < nc; ++kk)
1614 int dof_ctr = ip + kk * nnodes;
1615 (Pr->
GetData())[vdofs[dof_ctr]] = phCrd[kk];
1619 apf::destroyElement(elem);
1620 apf::destroyMeshElement(mE);
1628 #endif // MFEM_USE_MPI
1629 #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.
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 Copy(Array ©) const
Create a copy of the current array.
Class for PUMI grid functions.
int GetNE() const
Returns number of elements.
Abstract parallel finite element space.
Array< Vert3 > shared_trias
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
int Append(const T &el)
Append element to array, resize if necessary.
const IntegrationRule & GetNodes() const
int Insert(IntegerSet &s)
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 GetVDim() const
Returns vector dimension.
FiniteElementSpace * FESpace()
Array< Vert4 > shared_quads
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...
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