Actual source code: plexegads.c

petsc-3.14.6 2021-03-30
Report Typos and Errors
  1: #include <petsc/private/dmpleximpl.h>

  3: #ifdef PETSC_HAVE_EGADS
  4: #include <egads.h>
  5: #endif

  7: /* We need to understand how to natively parse STEP files. There seems to be only one open source implementation of
  8:    the STEP parser contained in the OpenCASCADE package. It is enough to make a strong man weep:

 10:      https://github.com/tpaviot/oce/tree/master/src/STEPControl

 12:    The STEP, and inner EXPRESS, formats are ISO standards, so they are documented

 14:      https://stackoverflow.com/questions/26774037/documentation-or-specification-for-step-and-stp-files
 15:      http://stepmod.sourceforge.net/express_model_spec/

 17:    but again it seems that there has been a deliberate effort at obfuscation, probably to raise the bar for entrants.
 18: */


 21: /*@
 22:   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.

 24:   Not collective

 26:   Input Parameters:
 27: + dm      - The DMPlex object
 28: . p       - The mesh point
 29: - mcoords - A coordinate point lying on the mesh point

 31:   Output Parameter:
 32: . gcoords - The closest coordinate point on the geometry model associated with 'p' to the given point

 34:   Note: Returns the original coordinates if no geometry model is found. Right now the only supported geometry model is EGADS.

 36:   Level: intermediate

 38: .seealso: DMRefine(), DMPlexCreate(), DMPlexSetRefinementUniform()
 39: @*/
 40: PetscErrorCode DMPlexSnapToGeomModel(DM dm, PetscInt p, const PetscScalar mcoords[], PetscScalar gcoords[])
 41: {
 42: #ifdef PETSC_HAVE_EGADS
 43:   DM             cdm;
 44:   DMLabel        bodyLabel, faceLabel, edgeLabel;
 45:   PetscContainer modelObj;
 46:   PetscInt       bodyID, faceID, edgeID;
 47:   ego           *bodies;
 48:   ego            model, geom, body, obj;
 49:   /* result has to hold derviatives, along with the value */
 50:   double         params[3], result[18], paramsV[16*3], resultV[16*3];
 51:   int            Nb, oclass, mtype, *senses;
 52:   Vec            coordinatesLocal;
 53:   PetscScalar   *coords = NULL;
 54:   PetscInt       Nv, v, Np = 0, pm;
 55: #endif
 56:   PetscInt       dE, d;

 60:   DMGetCoordinateDim(dm, &dE);
 61: #ifdef PETSC_HAVE_EGADS
 62:   DMGetLabel(dm, "EGADS Body ID",   &bodyLabel);
 63:   DMGetLabel(dm, "EGADS Face ID",   &faceLabel);
 64:   DMGetLabel(dm, "EGADS Edge ID",   &edgeLabel);
 65:   if (!bodyLabel || !faceLabel || !edgeLabel) {
 66:     for (d = 0; d < dE; ++d) gcoords[d] = mcoords[d];
 67:     return(0);
 68:   }
 69:   DMGetCoordinateDM(dm, &cdm);
 70:   DMGetCoordinatesLocal(dm, &coordinatesLocal);
 71:   DMLabelGetValue(bodyLabel,   p, &bodyID);
 72:   DMLabelGetValue(faceLabel,   p, &faceID);
 73:   DMLabelGetValue(edgeLabel,   p, &edgeID);
 74:   PetscObjectQuery((PetscObject) dm, "EGADS Model", (PetscObject *) &modelObj);
 75:   PetscContainerGetPointer(modelObj, (void **) &model);
 76:   EG_getTopology(model, &geom, &oclass, &mtype, NULL, &Nb, &bodies, &senses);
 77:   if (bodyID < 0 || bodyID >= Nb) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Body %D is not in [0, %d)", bodyID, Nb);
 78:   body = bodies[bodyID];

 80:   if (edgeID >= 0)      {EG_objectBodyTopo(body, EDGE, edgeID, &obj); Np = 1;}
 81:   else if (faceID >= 0) {EG_objectBodyTopo(body, FACE, faceID, &obj); Np = 2;}
 82:   else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %D is not in edge or face label for EGADS", p);
 83:   /* Calculate parameters (t or u,v) for vertices */
 84:   DMPlexVecGetClosure(cdm, NULL, coordinatesLocal, p, &Nv, &coords);
 85:   Nv  /= dE;
 86:   if (Nv == 1) {
 87:     DMPlexVecRestoreClosure(cdm, NULL, coordinatesLocal, p, &Nv, &coords);
 88:     for (d = 0; d < dE; ++d) gcoords[d] = mcoords[d];
 89:     return(0);
 90:   }
 91:   if (Nv > 16) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle %D coordinates associated to point %D", Nv, p);
 92:   for (v = 0; v < Nv; ++v) {EG_invEvaluate(obj, &coords[v*dE], &paramsV[v*3], &resultV[v*3]);}
 93:   DMPlexVecRestoreClosure(cdm, NULL, coordinatesLocal, p, &Nv, &coords);
 94:   /* Calculate parameters (t or u,v) for new vertex at edge midpoint */
 95:   for (pm = 0; pm < Np; ++pm) {
 96:     params[pm] = 0.;
 97:     for (v = 0; v < Nv; ++v) {params[pm] += paramsV[v*3+pm];}
 98:     params[pm] /= Nv;
 99:   }
100:   /* TODO Check
101:     double range[4]; // [umin, umax, vmin, vmax]
102:     int    peri;
103:     EG_getRange(face, range, &peri);
104:     if ((paramsNew[0] < range[0]) || (paramsNew[0] > range[1]) || (paramsNew[1] < range[2]) || (paramsNew[1] > range[3])) SETERRQ();
105:   */
106:   /* Put coordinates for new vertex in result[] */
107:   EG_evaluate(obj, params, result);
108:   for (d = 0; d < dE; ++d) gcoords[d] = result[d];
109: #else
110:   for (d = 0; d < dE; ++d) gcoords[d] = mcoords[d];
111: #endif
112:   return(0);
113: }