17625649eSMatthew G. Knepley #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 27625649eSMatthew G. Knepley 37625649eSMatthew G. Knepley PetscFunctionList DMGeomModelList = NULL; 47625649eSMatthew G. Knepley PetscBool DMGeomModelRegisterAllCalled = PETSC_FALSE; 57625649eSMatthew G. Knepley 67625649eSMatthew G. Knepley #if defined(PETSC_HAVE_EGADS) 77625649eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSnapToGeomModel_EGADS(DM, PetscInt, PetscInt, const PetscScalar[], PetscScalar[]); 87625649eSMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSnapToGeomModel_EGADSLite(DM, PetscInt, PetscInt, const PetscScalar[], PetscScalar[]); 97625649eSMatthew G. Knepley #endif 107625649eSMatthew G. Knepley 117625649eSMatthew G. Knepley static PetscErrorCode DMSnapToGeomModelBall(DM dm, PetscInt p, PetscInt dE, const PetscScalar mcoords[], PetscScalar gcoords[]) 127625649eSMatthew G. Knepley { 137625649eSMatthew G. Knepley PetscInt val; 147625649eSMatthew G. Knepley 157625649eSMatthew G. Knepley PetscFunctionBeginUser; 167625649eSMatthew G. Knepley PetscCall(DMGetLabelValue(dm, "marker", p, &val)); 177625649eSMatthew G. Knepley if (val >= 0) { 187625649eSMatthew G. Knepley PetscReal norm = 0.; 197625649eSMatthew G. Knepley 207625649eSMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) norm += PetscSqr(PetscRealPart(mcoords[d])); 217625649eSMatthew G. Knepley norm = PetscSqrtReal(norm); 227625649eSMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) gcoords[d] = mcoords[d] / norm; 237625649eSMatthew G. Knepley } else { 247625649eSMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) gcoords[d] = mcoords[d]; 257625649eSMatthew G. Knepley } 267625649eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 277625649eSMatthew G. Knepley } 287625649eSMatthew G. Knepley 297625649eSMatthew G. Knepley static PetscErrorCode DMSnapToGeomModelCylinder(DM dm, PetscInt p, PetscInt dE, const PetscScalar mcoords[], PetscScalar gcoords[]) 307625649eSMatthew G. Knepley { 317625649eSMatthew G. Knepley PetscReal gmin[3], gmax[3]; 327625649eSMatthew G. Knepley PetscInt val; 337625649eSMatthew G. Knepley 347625649eSMatthew G. Knepley PetscFunctionBeginUser; 357625649eSMatthew G. Knepley PetscCall(DMGetBoundingBox(dm, gmin, gmax)); 367625649eSMatthew G. Knepley PetscCall(DMGetLabelValue(dm, "generatrix", p, &val)); 377625649eSMatthew G. Knepley if (val >= 0) { 387625649eSMatthew G. Knepley PetscReal norm = 0.; 397625649eSMatthew G. Knepley 407625649eSMatthew G. Knepley for (PetscInt d = 0; d < dE - 1; ++d) norm += PetscSqr(PetscRealPart(mcoords[d])); 417625649eSMatthew G. Knepley norm = PetscSqrtReal(norm); 42883424caSPierre Jolivet for (PetscInt d = 0; d < dE - 1; ++d) gcoords[d] = mcoords[d] * gmax[0] / norm; 437625649eSMatthew G. Knepley gcoords[dE - 1] = mcoords[dE - 1]; 447625649eSMatthew G. Knepley } else { 457625649eSMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) gcoords[d] = mcoords[d]; 467625649eSMatthew G. Knepley } 477625649eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 487625649eSMatthew G. Knepley } 497625649eSMatthew G. Knepley 507625649eSMatthew G. Knepley /*@C 517625649eSMatthew G. Knepley DMGeomModelRegisterAll - Registers all of the geometry model methods in the `DM` package. 527625649eSMatthew G. Knepley 537625649eSMatthew G. Knepley Not Collective 547625649eSMatthew G. Knepley 557625649eSMatthew G. Knepley Level: advanced 567625649eSMatthew G. Knepley 577625649eSMatthew G. Knepley .seealso: `DM`, `DMGeomModelRegisterDestroy()` 587625649eSMatthew G. Knepley @*/ 597625649eSMatthew G. Knepley PetscErrorCode DMGeomModelRegisterAll(void) 607625649eSMatthew G. Knepley { 617625649eSMatthew G. Knepley PetscFunctionBegin; 627625649eSMatthew G. Knepley if (DMGeomModelRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 637625649eSMatthew G. Knepley DMGeomModelRegisterAllCalled = PETSC_TRUE; 647625649eSMatthew G. Knepley PetscCall(DMGeomModelRegister("ball", DMSnapToGeomModelBall)); 657625649eSMatthew G. Knepley PetscCall(DMGeomModelRegister("cylinder", DMSnapToGeomModelCylinder)); 667625649eSMatthew G. Knepley #if defined(PETSC_HAVE_EGADS) 675552b385SBrandon // FIXME: Brandon uses DMPlexSnapToGeomModel() here instead 687625649eSMatthew G. Knepley PetscCall(DMGeomModelRegister("egads", DMSnapToGeomModel_EGADS)); 697625649eSMatthew G. Knepley #endif 707625649eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 717625649eSMatthew G. Knepley } 727625649eSMatthew G. Knepley 737625649eSMatthew G. Knepley /*@C 747625649eSMatthew G. Knepley DMGeomModelRegister - Adds a geometry model to `DM` 757625649eSMatthew G. Knepley 767625649eSMatthew G. Knepley Not Collective, No Fortran Support 777625649eSMatthew G. Knepley 787625649eSMatthew G. Knepley Input Parameters: 79d7c1f440SPierre Jolivet + sname - name of a new user-defined geometry model 807625649eSMatthew G. Knepley - fnc - geometry model function 817625649eSMatthew G. Knepley 827625649eSMatthew G. Knepley Example Usage: 837625649eSMatthew G. Knepley .vb 847625649eSMatthew G. Knepley DMGeomModelRegister("my_geom_model", MySnapToGeomModel); 857625649eSMatthew G. Knepley .ve 867625649eSMatthew G. Knepley 877625649eSMatthew G. Knepley Then, your generator can be chosen with the procedural interface via 88*b44f4de4SBarry Smith .vb 89*b44f4de4SBarry Smith DMSetGeomModel(dm, "my_geom_model",...) 90*b44f4de4SBarry Smith .ve 917625649eSMatthew G. Knepley or at runtime via the option 92*b44f4de4SBarry Smith .vb 93*b44f4de4SBarry Smith -dm_geom_model my_geom_model 94*b44f4de4SBarry Smith .ve 957625649eSMatthew G. Knepley 967625649eSMatthew G. Knepley Level: advanced 977625649eSMatthew G. Knepley 987625649eSMatthew G. Knepley Note: 997625649eSMatthew G. Knepley `DMGeomModelRegister()` may be called multiple times to add several user-defined generators 1007625649eSMatthew G. Knepley 1017625649eSMatthew G. Knepley .seealso: `DM`, `DMGeomModelRegisterAll()`, `DMPlexGeomModel()`, `DMGeomModelRegisterDestroy()` 1027625649eSMatthew G. Knepley @*/ 1037625649eSMatthew G. Knepley PetscErrorCode DMGeomModelRegister(const char sname[], PetscErrorCode (*fnc)(DM, PetscInt, PetscInt, const PetscScalar[], PetscScalar[])) 1047625649eSMatthew G. Knepley { 1057625649eSMatthew G. Knepley PetscFunctionBegin; 106835f2295SStefano Zampini PetscCall(PetscFunctionListAdd(&DMGeomModelList, sname, fnc)); 1077625649eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1087625649eSMatthew G. Knepley } 1097625649eSMatthew G. Knepley 1107625649eSMatthew G. Knepley extern PetscBool DMGeomModelRegisterAllCalled; 1117625649eSMatthew G. Knepley 1127625649eSMatthew G. Knepley PetscErrorCode DMGeomModelRegisterDestroy(void) 1137625649eSMatthew G. Knepley { 1147625649eSMatthew G. Knepley PetscFunctionBegin; 1157625649eSMatthew G. Knepley PetscCall(PetscFunctionListDestroy(&DMGeomModelList)); 1167625649eSMatthew G. Knepley DMGeomModelRegisterAllCalled = PETSC_FALSE; 1177625649eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1187625649eSMatthew G. Knepley } 1197625649eSMatthew G. Knepley 1207625649eSMatthew G. Knepley /*@ 1217625649eSMatthew G. Knepley DMSetSnapToGeomModel - Choose a geometry model for this `DM`. 1227625649eSMatthew G. Knepley 1237625649eSMatthew G. Knepley Not Collective 1247625649eSMatthew G. Knepley 1257625649eSMatthew G. Knepley Input Parameters: 1267625649eSMatthew G. Knepley + dm - The `DM` object 1277625649eSMatthew G. Knepley - name - A geometry model name, or `NULL` for the default 1287625649eSMatthew G. Knepley 1297625649eSMatthew G. Knepley Level: intermediate 1307625649eSMatthew G. Knepley 1317625649eSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMRefine()`, `DMPlexCreate()`, `DMSnapToGeomModel()` 1327625649eSMatthew G. Knepley @*/ 1337625649eSMatthew G. Knepley PetscErrorCode DMSetSnapToGeomModel(DM dm, const char name[]) 1347625649eSMatthew G. Knepley { 1357625649eSMatthew G. Knepley char geomname[PETSC_MAX_PATH_LEN]; 1367625649eSMatthew G. Knepley PetscBool flg; 1377625649eSMatthew G. Knepley 1387625649eSMatthew G. Knepley PetscFunctionBegin; 1397625649eSMatthew G. Knepley if (!name && dm->ops->snaptogeommodel) PetscFunctionReturn(PETSC_SUCCESS); 1407625649eSMatthew G. Knepley PetscCall(PetscOptionsGetString(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dm_geom_model", geomname, sizeof(geomname), &flg)); 1417625649eSMatthew G. Knepley if (flg) name = geomname; 1427625649eSMatthew G. Knepley if (!name) { 1437625649eSMatthew G. Knepley PetscObject modelObj; 1447625649eSMatthew G. Knepley 145835f2295SStefano Zampini PetscCall(PetscObjectQuery((PetscObject)dm, "EGADS Model", &modelObj)); 1467625649eSMatthew G. Knepley if (modelObj) name = "egads"; 1477625649eSMatthew G. Knepley else { 1485552b385SBrandon PetscCall(PetscObjectQuery((PetscObject)dm, "EGADSlite Model", &modelObj)); 1495552b385SBrandon if (modelObj) name = "egads"; 1507625649eSMatthew G. Knepley } 1517625649eSMatthew G. Knepley } 1527625649eSMatthew G. Knepley if (!name) PetscFunctionReturn(PETSC_SUCCESS); 1537625649eSMatthew G. Knepley 1547625649eSMatthew G. Knepley PetscCall(PetscFunctionListFind(DMGeomModelList, name, &dm->ops->snaptogeommodel)); 1557625649eSMatthew G. Knepley PetscCheck(dm->ops->snaptogeommodel, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Geometry model %s not registered; you may need to add --download-%s to your ./configure options", name, name); 1567625649eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1577625649eSMatthew G. Knepley } 1587625649eSMatthew G. Knepley 1597625649eSMatthew G. Knepley /*@ 1607625649eSMatthew G. Knepley DMSnapToGeomModel - Given a coordinate point 'mcoords' on the mesh point 'p', return the closest coordinate point 'gcoords' on the geometry model associated with that point. 1617625649eSMatthew G. Knepley 1627625649eSMatthew G. Knepley Not Collective 1637625649eSMatthew G. Knepley 1647625649eSMatthew G. Knepley Input Parameters: 1657625649eSMatthew G. Knepley + dm - The `DMPLEX` object 1667625649eSMatthew G. Knepley . p - The mesh point 1677625649eSMatthew G. Knepley . dE - The coordinate dimension 1687625649eSMatthew G. Knepley - mcoords - A coordinate point lying on the mesh point 1697625649eSMatthew G. Knepley 1707625649eSMatthew G. Knepley Output Parameter: 1717625649eSMatthew G. Knepley . gcoords - The closest coordinate point on the geometry model associated with 'p' to the given point 1727625649eSMatthew G. Knepley 1737625649eSMatthew G. Knepley Level: intermediate 1747625649eSMatthew G. Knepley 1757625649eSMatthew G. Knepley Note: 1767625649eSMatthew G. Knepley Returns the original coordinates if no geometry model is found. 1777625649eSMatthew G. Knepley 1787625649eSMatthew G. Knepley The coordinate dimension may be different from the coordinate dimension of the `dm`, for example if the transformation is extrusion. 1797625649eSMatthew G. Knepley 1807625649eSMatthew G. Knepley .seealso: [](ch_unstructured), `DM`, `DMPLEX`, `DMRefine()`, `DMPlexCreate()`, `DMPlexSetRefinementUniform()` 1817625649eSMatthew G. Knepley @*/ 1827625649eSMatthew G. Knepley PetscErrorCode DMSnapToGeomModel(DM dm, PetscInt p, PetscInt dE, const PetscScalar mcoords[], PetscScalar gcoords[]) 1837625649eSMatthew G. Knepley { 1847625649eSMatthew G. Knepley PetscFunctionBegin; 1857625649eSMatthew G. Knepley if (!dm->ops->snaptogeommodel) 1867625649eSMatthew G. Knepley for (PetscInt d = 0; d < dE; ++d) gcoords[d] = mcoords[d]; 1877625649eSMatthew G. Knepley else PetscUseTypeMethod(dm, snaptogeommodel, p, dE, mcoords, gcoords); 1887625649eSMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 1897625649eSMatthew G. Knepley } 190