1a8ededdfSMatthew G. Knepley #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2*7bee2925SMatthew Knepley #include <petsc/private/hashmapi.h> 3a8ededdfSMatthew G. Knepley 4a8ededdfSMatthew G. Knepley #ifdef PETSC_HAVE_EGADS 5a8ededdfSMatthew G. Knepley #include <egads.h> 6a8ededdfSMatthew G. Knepley #endif 7a8ededdfSMatthew G. Knepley 8a8ededdfSMatthew G. Knepley /* We need to understand how to natively parse STEP files. There seems to be only one open source implementation of 9a8ededdfSMatthew G. Knepley the STEP parser contained in the OpenCASCADE package. It is enough to make a strong man weep: 10a8ededdfSMatthew G. Knepley 11a8ededdfSMatthew G. Knepley https://github.com/tpaviot/oce/tree/master/src/STEPControl 12a8ededdfSMatthew G. Knepley 13a8ededdfSMatthew G. Knepley The STEP, and inner EXPRESS, formats are ISO standards, so they are documented 14a8ededdfSMatthew G. Knepley 15a8ededdfSMatthew G. Knepley https://stackoverflow.com/questions/26774037/documentation-or-specification-for-step-and-stp-files 16a8ededdfSMatthew G. Knepley http://stepmod.sourceforge.net/express_model_spec/ 17a8ededdfSMatthew G. Knepley 18a8ededdfSMatthew G. Knepley but again it seems that there has been a deliberate effort at obfuscation, probably to raise the bar for entrants. 19a8ededdfSMatthew G. Knepley */ 20a8ededdfSMatthew G. Knepley 21a8ededdfSMatthew G. Knepley 22a8ededdfSMatthew G. Knepley /*@ 23a8ededdfSMatthew G. Knepley DMPlexSnapToGeomModel - Given a coordinate point 'mcoords' on the mesh point 'p', return the closest coordinate point 'gcoords' on the geometry model associated with that point. 24a8ededdfSMatthew G. Knepley 25a8ededdfSMatthew G. Knepley Not collective 26a8ededdfSMatthew G. Knepley 27a8ededdfSMatthew G. Knepley Input Parameters: 28a8ededdfSMatthew G. Knepley + dm - The DMPlex object 29a8ededdfSMatthew G. Knepley . p - The mesh point 30a8ededdfSMatthew G. Knepley - mcoords - A coordinate point lying on the mesh point 31a8ededdfSMatthew G. Knepley 32a8ededdfSMatthew G. Knepley Output Parameter: 33a8ededdfSMatthew G. Knepley . gcoords - The closest coordinate point on the geometry model associated with 'p' to the given point 34a8ededdfSMatthew G. Knepley 35a8ededdfSMatthew G. Knepley Note: Returns the original coordinates if no geometry model is found. Right now the only supported geometry model is EGADS. 36a8ededdfSMatthew G. Knepley 37a8ededdfSMatthew G. Knepley Level: intermediate 38a8ededdfSMatthew G. Knepley 39a8ededdfSMatthew G. Knepley .seealso: DMRefine(), DMPlexCreate(), DMPlexSetRefinementUniform() 40a8ededdfSMatthew G. Knepley @*/ 41a8ededdfSMatthew G. Knepley PetscErrorCode DMPlexSnapToGeomModel(DM dm, PetscInt p, const PetscScalar mcoords[], PetscScalar gcoords[]) 42a8ededdfSMatthew G. Knepley { 43a8ededdfSMatthew G. Knepley #ifdef PETSC_HAVE_EGADS 44f0fcf0adSMatthew G. Knepley DM cdm; 45a8ededdfSMatthew G. Knepley DMLabel bodyLabel, faceLabel, edgeLabel; 46a8ededdfSMatthew G. Knepley PetscContainer modelObj; 47a8ededdfSMatthew G. Knepley PetscInt bodyID, faceID, edgeID; 48a8ededdfSMatthew G. Knepley ego *bodies; 49f0fcf0adSMatthew G. Knepley ego model, geom, body, obj; 50f0fcf0adSMatthew G. Knepley /* result has to hold derviatives, along with the value */ 51f0fcf0adSMatthew G. Knepley double params[3], result[18], paramsV[16*3], resultV[16*3]; 52a8ededdfSMatthew G. Knepley int Nb, oclass, mtype, *senses; 53f0fcf0adSMatthew G. Knepley Vec coordinatesLocal; 54f0fcf0adSMatthew G. Knepley PetscScalar *coords = NULL; 55f0fcf0adSMatthew G. Knepley PetscInt Nv, v, Np = 0, pm; 56a8ededdfSMatthew G. Knepley #endif 57f0fcf0adSMatthew G. Knepley PetscInt dE, d; 58a8ededdfSMatthew G. Knepley PetscErrorCode ierr; 59a8ededdfSMatthew G. Knepley 60a8ededdfSMatthew G. Knepley PetscFunctionBegin; 61f0fcf0adSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 62a8ededdfSMatthew G. Knepley #ifdef PETSC_HAVE_EGADS 63a8ededdfSMatthew G. Knepley ierr = DMGetLabel(dm, "EGADS Body ID", &bodyLabel);CHKERRQ(ierr); 64a8ededdfSMatthew G. Knepley ierr = DMGetLabel(dm, "EGADS Face ID", &faceLabel);CHKERRQ(ierr); 65a8ededdfSMatthew G. Knepley ierr = DMGetLabel(dm, "EGADS Edge ID", &edgeLabel);CHKERRQ(ierr); 66a8ededdfSMatthew G. Knepley if (!bodyLabel || !faceLabel || !edgeLabel) { 67f0fcf0adSMatthew G. Knepley for (d = 0; d < dE; ++d) gcoords[d] = mcoords[d]; 68a8ededdfSMatthew G. Knepley PetscFunctionReturn(0); 69a8ededdfSMatthew G. Knepley } 70f0fcf0adSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 71f0fcf0adSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinatesLocal);CHKERRQ(ierr); 72a8ededdfSMatthew G. Knepley ierr = DMLabelGetValue(bodyLabel, p, &bodyID);CHKERRQ(ierr); 73a8ededdfSMatthew G. Knepley ierr = DMLabelGetValue(faceLabel, p, &faceID);CHKERRQ(ierr); 74a8ededdfSMatthew G. Knepley ierr = DMLabelGetValue(edgeLabel, p, &edgeID);CHKERRQ(ierr); 75a8ededdfSMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) dm, "EGADS Model", (PetscObject *) &modelObj);CHKERRQ(ierr); 76a8ededdfSMatthew G. Knepley ierr = PetscContainerGetPointer(modelObj, (void **) &model);CHKERRQ(ierr); 77a8ededdfSMatthew G. Knepley ierr = EG_getTopology(model, &geom, &oclass, &mtype, NULL, &Nb, &bodies, &senses);CHKERRQ(ierr); 78f0fcf0adSMatthew G. Knepley if (bodyID < 0 || bodyID >= Nb) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Body %D is not in [0, %d)", bodyID, Nb); 79a8ededdfSMatthew G. Knepley body = bodies[bodyID]; 80f0fcf0adSMatthew G. Knepley 81f0fcf0adSMatthew G. Knepley if (edgeID >= 0) {ierr = EG_objectBodyTopo(body, EDGE, edgeID, &obj);CHKERRQ(ierr); Np = 1;} 82f0fcf0adSMatthew G. Knepley else if (faceID >= 0) {ierr = EG_objectBodyTopo(body, FACE, faceID, &obj);CHKERRQ(ierr); Np = 2;} 83f0fcf0adSMatthew G. Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %D is not in edge or face label for EGADS", p); 84f0fcf0adSMatthew G. Knepley /* Calculate parameters (t or u,v) for vertices */ 85f0fcf0adSMatthew G. Knepley ierr = DMPlexVecGetClosure(cdm, NULL, coordinatesLocal, p, &Nv, &coords);CHKERRQ(ierr); 86f0fcf0adSMatthew G. Knepley Nv /= dE; 87f0fcf0adSMatthew G. Knepley if (Nv == 1) { 88f0fcf0adSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, NULL, coordinatesLocal, p, &Nv, &coords);CHKERRQ(ierr); 89f0fcf0adSMatthew G. Knepley for (d = 0; d < dE; ++d) gcoords[d] = mcoords[d]; 90f0fcf0adSMatthew G. Knepley PetscFunctionReturn(0); 91a8ededdfSMatthew G. Knepley } 92f0fcf0adSMatthew G. Knepley if (Nv > 16) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %D coordinates associated to point %D", Nv, p); 93f0fcf0adSMatthew G. Knepley for (v = 0; v < Nv; ++v) {ierr = EG_invEvaluate(obj, &coords[v*dE], ¶msV[v*3], &resultV[v*3]);CHKERRQ(ierr);} 94f0fcf0adSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(cdm, NULL, coordinatesLocal, p, &Nv, &coords);CHKERRQ(ierr); 95f0fcf0adSMatthew G. Knepley /* Calculate parameters (t or u,v) for new vertex at edge midpoint */ 96f0fcf0adSMatthew G. Knepley for (pm = 0; pm < Np; ++pm) { 97f0fcf0adSMatthew G. Knepley params[pm] = 0.; 98f0fcf0adSMatthew G. Knepley for (v = 0; v < Nv; ++v) {params[pm] += paramsV[v*3+pm];} 99f0fcf0adSMatthew G. Knepley params[pm] /= Nv; 100f0fcf0adSMatthew G. Knepley } 101f0fcf0adSMatthew G. Knepley /* TODO Check 102f0fcf0adSMatthew G. Knepley double range[4]; // [umin, umax, vmin, vmax] 103f0fcf0adSMatthew G. Knepley int peri; 104f0fcf0adSMatthew G. Knepley ierr = EG_getRange(face, range, &peri);CHKERRQ(ierr); 105f0fcf0adSMatthew G. Knepley if ((paramsNew[0] < range[0]) || (paramsNew[0] > range[1]) || (paramsNew[1] < range[2]) || (paramsNew[1] > range[3])) SETERRQ(); 106f0fcf0adSMatthew G. Knepley */ 107f0fcf0adSMatthew G. Knepley /* Put coordinates for new vertex in result[] */ 108f0fcf0adSMatthew G. Knepley ierr = EG_evaluate(obj, params, result);CHKERRQ(ierr); 109f0fcf0adSMatthew G. Knepley for (d = 0; d < dE; ++d) gcoords[d] = result[d]; 110a8ededdfSMatthew G. Knepley #else 111f0fcf0adSMatthew G. Knepley for (d = 0; d < dE; ++d) gcoords[d] = mcoords[d]; 112a8ededdfSMatthew G. Knepley #endif 113a8ededdfSMatthew G. Knepley PetscFunctionReturn(0); 114a8ededdfSMatthew G. Knepley } 115*7bee2925SMatthew Knepley 116*7bee2925SMatthew Knepley #if defined(PETSC_HAVE_EGADS) 117*7bee2925SMatthew Knepley static PetscErrorCode DMPlexEGADSPrintModel(ego model) 118*7bee2925SMatthew Knepley { 119*7bee2925SMatthew Knepley ego geom, *bodies, *objs, *nobjs, *mobjs, *lobjs; 120*7bee2925SMatthew Knepley int oclass, mtype, *senses; 121*7bee2925SMatthew Knepley int Nb, b; 122*7bee2925SMatthew Knepley PetscErrorCode ierr; 123*7bee2925SMatthew Knepley 124*7bee2925SMatthew Knepley PetscFunctionBeginUser; 125*7bee2925SMatthew Knepley /* test bodyTopo functions */ 126*7bee2925SMatthew Knepley ierr = EG_getTopology(model, &geom, &oclass, &mtype, NULL, &Nb, &bodies, &senses);CHKERRQ(ierr); 127*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Number of BODIES (nbodies): %d \n", Nb);CHKERRQ(ierr); 128*7bee2925SMatthew Knepley 129*7bee2925SMatthew Knepley for (b = 0; b < Nb; ++b) { 130*7bee2925SMatthew Knepley ego body = bodies[b]; 131*7bee2925SMatthew Knepley int id, Nsh, Nf, Nl, l, Ne, e, Nv, v; 132*7bee2925SMatthew Knepley 133*7bee2925SMatthew Knepley /* Output Basic Model Topology */ 134*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, SHELL, &Nsh, &objs);CHKERRQ(ierr); 135*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Number of SHELLS: %d \n", Nsh);CHKERRQ(ierr); 136*7bee2925SMatthew Knepley EG_free(objs); 137*7bee2925SMatthew Knepley 138*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, FACE, &Nf, &objs);CHKERRQ(ierr); 139*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Number of FACES: %d \n", Nf);CHKERRQ(ierr); 140*7bee2925SMatthew Knepley EG_free(objs); 141*7bee2925SMatthew Knepley 142*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, LOOP, &Nl, &lobjs);CHKERRQ(ierr); 143*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Number of LOOPS: %d \n", Nl);CHKERRQ(ierr); 144*7bee2925SMatthew Knepley 145*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, EDGE, &Ne, &objs);CHKERRQ(ierr); 146*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Number of EDGES: %d \n", Ne);CHKERRQ(ierr); 147*7bee2925SMatthew Knepley EG_free(objs); 148*7bee2925SMatthew Knepley 149*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, NODE, &Nv, &objs);CHKERRQ(ierr); 150*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Number of NODES: %d \n", Nv);CHKERRQ(ierr); 151*7bee2925SMatthew Knepley EG_free(objs); 152*7bee2925SMatthew Knepley 153*7bee2925SMatthew Knepley for (l = 0; l < Nl; ++l) { 154*7bee2925SMatthew Knepley ego loop = lobjs[l]; 155*7bee2925SMatthew Knepley 156*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, loop); 157*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " LOOP ID: %d\n", id);CHKERRQ(ierr); 158*7bee2925SMatthew Knepley 159*7bee2925SMatthew Knepley /* Get EDGE info which associated with the current LOOP */ 160*7bee2925SMatthew Knepley ierr = EG_getTopology(loop, &geom, &oclass, &mtype, NULL, &Ne, &objs, &senses);CHKERRQ(ierr); 161*7bee2925SMatthew Knepley 162*7bee2925SMatthew Knepley for (e = 0; e < Ne; ++e) { 163*7bee2925SMatthew Knepley ego edge = objs[e]; 164*7bee2925SMatthew Knepley double range[4] = {0., 0., 0., 0.}; 165*7bee2925SMatthew Knepley double point[3] = {0., 0., 0.}; 166*7bee2925SMatthew Knepley int peri; 167*7bee2925SMatthew Knepley 168*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, edge);CHKERRQ(ierr); 169*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " EDGE ID: %d\n", id);CHKERRQ(ierr); 170*7bee2925SMatthew Knepley 171*7bee2925SMatthew Knepley ierr = EG_getRange(objs[e], range, &peri);CHKERRQ(ierr); 172*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Range = %lf, %lf, %lf, %lf \n", range[0], range[1], range[2], range[3]); 173*7bee2925SMatthew Knepley 174*7bee2925SMatthew Knepley /* Get NODE info which associated with the current EDGE */ 175*7bee2925SMatthew Knepley ierr = EG_getTopology(edge, &geom, &oclass, &mtype, NULL, &Nv, &nobjs, &senses);CHKERRQ(ierr); 176*7bee2925SMatthew Knepley 177*7bee2925SMatthew Knepley for (v = 0; v < Nv; ++v) { 178*7bee2925SMatthew Knepley ego vertex = nobjs[v]; 179*7bee2925SMatthew Knepley double limits[4]; 180*7bee2925SMatthew Knepley int dummy; 181*7bee2925SMatthew Knepley 182*7bee2925SMatthew Knepley ierr = EG_getTopology(vertex, &geom, &oclass, &mtype, limits, &dummy, &mobjs, &senses);CHKERRQ(ierr); 183*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, vertex); 184*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " NODE ID: %d \n", id);CHKERRQ(ierr); 185*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " (x, y, z) = (%lf, %lf, %lf) \n", limits[0], limits[1], limits[2]); 186*7bee2925SMatthew Knepley 187*7bee2925SMatthew Knepley point[0] = point[0] + limits[0]; 188*7bee2925SMatthew Knepley point[1] = point[1] + limits[1]; 189*7bee2925SMatthew Knepley point[2] = point[2] + limits[2]; 190*7bee2925SMatthew Knepley } 191*7bee2925SMatthew Knepley } 192*7bee2925SMatthew Knepley } 193*7bee2925SMatthew Knepley EG_free(lobjs); 194*7bee2925SMatthew Knepley } 195*7bee2925SMatthew Knepley PetscFunctionReturn(0); 196*7bee2925SMatthew Knepley } 197*7bee2925SMatthew Knepley 198*7bee2925SMatthew Knepley static PetscErrorCode DMPlexEGADSDestroy_Private(void *context) 199*7bee2925SMatthew Knepley { 200*7bee2925SMatthew Knepley if (context) EG_close((ego) context); 201*7bee2925SMatthew Knepley return 0; 202*7bee2925SMatthew Knepley } 203*7bee2925SMatthew Knepley 204*7bee2925SMatthew Knepley static PetscErrorCode DMPlexCreateEGADS(MPI_Comm comm, ego context, ego model, DM *newdm) 205*7bee2925SMatthew Knepley { 206*7bee2925SMatthew Knepley DMLabel bodyLabel, faceLabel, edgeLabel; 207*7bee2925SMatthew Knepley PetscInt cStart, cEnd, c; 208*7bee2925SMatthew Knepley /* EGADSLite variables */ 209*7bee2925SMatthew Knepley ego geom, *bodies, *objs, *nobjs, *mobjs, *lobjs; 210*7bee2925SMatthew Knepley int oclass, mtype, nbodies, *senses; 211*7bee2925SMatthew Knepley int b; 212*7bee2925SMatthew Knepley /* PETSc variables */ 213*7bee2925SMatthew Knepley DM dm; 214*7bee2925SMatthew Knepley PetscHMapI edgeMap = NULL; 215*7bee2925SMatthew Knepley PetscInt dim = -1, cdim = -1, numCorners = 0, maxCorners = 0, numVertices = 0, newVertices = 0, numEdges = 0, numCells = 0, newCells = 0, numQuads = 0, cOff = 0, fOff = 0; 216*7bee2925SMatthew Knepley PetscInt *cells = NULL, *cone = NULL; 217*7bee2925SMatthew Knepley PetscReal *coords = NULL; 218*7bee2925SMatthew Knepley PetscMPIInt rank; 219*7bee2925SMatthew Knepley PetscErrorCode ierr; 220*7bee2925SMatthew Knepley 221*7bee2925SMatthew Knepley PetscFunctionBegin; 222*7bee2925SMatthew Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 223*7bee2925SMatthew Knepley if (!rank) { 224*7bee2925SMatthew Knepley /* --------------------------------------------------------------------------------------------------- 225*7bee2925SMatthew Knepley Generate Petsc Plex 226*7bee2925SMatthew Knepley Get all Nodes in model, record coordinates in a correctly formatted array 227*7bee2925SMatthew Knepley Cycle through bodies, cycle through loops, recorde NODE IDs in a correctly formatted array 228*7bee2925SMatthew Knepley We need to uniformly refine the initial geometry to guarantee a valid mesh 229*7bee2925SMatthew Knepley */ 230*7bee2925SMatthew Knepley 231*7bee2925SMatthew Knepley /* Calculate cell and vertex sizes */ 232*7bee2925SMatthew Knepley ierr = EG_getTopology(model, &geom, &oclass, &mtype, NULL, &nbodies, &bodies, &senses);CHKERRQ(ierr); 233*7bee2925SMatthew Knepley ierr = PetscHMapICreate(&edgeMap);CHKERRQ(ierr); 234*7bee2925SMatthew Knepley numEdges = 0; 235*7bee2925SMatthew Knepley for (b = 0; b < nbodies; ++b) { 236*7bee2925SMatthew Knepley ego body = bodies[b]; 237*7bee2925SMatthew Knepley int id, Nl, l, Nv, v; 238*7bee2925SMatthew Knepley 239*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, LOOP, &Nl, &lobjs);CHKERRQ(ierr); 240*7bee2925SMatthew Knepley for (l = 0; l < Nl; ++l) { 241*7bee2925SMatthew Knepley ego loop = lobjs[l]; 242*7bee2925SMatthew Knepley int Ner = 0, Ne, e, Nc; 243*7bee2925SMatthew Knepley 244*7bee2925SMatthew Knepley ierr = EG_getTopology(loop, &geom, &oclass, &mtype, NULL, &Ne, &objs, &senses);CHKERRQ(ierr); 245*7bee2925SMatthew Knepley for (e = 0; e < Ne; ++e) { 246*7bee2925SMatthew Knepley ego edge = objs[e]; 247*7bee2925SMatthew Knepley int Nv, id; 248*7bee2925SMatthew Knepley PetscHashIter iter; 249*7bee2925SMatthew Knepley PetscBool found; 250*7bee2925SMatthew Knepley 251*7bee2925SMatthew Knepley ierr = EG_getTopology(edge, &geom, &oclass, &mtype, NULL, &Nv, &nobjs, &senses); 252*7bee2925SMatthew Knepley if (mtype == DEGENERATE) continue; 253*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, edge);CHKERRQ(ierr); 254*7bee2925SMatthew Knepley ierr = PetscHMapIFind(edgeMap, id-1, &iter, &found);CHKERRQ(ierr); 255*7bee2925SMatthew Knepley if (!found) {ierr = PetscHMapISet(edgeMap, id-1, numEdges++);CHKERRQ(ierr);} 256*7bee2925SMatthew Knepley ++Ner; 257*7bee2925SMatthew Knepley } 258*7bee2925SMatthew Knepley if (Ner == 2) {Nc = 2;} 259*7bee2925SMatthew Knepley else if (Ner == 3) {Nc = 4;} 260*7bee2925SMatthew Knepley else if (Ner == 4) {Nc = 8; ++numQuads;} 261*7bee2925SMatthew Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot support loop with %d edges", Ner); 262*7bee2925SMatthew Knepley numCells += Nc; 263*7bee2925SMatthew Knepley newCells += Nc-1; 264*7bee2925SMatthew Knepley maxCorners = PetscMax(Ner*2+1, maxCorners); 265*7bee2925SMatthew Knepley } 266*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, NODE, &Nv, &nobjs);CHKERRQ(ierr); 267*7bee2925SMatthew Knepley for (v = 0; v < Nv; ++v) { 268*7bee2925SMatthew Knepley ego vertex = nobjs[v]; 269*7bee2925SMatthew Knepley 270*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, vertex); 271*7bee2925SMatthew Knepley /* TODO: Instead of assuming contiguous ids, we could use a hash table */ 272*7bee2925SMatthew Knepley numVertices = PetscMax(id, numVertices); 273*7bee2925SMatthew Knepley } 274*7bee2925SMatthew Knepley EG_free(lobjs); 275*7bee2925SMatthew Knepley EG_free(nobjs); 276*7bee2925SMatthew Knepley } 277*7bee2925SMatthew Knepley ierr = PetscHMapIGetSize(edgeMap, &numEdges);CHKERRQ(ierr); 278*7bee2925SMatthew Knepley newVertices = numEdges + numQuads; 279*7bee2925SMatthew Knepley numVertices += newVertices; 280*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\nPLEX Input Array Checkouts\n");CHKERRQ(ierr); 281*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Total Number of Unique Cells = %D (%D)\n", numCells, newCells);CHKERRQ(ierr); 282*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Total Number of Unique Vertices = %D (%D) \n", numVertices, newVertices);CHKERRQ(ierr); 283*7bee2925SMatthew Knepley 284*7bee2925SMatthew Knepley dim = 2; /* Assume 3D Models :: Need to update to handle 2D Models in the future */ 285*7bee2925SMatthew Knepley cdim = 3; /* Assume 3D Models :: Need to update to handle 2D Models in the future */ 286*7bee2925SMatthew Knepley numCorners = 3; /* Split cells into triangles */ 287*7bee2925SMatthew Knepley ierr = PetscMalloc3(numVertices*cdim, &coords, numCells*numCorners, &cells, maxCorners, &cone);CHKERRQ(ierr); 288*7bee2925SMatthew Knepley 289*7bee2925SMatthew Knepley /* Get vertex coordinates */ 290*7bee2925SMatthew Knepley for (b = 0; b < nbodies; ++b) { 291*7bee2925SMatthew Knepley ego body = bodies[b]; 292*7bee2925SMatthew Knepley int id, Nv, v; 293*7bee2925SMatthew Knepley 294*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, NODE, &Nv, &nobjs);CHKERRQ(ierr); 295*7bee2925SMatthew Knepley for (v = 0; v < Nv; ++v) { 296*7bee2925SMatthew Knepley ego vertex = nobjs[v]; 297*7bee2925SMatthew Knepley double limits[4]; 298*7bee2925SMatthew Knepley int dummy; 299*7bee2925SMatthew Knepley 300*7bee2925SMatthew Knepley ierr = EG_getTopology(vertex, &geom, &oclass, &mtype, limits, &dummy, &mobjs, &senses);CHKERRQ(ierr); 301*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, vertex);CHKERRQ(ierr); 302*7bee2925SMatthew Knepley coords[(id-1)*cdim+0] = limits[0]; 303*7bee2925SMatthew Knepley coords[(id-1)*cdim+1] = limits[1]; 304*7bee2925SMatthew Knepley coords[(id-1)*cdim+2] = limits[2]; 305*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Node ID = %d (%d)\n", id, id-1); 306*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " (x,y,z) = (%lf, %lf, %lf) \n \n", coords[(id-1)*cdim+0], coords[(id-1)*cdim+1],coords[(id-1)*cdim+2]); 307*7bee2925SMatthew Knepley } 308*7bee2925SMatthew Knepley EG_free(nobjs); 309*7bee2925SMatthew Knepley } 310*7bee2925SMatthew Knepley ierr = PetscHMapIClear(edgeMap);CHKERRQ(ierr); 311*7bee2925SMatthew Knepley fOff = numVertices - newVertices + numEdges; 312*7bee2925SMatthew Knepley numEdges = 0; 313*7bee2925SMatthew Knepley numQuads = 0; 314*7bee2925SMatthew Knepley for (b = 0; b < nbodies; ++b) { 315*7bee2925SMatthew Knepley ego body = bodies[b]; 316*7bee2925SMatthew Knepley int Nl, l; 317*7bee2925SMatthew Knepley 318*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, LOOP, &Nl, &lobjs);CHKERRQ(ierr); 319*7bee2925SMatthew Knepley for (l = 0; l < Nl; ++l) { 320*7bee2925SMatthew Knepley ego loop = lobjs[l]; 321*7bee2925SMatthew Knepley int lid, Ner = 0, Ne, e; 322*7bee2925SMatthew Knepley 323*7bee2925SMatthew Knepley lid = EG_indexBodyTopo(body, loop);CHKERRQ(ierr); 324*7bee2925SMatthew Knepley ierr = EG_getTopology(loop, &geom, &oclass, &mtype, NULL, &Ne, &objs, &senses);CHKERRQ(ierr); 325*7bee2925SMatthew Knepley for (e = 0; e < Ne; ++e) { 326*7bee2925SMatthew Knepley ego edge = objs[e]; 327*7bee2925SMatthew Knepley int eid, Nv; 328*7bee2925SMatthew Knepley PetscHashIter iter; 329*7bee2925SMatthew Knepley PetscBool found; 330*7bee2925SMatthew Knepley 331*7bee2925SMatthew Knepley ierr = EG_getTopology(edge, &geom, &oclass, &mtype, NULL, &Nv, &nobjs, &senses); 332*7bee2925SMatthew Knepley if (mtype == DEGENERATE) continue; 333*7bee2925SMatthew Knepley ++Ner; 334*7bee2925SMatthew Knepley eid = EG_indexBodyTopo(body, edge);CHKERRQ(ierr); 335*7bee2925SMatthew Knepley ierr = PetscHMapIFind(edgeMap, eid-1, &iter, &found);CHKERRQ(ierr); 336*7bee2925SMatthew Knepley if (!found) { 337*7bee2925SMatthew Knepley PetscInt v = numVertices - newVertices + numEdges; 338*7bee2925SMatthew Knepley double range[4], params[3] = {0., 0., 0.}, result[18]; 339*7bee2925SMatthew Knepley int periodic[2]; 340*7bee2925SMatthew Knepley 341*7bee2925SMatthew Knepley ierr = PetscHMapISet(edgeMap, eid-1, numEdges++);CHKERRQ(ierr); 342*7bee2925SMatthew Knepley ierr = EG_getRange(edge, range, periodic);CHKERRQ(ierr); 343*7bee2925SMatthew Knepley params[0] = 0.5*(range[0] + range[1]); 344*7bee2925SMatthew Knepley ierr = EG_evaluate(edge, params, result);CHKERRQ(ierr); 345*7bee2925SMatthew Knepley coords[v*cdim+0] = result[0]; 346*7bee2925SMatthew Knepley coords[v*cdim+1] = result[1]; 347*7bee2925SMatthew Knepley coords[v*cdim+2] = result[2]; 348*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Edge ID = %d (%D) \n", eid, v); 349*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " (x,y,z) = (%lf, %lf, %lf)\n", coords[v*cdim+0], coords[v*cdim+1],coords[v*cdim+2]); 350*7bee2925SMatthew Knepley params[0] = range[0]; 351*7bee2925SMatthew Knepley ierr = EG_evaluate(edge, params, result);CHKERRQ(ierr); 352*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " between (%lf, %lf, %lf)", result[0], result[1], result[2]); 353*7bee2925SMatthew Knepley params[0] = range[1]; 354*7bee2925SMatthew Knepley ierr = EG_evaluate(edge, params, result);CHKERRQ(ierr); 355*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " and (%lf, %lf, %lf)\n\n", result[0], result[1], result[2]); 356*7bee2925SMatthew Knepley } 357*7bee2925SMatthew Knepley } 358*7bee2925SMatthew Knepley if (Ner == 4) { 359*7bee2925SMatthew Knepley PetscInt v = fOff + numQuads++; 360*7bee2925SMatthew Knepley ego *fobjs; 361*7bee2925SMatthew Knepley double range[4], params[3] = {0., 0., 0.}, result[18]; 362*7bee2925SMatthew Knepley int Nf, face, periodic[2]; 363*7bee2925SMatthew Knepley 364*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, loop, FACE, &Nf, &fobjs);CHKERRQ(ierr); 365*7bee2925SMatthew Knepley if (Nf != 1) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Loop %d has %d faces, instead of 1", lid-1, Nf); 366*7bee2925SMatthew Knepley face = EG_indexBodyTopo(body, fobjs[0]);CHKERRQ(ierr); 367*7bee2925SMatthew Knepley ierr = EG_getRange(fobjs[0], range, periodic);CHKERRQ(ierr); 368*7bee2925SMatthew Knepley params[0] = 0.5*(range[0] + range[1]); 369*7bee2925SMatthew Knepley params[1] = 0.5*(range[2] + range[3]); 370*7bee2925SMatthew Knepley ierr = EG_evaluate(fobjs[0], params, result);CHKERRQ(ierr); 371*7bee2925SMatthew Knepley coords[v*cdim+0] = result[0]; 372*7bee2925SMatthew Knepley coords[v*cdim+1] = result[1]; 373*7bee2925SMatthew Knepley coords[v*cdim+2] = result[2]; 374*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Face ID = %d (%D) \n", face-1, v); 375*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " (x,y,z) = (%lf, %lf, %lf) \n \n", coords[v*cdim+0], coords[v*cdim+1],coords[v*cdim+2]); 376*7bee2925SMatthew Knepley } 377*7bee2925SMatthew Knepley } 378*7bee2925SMatthew Knepley } 379*7bee2925SMatthew Knepley if (numEdges + numQuads != newVertices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of new vertices %D != %D previous count", numEdges + numQuads, newVertices); 380*7bee2925SMatthew Knepley CHKMEMQ; 381*7bee2925SMatthew Knepley 382*7bee2925SMatthew Knepley /* Get cell vertices by traversing loops */ 383*7bee2925SMatthew Knepley numQuads = 0; 384*7bee2925SMatthew Knepley cOff = 0; 385*7bee2925SMatthew Knepley for (b = 0; b < nbodies; ++b) { 386*7bee2925SMatthew Knepley ego body = bodies[b]; 387*7bee2925SMatthew Knepley int id, Nl, l; 388*7bee2925SMatthew Knepley 389*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, LOOP, &Nl, &lobjs);CHKERRQ(ierr); 390*7bee2925SMatthew Knepley for (l = 0; l < Nl; ++l) { 391*7bee2925SMatthew Knepley ego loop = lobjs[l]; 392*7bee2925SMatthew Knepley int lid, Ner = 0, Ne, e, nc = 0, c, Nt, t; 393*7bee2925SMatthew Knepley 394*7bee2925SMatthew Knepley lid = EG_indexBodyTopo(body, loop);CHKERRQ(ierr); 395*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " LOOP ID: %d \n", lid);CHKERRQ(ierr); 396*7bee2925SMatthew Knepley ierr = EG_getTopology(loop, &geom, &oclass, &mtype, NULL, &Ne, &objs, &senses);CHKERRQ(ierr); 397*7bee2925SMatthew Knepley 398*7bee2925SMatthew Knepley for (e = 0; e < Ne; ++e) { 399*7bee2925SMatthew Knepley ego edge = objs[e]; 400*7bee2925SMatthew Knepley int points[3]; 401*7bee2925SMatthew Knepley int eid, Nv, v, tmp; 402*7bee2925SMatthew Knepley 403*7bee2925SMatthew Knepley eid = EG_indexBodyTopo(body, edge); 404*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " EDGE ID: %d \n", eid);CHKERRQ(ierr); 405*7bee2925SMatthew Knepley ierr = EG_getTopology(edge, &geom, &oclass, &mtype, NULL, &Nv, &nobjs, &senses); 406*7bee2925SMatthew Knepley if (mtype == DEGENERATE) {ierr = PetscPrintf(PETSC_COMM_SELF, " EGDE %d is DEGENERATE \n", eid);CHKERRQ(ierr); continue;} 407*7bee2925SMatthew Knepley else {++Ner;} 408*7bee2925SMatthew Knepley if (Nv != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Edge %d has %d vertices != 2", eid, Nv); 409*7bee2925SMatthew Knepley 410*7bee2925SMatthew Knepley for (v = 0; v < Nv; ++v) { 411*7bee2925SMatthew Knepley ego vertex = nobjs[v]; 412*7bee2925SMatthew Knepley 413*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, vertex); 414*7bee2925SMatthew Knepley points[v*2] = id-1; 415*7bee2925SMatthew Knepley } 416*7bee2925SMatthew Knepley { 417*7bee2925SMatthew Knepley PetscInt edgeNum; 418*7bee2925SMatthew Knepley 419*7bee2925SMatthew Knepley ierr = PetscHMapIGet(edgeMap, eid-1, &edgeNum);CHKERRQ(ierr); 420*7bee2925SMatthew Knepley points[1] = numVertices - newVertices + edgeNum; 421*7bee2925SMatthew Knepley } 422*7bee2925SMatthew Knepley /* EGADS loops are not oriented, but seem to be in order, so we must piece them together */ 423*7bee2925SMatthew Knepley if (!nc) { 424*7bee2925SMatthew Knepley for (v = 0; v < Nv+1; ++v) cone[nc++] = points[v]; 425*7bee2925SMatthew Knepley } else { 426*7bee2925SMatthew Knepley if (cone[nc-1] == points[0]) {cone[nc++] = points[1]; if (cone[0] != points[2]) cone[nc++] = points[2];} 427*7bee2925SMatthew Knepley else if (cone[nc-1] == points[2]) {cone[nc++] = points[1]; if (cone[0] != points[0]) cone[nc++] = points[0];} 428*7bee2925SMatthew Knepley else if (cone[nc-3] == points[0]) {tmp = cone[nc-3]; cone[nc-3] = cone[nc-1]; cone[nc-1] = tmp; cone[nc++] = points[1]; if (cone[0] != points[2]) cone[nc++] = points[2];} 429*7bee2925SMatthew Knepley else if (cone[nc-3] == points[2]) {tmp = cone[nc-3]; cone[nc-3] = cone[nc-1]; cone[nc-1] = tmp; cone[nc++] = points[1]; if (cone[0] != points[0]) cone[nc++] = points[0];} 430*7bee2925SMatthew Knepley else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %d does not match its predecessor", eid); 431*7bee2925SMatthew Knepley } 432*7bee2925SMatthew Knepley } 433*7bee2925SMatthew Knepley if (nc != 2*Ner) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of corners %D != %D", nc, 2*Ner); 434*7bee2925SMatthew Knepley if (Ner == 4) {cone[nc++] = numVertices - newVertices + numEdges + numQuads++;} 435*7bee2925SMatthew Knepley if (nc > maxCorners) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Number of corners %D > %D max", nc, maxCorners); 436*7bee2925SMatthew Knepley /* Triangulate the loop */ 437*7bee2925SMatthew Knepley switch (Ner) { 438*7bee2925SMatthew Knepley case 2: /* Bi-Segment -> 2 triangles */ 439*7bee2925SMatthew Knepley Nt = 2; 440*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[0]; 441*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[1]; 442*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[2]; 443*7bee2925SMatthew Knepley ++cOff; 444*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[0]; 445*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[2]; 446*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[3]; 447*7bee2925SMatthew Knepley ++cOff; 448*7bee2925SMatthew Knepley break; 449*7bee2925SMatthew Knepley case 3: /* Triangle -> 4 triangles */ 450*7bee2925SMatthew Knepley Nt = 4; 451*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[0]; 452*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[1]; 453*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[5]; 454*7bee2925SMatthew Knepley ++cOff; 455*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[1]; 456*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[2]; 457*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[3]; 458*7bee2925SMatthew Knepley ++cOff; 459*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[5]; 460*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[3]; 461*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[4]; 462*7bee2925SMatthew Knepley ++cOff; 463*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[1]; 464*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[3]; 465*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[5]; 466*7bee2925SMatthew Knepley ++cOff; 467*7bee2925SMatthew Knepley break; 468*7bee2925SMatthew Knepley case 4: /* Quad -> 8 triangles */ 469*7bee2925SMatthew Knepley Nt = 8; 470*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[0]; 471*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[1]; 472*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[7]; 473*7bee2925SMatthew Knepley ++cOff; 474*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[1]; 475*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[2]; 476*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[3]; 477*7bee2925SMatthew Knepley ++cOff; 478*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[3]; 479*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[4]; 480*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[5]; 481*7bee2925SMatthew Knepley ++cOff; 482*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[5]; 483*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[6]; 484*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[7]; 485*7bee2925SMatthew Knepley ++cOff; 486*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[8]; 487*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[1]; 488*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[3]; 489*7bee2925SMatthew Knepley ++cOff; 490*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[8]; 491*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[3]; 492*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[5]; 493*7bee2925SMatthew Knepley ++cOff; 494*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[8]; 495*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[5]; 496*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[7]; 497*7bee2925SMatthew Knepley ++cOff; 498*7bee2925SMatthew Knepley cells[cOff*numCorners+0] = cone[8]; 499*7bee2925SMatthew Knepley cells[cOff*numCorners+1] = cone[7]; 500*7bee2925SMatthew Knepley cells[cOff*numCorners+2] = cone[1]; 501*7bee2925SMatthew Knepley ++cOff; 502*7bee2925SMatthew Knepley break; 503*7bee2925SMatthew Knepley default: SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Loop %d has %d edges, which we do not support", lid, Ner); 504*7bee2925SMatthew Knepley } 505*7bee2925SMatthew Knepley for (t = 0; t < Nt; ++t) { 506*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " LOOP Corner NODEs Triangle %D (", t);CHKERRQ(ierr); 507*7bee2925SMatthew Knepley for (c = 0; c < numCorners; ++c) { 508*7bee2925SMatthew Knepley if (c > 0) {ierr = PetscPrintf(PETSC_COMM_SELF, ", ");CHKERRQ(ierr);} 509*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "%D", cells[(cOff-Nt+t)*numCorners+c]);CHKERRQ(ierr); 510*7bee2925SMatthew Knepley } 511*7bee2925SMatthew Knepley ierr = PetscPrintf(PETSC_COMM_SELF, ")\n");CHKERRQ(ierr); 512*7bee2925SMatthew Knepley } 513*7bee2925SMatthew Knepley } 514*7bee2925SMatthew Knepley EG_free(lobjs); 515*7bee2925SMatthew Knepley } 516*7bee2925SMatthew Knepley } 517*7bee2925SMatthew Knepley if (cOff != numCells) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count of total cells %D != %D previous count", cOff, numCells); 518*7bee2925SMatthew Knepley ierr = DMPlexCreateFromCellListPetsc(PETSC_COMM_WORLD, dim, numCells, numVertices, numCorners, PETSC_TRUE, cells, cdim, coords, &dm);CHKERRQ(ierr); 519*7bee2925SMatthew Knepley ierr = PetscFree3(coords, cells, cone);CHKERRQ(ierr); 520*7bee2925SMatthew Knepley /* Embed EGADS model in DM */ 521*7bee2925SMatthew Knepley { 522*7bee2925SMatthew Knepley PetscContainer modelObj, contextObj; 523*7bee2925SMatthew Knepley 524*7bee2925SMatthew Knepley ierr = PetscContainerCreate(PETSC_COMM_SELF, &modelObj);CHKERRQ(ierr); 525*7bee2925SMatthew Knepley ierr = PetscContainerSetPointer(modelObj, model);CHKERRQ(ierr); 526*7bee2925SMatthew Knepley ierr = PetscObjectCompose((PetscObject) dm, "EGADS Model", (PetscObject) modelObj);CHKERRQ(ierr); 527*7bee2925SMatthew Knepley ierr = PetscContainerDestroy(&modelObj);CHKERRQ(ierr); 528*7bee2925SMatthew Knepley 529*7bee2925SMatthew Knepley ierr = PetscContainerCreate(PETSC_COMM_SELF, &contextObj);CHKERRQ(ierr); 530*7bee2925SMatthew Knepley ierr = PetscContainerSetPointer(contextObj, context);CHKERRQ(ierr); 531*7bee2925SMatthew Knepley ierr = PetscContainerSetUserDestroy(contextObj, DMPlexEGADSDestroy_Private);CHKERRQ(ierr); 532*7bee2925SMatthew Knepley ierr = PetscObjectCompose((PetscObject) dm, "EGADS Context", (PetscObject) contextObj);CHKERRQ(ierr); 533*7bee2925SMatthew Knepley ierr = PetscContainerDestroy(&contextObj);CHKERRQ(ierr); 534*7bee2925SMatthew Knepley } 535*7bee2925SMatthew Knepley /* Label points */ 536*7bee2925SMatthew Knepley ierr = DMCreateLabel(dm, "EGADS Body ID");CHKERRQ(ierr); 537*7bee2925SMatthew Knepley ierr = DMGetLabel(dm, "EGADS Body ID", &bodyLabel);CHKERRQ(ierr); 538*7bee2925SMatthew Knepley ierr = DMCreateLabel(dm, "EGADS Face ID");CHKERRQ(ierr); 539*7bee2925SMatthew Knepley ierr = DMGetLabel(dm, "EGADS Face ID", &faceLabel);CHKERRQ(ierr); 540*7bee2925SMatthew Knepley ierr = DMCreateLabel(dm, "EGADS Edge ID");CHKERRQ(ierr); 541*7bee2925SMatthew Knepley ierr = DMGetLabel(dm, "EGADS Edge ID", &edgeLabel);CHKERRQ(ierr); 542*7bee2925SMatthew Knepley cOff = 0; 543*7bee2925SMatthew Knepley for (b = 0; b < nbodies; ++b) { 544*7bee2925SMatthew Knepley ego body = bodies[b]; 545*7bee2925SMatthew Knepley int id, Nl, l; 546*7bee2925SMatthew Knepley 547*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, NULL, LOOP, &Nl, &lobjs);CHKERRQ(ierr); 548*7bee2925SMatthew Knepley for (l = 0; l < Nl; ++l) { 549*7bee2925SMatthew Knepley ego loop = lobjs[l]; 550*7bee2925SMatthew Knepley ego *fobjs; 551*7bee2925SMatthew Knepley int lid, Nf, fid, Ner = 0, Ne, e, Nt = 0, t; 552*7bee2925SMatthew Knepley 553*7bee2925SMatthew Knepley lid = EG_indexBodyTopo(body, loop);CHKERRQ(ierr); 554*7bee2925SMatthew Knepley ierr = EG_getBodyTopos(body, loop, FACE, &Nf, &fobjs);CHKERRQ(ierr); 555*7bee2925SMatthew Knepley if (Nf > 1) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_SUP, "Loop %d has %d > 1 faces, which is not supported", lid, Nf);CHKERRQ(ierr); 556*7bee2925SMatthew Knepley fid = EG_indexBodyTopo(body, fobjs[0]);CHKERRQ(ierr); 557*7bee2925SMatthew Knepley EG_free(fobjs); 558*7bee2925SMatthew Knepley ierr = EG_getTopology(loop, &geom, &oclass, &mtype, NULL, &Ne, &objs, &senses);CHKERRQ(ierr); 559*7bee2925SMatthew Knepley for (e = 0; e < Ne; ++e) { 560*7bee2925SMatthew Knepley ego edge = objs[e]; 561*7bee2925SMatthew Knepley int eid, Nv, v; 562*7bee2925SMatthew Knepley PetscInt points[3], support[2], numEdges, edgeNum; 563*7bee2925SMatthew Knepley const PetscInt *edges; 564*7bee2925SMatthew Knepley 565*7bee2925SMatthew Knepley eid = EG_indexBodyTopo(body, edge); 566*7bee2925SMatthew Knepley ierr = EG_getTopology(edge, &geom, &oclass, &mtype, NULL, &Nv, &nobjs, &senses); 567*7bee2925SMatthew Knepley if (mtype == DEGENERATE) continue; 568*7bee2925SMatthew Knepley else ++Ner; 569*7bee2925SMatthew Knepley for (v = 0; v < Nv; ++v) { 570*7bee2925SMatthew Knepley ego vertex = nobjs[v]; 571*7bee2925SMatthew Knepley 572*7bee2925SMatthew Knepley id = EG_indexBodyTopo(body, vertex); 573*7bee2925SMatthew Knepley ierr = DMLabelSetValue(edgeLabel, numCells + id-1, eid);CHKERRQ(ierr); 574*7bee2925SMatthew Knepley points[v*2] = numCells + id-1; 575*7bee2925SMatthew Knepley } 576*7bee2925SMatthew Knepley ierr = PetscHMapIGet(edgeMap, eid-1, &edgeNum);CHKERRQ(ierr); 577*7bee2925SMatthew Knepley points[1] = numCells + numVertices - newVertices + edgeNum; 578*7bee2925SMatthew Knepley 579*7bee2925SMatthew Knepley ierr = DMLabelSetValue(edgeLabel, points[1], eid);CHKERRQ(ierr); 580*7bee2925SMatthew Knepley support[0] = points[0]; 581*7bee2925SMatthew Knepley support[1] = points[1]; 582*7bee2925SMatthew Knepley ierr = DMPlexGetJoin(dm, 2, support, &numEdges, &edges);CHKERRQ(ierr); 583*7bee2925SMatthew Knepley if (numEdges != 1) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Vertices (%D, %D) should only bound 1 edge, not %D", support[0], support[1], numEdges); 584*7bee2925SMatthew Knepley ierr = DMLabelSetValue(edgeLabel, edges[0], eid);CHKERRQ(ierr); 585*7bee2925SMatthew Knepley ierr = DMPlexRestoreJoin(dm, 2, support, &numEdges, &edges);CHKERRQ(ierr); 586*7bee2925SMatthew Knepley support[0] = points[1]; 587*7bee2925SMatthew Knepley support[1] = points[2]; 588*7bee2925SMatthew Knepley ierr = DMPlexGetJoin(dm, 2, support, &numEdges, &edges);CHKERRQ(ierr); 589*7bee2925SMatthew Knepley if (numEdges != 1) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Vertices (%D, %D) should only bound 1 edge, not %D", support[0], support[1], numEdges); 590*7bee2925SMatthew Knepley ierr = DMLabelSetValue(edgeLabel, edges[0], eid);CHKERRQ(ierr); 591*7bee2925SMatthew Knepley ierr = DMPlexRestoreJoin(dm, 2, support, &numEdges, &edges);CHKERRQ(ierr); 592*7bee2925SMatthew Knepley } 593*7bee2925SMatthew Knepley switch (Ner) { 594*7bee2925SMatthew Knepley case 2: Nt = 2;break; 595*7bee2925SMatthew Knepley case 3: Nt = 4;break; 596*7bee2925SMatthew Knepley case 4: Nt = 8;break; 597*7bee2925SMatthew Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Loop with %d edges is unsupported", Ner); 598*7bee2925SMatthew Knepley } 599*7bee2925SMatthew Knepley for (t = 0; t < Nt; ++t) { 600*7bee2925SMatthew Knepley ierr = DMLabelSetValue(bodyLabel, cOff+t, b);CHKERRQ(ierr); 601*7bee2925SMatthew Knepley ierr = DMLabelSetValue(faceLabel, cOff+t, fid);CHKERRQ(ierr); 602*7bee2925SMatthew Knepley } 603*7bee2925SMatthew Knepley cOff += Nt; 604*7bee2925SMatthew Knepley } 605*7bee2925SMatthew Knepley EG_free(lobjs); 606*7bee2925SMatthew Knepley } 607*7bee2925SMatthew Knepley ierr = PetscHMapIDestroy(&edgeMap);CHKERRQ(ierr); 608*7bee2925SMatthew Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 609*7bee2925SMatthew Knepley for (c = cStart; c < cEnd; ++c) { 610*7bee2925SMatthew Knepley PetscInt *closure = NULL; 611*7bee2925SMatthew Knepley PetscInt clSize, cl, bval, fval; 612*7bee2925SMatthew Knepley 613*7bee2925SMatthew Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 614*7bee2925SMatthew Knepley ierr = DMLabelGetValue(bodyLabel, c, &bval);CHKERRQ(ierr); 615*7bee2925SMatthew Knepley ierr = DMLabelGetValue(faceLabel, c, &fval);CHKERRQ(ierr); 616*7bee2925SMatthew Knepley for (cl = 0; cl < clSize*2; cl += 2) { 617*7bee2925SMatthew Knepley ierr = DMLabelSetValue(bodyLabel, closure[cl], bval);CHKERRQ(ierr); 618*7bee2925SMatthew Knepley ierr = DMLabelSetValue(faceLabel, closure[cl], fval);CHKERRQ(ierr); 619*7bee2925SMatthew Knepley } 620*7bee2925SMatthew Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 621*7bee2925SMatthew Knepley } 622*7bee2925SMatthew Knepley *newdm = dm; 623*7bee2925SMatthew Knepley PetscFunctionReturn(0); 624*7bee2925SMatthew Knepley } 625*7bee2925SMatthew Knepley #endif 626*7bee2925SMatthew Knepley 627*7bee2925SMatthew Knepley /*@C 628*7bee2925SMatthew Knepley DMPlexCreateEGADSFromFile - Create a DMPlex mesh from an EGADSLite file. 629*7bee2925SMatthew Knepley 630*7bee2925SMatthew Knepley Collective 631*7bee2925SMatthew Knepley 632*7bee2925SMatthew Knepley Input Parameters: 633*7bee2925SMatthew Knepley + comm - The MPI communicator 634*7bee2925SMatthew Knepley - filename - The name of the ExodusII file 635*7bee2925SMatthew Knepley 636*7bee2925SMatthew Knepley Output Parameter: 637*7bee2925SMatthew Knepley . dm - The DM object representing the mesh 638*7bee2925SMatthew Knepley 639*7bee2925SMatthew Knepley Level: beginner 640*7bee2925SMatthew Knepley 641*7bee2925SMatthew Knepley .seealso: DMPLEX, DMCreate(), DMPlexCreateEGADS() 642*7bee2925SMatthew Knepley @*/ 643*7bee2925SMatthew Knepley PetscErrorCode DMPlexCreateEGADSFromFile(MPI_Comm comm, const char filename[], DM *dm) 644*7bee2925SMatthew Knepley { 645*7bee2925SMatthew Knepley PetscMPIInt rank; 646*7bee2925SMatthew Knepley #if defined(PETSC_HAVE_EGADS) 647*7bee2925SMatthew Knepley ego context= NULL, model = NULL; 648*7bee2925SMatthew Knepley #endif 649*7bee2925SMatthew Knepley PetscBool printModel; 650*7bee2925SMatthew Knepley PetscErrorCode ierr; 651*7bee2925SMatthew Knepley 652*7bee2925SMatthew Knepley PetscFunctionBegin; 653*7bee2925SMatthew Knepley PetscValidCharPointer(filename, 2); 654*7bee2925SMatthew Knepley ierr = PetscOptionsGetBool(NULL, NULL, "-dm_plex_egads_print_model", &printModel, NULL);CHKERRQ(ierr); 655*7bee2925SMatthew Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 656*7bee2925SMatthew Knepley #if defined(PETSC_HAVE_EGADS) 657*7bee2925SMatthew Knepley if (!rank) { 658*7bee2925SMatthew Knepley 659*7bee2925SMatthew Knepley ierr = EG_open(&context);CHKERRQ(ierr); 660*7bee2925SMatthew Knepley ierr = EG_loadModel(context, 0, filename, &model);CHKERRQ(ierr); 661*7bee2925SMatthew Knepley if (printModel) {ierr = DMPlexEGADSPrintModel(model);CHKERRQ(ierr);} 662*7bee2925SMatthew Knepley 663*7bee2925SMatthew Knepley } 664*7bee2925SMatthew Knepley ierr = DMPlexCreateEGADS(comm, context, model, dm);CHKERRQ(ierr); 665*7bee2925SMatthew Knepley #else 666*7bee2925SMatthew Knepley SETERRQ(comm, PETSC_ERR_SUP, "This method requires EGADSLite support. Reconfigure using --download-egads"); 667*7bee2925SMatthew Knepley #endif 668*7bee2925SMatthew Knepley PetscFunctionReturn(0); 669*7bee2925SMatthew Knepley } 670