10 static apf::Numbering* numberOwnedEntitiesFirst(apf::Mesh* m,
int dimension,
int initialReconstructed)
13 ss <<
"proteus_number_" << dimension;
14 std::string
s = ss.str();
15 apf::FieldShape* shape;
17 shape = apf::getConstant(dimension);
19 shape = m->getShape();
20 apf::Numbering*
n = createNumbering(m,
s.c_str(), shape, 1);
22 apf::MeshIterator* it = m->begin(dimension);
24 if(initialReconstructed){
25 while ((e = m->iterate(it)))
30 while ((e = m->iterate(it)))
34 it = m->begin(dimension);
35 while ((e = m->iterate(it)))
50 logEvent(
"Constructing global data structures",4);
52 int dim = m->getDimension();
74 apf::fail(
"dimension is not 2 or 3\n");
78 std::cerr <<
"*******Proteus Mesh Stats*********\n";
80 std::cerr <<
"Number of nodes " << mesh.
nNodes_global <<
"\n";
82 std::cerr <<
"Number of edges " << mesh.
nEdges_global <<
"\n";
87 constructElements(mesh);
88 constructBoundaries(mesh);
90 constructMaterialArrays(mesh);
97 for (
int d = 0; d <= m->getDimension(); ++d) {
98 freeNumbering(local[d]);
107 return getNumber(local[apf::getDimension(m, e)], e, 0, 0);
110 int MeshAdaptPUMIDrvr::constructNodes(
Mesh& mesh)
113 apf::MeshIterator* it = m->begin(0);
115 while ((e = m->iterate(it))) {
118 m->getPoint(e, 0, x);
119 for(
int j=0; j<3; j++)
126 int MeshAdaptPUMIDrvr::constructElements(
Mesh& mesh)
129 apf::MeshIterator* it = m->begin(m->getDimension());
131 while ((e = m->iterate(it))) {
134 int iNumVtx = m->getDownward(e, 0,
v);
135 for (
int j = 0; j < iNumVtx; ++j) {
158 int dim = m->getDimension();
159 int nfs = m->getDownward(e, dim - 1, fs);
160 int idx_apf = apf::findIn(fs, nfs,
f);
165 static int const tet_boundary_map[4] = {3,2,0,1};
166 static int const tri_boundary_map[3] = {2,0,1};
167 static int const*
const boundary_maps[4] = {
173 return boundary_maps[dim][idx_apf];
176 int MeshAdaptPUMIDrvr::constructBoundaries(
Mesh& mesh)
180 std::set<int> interiorElementBoundaries;
181 std::set<int> exteriorElementBoundaries;
197 int dim = m->getDimension();
198 apf::MeshIterator* it = m->begin(dim - 1);
200 while ((
f = m->iterate(it))) {
204 int iNumVtx = m->getDownward(
f, 0, vs);
205 for (
int iVtx = 0; iVtx < iNumVtx; ++iVtx) {
214 int RgnID[2] = {-1,-1};
215 int localBoundaryNumber[2] = {-1,-1};
216 for (
int iRgn = 0; iRgn < iNumRgn; ++iRgn) {
220 assert(localBoundaryNumber[iRgn] != -1);
222 i * 2 + iRgn] = localBoundaryNumber[iRgn];
225 int leftRgnID = RgnID[0];
int leftLocalBoundaryNumber = localBoundaryNumber[0];
226 int rightRgnID = RgnID[1];
int rightLocalBoundaryNumber = localBoundaryNumber[1];
240 assert(RgnID[1]==-1);
241 assert(localBoundaryNumber[1]==-1);
245 exteriorElementBoundaries.insert(i);
258 interiorElementBoundaries.insert(i);
270 for (std::set<int>::iterator ebN=interiorElementBoundaries.begin();ebN != interiorElementBoundaries.end(); ebN++,ebNI++)
272 for (std::set<int>::iterator ebN=exteriorElementBoundaries.begin();ebN != exteriorElementBoundaries.end(); ebN++,ebNE++)
282 static void createStars(
Mesh& mesh)
300 for (std::set<int>::iterator nN_star=nodeStar[nN].begin();
301 nN_star!=nodeStar[nN].end();
311 std::vector<std::set<int> > nodeElementsStar(mesh.
nNodes_global);
324 for (std::set<int>::iterator eN_star = nodeElementsStar[nN].begin();
325 eN_star != nodeElementsStar[nN].end();
330 int MeshAdaptPUMIDrvr::constructEdges(
Mesh& mesh)
333 apf::MeshIterator* it = m->begin(1);
335 while ((e = m->iterate(it))) {
337 apf::MeshEntity*
v[2];
338 m->getDownward(e, 0,
v);
339 for(
int iVtx=0; iVtx < 2; ++iVtx) {
349 #define INTERIOR_MATERIAL 0
350 #define EXTERIOR_MATERIAL 1
351 #define DEFAULT_ELEMENT_MATERIAL INTERIOR_MATERIAL
353 static int getInOutMaterial(apf::Mesh* m, apf::MeshEntity* e)
355 if (m->getModelType(m->toModel(e)) == m->getDimension())
369 int MeshAdaptPUMIDrvr::constructMaterialArrays(
Mesh& mesh)
376 int dim = m->getDimension();
377 apf::MeshIterator* it = m->begin(dim - 1);
379 while ((
f = m->iterate(it))) {
386 while ((
v = m->iterate(it))) {
402 int proteus_material,
406 apf::ModelEntity* geomEnt = m->findModelEntity(dim, scorec_tag);
407 apf::MeshIterator* it = m->begin(dim);
409 if(dim==m->getDimension()){
410 while ((
f = m->iterate(it))) {
411 if (m->toModel(
f) == geomEnt) {
418 while ((
f = m->iterate(it))) {
419 if (m->toModel(
f) == geomEnt) {
424 apf::DynamicArray<apf::Node> nodes;
425 apf::getNodesOnClosure(m, geomEnt, nodes);
426 for (
size_t i = 0; i < nodes.getSize(); ++i) {
443 apf::ModelEntity* geomEnt;
444 apf::MeshIterator* it;
449 while(
f = m->iterate(it)){
451 geomEnt = m->toModel(
f);
452 geomTag = m->getModelTag(geomEnt);
453 if(m->getModelType(geomEnt) == dim){
456 else if(m->getModelType(geomEnt)==(m->getDimension()-1)){
460 else if(m->getDimension()==3 && m->getModelType(geomEnt)==1){
461 apf::Adjacent vert_adjFace;
462 m->getAdjacent(
f,2,vert_adjFace);
463 for(
int j=0;j<vert_adjFace.getSize();j++){
464 apf::ModelEntity* adjEnt = m->toModel(vert_adjFace[j]);
465 if(m->getModelType(adjEnt) == 2){
475 if(m->getDimension()==2)
480 while(
f = m->iterate(it)){
481 geomEnt = m->toModel(
f);
483 if(m->getModelType(geomEnt) == dim){
484 geomTag = m->getModelTag(m->toModel(
f));
488 geomTag = m->getModelTag(m->toModel(
f));
497 while(
f = m->iterate(it)){
498 geomEnt = m->toModel(
f);
500 assert(m->getModelType(geomEnt)==dim);
501 geomTag = m->getModelTag(m->toModel(
f));
511 logEvent(
"Starting to update material arrays",4);
513 apf::ModelEntity* geomEnt;
514 apf::MeshIterator* it;
525 apf::Field* nodeMaterials = apf::createLagrangeField(m,
"nodeMaterials", apf::SCALAR, 1);
528 while(
f = m->iterate(it))
530 geomEnt = m->toModel(
f);
532 if(m->getModelType(geomEnt) == m->getDimension())
534 apf::setScalar(nodeMaterials,
f,0,0);
538 apf::Adjacent vert_adjFace;
539 m->getAdjacent(
f,m->getDimension()-1,vert_adjFace);
540 apf::MeshEntity* face;
541 for(
int i =0; i<vert_adjFace.getSize();i++)
543 face=vert_adjFace[i];
544 geomEnt = m->toModel(face);
547 if(m->getModelType(geomEnt) == m->getDimension()-1)
549 geomTag = m->getModelTag(geomEnt);
550 apf::setScalar(nodeMaterials,
f,0,geomTag);
554 m->getRemotes(
f,remotes);
555 for(apf::Copies::iterator iter = remotes.begin(); iter != remotes.end(); ++iter)
557 PCU_COMM_PACK(iter->first,iter->second);
558 PCU_COMM_PACK(iter->first,geomTag);
563 if(i == vert_adjFace.getSize()-1 )
564 apf::setScalar(nodeMaterials,
f,0,-1);
570 while(PCU_Comm_Receive())
573 PCU_COMM_UNPACK(geomTag);
574 int currentTag = apf::getScalar(nodeMaterials,
f,0);
575 int newTag =
std::min(currentTag,geomTag);
579 apf::setScalar(nodeMaterials,
f,0,geomTag);
581 apf::setScalar(nodeMaterials,
f,0,newTag);
584 apf::synchronize(nodeMaterials);
586 while(
f=m->iterate(it))
594 int dim = m->getDimension()-1;
596 while(
f = m->iterate(it))
599 geomEnt = m->toModel(
f);
600 geomTag = m->getModelTag(geomEnt);
601 if(m->getModelType(geomEnt) == dim)
608 apf::destroyField(nodeMaterials);
611 dim = m->getDimension();
613 while(
f = m->iterate(it)){
615 geomEnt = m->toModel(
f);
616 geomTag = m->getModelTag(geomEnt);
617 if(m->getModelType(geomEnt) == dim){
633 #include "apfConvert.h"
634 #include "apfMesh2.h"
636 #include "apfNumbering.h"
643 static void constructVerts(
644 Mesh2* m,
int nverts,
645 int* local2globalMap,
646 GlobalToVert& result)
648 ModelEntity* interior = m->findModelEntity(m->getDimension(), 0);
649 for (
int i = 0; i < nverts; ++i)
650 result[local2globalMap[i]] = m->createVert_(interior);
654 static void constructBoundaryElements(
655 Mesh2* m,
const Gid* conn_b,
int nelem_b,
int etype_b,
656 GlobalToVert& globalToVert)
658 ModelEntity* interior = m->findModelEntity(m->getDimension(), 0);
659 int nev = apf::Mesh::adjacentCount[etype_b][0];
660 for (
int i = 0; i < nelem_b; ++i) {
662 int offset = i * nev;
663 for (
int j = 0; j < nev; ++j){
664 verts[j] = globalToVert[conn_b[j + offset]];
668 if(m->getDimension()==2)
669 m->createEntity(etype_b,interior,verts);
671 apf::buildElement(m,interior,2,verts);
674 static void constructElements(
675 Mesh2* m,
const Gid* conn,
int nelem,
int etype,
676 GlobalToVert& globalToVert)
678 ModelEntity* interior = m->findModelEntity(m->getDimension(), 0);
679 int nev = apf::Mesh::adjacentCount[etype][0];
680 for (
int i = 0; i < nelem; ++i) {
682 int offset = i * nev;
683 for (
int j = 0; j < nev; ++j)
684 verts[j] = globalToVert[conn[j + offset]];
685 buildElement(m, interior, etype, verts);
689 static Gid getMax(
const GlobalToVert& globalToVert)
692 APF_CONST_ITERATE(GlobalToVert, globalToVert, it)
694 return PCU_Max_Int(
max);
702 static void constructResidence(Mesh2* m, GlobalToVert& globalToVert)
704 Gid max = getMax(globalToVert);
706 int peers = PCU_Comm_Peers();
707 int quotient = total / peers;
708 int remainder = total % peers;
709 int mySize = quotient;
710 int self = PCU_Comm_Self();
711 if (
self == (peers - 1))
713 typedef std::vector< std::vector<int> > TmpParts;
714 TmpParts tmpParts(mySize);
718 APF_ITERATE(GlobalToVert, globalToVert, it) {
720 int to =
std::min(peers - 1, gid / quotient);
721 PCU_COMM_PACK(to, gid);
724 int myOffset =
self * quotient;
727 while (PCU_Comm_Receive()) {
729 PCU_COMM_UNPACK(gid);
730 int from = PCU_Comm_Sender();
731 tmpParts.at(gid - myOffset).push_back(from);
736 for (
int i = 0; i < mySize; ++i) {
737 std::vector<int>& parts = tmpParts[i];
738 for (
size_t j = 0; j < parts.size(); ++j) {
740 int gid = i + myOffset;
741 int nparts = parts.size();
742 PCU_COMM_PACK(to, gid);
743 PCU_COMM_PACK(to, nparts);
744 for (
size_t k = 0; k < parts.size(); ++k)
745 PCU_COMM_PACK(to, parts[k]);
752 while (PCU_Comm_Receive()) {
754 PCU_COMM_UNPACK(gid);
756 PCU_COMM_UNPACK(nparts);
758 for (
int i = 0; i < nparts; ++i) {
760 PCU_COMM_UNPACK(part);
761 residence.insert(part);
763 MeshEntity* vert = globalToVert[gid];
764 m->setResidence(vert, residence);
771 static void constructRemotes(Mesh2* m, GlobalToVert& globalToVert)
773 int self = PCU_Comm_Self();
775 APF_ITERATE(GlobalToVert, globalToVert, it) {
777 MeshEntity* vert = it->second;
779 m->getResidence(vert, residence);
780 APF_ITERATE(Parts, residence, rit)
782 PCU_COMM_PACK(*rit, gid);
783 PCU_COMM_PACK(*rit, vert);
787 while (PCU_Comm_Receive()) {
789 PCU_COMM_UNPACK(gid);
791 PCU_COMM_UNPACK(remote);
792 int from = PCU_Comm_Sender();
793 MeshEntity* vert = globalToVert[gid];
794 m->addRemote(vert, from, remote);
798 void construct(Mesh2* m,
const int* conn,
const int* conn_b,
int nelem,
799 int nelem_b,
int nverts,
int etype,
int etype_b,
int* local2globalMap,
800 GlobalToVert& globalToVert)
802 constructVerts(m, nverts,local2globalMap,globalToVert);
803 constructBoundaryElements(m, conn_b, nelem_b, etype_b, globalToVert);
804 constructElements(m, conn, nelem, etype, globalToVert);
805 constructResidence(m, globalToVert);
806 constructRemotes(m, globalToVert);
840 #include <gmi_null.h>
841 #include <gmi_mesh.h>
844 #include <apfMesh2.h>
845 #include <apfConvert.h>
850 #include <gmi_lookup.h>
874 if(PCU_Comm_Self()==0)
875 std::cout<<
"STARTING RECONSTRUCTION\n";
879 comm_size = PCU_Comm_Peers();
880 comm_rank = PCU_Comm_Self();
884 int numModelBoundaries;
887 int nBoundaryNodes=0;
911 numModelBoundaries = numModelEdges;
915 numModelNodes = nBoundaryNodes;
921 assert(numModelRegions>0);
936 struct gmi_base* gMod_base;
937 gMod_base = (gmi_base*)malloc(
sizeof(*gMod_base));
938 gMod_base->model.ops = &gmi_base_ops;
939 gmi_base_init(gMod_base);
954 gmi_base_reserve(gMod_base,AGM_REGION,0);
965 gMod = &gMod_base->model;
972 m = apf::makeEmptyMdsMesh(gMod,numDim,
false);
975 int boundaryDim = numDim-1;
976 apf::GlobalToVert outMap;
978 etype = apf::Mesh::TRIANGLE;
979 etype_b = apf::Mesh::EDGE;
982 etype = apf::Mesh::TET;
983 etype_b = apf::Mesh::TRIANGLE;
988 int* local2global_elementBoundaryNodes;
989 local2global_elementBoundaryNodes = (
int*) malloc(
sizeof(
int)*mesh.
nElementBoundaries_global*apf::Mesh::adjacentCount[etype_b][0]);
993 int* local2global_elementNodes;
994 local2global_elementNodes = (
int*) malloc(
sizeof(
int)*mesh.
nElements_global*apf::Mesh::adjacentCount[etype][0]);
995 for(
int i=0;i<mesh.
nElements_global*apf::Mesh::adjacentCount[etype][0];i++){
1000 apf::construct(m,local2global_elementNodes,local2global_elementBoundaryNodes,
1010 apf::MeshIterator* entIter=m->begin(0);
1011 apf::MeshEntity* ent;
1013 while((ent=m->iterate(entIter))){
1014 if(m->isOwned(ent)){
1022 entIter=m->begin(boundaryDim);
1024 int nExteriorElementBoundaries_owned = 0;
1025 while((ent=m->iterate(entIter))){
1026 if(m->isOwned(ent)){
1028 nExteriorElementBoundaries_owned++;
1040 numModelBoundaries = numModelEdges;
1044 numModelNodes = nBoundaryNodes;
1046 numModelBoundaries = nExteriorElementBoundaries_owned;
1061 entIter = m->begin(numDim);
1062 int regStartMaterial = 100;
1064 while(ent = m->iterate(entIter)){
1081 apf::ModelEntity* g_vertEnt;
1082 apf::ModelEntity* g_edgeEnt;
1083 apf::ModelEntity* g_faceEnt;
1084 apf::MeshEntity* vertEnt;
1093 gmi_unfreeze_lookups(gMod_base->lookup);
1095 e = agm_add_ent(gMod_base->topo, AGM_VERTEX);
1096 gmi_set_lookup(gMod_base->lookup, e, i);
1098 gmi_freeze_lookup(gMod_base->lookup, (agm_ent_type)0);
1102 e = agm_add_ent(gMod_base->topo, AGM_EDGE);
1104 e = agm_add_ent(gMod_base->topo, AGM_FACE);
1105 gmi_set_lookup(gMod_base->lookup, e, i);
1107 gmi_freeze_lookup(gMod_base->lookup, (agm_ent_type)boundaryDim);
1109 for(
int i=0;i<numModelRegions;i++){
1111 e = agm_add_ent(gMod_base->topo, AGM_FACE);
1113 e = agm_add_ent(gMod_base->topo, AGM_REGION);
1116 gmi_set_lookup(gMod_base->lookup, e, i+regStartMaterial);
1118 b = agm_add_bdry(gMod_base->topo, e);
1123 agm_add_use(gMod_base->topo,b,d);
1128 gmi_freeze_lookup(gMod_base->lookup, (agm_ent_type)numDim);
1132 e = agm_add_ent(gMod_base->topo, AGM_EDGE);
1133 gmi_set_lookup(gMod_base->lookup, e, i);
1135 gmi_freeze_lookup(gMod_base->lookup, (agm_ent_type)1);
1139 apf::ModelEntity* gEnt;
1144 entIter = m->begin(0);
1146 while(ent = m->iterate(entIter)){
1150 m->setPoint(ent,0,pt);
1151 if(m->isOwned(ent)){
1163 gEnt = m->findModelEntity(numDim,matTag);
1167 gEnt = m->findModelEntity(0,vertCounter);
1172 m->setModelEntity(ent,gEnt);
1174 if(m->isShared(ent)){
1175 apf::Copies remotes;
1176 m->getRemotes(ent,remotes);
1177 for(apf::Copies::iterator it = remotes.begin(); it != remotes.end(); ++it){
1178 PCU_COMM_PACK(it->first,it->second);
1179 PCU_COMM_PACK(it->first,gEnt);
1188 while(PCU_Comm_Receive()){
1189 PCU_COMM_UNPACK(ent);
1190 PCU_COMM_UNPACK(gEnt);
1191 m->setModelEntity(ent,gEnt);
1202 int boundaryCounter = 0;
1205 apf::ModelEntity* edg_gEnt;
1206 entIter=m->begin(boundaryDim);
1208 while(ent = m->iterate(entIter)){
1217 gEnt = m->findModelEntity(boundaryDim,boundaryMaterialCounter);
1220 boundaryMaterialCounter++;
1224 apf::Adjacent adj_edges;
1225 m->getAdjacent(ent,1,adj_edges);
1226 for(
int i=0;i<adj_edges.getSize();i++){
1228 if(m->getModelType(m->toModel(adj_edges[i]))>m->getModelType(gEnt) || (m->getModelType(m->toModel(adj_edges[i]))==0)){
1229 edg_gEnt = m->findModelEntity(1,edgCounter);
1230 m->setModelEntity(adj_edges[i],edg_gEnt);
1233 if(m->isOwned(adj_edges[i]) && m->isShared(adj_edges[i])){
1234 apf::Copies remotes;
1235 m->getRemotes(ent,remotes);
1236 for(apf::Copies::iterator it = remotes.begin(); it != remotes.end(); ++it){
1237 PCU_COMM_PACK(it->first,it->second);
1238 PCU_COMM_PACK(it->first,edg_gEnt);
1256 gEnt = m->findModelEntity(numDim,matTag);
1259 apf::Adjacent adj_edges;
1260 m->getAdjacent(ent,1,adj_edges);
1261 for(
int i=0;i<adj_edges.getSize();i++){
1263 if(m->getModelType(m->toModel(adj_edges[i]))>m->getModelType(gEnt) || (m->getModelType(m->toModel(adj_edges[i]))==0)){
1264 m->setModelEntity(adj_edges[i],gEnt);
1266 if(m->isOwned(adj_edges[i]) && m->isShared(adj_edges[i])){
1267 apf::Copies remotes;
1268 m->getRemotes(ent,remotes);
1269 for(apf::Copies::iterator it = remotes.begin(); it != remotes.end(); ++it){
1270 PCU_COMM_PACK(it->first,it->second);
1271 PCU_COMM_PACK(it->first,gEnt);
1280 m->setModelEntity(ent,gEnt);
1285 while(PCU_Comm_Receive()){
1286 PCU_COMM_UNPACK(ent);
1287 PCU_COMM_UNPACK(gEnt);
1288 m->setModelEntity(ent,gEnt);
1298 for(
int i=0;i<numModelRegions;i++)
1302 entIter = m->begin(numDim);
1303 while(ent = m->iterate(entIter)){
1305 m->setModelEntity(ent,gEnt);
1319 apf::alignMdsRemotes(m);
1327 free(local2global_elementBoundaryNodes);
1328 free(local2global_elementNodes);
1330 if(PCU_Comm_Self()==0)
1331 std::cout<<
"FINISHING RECONSTRUCTION\n";
1342 elementType = apf::Mesh::TRIANGLE;
1346 elementType = apf::Mesh::TET;
1353 isModelVert_bool[i] = isModelVert[i] != 0;
1355 static int numEntries = 2+dim;
1357 int bEdges_1D[nBFaces][4];
1358 int bFaces_2D[nBFaces][5];
1361 for(
int i=0;i<nBFaces;i++){
1362 int idx = i*numEntries;
1363 for(
int j=0;j<numEntries;j++)
1364 bEdges_1D[i][j] = bFaces[idx+j];
1368 for(
int i=0;i<nBFaces;i++){
1369 int idx = i*numEntries;
1370 for(
int j=0;j<numEntries;j++)
1371 bFaces_2D[i][j] = bFaces[idx+j];
1383 apf::GlobalToVert outMap;
1385 gmi_model* tempModel = gmi_load(
".null");
1386 m = apf::makeEmptyMdsMesh(tempModel,dim,
false);
1391 std::map<int,apf::MeshEntity*> globalToRegion;
1392 apf::MeshIterator* it = m->begin(dim);
1393 apf::MeshEntity* ent;
1395 while( ent = m->iterate(it) ){
1396 globalToRegion.insert(std::pair<int,apf::MeshEntity*> (counter,ent ));
1401 apf::derive2DMdlFromManifold(m,isModelVert_bool,nBFaces,bEdges_1D,outMap,globalToRegion);
1403 apf::deriveMdlFromManifold(m,isModelVert_bool,nBFaces,bFaces_2D,outMap,globalToRegion);
1404 m->writeNative(
"Reconstructed.smb");
1405 gmi_write_dmg(m->getModel(),
"Reconstructed.dmg");
1406 std::cout<<
"Finished Reconstruction, terminating program. Rerun with PUMI workflow\n";