1c0517cd5SMatthew G. Knepley #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 2c0517cd5SMatthew G. Knepley 3c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMIsForest(DM, PetscBool *); 4c0517cd5SMatthew G. Knepley 5c0517cd5SMatthew G. Knepley DMGeneratorFunctionList DMGenerateList = NULL; 6c0517cd5SMatthew G. Knepley PetscBool DMGenerateRegisterAllCalled = PETSC_FALSE; 7c0517cd5SMatthew G. Knepley 8c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 9c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexGenerate_Triangle(DM, PetscBool, DM *); 1004f3ee44SStefano Zampini PETSC_EXTERN PetscErrorCode DMPlexRefine_Triangle(DM, PetscReal *, DM *); 11c0517cd5SMatthew G. Knepley #endif 12c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 13c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexGenerate_Tetgen(DM, PetscBool, DM *); 14c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexRefine_Tetgen(DM, double *, DM *); 15c0517cd5SMatthew G. Knepley #endif 16c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 17c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexGenerate_CTetgen(DM, PetscBool, DM *); 18c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexRefine_CTetgen(DM, double *, DM *); 19c0517cd5SMatthew G. Knepley #endif 20c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMATIC) 219fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptMetric_Pragmatic_Plex(DM, Vec, DMLabel, DMLabel, DM *); 22c0517cd5SMatthew G. Knepley #endif 23c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_MMG) 249fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptMetric_Mmg_Plex(DM, Vec, DMLabel, DMLabel, DM *); 25c0517cd5SMatthew G. Knepley #endif 26c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PARMMG) 279fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptMetric_ParMmg_Plex(DM, Vec, DMLabel, DMLabel, DM *); 28c0517cd5SMatthew G. Knepley #endif 299fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMPlexTransformAdaptLabel(DM, Vec, DMLabel, DMLabel, DM *); 309fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptLabel_Forest(DM, Vec, DMLabel, DMLabel, DM *); 31c0517cd5SMatthew G. Knepley 32c0517cd5SMatthew G. Knepley /*@C 3316a05f60SBarry Smith DMGenerateRegisterAll - Registers all of the mesh generation methods in the `DM` package. 34c0517cd5SMatthew G. Knepley 35c0517cd5SMatthew G. Knepley Not Collective 36c0517cd5SMatthew G. Knepley 37c0517cd5SMatthew G. Knepley Level: advanced 38c0517cd5SMatthew G. Knepley 3916a05f60SBarry Smith .seealso: `DM`, `DMGenerateRegisterDestroy()` 40c0517cd5SMatthew G. Knepley @*/ 41d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGenerateRegisterAll(void) 42d71ae5a4SJacob Faibussowitsch { 43c0517cd5SMatthew G. Knepley PetscFunctionBegin; 443ba16761SJacob Faibussowitsch if (DMGenerateRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS); 45c0517cd5SMatthew G. Knepley DMGenerateRegisterAllCalled = PETSC_TRUE; 46c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 479566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("triangle", DMPlexGenerate_Triangle, DMPlexRefine_Triangle, NULL, 1)); 48c0517cd5SMatthew G. Knepley #endif 49c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 509566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("ctetgen", DMPlexGenerate_CTetgen, DMPlexRefine_CTetgen, NULL, 2)); 51c0517cd5SMatthew G. Knepley #endif 52c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 539566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("tetgen", DMPlexGenerate_Tetgen, DMPlexRefine_Tetgen, NULL, 2)); 54c0517cd5SMatthew G. Knepley #endif 55c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMATIC) 569566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("pragmatic", NULL, NULL, DMAdaptMetric_Pragmatic_Plex, -1)); 57c0517cd5SMatthew G. Knepley #endif 58c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_MMG) 599566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("mmg", NULL, NULL, DMAdaptMetric_Mmg_Plex, -1)); 60c0517cd5SMatthew G. Knepley #endif 61c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PARMMG) 629566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("parmmg", NULL, NULL, DMAdaptMetric_ParMmg_Plex, -1)); 63c0517cd5SMatthew G. Knepley #endif 649566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("cellrefiner", NULL, NULL, DMPlexTransformAdaptLabel, -1)); 659566063dSJacob Faibussowitsch PetscCall(DMGenerateRegister("forest", NULL, NULL, DMAdaptLabel_Forest, -1)); 663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 67c0517cd5SMatthew G. Knepley } 68c0517cd5SMatthew G. Knepley 69c0517cd5SMatthew G. Knepley /*@C 7016a05f60SBarry Smith DMGenerateRegister - Adds a grid generator to `DM` 71c0517cd5SMatthew G. Knepley 72a3b724e8SBarry Smith Not Collective, No Fortran Support 73c0517cd5SMatthew G. Knepley 74c0517cd5SMatthew G. Knepley Input Parameters: 7520f4b53cSBarry Smith + sname - name of a new user-defined grid generator 76c0517cd5SMatthew G. Knepley . fnc - generator function 77c0517cd5SMatthew G. Knepley . rfnc - refinement function 78c0517cd5SMatthew G. Knepley . alfnc - adapt by label function 79c0517cd5SMatthew G. Knepley - dim - dimension of boundary of domain 80c0517cd5SMatthew G. Knepley 8160225df5SJacob Faibussowitsch Example Usage: 82c0517cd5SMatthew G. Knepley .vb 83c0517cd5SMatthew G. Knepley DMGenerateRegister("my_generator", MyGeneratorCreate, MyGeneratorRefiner, MyGeneratorAdaptor, dim); 84c0517cd5SMatthew G. Knepley .ve 85c0517cd5SMatthew G. Knepley 86c0517cd5SMatthew G. Knepley Then, your generator can be chosen with the procedural interface via 87*b44f4de4SBarry Smith .vb 88*b44f4de4SBarry Smith DMGenerate(dm, "my_generator",...) 89*b44f4de4SBarry Smith .ve 90c0517cd5SMatthew G. Knepley or at runtime via the option 91*b44f4de4SBarry Smith .vb 92*b44f4de4SBarry Smith -dm_generator my_generator 93*b44f4de4SBarry Smith .ve 94c0517cd5SMatthew G. Knepley 95c0517cd5SMatthew G. Knepley Level: advanced 96c0517cd5SMatthew G. Knepley 9720f4b53cSBarry Smith Note: 9820f4b53cSBarry Smith `DMGenerateRegister()` may be called multiple times to add several user-defined generators 99c0517cd5SMatthew G. Knepley 10020f4b53cSBarry Smith .seealso: `DM`, `DMGenerateRegisterAll()`, `DMPlexGenerate()`, `DMGenerateRegisterDestroy()` 101c0517cd5SMatthew G. Knepley @*/ 102d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGenerateRegister(const char sname[], PetscErrorCode (*fnc)(DM, PetscBool, DM *), PetscErrorCode (*rfnc)(DM, PetscReal *, DM *), PetscErrorCode (*alfnc)(DM, Vec, DMLabel, DMLabel, DM *), PetscInt dim) 103d71ae5a4SJacob Faibussowitsch { 104c0517cd5SMatthew G. Knepley DMGeneratorFunctionList entry; 105c0517cd5SMatthew G. Knepley 106c0517cd5SMatthew G. Knepley PetscFunctionBegin; 1079566063dSJacob Faibussowitsch PetscCall(PetscNew(&entry)); 1089566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(sname, &entry->name)); 109c0517cd5SMatthew G. Knepley entry->generate = fnc; 110c0517cd5SMatthew G. Knepley entry->refine = rfnc; 111c0517cd5SMatthew G. Knepley entry->adapt = alfnc; 112c0517cd5SMatthew G. Knepley entry->dim = dim; 113c0517cd5SMatthew G. Knepley entry->next = NULL; 114c0517cd5SMatthew G. Knepley if (!DMGenerateList) DMGenerateList = entry; 115c0517cd5SMatthew G. Knepley else { 116c0517cd5SMatthew G. Knepley DMGeneratorFunctionList fl = DMGenerateList; 117c0517cd5SMatthew G. Knepley while (fl->next) fl = fl->next; 118c0517cd5SMatthew G. Knepley fl->next = entry; 119c0517cd5SMatthew G. Knepley } 1203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 121c0517cd5SMatthew G. Knepley } 122c0517cd5SMatthew G. Knepley 123c0517cd5SMatthew G. Knepley extern PetscBool DMGenerateRegisterAllCalled; 124c0517cd5SMatthew G. Knepley 125d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGenerateRegisterDestroy(void) 126d71ae5a4SJacob Faibussowitsch { 127c0517cd5SMatthew G. Knepley DMGeneratorFunctionList next, fl; 128c0517cd5SMatthew G. Knepley 129c0517cd5SMatthew G. Knepley PetscFunctionBegin; 130c0517cd5SMatthew G. Knepley next = fl = DMGenerateList; 131c0517cd5SMatthew G. Knepley while (next) { 132c0517cd5SMatthew G. Knepley next = fl ? fl->next : NULL; 1339566063dSJacob Faibussowitsch if (fl) PetscCall(PetscFree(fl->name)); 1349566063dSJacob Faibussowitsch PetscCall(PetscFree(fl)); 135c0517cd5SMatthew G. Knepley fl = next; 136c0517cd5SMatthew G. Knepley } 137c0517cd5SMatthew G. Knepley DMGenerateList = NULL; 138c0517cd5SMatthew G. Knepley DMGenerateRegisterAllCalled = PETSC_FALSE; 1393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 140c0517cd5SMatthew G. Knepley } 141c0517cd5SMatthew G. Knepley 1425d83a8b1SBarry Smith /*@ 14320f4b53cSBarry Smith DMAdaptLabel - Adapt a `DM` based on a `DMLabel` with values interpreted as coarsening and refining flags. Specific implementations of `DM` maybe have 14420f4b53cSBarry Smith specialized flags, but all implementations should accept flag values `DM_ADAPT_DETERMINE`, `DM_ADAPT_KEEP`, `DM_ADAPT_REFINE`, and, 14520f4b53cSBarry Smith `DM_ADAPT_COARSEN`. 146c0517cd5SMatthew G. Knepley 14720f4b53cSBarry Smith Collective 148c0517cd5SMatthew G. Knepley 14960225df5SJacob Faibussowitsch Input Parameters: 15020f4b53cSBarry Smith + dm - the pre-adaptation `DM` object 151c0517cd5SMatthew G. Knepley - label - label with the flags 152c0517cd5SMatthew G. Knepley 15360225df5SJacob Faibussowitsch Output Parameters: 15420f4b53cSBarry Smith . dmAdapt - the adapted `DM` object: may be `NULL` if an adapted `DM` could not be produced. 155c0517cd5SMatthew G. Knepley 156c0517cd5SMatthew G. Knepley Level: intermediate 157c0517cd5SMatthew G. Knepley 15820f4b53cSBarry Smith .seealso: `DM`, `DMAdaptMetric()`, `DMCoarsen()`, `DMRefine()` 159c0517cd5SMatthew G. Knepley @*/ 160d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 161d71ae5a4SJacob Faibussowitsch { 162c0517cd5SMatthew G. Knepley DMGeneratorFunctionList fl; 163c0517cd5SMatthew G. Knepley char adaptname[PETSC_MAX_PATH_LEN]; 164c0517cd5SMatthew G. Knepley const char *name; 165c0517cd5SMatthew G. Knepley PetscInt dim; 166c0517cd5SMatthew G. Knepley PetscBool flg, isForest, found = PETSC_FALSE; 167c0517cd5SMatthew G. Knepley 168c0517cd5SMatthew G. Knepley PetscFunctionBegin; 169c0517cd5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 170292bffcbSToby Isaac if (label) PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 2); 1714f572ea9SToby Isaac PetscAssertPointer(dmAdapt, 3); 172c0517cd5SMatthew G. Knepley *dmAdapt = NULL; 1739566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 1749566063dSJacob Faibussowitsch PetscCall(DMIsForest(dm, &isForest)); 175c0517cd5SMatthew G. Knepley name = isForest ? "forest" : "cellrefiner"; 1769566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dm_adaptor", adaptname, sizeof(adaptname), &flg)); 177c0517cd5SMatthew G. Knepley if (flg) name = adaptname; 178c0517cd5SMatthew G. Knepley 179c0517cd5SMatthew G. Knepley fl = DMGenerateList; 180c0517cd5SMatthew G. Knepley while (fl) { 1819566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(fl->name, name, &flg)); 182c0517cd5SMatthew G. Knepley if (flg) { 1839566063dSJacob Faibussowitsch PetscCall((*fl->adapt)(dm, NULL, label, NULL, dmAdapt)); 184c0517cd5SMatthew G. Knepley found = PETSC_TRUE; 185c0517cd5SMatthew G. Knepley } 186c0517cd5SMatthew G. Knepley fl = fl->next; 187c0517cd5SMatthew G. Knepley } 1887a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Grid adaptor %s not registered; you may need to add --download-%s to your ./configure options", name, name); 189c0517cd5SMatthew G. Knepley if (*dmAdapt) { 1903a336bb1SMatthew G. Knepley void *ctx; 1913a336bb1SMatthew G. Knepley 192c0517cd5SMatthew G. Knepley (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 1939566063dSJacob Faibussowitsch PetscCall(PetscFree((*dmAdapt)->vectype)); 1949566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*dmAdapt)->vectype)); 1959566063dSJacob Faibussowitsch PetscCall(PetscFree((*dmAdapt)->mattype)); 1969566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*dmAdapt)->mattype)); 1973a336bb1SMatthew G. Knepley PetscCall(DMGetApplicationContext(dm, &ctx)); 1983a336bb1SMatthew G. Knepley PetscCall(DMSetApplicationContext(*dmAdapt, ctx)); 199c0517cd5SMatthew G. Knepley } 2003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 201c0517cd5SMatthew G. Knepley } 202c0517cd5SMatthew G. Knepley 2035d83a8b1SBarry Smith /*@ 204c0517cd5SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field. 205c0517cd5SMatthew G. Knepley 206c0517cd5SMatthew G. Knepley Input Parameters: 207c0517cd5SMatthew G. Knepley + dm - The DM object 208c0517cd5SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 209dc9a610eSPierre Jolivet . bdLabel - Label for boundary tags, which will be preserved in the output mesh. `bdLabel` should be `NULL` if there is no such label, and should be different from "_boundary_". 210dc9a610eSPierre Jolivet - rgLabel - Label for cell tags, which will be preserved in the output mesh. `rgLabel` should be `NULL` if there is no such label, and should be different from "_regions_". 211c0517cd5SMatthew G. Knepley 212c0517cd5SMatthew G. Knepley Output Parameter: 213a3b724e8SBarry Smith . dmAdapt - Pointer to the `DM` object containing the adapted mesh 214c0517cd5SMatthew G. Knepley 215a4e35b19SJacob Faibussowitsch Note: 216a4e35b19SJacob Faibussowitsch The label in the adapted mesh will be registered under the name of the input `DMLabel` object 217c0517cd5SMatthew G. Knepley 218c0517cd5SMatthew G. Knepley Level: advanced 219c0517cd5SMatthew G. Knepley 220db781477SPatrick Sanan .seealso: `DMAdaptLabel()`, `DMCoarsen()`, `DMRefine()` 221c0517cd5SMatthew G. Knepley @*/ 222d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DMLabel rgLabel, DM *dmAdapt) 223d71ae5a4SJacob Faibussowitsch { 224c0517cd5SMatthew G. Knepley DMGeneratorFunctionList fl; 225c0517cd5SMatthew G. Knepley char adaptname[PETSC_MAX_PATH_LEN]; 22606716a2aSJoe Wallwork const char *name; 22706716a2aSJoe Wallwork const char *const adaptors[3] = {"pragmatic", "mmg", "parmmg"}; 228c0517cd5SMatthew G. Knepley PetscInt dim; 229c0517cd5SMatthew G. Knepley PetscBool flg, found = PETSC_FALSE; 230c0517cd5SMatthew G. Knepley 231c0517cd5SMatthew G. Knepley PetscFunctionBegin; 232c0517cd5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 233c0517cd5SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 234292bffcbSToby Isaac if (bdLabel) PetscValidHeaderSpecific(bdLabel, DMLABEL_CLASSID, 3); 235292bffcbSToby Isaac if (rgLabel) PetscValidHeaderSpecific(rgLabel, DMLABEL_CLASSID, 4); 2364f572ea9SToby Isaac PetscAssertPointer(dmAdapt, 5); 237c0517cd5SMatthew G. Knepley *dmAdapt = NULL; 2389566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 2399566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetString(((PetscObject)dm)->options, ((PetscObject)dm)->prefix, "-dm_adaptor", adaptname, sizeof(adaptname), &flg)); 24006716a2aSJoe Wallwork 24106716a2aSJoe Wallwork /* Default to Mmg in serial and ParMmg in parallel */ 242c0517cd5SMatthew G. Knepley if (flg) name = adaptname; 24306716a2aSJoe Wallwork else { 24406716a2aSJoe Wallwork MPI_Comm comm; 24506716a2aSJoe Wallwork PetscMPIInt size; 24606716a2aSJoe Wallwork 2479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 2489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 24906716a2aSJoe Wallwork if (size == 1) name = adaptors[1]; 25006716a2aSJoe Wallwork else name = adaptors[2]; 25106716a2aSJoe Wallwork } 252c0517cd5SMatthew G. Knepley 253c0517cd5SMatthew G. Knepley fl = DMGenerateList; 254c0517cd5SMatthew G. Knepley while (fl) { 2559566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(fl->name, name, &flg)); 256c0517cd5SMatthew G. Knepley if (flg) { 2579566063dSJacob Faibussowitsch PetscCall((*fl->adapt)(dm, metric, bdLabel, rgLabel, dmAdapt)); 258c0517cd5SMatthew G. Knepley found = PETSC_TRUE; 259c0517cd5SMatthew G. Knepley } 260c0517cd5SMatthew G. Knepley fl = fl->next; 261c0517cd5SMatthew G. Knepley } 2627a8be351SBarry Smith PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Grid adaptor %s not registered; you may need to add --download-%s to your ./configure options", name, name); 263c0517cd5SMatthew G. Knepley if (*dmAdapt) { 264c0517cd5SMatthew G. Knepley (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 2659566063dSJacob Faibussowitsch PetscCall(PetscFree((*dmAdapt)->vectype)); 2669566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->vectype, (char **)&(*dmAdapt)->vectype)); 2679566063dSJacob Faibussowitsch PetscCall(PetscFree((*dmAdapt)->mattype)); 2689566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(dm->mattype, (char **)&(*dmAdapt)->mattype)); 269c0517cd5SMatthew G. Knepley } 2703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 271c0517cd5SMatthew G. Knepley } 272