19be51f97SToby Isaac #include <petsc/private/dmforestimpl.h> /*I "petscdmforest.h" I*/ 29be51f97SToby Isaac #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 3a1b0c543SToby Isaac #include <petsc/private/dmlabelimpl.h> /*I "petscdmlabel.h" I*/ 4ef19d27cSToby Isaac #include <petscsf.h> 5db4d5e8cSToby Isaac 627d4645fSToby Isaac PetscBool DMForestPackageInitialized = PETSC_FALSE; 727d4645fSToby Isaac 827d4645fSToby Isaac typedef struct _DMForestTypeLink *DMForestTypeLink; 927d4645fSToby Isaac 109371c9d4SSatish Balay struct _DMForestTypeLink { 1127d4645fSToby Isaac char *name; 1227d4645fSToby Isaac DMForestTypeLink next; 1327d4645fSToby Isaac }; 1427d4645fSToby Isaac 1527d4645fSToby Isaac DMForestTypeLink DMForestTypeList; 1627d4645fSToby Isaac 17d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMForestPackageFinalize(void) 18d71ae5a4SJacob Faibussowitsch { 1927d4645fSToby Isaac DMForestTypeLink oldLink, link = DMForestTypeList; 2027d4645fSToby Isaac 2127d4645fSToby Isaac PetscFunctionBegin; 2227d4645fSToby Isaac while (link) { 2327d4645fSToby Isaac oldLink = link; 249566063dSJacob Faibussowitsch PetscCall(PetscFree(oldLink->name)); 2527d4645fSToby Isaac link = oldLink->next; 269566063dSJacob Faibussowitsch PetscCall(PetscFree(oldLink)); 2727d4645fSToby Isaac } 283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2927d4645fSToby Isaac } 3027d4645fSToby Isaac 31d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMForestPackageInitialize(void) 32d71ae5a4SJacob Faibussowitsch { 3327d4645fSToby Isaac PetscFunctionBegin; 343ba16761SJacob Faibussowitsch if (DMForestPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS); 3527d4645fSToby Isaac DMForestPackageInitialized = PETSC_TRUE; 36f885a11aSToby Isaac 379566063dSJacob Faibussowitsch PetscCall(DMForestRegisterType(DMFOREST)); 389566063dSJacob Faibussowitsch PetscCall(PetscRegisterFinalize(DMForestPackageFinalize)); 393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4027d4645fSToby Isaac } 4127d4645fSToby Isaac 429be51f97SToby Isaac /*@C 43dce8aebaSBarry Smith DMForestRegisterType - Registers a `DMType` as a subtype of `DMFOREST` (so that `DMIsForest()` will be correct) 449be51f97SToby Isaac 459be51f97SToby Isaac Not Collective 469be51f97SToby Isaac 479be51f97SToby Isaac Input parameter: 489be51f97SToby Isaac . name - the name of the type 499be51f97SToby Isaac 509be51f97SToby Isaac Level: advanced 519be51f97SToby Isaac 52db781477SPatrick Sanan .seealso: `DMFOREST`, `DMIsForest()` 539be51f97SToby Isaac @*/ 54d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestRegisterType(DMType name) 55d71ae5a4SJacob Faibussowitsch { 5627d4645fSToby Isaac DMForestTypeLink link; 5727d4645fSToby Isaac 5827d4645fSToby Isaac PetscFunctionBegin; 599566063dSJacob Faibussowitsch PetscCall(DMForestPackageInitialize()); 609566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 619566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &link->name)); 6227d4645fSToby Isaac link->next = DMForestTypeList; 6327d4645fSToby Isaac DMForestTypeList = link; 643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6527d4645fSToby Isaac } 6627d4645fSToby Isaac 679be51f97SToby Isaac /*@ 689be51f97SToby Isaac DMIsForest - Check whether a DM uses the DMFOREST interface for hierarchically-refined meshes 699be51f97SToby Isaac 709be51f97SToby Isaac Not Collective 719be51f97SToby Isaac 729be51f97SToby Isaac Input parameter: 739be51f97SToby Isaac . dm - the DM object 749be51f97SToby Isaac 759be51f97SToby Isaac Output parameter: 769be51f97SToby Isaac . isForest - whether dm is a subtype of DMFOREST 779be51f97SToby Isaac 789be51f97SToby Isaac Level: intermediate 799be51f97SToby Isaac 80db781477SPatrick Sanan .seealso: `DMFOREST`, `DMForestRegisterType()` 819be51f97SToby Isaac @*/ 82d71ae5a4SJacob Faibussowitsch PetscErrorCode DMIsForest(DM dm, PetscBool *isForest) 83d71ae5a4SJacob Faibussowitsch { 8427d4645fSToby Isaac DMForestTypeLink link = DMForestTypeList; 8527d4645fSToby Isaac 8627d4645fSToby Isaac PetscFunctionBegin; 8727d4645fSToby Isaac while (link) { 8827d4645fSToby Isaac PetscBool sameType; 899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dm, link->name, &sameType)); 9027d4645fSToby Isaac if (sameType) { 9127d4645fSToby Isaac *isForest = PETSC_TRUE; 923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9327d4645fSToby Isaac } 9427d4645fSToby Isaac link = link->next; 9527d4645fSToby Isaac } 9627d4645fSToby Isaac *isForest = PETSC_FALSE; 973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9827d4645fSToby Isaac } 9927d4645fSToby Isaac 1009be51f97SToby Isaac /*@ 101*20f4b53cSBarry Smith DMForestTemplate - Create a new `DM` that will be adapted from a source `DM`. The new `DM` reproduces the configuration 102*20f4b53cSBarry Smith of the source, but is not yet setup, so that the user can then define only the ways that the new `DM` should differ 103*20f4b53cSBarry Smith (by, e.g., refinement or repartitioning). The source `DM` is also set as the adaptivity source `DM` of the new `DM` (see 104*20f4b53cSBarry Smith `DMForestSetAdaptivityForest()`). 1059be51f97SToby Isaac 106*20f4b53cSBarry Smith Collective 1079be51f97SToby Isaac 1089be51f97SToby Isaac Input Parameters: 109*20f4b53cSBarry Smith + dm - the source `DM` object 110*20f4b53cSBarry Smith - comm - the communicator for the new `DM` (this communicator is currently ignored, but is present so that `DMForestTemplate()` can be used within `DMCoarsen()`) 1119be51f97SToby Isaac 1129be51f97SToby Isaac Output Parameter: 113*20f4b53cSBarry Smith . tdm - the new `DM` object 1149be51f97SToby Isaac 1159be51f97SToby Isaac Level: intermediate 1169be51f97SToby Isaac 117*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetAdaptivityForest()` 1189be51f97SToby Isaac @*/ 119d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestTemplate(DM dm, MPI_Comm comm, DM *tdm) 120d71ae5a4SJacob Faibussowitsch { 121a0452a8eSToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 12220e8089bSToby Isaac DMType type; 123a0452a8eSToby Isaac DM base; 124a0452a8eSToby Isaac DMForestTopology topology; 12505e99e11SStefano Zampini MatType mtype; 126a0452a8eSToby Isaac PetscInt dim, overlap, ref, factor; 127a0452a8eSToby Isaac DMForestAdaptivityStrategy strat; 128795844e7SToby Isaac void *ctx; 12949fc9a2fSToby Isaac PetscErrorCode (*map)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void *); 1303e58adeeSToby Isaac void *mapCtx; 131a0452a8eSToby Isaac 132a0452a8eSToby Isaac PetscFunctionBegin; 133a0452a8eSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1349566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), tdm)); 1359566063dSJacob Faibussowitsch PetscCall(DMGetType(dm, &type)); 1369566063dSJacob Faibussowitsch PetscCall(DMSetType(*tdm, type)); 1379566063dSJacob Faibussowitsch PetscCall(DMForestGetBaseDM(dm, &base)); 1389566063dSJacob Faibussowitsch PetscCall(DMForestSetBaseDM(*tdm, base)); 1399566063dSJacob Faibussowitsch PetscCall(DMForestGetTopology(dm, &topology)); 1409566063dSJacob Faibussowitsch PetscCall(DMForestSetTopology(*tdm, topology)); 1419566063dSJacob Faibussowitsch PetscCall(DMForestGetAdjacencyDimension(dm, &dim)); 1429566063dSJacob Faibussowitsch PetscCall(DMForestSetAdjacencyDimension(*tdm, dim)); 1439566063dSJacob Faibussowitsch PetscCall(DMForestGetPartitionOverlap(dm, &overlap)); 1449566063dSJacob Faibussowitsch PetscCall(DMForestSetPartitionOverlap(*tdm, overlap)); 1459566063dSJacob Faibussowitsch PetscCall(DMForestGetMinimumRefinement(dm, &ref)); 1469566063dSJacob Faibussowitsch PetscCall(DMForestSetMinimumRefinement(*tdm, ref)); 1479566063dSJacob Faibussowitsch PetscCall(DMForestGetMaximumRefinement(dm, &ref)); 1489566063dSJacob Faibussowitsch PetscCall(DMForestSetMaximumRefinement(*tdm, ref)); 1499566063dSJacob Faibussowitsch PetscCall(DMForestGetAdaptivityStrategy(dm, &strat)); 1509566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityStrategy(*tdm, strat)); 1519566063dSJacob Faibussowitsch PetscCall(DMForestGetGradeFactor(dm, &factor)); 1529566063dSJacob Faibussowitsch PetscCall(DMForestSetGradeFactor(*tdm, factor)); 1539566063dSJacob Faibussowitsch PetscCall(DMForestGetBaseCoordinateMapping(dm, &map, &mapCtx)); 1549566063dSJacob Faibussowitsch PetscCall(DMForestSetBaseCoordinateMapping(*tdm, map, mapCtx)); 1551baa6e33SBarry Smith if (forest->ftemplate) PetscCall((*forest->ftemplate)(dm, *tdm)); 1569566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityForest(*tdm, dm)); 1579566063dSJacob Faibussowitsch PetscCall(DMCopyDisc(dm, *tdm)); 1589566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dm, &ctx)); 1599566063dSJacob Faibussowitsch PetscCall(DMSetApplicationContext(*tdm, &ctx)); 16090b157c4SStefano Zampini { 1614fb89dddSMatthew G. Knepley const PetscReal *maxCell, *L, *Lstart; 162795844e7SToby Isaac 1634fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L)); 1644fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(*tdm, maxCell, Lstart, L)); 165795844e7SToby Isaac } 1669566063dSJacob Faibussowitsch PetscCall(DMGetMatType(dm, &mtype)); 1679566063dSJacob Faibussowitsch PetscCall(DMSetMatType(*tdm, mtype)); 1683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 169a0452a8eSToby Isaac } 170a0452a8eSToby Isaac 17101d9d024SToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm); 17201d9d024SToby Isaac 173d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm) 174d71ae5a4SJacob Faibussowitsch { 175db4d5e8cSToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 176db4d5e8cSToby Isaac const char *type; 177db4d5e8cSToby Isaac 178db4d5e8cSToby Isaac PetscFunctionBegin; 179db4d5e8cSToby Isaac forest->refct++; 180db4d5e8cSToby Isaac (*newdm)->data = forest; 1819566063dSJacob Faibussowitsch PetscCall(PetscObjectGetType((PetscObject)dm, &type)); 1829566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)*newdm, type)); 1839566063dSJacob Faibussowitsch PetscCall(DMInitialize_Forest(*newdm)); 1843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 185db4d5e8cSToby Isaac } 186db4d5e8cSToby Isaac 187d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMDestroy_Forest(DM dm) 188d71ae5a4SJacob Faibussowitsch { 189db4d5e8cSToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 190db4d5e8cSToby Isaac 191db4d5e8cSToby Isaac PetscFunctionBegin; 1923ba16761SJacob Faibussowitsch if (--forest->refct > 0) PetscFunctionReturn(PETSC_SUCCESS); 1939566063dSJacob Faibussowitsch if (forest->destroy) PetscCall((*forest->destroy)(dm)); 1949566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&forest->cellSF)); 1959566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&forest->preCoarseToFine)); 1969566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&forest->coarseToPreFine)); 1979566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&forest->adaptLabel)); 1989566063dSJacob Faibussowitsch PetscCall(PetscFree(forest->adaptStrategy)); 1999566063dSJacob Faibussowitsch PetscCall(DMDestroy(&forest->base)); 2009566063dSJacob Faibussowitsch PetscCall(DMDestroy(&forest->adapt)); 2019566063dSJacob Faibussowitsch PetscCall(PetscFree(forest->topology)); 2029566063dSJacob Faibussowitsch PetscCall(PetscFree(forest)); 2033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 204db4d5e8cSToby Isaac } 205db4d5e8cSToby Isaac 2069be51f97SToby Isaac /*@C 207*20f4b53cSBarry Smith DMForestSetTopology - Set the topology of a `DMFOREST` during the pre-setup phase. The topology is a string (e.g. 208*20f4b53cSBarry Smith "cube", "shell") and can be interpreted by subtypes of `DMFOREST`) to construct the base DM of a forest during 209*20f4b53cSBarry Smith `DMSetUp()`. 2109be51f97SToby Isaac 211*20f4b53cSBarry Smith Logically collectiv 2129be51f97SToby Isaac 2139be51f97SToby Isaac Input parameters: 2149be51f97SToby Isaac + dm - the forest 2159be51f97SToby Isaac - topology - the topology of the forest 2169be51f97SToby Isaac 2179be51f97SToby Isaac Level: intermediate 2189be51f97SToby Isaac 219*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetTopology()`, `DMForestSetBaseDM()` 2209be51f97SToby Isaac @*/ 221d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology) 222d71ae5a4SJacob Faibussowitsch { 223db4d5e8cSToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 224db4d5e8cSToby Isaac 225db4d5e8cSToby Isaac PetscFunctionBegin; 226db4d5e8cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22728b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the topology after setup"); 2289566063dSJacob Faibussowitsch PetscCall(PetscFree(forest->topology)); 2299566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy((const char *)topology, (char **)&forest->topology)); 2303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 231db4d5e8cSToby Isaac } 232db4d5e8cSToby Isaac 2339be51f97SToby Isaac /*@C 234*20f4b53cSBarry Smith DMForestGetTopology - Get a string describing the topology of a `DMFOREST`. 2359be51f97SToby Isaac 236*20f4b53cSBarry Smith Not Collective 2379be51f97SToby Isaac 2389be51f97SToby Isaac Input parameter: 2399be51f97SToby Isaac . dm - the forest 2409be51f97SToby Isaac 2419be51f97SToby Isaac Output parameter: 2429be51f97SToby Isaac . topology - the topology of the forest (e.g., 'cube', 'shell') 2439be51f97SToby Isaac 2449be51f97SToby Isaac Level: intermediate 2459be51f97SToby Isaac 246*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetTopology()` 2479be51f97SToby Isaac @*/ 248d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology) 249d71ae5a4SJacob Faibussowitsch { 250dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 251dd8e54a2SToby Isaac 252dd8e54a2SToby Isaac PetscFunctionBegin; 253dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 254dd8e54a2SToby Isaac PetscValidPointer(topology, 2); 255dd8e54a2SToby Isaac *topology = forest->topology; 2563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 257dd8e54a2SToby Isaac } 258dd8e54a2SToby Isaac 2599be51f97SToby Isaac /*@ 260*20f4b53cSBarry Smith DMForestSetBaseDM - During the pre-setup phase, set the `DM` that defines the base mesh of a `DMFOREST` forest. The 2619be51f97SToby Isaac forest will be hierarchically refined from the base, and all refinements/coarsenings of the forest will share its 262765b024eSBarry Smith base. In general, two forest must share a base to be comparable, to do things like construct interpolators. 2639be51f97SToby Isaac 264*20f4b53cSBarry Smith Logically Collective 2659be51f97SToby Isaac 2669be51f97SToby Isaac Input Parameters: 2679be51f97SToby Isaac + dm - the forest 268*20f4b53cSBarry Smith - base - the base `DM` of the forest 269765b024eSBarry Smith 2709be51f97SToby Isaac Level: intermediate 2719be51f97SToby Isaac 272*20f4b53cSBarry Smith Note: 273*20f4b53cSBarry Smith Currently the base `DM` must be a `DMPLEX` 274*20f4b53cSBarry Smith 275*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetBaseDM()` 2769be51f97SToby Isaac @*/ 277d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetBaseDM(DM dm, DM base) 278d71ae5a4SJacob Faibussowitsch { 279dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 280dd8e54a2SToby Isaac PetscInt dim, dimEmbed; 281dd8e54a2SToby Isaac 282dd8e54a2SToby Isaac PetscFunctionBegin; 283dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 28428b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the base after setup"); 2859566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)base)); 2869566063dSJacob Faibussowitsch PetscCall(DMDestroy(&forest->base)); 287dd8e54a2SToby Isaac forest->base = base; 288a0452a8eSToby Isaac if (base) { 2894fb89dddSMatthew G. Knepley const PetscReal *maxCell, *Lstart, *L; 29028dfcf7cSStefano Zampini 291a0452a8eSToby Isaac PetscValidHeaderSpecific(base, DM_CLASSID, 2); 2929566063dSJacob Faibussowitsch PetscCall(DMGetDimension(base, &dim)); 2939566063dSJacob Faibussowitsch PetscCall(DMSetDimension(dm, dim)); 2949566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(base, &dimEmbed)); 2959566063dSJacob Faibussowitsch PetscCall(DMSetCoordinateDim(dm, dimEmbed)); 2964fb89dddSMatthew G. Knepley PetscCall(DMGetPeriodicity(base, &maxCell, &Lstart, &L)); 2974fb89dddSMatthew G. Knepley PetscCall(DMSetPeriodicity(dm, maxCell, Lstart, L)); 2984fb89dddSMatthew G. Knepley } else PetscCall(DMSetPeriodicity(dm, NULL, NULL, NULL)); 2993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 300dd8e54a2SToby Isaac } 301dd8e54a2SToby Isaac 3029be51f97SToby Isaac /*@ 3039be51f97SToby Isaac DMForestGetBaseDM - Get the base DM of a DMForest forest. The forest will be hierarchically refined from the base, 30468d54884SBarry Smith and all refinements/coarsenings of the forest will share its base. In general, two forest must share a base to be 3059be51f97SToby Isaac comparable, to do things like construct interpolators. 3069be51f97SToby Isaac 307*20f4b53cSBarry Smith Not Collective 3089be51f97SToby Isaac 3099be51f97SToby Isaac Input Parameter: 3109be51f97SToby Isaac . dm - the forest 3119be51f97SToby Isaac 3129be51f97SToby Isaac Output Parameter: 3139be51f97SToby Isaac . base - the base DM of the forest 3149be51f97SToby Isaac 315367003a6SStefano Zampini Notes: 316367003a6SStefano Zampini After DMSetUp(), the base DM will be redundantly distributed across MPI processes 317367003a6SStefano Zampini 3189be51f97SToby Isaac Level: intermediate 3199be51f97SToby Isaac 320*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetBaseDM()` 3219be51f97SToby Isaac @*/ 322d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetBaseDM(DM dm, DM *base) 323d71ae5a4SJacob Faibussowitsch { 324dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 325dd8e54a2SToby Isaac 326dd8e54a2SToby Isaac PetscFunctionBegin; 327dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 328dd8e54a2SToby Isaac PetscValidPointer(base, 2); 329dd8e54a2SToby Isaac *base = forest->base; 3303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 331dd8e54a2SToby Isaac } 332dd8e54a2SToby Isaac 333d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetBaseCoordinateMapping(DM dm, PetscErrorCode (*func)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void *), void *ctx) 334d71ae5a4SJacob Faibussowitsch { 335cf38a08cSToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 336cf38a08cSToby Isaac 337cf38a08cSToby Isaac PetscFunctionBegin; 338cf38a08cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 339cf38a08cSToby Isaac forest->mapcoordinates = func; 340cf38a08cSToby Isaac forest->mapcoordinatesctx = ctx; 3413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 342cf38a08cSToby Isaac } 343cf38a08cSToby Isaac 344d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetBaseCoordinateMapping(DM dm, PetscErrorCode (**func)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void *), void *ctx) 345d71ae5a4SJacob Faibussowitsch { 346cf38a08cSToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 347cf38a08cSToby Isaac 348cf38a08cSToby Isaac PetscFunctionBegin; 349cf38a08cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 350cf38a08cSToby Isaac if (func) *func = forest->mapcoordinates; 351cf38a08cSToby Isaac if (ctx) *((void **)ctx) = forest->mapcoordinatesctx; 3523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 353cf38a08cSToby Isaac } 354cf38a08cSToby Isaac 3559be51f97SToby Isaac /*@ 3569be51f97SToby Isaac DMForestSetAdaptivityForest - During the pre-setup phase, set the forest from which the current forest will be 357*20f4b53cSBarry Smith adapted (e.g., the current forest will be refined/coarsened/repartitioned from it) in `DMSetUp()`. Usually not needed 358*20f4b53cSBarry Smith by users directly: `DMForestTemplate()` constructs a new forest to be adapted from an old forest and calls this 3599be51f97SToby Isaac routine. 3609be51f97SToby Isaac 361*20f4b53cSBarry Smith Logically Collective 3629be51f97SToby Isaac 363d8d19677SJose E. Roman Input Parameters: 3649be51f97SToby Isaac + dm - the new forest, which will be constructed from adapt 3659be51f97SToby Isaac - adapt - the old forest 3669be51f97SToby Isaac 3679be51f97SToby Isaac Level: intermediate 3689be51f97SToby Isaac 369*20f4b53cSBarry Smith Note: 370*20f4b53cSBarry Smith This can be called after setup with `adapt` = `NULL`, which will clear all internal data related to the 371*20f4b53cSBarry Smith adaptivity forest from `dm`. This way, repeatedly adapting does not leave stale `DM` objects in memory. 372*20f4b53cSBarry Smith 373*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetAdaptivityForest()`, `DMForestSetAdaptivityPurpose()` 3749be51f97SToby Isaac @*/ 375d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetAdaptivityForest(DM dm, DM adapt) 376d71ae5a4SJacob Faibussowitsch { 377dffe73a3SToby Isaac DM_Forest *forest, *adaptForest, *oldAdaptForest; 378dffe73a3SToby Isaac DM oldAdapt; 379456cc5b7SMatthew G. Knepley PetscBool isForest; 380dd8e54a2SToby Isaac 381dd8e54a2SToby Isaac PetscFunctionBegin; 382dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3831fd50544SStefano Zampini if (adapt) PetscValidHeaderSpecific(adapt, DM_CLASSID, 2); 3849566063dSJacob Faibussowitsch PetscCall(DMIsForest(dm, &isForest)); 3853ba16761SJacob Faibussowitsch if (!isForest) PetscFunctionReturn(PETSC_SUCCESS); 3861dca8a05SBarry Smith PetscCheck(adapt == NULL || !dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the adaptation forest after setup"); 387ba936b91SToby Isaac forest = (DM_Forest *)dm->data; 3889566063dSJacob Faibussowitsch PetscCall(DMForestGetAdaptivityForest(dm, &oldAdapt)); 389193eb951SToby Isaac adaptForest = (DM_Forest *)(adapt ? adapt->data : NULL); 390193eb951SToby Isaac oldAdaptForest = (DM_Forest *)(oldAdapt ? oldAdapt->data : NULL); 391dffe73a3SToby Isaac if (adaptForest != oldAdaptForest) { 3929566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&forest->preCoarseToFine)); 3939566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&forest->coarseToPreFine)); 3949566063dSJacob Faibussowitsch if (forest->clearadaptivityforest) PetscCall((*forest->clearadaptivityforest)(dm)); 395dffe73a3SToby Isaac } 39626d9498aSToby Isaac switch (forest->adaptPurpose) { 397cd3c525cSToby Isaac case DM_ADAPT_DETERMINE: 3989566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)adapt)); 3999566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(forest->adapt))); 400ba936b91SToby Isaac forest->adapt = adapt; 40126d9498aSToby Isaac break; 402d71ae5a4SJacob Faibussowitsch case DM_ADAPT_REFINE: 403d71ae5a4SJacob Faibussowitsch PetscCall(DMSetCoarseDM(dm, adapt)); 404d71ae5a4SJacob Faibussowitsch break; 405a1b0c543SToby Isaac case DM_ADAPT_COARSEN: 406d71ae5a4SJacob Faibussowitsch case DM_ADAPT_COARSEN_LAST: 407d71ae5a4SJacob Faibussowitsch PetscCall(DMSetFineDM(dm, adapt)); 408d71ae5a4SJacob Faibussowitsch break; 409d71ae5a4SJacob Faibussowitsch default: 410d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "invalid adaptivity purpose"); 41126d9498aSToby Isaac } 4123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 413dd8e54a2SToby Isaac } 414dd8e54a2SToby Isaac 4159be51f97SToby Isaac /*@ 4169be51f97SToby Isaac DMForestGetAdaptivityForest - Get the forest from which the current forest is adapted. 4179be51f97SToby Isaac 418*20f4b53cSBarry Smith Not Collective 4199be51f97SToby Isaac 4209be51f97SToby Isaac Input Parameter: 4219be51f97SToby Isaac . dm - the forest 4229be51f97SToby Isaac 4239be51f97SToby Isaac Output Parameter: 424*20f4b53cSBarry Smith . adapt - the forest from which `dm` is/was adapted 4259be51f97SToby Isaac 4269be51f97SToby Isaac Level: intermediate 4279be51f97SToby Isaac 428*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetAdaptivityForest()`, `DMForestSetAdaptivityPurpose()` 4299be51f97SToby Isaac @*/ 430d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt) 431d71ae5a4SJacob Faibussowitsch { 432ba936b91SToby Isaac DM_Forest *forest; 433dd8e54a2SToby Isaac 434dd8e54a2SToby Isaac PetscFunctionBegin; 435dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 436ba936b91SToby Isaac forest = (DM_Forest *)dm->data; 43726d9498aSToby Isaac switch (forest->adaptPurpose) { 438d71ae5a4SJacob Faibussowitsch case DM_ADAPT_DETERMINE: 439d71ae5a4SJacob Faibussowitsch *adapt = forest->adapt; 440d71ae5a4SJacob Faibussowitsch break; 441d71ae5a4SJacob Faibussowitsch case DM_ADAPT_REFINE: 442d71ae5a4SJacob Faibussowitsch PetscCall(DMGetCoarseDM(dm, adapt)); 443d71ae5a4SJacob Faibussowitsch break; 444a1b0c543SToby Isaac case DM_ADAPT_COARSEN: 445d71ae5a4SJacob Faibussowitsch case DM_ADAPT_COARSEN_LAST: 446d71ae5a4SJacob Faibussowitsch PetscCall(DMGetFineDM(dm, adapt)); 447d71ae5a4SJacob Faibussowitsch break; 448d71ae5a4SJacob Faibussowitsch default: 449d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "invalid adaptivity purpose"); 45026d9498aSToby Isaac } 4513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45226d9498aSToby Isaac } 45326d9498aSToby Isaac 4549be51f97SToby Isaac /*@ 455*20f4b53cSBarry Smith DMForestSetAdaptivityPurpose - During the pre-setup phase, set whether the current `DM` is being adapted from its 456*20f4b53cSBarry Smith source (set with `DMForestSetAdaptivityForest()`) for the purpose of refinement (`DM_ADAPT_REFINE`), coarsening 457*20f4b53cSBarry Smith (`DM_ADAPT_COARSEN`), or undefined (`DM_ADAPT_DETERMINE`). This only matters for the purposes of reference counting: 458*20f4b53cSBarry Smith during `DMDestroy()`, cyclic references can be found between `DM`s only if the cyclic reference is due to a fine/coarse 459*20f4b53cSBarry Smith relationship (see `DMSetFineDM()`/`DMSetCoarseDM()`). If the purpose is not refinement or coarsening, and the user does 460*20f4b53cSBarry Smith not maintain a reference to the post-adaptation forest (i.e., the one created by `DMForestTemplate()`), then this can 461*20f4b53cSBarry Smith cause a memory leak. This method is used by subtypes of `DMFOREST` when automatically constructing mesh hierarchies. 4629be51f97SToby Isaac 463*20f4b53cSBarry Smith Logically Collective 4649be51f97SToby Isaac 4659be51f97SToby Isaac Input Parameters: 4669be51f97SToby Isaac + dm - the forest 467bf2d5fbbSStefano Zampini - purpose - the adaptivity purpose 4689be51f97SToby Isaac 4699be51f97SToby Isaac Level: advanced 4709be51f97SToby Isaac 471*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestTemplate()`, `DMForestSetAdaptivityForest()`, `DMForestGetAdaptivityForest()`, `DMAdaptFlag` 4729be51f97SToby Isaac @*/ 473d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMAdaptFlag purpose) 474d71ae5a4SJacob Faibussowitsch { 47526d9498aSToby Isaac DM_Forest *forest; 47626d9498aSToby Isaac 47726d9498aSToby Isaac PetscFunctionBegin; 47826d9498aSToby Isaac forest = (DM_Forest *)dm->data; 47928b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the adaptation forest after setup"); 48026d9498aSToby Isaac if (purpose != forest->adaptPurpose) { 48126d9498aSToby Isaac DM adapt; 48226d9498aSToby Isaac 4839566063dSJacob Faibussowitsch PetscCall(DMForestGetAdaptivityForest(dm, &adapt)); 4849566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)adapt)); 4859566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityForest(dm, NULL)); 486f885a11aSToby Isaac 48726d9498aSToby Isaac forest->adaptPurpose = purpose; 488f885a11aSToby Isaac 4899566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityForest(dm, adapt)); 4909566063dSJacob Faibussowitsch PetscCall(DMDestroy(&adapt)); 49126d9498aSToby Isaac } 4923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 493dd8e54a2SToby Isaac } 494dd8e54a2SToby Isaac 49556c0450aSToby Isaac /*@ 496*20f4b53cSBarry Smith DMForestGetAdaptivityPurpose - Get whether the current `DM` is being adapted from its source (set with 497*20f4b53cSBarry Smith `DMForestSetAdaptivityForest()`) for the purpose of refinement (`DM_ADAPT_REFINE`), coarsening (`DM_ADAPT_COARSEN`), 498*20f4b53cSBarry Smith coarsening only the last level (`DM_ADAPT_COARSEN_LAST`) or undefined (`DM_ADAPT_DETERMINE`). 499*20f4b53cSBarry Smith This only matters for the purposes of reference counting: during `DMDestroy()`, cyclic 500*20f4b53cSBarry Smith references can be found between `DM`s only if the cyclic reference is due to a fine/coarse relationship (see 501*20f4b53cSBarry Smith `DMSetFineDM()`/`DMSetCoarseDM()`). If the purpose is not refinement or coarsening, and the user does not maintain a 502*20f4b53cSBarry Smith reference to the post-adaptation forest (i.e., the one created by `DMForestTemplate()`), then this can cause a memory 503*20f4b53cSBarry Smith leak. This method is used by subtypes of `DMFOREST` when automatically constructing mesh hierarchies. 50456c0450aSToby Isaac 505*20f4b53cSBarry Smith Not Collective 50656c0450aSToby Isaac 50756c0450aSToby Isaac Input Parameter: 50856c0450aSToby Isaac . dm - the forest 50956c0450aSToby Isaac 51056c0450aSToby Isaac Output Parameter: 511bf2d5fbbSStefano Zampini . purpose - the adaptivity purpose 51256c0450aSToby Isaac 51356c0450aSToby Isaac Level: advanced 51456c0450aSToby Isaac 515*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestTemplate()`, `DMForestSetAdaptivityForest()`, `DMForestGetAdaptivityForest()`, `DMAdaptFlag` 51656c0450aSToby Isaac @*/ 517d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdaptivityPurpose(DM dm, DMAdaptFlag *purpose) 518d71ae5a4SJacob Faibussowitsch { 51956c0450aSToby Isaac DM_Forest *forest; 52056c0450aSToby Isaac 52156c0450aSToby Isaac PetscFunctionBegin; 52256c0450aSToby Isaac forest = (DM_Forest *)dm->data; 52356c0450aSToby Isaac *purpose = forest->adaptPurpose; 5243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 52556c0450aSToby Isaac } 52656c0450aSToby Isaac 5279be51f97SToby Isaac /*@ 5289be51f97SToby Isaac DMForestSetAdjacencyDimension - During the pre-setup phase, set the dimension of interface points that determine 5299be51f97SToby Isaac cell adjacency (for the purposes of partitioning and overlap). 5309be51f97SToby Isaac 531*20f4b53cSBarry Smith Logically Collective 5329be51f97SToby Isaac 5339be51f97SToby Isaac Input Parameters: 5349be51f97SToby Isaac + dm - the forest 5359be51f97SToby Isaac - adjDim - default 0 (i.e., vertices determine adjacency) 5369be51f97SToby Isaac 5379be51f97SToby Isaac Level: intermediate 5389be51f97SToby Isaac 539*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()`, `DMForestSetPartitionOverlap()` 5409be51f97SToby Isaac @*/ 541d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim) 542d71ae5a4SJacob Faibussowitsch { 543dd8e54a2SToby Isaac PetscInt dim; 544dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 545dd8e54a2SToby Isaac 546dd8e54a2SToby Isaac PetscFunctionBegin; 547dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54828b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the adjacency dimension after setup"); 54963a3b9bcSJacob Faibussowitsch PetscCheck(adjDim >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "adjacency dim cannot be < 0: %" PetscInt_FMT, adjDim); 5509566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 55163a3b9bcSJacob Faibussowitsch PetscCheck(adjDim <= dim, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "adjacency dim cannot be > %" PetscInt_FMT ": %" PetscInt_FMT, dim, adjDim); 552dd8e54a2SToby Isaac forest->adjDim = adjDim; 5533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 554dd8e54a2SToby Isaac } 555dd8e54a2SToby Isaac 5569be51f97SToby Isaac /*@ 557*20f4b53cSBarry Smith DMForestSetAdjacencyCodimension - Like `DMForestSetAdjacencyDimension()`, but specified as a co-dimension (so that, 5589be51f97SToby Isaac e.g., adjacency based on facets can be specified by codimension 1 in all cases) 5599be51f97SToby Isaac 560*20f4b53cSBarry Smith Logically Collective 5619be51f97SToby Isaac 5629be51f97SToby Isaac Input Parameters: 5639be51f97SToby Isaac + dm - the forest 564*20f4b53cSBarry Smith - adjCodim - default is the dimension of the forest (see `DMGetDimension()`), since this is the codimension of vertices 5659be51f97SToby Isaac 5669be51f97SToby Isaac Level: intermediate 5679be51f97SToby Isaac 568*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetAdjacencyCodimension()`, `DMForestSetAdjacencyDimension()` 5699be51f97SToby Isaac @*/ 570d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim) 571d71ae5a4SJacob Faibussowitsch { 572dd8e54a2SToby Isaac PetscInt dim; 573dd8e54a2SToby Isaac 574dd8e54a2SToby Isaac PetscFunctionBegin; 575dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5769566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 5779566063dSJacob Faibussowitsch PetscCall(DMForestSetAdjacencyDimension(dm, dim - adjCodim)); 5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 579dd8e54a2SToby Isaac } 580dd8e54a2SToby Isaac 5819be51f97SToby Isaac /*@ 5829be51f97SToby Isaac DMForestGetAdjacencyDimension - Get the dimension of interface points that determine cell adjacency (for the 5839be51f97SToby Isaac purposes of partitioning and overlap). 5849be51f97SToby Isaac 585*20f4b53cSBarry Smith Not Collective 5869be51f97SToby Isaac 5879be51f97SToby Isaac Input Parameter: 5889be51f97SToby Isaac . dm - the forest 5899be51f97SToby Isaac 5909be51f97SToby Isaac Output Parameter: 5919be51f97SToby Isaac . adjDim - default 0 (i.e., vertices determine adjacency) 5929be51f97SToby Isaac 5939be51f97SToby Isaac Level: intermediate 5949be51f97SToby Isaac 595*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetAdjacencyDimension()`, `DMForestGetAdjacencyCodimension()`, `DMForestSetPartitionOverlap()` 5969be51f97SToby Isaac @*/ 597d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim) 598d71ae5a4SJacob Faibussowitsch { 599dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 600dd8e54a2SToby Isaac 601dd8e54a2SToby Isaac PetscFunctionBegin; 602dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 603dd8e54a2SToby Isaac PetscValidIntPointer(adjDim, 2); 604dd8e54a2SToby Isaac *adjDim = forest->adjDim; 6053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 606dd8e54a2SToby Isaac } 607dd8e54a2SToby Isaac 6089be51f97SToby Isaac /*@ 609*20f4b53cSBarry Smith DMForestGetAdjacencyCodimension - Like `DMForestGetAdjacencyDimension()`, but specified as a co-dimension (so that, 6109be51f97SToby Isaac e.g., adjacency based on facets can be specified by codimension 1 in all cases) 6119be51f97SToby Isaac 612*20f4b53cSBarry Smith Not Collective 6139be51f97SToby Isaac 6149be51f97SToby Isaac Input Parameter: 6159be51f97SToby Isaac . dm - the forest 6169be51f97SToby Isaac 6179be51f97SToby Isaac Output Parameter: 618*20f4b53cSBarry Smith . adjCodim - default isthe dimension of the forest (see `DMGetDimension()`), since this is the codimension of vertices 6199be51f97SToby Isaac 6209be51f97SToby Isaac Level: intermediate 6219be51f97SToby Isaac 622*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetAdjacencyCodimension()`, `DMForestGetAdjacencyDimension()` 6239be51f97SToby Isaac @*/ 624d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim) 625d71ae5a4SJacob Faibussowitsch { 626dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 627dd8e54a2SToby Isaac PetscInt dim; 628dd8e54a2SToby Isaac 629dd8e54a2SToby Isaac PetscFunctionBegin; 630dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 631dd8e54a2SToby Isaac PetscValidIntPointer(adjCodim, 2); 6329566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 633dd8e54a2SToby Isaac *adjCodim = dim - forest->adjDim; 6343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 635dd8e54a2SToby Isaac } 636dd8e54a2SToby Isaac 6379be51f97SToby Isaac /*@ 6389be51f97SToby Isaac DMForestSetPartitionOverlap - During the pre-setup phase, set the amount of cell-overlap present in parallel 6399be51f97SToby Isaac partitions of a forest, with values > 0 indicating subdomains that are expanded by that many iterations of adding 6409be51f97SToby Isaac adjacent cells 6419be51f97SToby Isaac 642*20f4b53cSBarry Smith Logically Collective 6439be51f97SToby Isaac 6449be51f97SToby Isaac Input Parameters: 6459be51f97SToby Isaac + dm - the forest 6469be51f97SToby Isaac - overlap - default 0 6479be51f97SToby Isaac 6489be51f97SToby Isaac Level: intermediate 6499be51f97SToby Isaac 650*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetPartitionOverlap()`, `DMForestSetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()` 6519be51f97SToby Isaac @*/ 652d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap) 653d71ae5a4SJacob Faibussowitsch { 654dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 655dd8e54a2SToby Isaac 656dd8e54a2SToby Isaac PetscFunctionBegin; 657dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 65828b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the overlap after setup"); 65963a3b9bcSJacob Faibussowitsch PetscCheck(overlap >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "overlap cannot be < 0: %" PetscInt_FMT, overlap); 660dd8e54a2SToby Isaac forest->overlap = overlap; 6613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 662dd8e54a2SToby Isaac } 663dd8e54a2SToby Isaac 6649be51f97SToby Isaac /*@ 6659be51f97SToby Isaac DMForestGetPartitionOverlap - Get the amount of cell-overlap present in parallel partitions of a forest, with values 6669be51f97SToby Isaac > 0 indicating subdomains that are expanded by that many iterations of adding adjacent cells 6679be51f97SToby Isaac 668*20f4b53cSBarry Smith Not Collective 6699be51f97SToby Isaac 6709be51f97SToby Isaac Input Parameter: 6719be51f97SToby Isaac . dm - the forest 6729be51f97SToby Isaac 6739be51f97SToby Isaac Output Parameter: 6749be51f97SToby Isaac . overlap - default 0 6759be51f97SToby Isaac 6769be51f97SToby Isaac Level: intermediate 6779be51f97SToby Isaac 678*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetPartitionOverlap()`, `DMForestSetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()` 6799be51f97SToby Isaac @*/ 680d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap) 681d71ae5a4SJacob Faibussowitsch { 682dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 683dd8e54a2SToby Isaac 684dd8e54a2SToby Isaac PetscFunctionBegin; 685dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 686dd8e54a2SToby Isaac PetscValidIntPointer(overlap, 2); 687dd8e54a2SToby Isaac *overlap = forest->overlap; 6883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 689dd8e54a2SToby Isaac } 690dd8e54a2SToby Isaac 6919be51f97SToby Isaac /*@ 6929be51f97SToby Isaac DMForestSetMinimumRefinement - During the pre-setup phase, set the minimum level of refinement (relative to the base 693*20f4b53cSBarry Smith `DM`, see `DMForestGetBaseDM()`) allowed in the forest. If the forest is being created by coarsening a previous forest 694*20f4b53cSBarry Smith (see `DMForestGetAdaptivityForest()`) this limits the amount of coarsening. 6959be51f97SToby Isaac 696*20f4b53cSBarry Smith Logically Collective 6979be51f97SToby Isaac 6989be51f97SToby Isaac Input Parameters: 6999be51f97SToby Isaac + dm - the forest 700*20f4b53cSBarry Smith - minRefinement - default `PETSC_DEFAULT` (interpreted by the subtype of `DMFOREST`) 7019be51f97SToby Isaac 7029be51f97SToby Isaac Level: intermediate 7039be51f97SToby Isaac 704*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestSetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()` 7059be51f97SToby Isaac @*/ 706d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement) 707d71ae5a4SJacob Faibussowitsch { 708dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 709dd8e54a2SToby Isaac 710dd8e54a2SToby Isaac PetscFunctionBegin; 711dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71228b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the minimum refinement after setup"); 713dd8e54a2SToby Isaac forest->minRefinement = minRefinement; 7143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 715dd8e54a2SToby Isaac } 716dd8e54a2SToby Isaac 7179be51f97SToby Isaac /*@ 718*20f4b53cSBarry Smith DMForestGetMinimumRefinement - Get the minimum level of refinement (relative to the base `DM`, see 719*20f4b53cSBarry Smith `DMForestGetBaseDM()`) allowed in the forest. If the forest is being created by coarsening a previous forest (see 720*20f4b53cSBarry Smith `DMForestGetAdaptivityForest()`), this limits the amount of coarsening. 7219be51f97SToby Isaac 722*20f4b53cSBarry Smith Not Collective 7239be51f97SToby Isaac 7249be51f97SToby Isaac Input Parameter: 7259be51f97SToby Isaac . dm - the forest 7269be51f97SToby Isaac 7279be51f97SToby Isaac Output Parameter: 728*20f4b53cSBarry Smith . minRefinement - default `PETSC_DEFAULT` (interpreted by the subtype of `DMFOREST`) 7299be51f97SToby Isaac 7309be51f97SToby Isaac Level: intermediate 7319be51f97SToby Isaac 732*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetMinimumRefinement()`, `DMForestGetMaximumRefinement()`, `DMForestGetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()` 7339be51f97SToby Isaac @*/ 734d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement) 735d71ae5a4SJacob Faibussowitsch { 736dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 737dd8e54a2SToby Isaac 738dd8e54a2SToby Isaac PetscFunctionBegin; 739dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 740dd8e54a2SToby Isaac PetscValidIntPointer(minRefinement, 2); 741dd8e54a2SToby Isaac *minRefinement = forest->minRefinement; 7423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 743dd8e54a2SToby Isaac } 744dd8e54a2SToby Isaac 7459be51f97SToby Isaac /*@ 7469be51f97SToby Isaac DMForestSetInitialRefinement - During the pre-setup phase, set the initial level of refinement (relative to the base 747*20f4b53cSBarry Smith `DM`, see `DMForestGetBaseDM()`) allowed in the forest. 7489be51f97SToby Isaac 749*20f4b53cSBarry Smith Logically Collective 7509be51f97SToby Isaac 7519be51f97SToby Isaac Input Parameters: 7529be51f97SToby Isaac + dm - the forest 753*20f4b53cSBarry Smith - initefinement - default `PETSC_DEFAULT` (interpreted by the subtype of `DMFOREST`) 7549be51f97SToby Isaac 7559be51f97SToby Isaac Level: intermediate 7569be51f97SToby Isaac 757*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestGetBaseDM()` 7589be51f97SToby Isaac @*/ 759d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement) 760d71ae5a4SJacob Faibussowitsch { 76156ba9f64SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 76256ba9f64SToby Isaac 76356ba9f64SToby Isaac PetscFunctionBegin; 76456ba9f64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 76528b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the initial refinement after setup"); 76656ba9f64SToby Isaac forest->initRefinement = initRefinement; 7673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76856ba9f64SToby Isaac } 76956ba9f64SToby Isaac 7709be51f97SToby Isaac /*@ 771*20f4b53cSBarry Smith DMForestGetInitialRefinement - Get the initial level of refinement (relative to the base `DM`, see 772*20f4b53cSBarry Smith `DMForestGetBaseDM()`) allowed in the forest. 7739be51f97SToby Isaac 774*20f4b53cSBarry Smith Not Collective 7759be51f97SToby Isaac 7769be51f97SToby Isaac Input Parameter: 7779be51f97SToby Isaac . dm - the forest 7789be51f97SToby Isaac 77901d2d390SJose E. Roman Output Parameter: 780*20f4b53cSBarry Smith . initRefinement - default `PETSC_DEFAULT` (interpreted by the subtype of `DMFOREST`) 7819be51f97SToby Isaac 7829be51f97SToby Isaac Level: intermediate 7839be51f97SToby Isaac 784*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestGetBaseDM()` 7859be51f97SToby Isaac @*/ 786d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement) 787d71ae5a4SJacob Faibussowitsch { 78856ba9f64SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 78956ba9f64SToby Isaac 79056ba9f64SToby Isaac PetscFunctionBegin; 79156ba9f64SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 79256ba9f64SToby Isaac PetscValidIntPointer(initRefinement, 2); 79356ba9f64SToby Isaac *initRefinement = forest->initRefinement; 7943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 79556ba9f64SToby Isaac } 79656ba9f64SToby Isaac 7979be51f97SToby Isaac /*@ 7989be51f97SToby Isaac DMForestSetMaximumRefinement - During the pre-setup phase, set the maximum level of refinement (relative to the base 799*20f4b53cSBarry Smith `DM`, see `DMForestGetBaseDM()`) allowed in the forest. If the forest is being created by refining a previous forest 800*20f4b53cSBarry Smith (see `DMForestGetAdaptivityForest()`), this limits the amount of refinement. 8019be51f97SToby Isaac 802*20f4b53cSBarry Smith Logically Collective 8039be51f97SToby Isaac 8049be51f97SToby Isaac Input Parameters: 8059be51f97SToby Isaac + dm - the forest 806*20f4b53cSBarry Smith - maxRefinement - default `PETSC_DEFAULT` (interpreted by the subtype of `DMFOREST`) 8079be51f97SToby Isaac 8089be51f97SToby Isaac Level: intermediate 8099be51f97SToby Isaac 810*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestSetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityDM()` 8119be51f97SToby Isaac @*/ 812d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement) 813d71ae5a4SJacob Faibussowitsch { 814dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 815dd8e54a2SToby Isaac 816dd8e54a2SToby Isaac PetscFunctionBegin; 817dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 81828b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the maximum refinement after setup"); 819c7eeac06SToby Isaac forest->maxRefinement = maxRefinement; 8203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 821dd8e54a2SToby Isaac } 822dd8e54a2SToby Isaac 8239be51f97SToby Isaac /*@ 824*20f4b53cSBarry Smith DMForestGetMaximumRefinement - Get the maximum level of refinement (relative to the base `DM`, see 825*20f4b53cSBarry Smith `DMForestGetBaseDM()`) allowed in the forest. If the forest is being created by refining a previous forest (see 826*20f4b53cSBarry Smith `DMForestGetAdaptivityForest`()), this limits the amount of refinement. 8279be51f97SToby Isaac 828*20f4b53cSBarry Smith Not Collective 8299be51f97SToby Isaac 8309be51f97SToby Isaac Input Parameter: 8319be51f97SToby Isaac . dm - the forest 8329be51f97SToby Isaac 8339be51f97SToby Isaac Output Parameter: 834*20f4b53cSBarry Smith . maxRefinement - default `PETSC_DEFAULT` (interpreted by the subtype of `DMFOREST`) 8359be51f97SToby Isaac 8369be51f97SToby Isaac Level: intermediate 8379be51f97SToby Isaac 838*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetMaximumRefinement()`, `DMForestGetMinimumRefinement()`, `DMForestGetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()` 8399be51f97SToby Isaac @*/ 840d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement) 841d71ae5a4SJacob Faibussowitsch { 842dd8e54a2SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 843dd8e54a2SToby Isaac 844dd8e54a2SToby Isaac PetscFunctionBegin; 845dd8e54a2SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 846c7eeac06SToby Isaac PetscValidIntPointer(maxRefinement, 2); 847c7eeac06SToby Isaac *maxRefinement = forest->maxRefinement; 8483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 849dd8e54a2SToby Isaac } 850c7eeac06SToby Isaac 8519be51f97SToby Isaac /*@C 8529be51f97SToby Isaac DMForestSetAdaptivityStrategy - During the pre-setup phase, set the strategy for combining adaptivity labels from multiple processes. 8539be51f97SToby Isaac 854*20f4b53cSBarry Smith Logically Collective 8559be51f97SToby Isaac 8569be51f97SToby Isaac Input Parameters: 8579be51f97SToby Isaac + dm - the forest 858*20f4b53cSBarry Smith - adaptStrategy - default `DMFORESTADAPTALL` 8599be51f97SToby Isaac 8609be51f97SToby Isaac Level: advanced 8619be51f97SToby Isaac 862*20f4b53cSBarry Smith Notes: 863*20f4b53cSBarry Smith Subtypes of `DMFOREST` may define their own strategies. Two default strategies are `DMFORESTADAPTALL`, which indicates that all processes must agree 864*20f4b53cSBarry Smith for a refinement/coarsening flag to be valid, and `DMFORESTADAPTANY`, which indicates that only one process needs to 865*20f4b53cSBarry Smith specify refinement/coarsening. 866*20f4b53cSBarry Smith 867*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetAdaptivityStrategy()`, `DMFORESTADAPTALL`, `DMFORESTADAPTANY` 8689be51f97SToby Isaac @*/ 869d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy) 870d71ae5a4SJacob Faibussowitsch { 871c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 872c7eeac06SToby Isaac 873c7eeac06SToby Isaac PetscFunctionBegin; 874c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8759566063dSJacob Faibussowitsch PetscCall(PetscFree(forest->adaptStrategy)); 8769566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy((const char *)adaptStrategy, (char **)&forest->adaptStrategy)); 8773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 878c7eeac06SToby Isaac } 879c7eeac06SToby Isaac 8809be51f97SToby Isaac /*@C 881*20f4b53cSBarry Smith DMForestSetAdaptivityStrategy - Get the strategy for combining adaptivity labels from multiple processes. 8829be51f97SToby Isaac 883*20f4b53cSBarry Smith Not Collective 8849be51f97SToby Isaac 8859be51f97SToby Isaac Input Parameter: 8869be51f97SToby Isaac . dm - the forest 8879be51f97SToby Isaac 8889be51f97SToby Isaac Output Parameter: 889*20f4b53cSBarry Smith . adaptStrategy - the adaptivity strategy (default `DMFORESTADAPTALL`) 8909be51f97SToby Isaac 8919be51f97SToby Isaac Level: advanced 8929be51f97SToby Isaac 893*20f4b53cSBarry Smith Note: 894*20f4b53cSBarry Smith Subtypes 895*20f4b53cSBarry Smith of `DMFOREST` may define their own strategies. Two default strategies are `DMFORESTADAPTALL`, which indicates that all 896*20f4b53cSBarry Smith processes must agree for a refinement/coarsening flag to be valid, and `DMFORESTADAPTANY`, which indicates that only 897*20f4b53cSBarry Smith one process needs to specify refinement/coarsening. 898*20f4b53cSBarry Smith 899*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMFORESTADAPTALL`, `DMFORESTADAPTANY`, `DMForestSetAdaptivityStrategy()` 9009be51f97SToby Isaac @*/ 901d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy) 902d71ae5a4SJacob Faibussowitsch { 903c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 904c7eeac06SToby Isaac 905c7eeac06SToby Isaac PetscFunctionBegin; 906c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 907c7eeac06SToby Isaac PetscValidPointer(adaptStrategy, 2); 908c7eeac06SToby Isaac *adaptStrategy = forest->adaptStrategy; 9093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 910c7eeac06SToby Isaac } 911c7eeac06SToby Isaac 9122a133e43SToby Isaac /*@ 9132a133e43SToby Isaac DMForestGetAdaptivitySuccess - Return whether the requested adaptation (refinement, coarsening, repartitioning, 914*20f4b53cSBarry Smith etc.) was successful. 9152a133e43SToby Isaac 916*20f4b53cSBarry Smith Collective 9172a133e43SToby Isaac 9182a133e43SToby Isaac Input Parameter: 9192a133e43SToby Isaac . dm - the post-adaptation forest 9202a133e43SToby Isaac 9212a133e43SToby Isaac Output Parameter: 922*20f4b53cSBarry Smith . success - `PETSC_TRUE` if the post-adaptation forest is different from the pre-adaptation forest. 9232a133e43SToby Isaac 9242a133e43SToby Isaac Level: intermediate 9252a133e43SToby Isaac 926*20f4b53cSBarry Smith Notes: 927*20f4b53cSBarry Smith `PETSC_FALSE` indicates that the post-adaptation forest is the same as the pre-adpatation 928*20f4b53cSBarry Smith forest. A requested adaptation may have been unsuccessful if, for example, the requested refinement would have 929*20f4b53cSBarry Smith exceeded the maximum refinement level. 930*20f4b53cSBarry Smith 931*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST` 9322a133e43SToby Isaac @*/ 933d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdaptivitySuccess(DM dm, PetscBool *success) 934d71ae5a4SJacob Faibussowitsch { 9352a133e43SToby Isaac DM_Forest *forest; 9362a133e43SToby Isaac 9372a133e43SToby Isaac PetscFunctionBegin; 9382a133e43SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93928b400f6SJacob Faibussowitsch PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMSetUp() has not been called yet."); 9402a133e43SToby Isaac forest = (DM_Forest *)dm->data; 9419566063dSJacob Faibussowitsch PetscCall((forest->getadaptivitysuccess)(dm, success)); 9423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9432a133e43SToby Isaac } 9442a133e43SToby Isaac 945bf9b5d84SToby Isaac /*@ 946*20f4b53cSBarry Smith DMForestSetComputeAdaptivitySF - During the pre-setup phase, set whether transfer `PetscSF`s should be computed 947*20f4b53cSBarry Smith relating the cells of the pre-adaptation forest to the post-adaptiation forest. 948bf9b5d84SToby Isaac 949*20f4b53cSBarry Smith Logically Collective 950bf9b5d84SToby Isaac 951bf9b5d84SToby Isaac Input Parameters: 952bf9b5d84SToby Isaac + dm - the post-adaptation forest 953*20f4b53cSBarry Smith - computeSF - default `PETSC_TRUE` 954bf9b5d84SToby Isaac 955bf9b5d84SToby Isaac Level: advanced 956bf9b5d84SToby Isaac 957*20f4b53cSBarry Smith Note: 958*20f4b53cSBarry Smith After `DMSetUp()` is called, the transfer `PetscSF`s can be accessed with `DMForestGetAdaptivitySF()`. 959*20f4b53cSBarry Smith 960*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetComputeAdaptivitySF()`, `DMForestGetAdaptivitySF()` 961bf9b5d84SToby Isaac @*/ 962d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetComputeAdaptivitySF(DM dm, PetscBool computeSF) 963d71ae5a4SJacob Faibussowitsch { 964bf9b5d84SToby Isaac DM_Forest *forest; 965bf9b5d84SToby Isaac 966bf9b5d84SToby Isaac PetscFunctionBegin; 967bf9b5d84SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 96828b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot compute adaptivity PetscSFs after setup is called"); 969bf9b5d84SToby Isaac forest = (DM_Forest *)dm->data; 970bf9b5d84SToby Isaac forest->computeAdaptSF = computeSF; 9713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 972bf9b5d84SToby Isaac } 973bf9b5d84SToby Isaac 974d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestTransferVec(DM dmIn, Vec vecIn, DM dmOut, Vec vecOut, PetscBool useBCs, PetscReal time) 975d71ae5a4SJacob Faibussowitsch { 97680b27e07SToby Isaac DM_Forest *forest; 97780b27e07SToby Isaac 97880b27e07SToby Isaac PetscFunctionBegin; 97980b27e07SToby Isaac PetscValidHeaderSpecific(dmIn, DM_CLASSID, 1); 98080b27e07SToby Isaac PetscValidHeaderSpecific(vecIn, VEC_CLASSID, 2); 98180b27e07SToby Isaac PetscValidHeaderSpecific(dmOut, DM_CLASSID, 3); 98280b27e07SToby Isaac PetscValidHeaderSpecific(vecOut, VEC_CLASSID, 4); 98380b27e07SToby Isaac forest = (DM_Forest *)dmIn->data; 98428b400f6SJacob Faibussowitsch PetscCheck(forest->transfervec, PetscObjectComm((PetscObject)dmIn), PETSC_ERR_SUP, "DMForestTransferVec() not implemented"); 9859566063dSJacob Faibussowitsch PetscCall((forest->transfervec)(dmIn, vecIn, dmOut, vecOut, useBCs, time)); 9863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98780b27e07SToby Isaac } 98880b27e07SToby Isaac 989d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestTransferVecFromBase(DM dm, Vec vecIn, Vec vecOut) 990d71ae5a4SJacob Faibussowitsch { 991ac34a06fSStefano Zampini DM_Forest *forest; 992ac34a06fSStefano Zampini 993ac34a06fSStefano Zampini PetscFunctionBegin; 994ac34a06fSStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 995ac34a06fSStefano Zampini PetscValidHeaderSpecific(vecIn, VEC_CLASSID, 2); 996ac34a06fSStefano Zampini PetscValidHeaderSpecific(vecOut, VEC_CLASSID, 3); 997ac34a06fSStefano Zampini forest = (DM_Forest *)dm->data; 99828b400f6SJacob Faibussowitsch PetscCheck(forest->transfervecfrombase, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DMForestTransferVecFromBase() not implemented"); 9999566063dSJacob Faibussowitsch PetscCall((forest->transfervecfrombase)(dm, vecIn, vecOut)); 10003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1001ac34a06fSStefano Zampini } 1002ac34a06fSStefano Zampini 1003bf9b5d84SToby Isaac /*@ 1004*20f4b53cSBarry Smith DMForestGetComputeAdaptivitySF - Get whether transfer `PetscSF`s should be computed relating the cells of the 1005*20f4b53cSBarry Smith pre-adaptation forest to the post-adaptiation forest. After `DMSetUp()` is called, these transfer PetscSFs can be 1006*20f4b53cSBarry Smith accessed with `DMForestGetAdaptivitySF()`. 1007bf9b5d84SToby Isaac 1008*20f4b53cSBarry Smith Not Collective 1009bf9b5d84SToby Isaac 1010bf9b5d84SToby Isaac Input Parameter: 1011bf9b5d84SToby Isaac . dm - the post-adaptation forest 1012bf9b5d84SToby Isaac 1013bf9b5d84SToby Isaac Output Parameter: 1014*20f4b53cSBarry Smith . computeSF - default `PETSC_TRUE` 1015bf9b5d84SToby Isaac 1016bf9b5d84SToby Isaac Level: advanced 1017bf9b5d84SToby Isaac 1018*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetComputeAdaptivitySF()`, `DMForestGetAdaptivitySF()` 1019bf9b5d84SToby Isaac @*/ 1020d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetComputeAdaptivitySF(DM dm, PetscBool *computeSF) 1021d71ae5a4SJacob Faibussowitsch { 1022bf9b5d84SToby Isaac DM_Forest *forest; 1023bf9b5d84SToby Isaac 1024bf9b5d84SToby Isaac PetscFunctionBegin; 1025bf9b5d84SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1026bf9b5d84SToby Isaac forest = (DM_Forest *)dm->data; 1027bf9b5d84SToby Isaac *computeSF = forest->computeAdaptSF; 10283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1029bf9b5d84SToby Isaac } 1030bf9b5d84SToby Isaac 1031bf9b5d84SToby Isaac /*@ 1032*20f4b53cSBarry Smith DMForestGetAdaptivitySF - Get `PetscSF`s that relate the pre-adaptation forest to the post-adaptation forest. 1033bf9b5d84SToby Isaac Adaptation can be any combination of refinement, coarsening, repartition, and change of overlap, so there may be 1034bf9b5d84SToby Isaac some cells of the pre-adaptation that are parents of post-adaptation cells, and vice versa. Therefore there are two 1035*20f4b53cSBarry Smith `PetscSF`s: one that relates pre-adaptation coarse cells to post-adaptation fine cells, and one that relates 1036bf9b5d84SToby Isaac pre-adaptation fine cells to post-adaptation coarse cells. 1037bf9b5d84SToby Isaac 1038*20f4b53cSBarry Smith Not Collective 1039bf9b5d84SToby Isaac 1040bf9b5d84SToby Isaac Input Parameter: 1041*20f4b53cSBarry Smith . dm - the post-adaptation forest 1042bf9b5d84SToby Isaac 1043*20f4b53cSBarry Smith Output Parameters: 1044*20f4b53cSBarry Smith + preCoarseToFine - pre-adaptation coarse cells to post-adaptation fine cells: BCast goes from pre- to post- 1045*20f4b53cSBarry Smith - coarseToPreFine - post-adaptation coarse cells to pre-adaptation fine cells: BCast goes from post- to pre- 1046bf9b5d84SToby Isaac 1047bf9b5d84SToby Isaac Level: advanced 1048bf9b5d84SToby Isaac 1049*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetComputeAdaptivitySF()`, `DMForestSetComputeAdaptivitySF()` 1050bf9b5d84SToby Isaac @*/ 1051d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdaptivitySF(DM dm, PetscSF *preCoarseToFine, PetscSF *coarseToPreFine) 1052d71ae5a4SJacob Faibussowitsch { 1053bf9b5d84SToby Isaac DM_Forest *forest; 1054bf9b5d84SToby Isaac 1055bf9b5d84SToby Isaac PetscFunctionBegin; 1056bf9b5d84SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10579566063dSJacob Faibussowitsch PetscCall(DMSetUp(dm)); 1058bf9b5d84SToby Isaac forest = (DM_Forest *)dm->data; 1059f885a11aSToby Isaac if (preCoarseToFine) *preCoarseToFine = forest->preCoarseToFine; 1060f885a11aSToby Isaac if (coarseToPreFine) *coarseToPreFine = forest->coarseToPreFine; 10613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1062bf9b5d84SToby Isaac } 1063bf9b5d84SToby Isaac 10649be51f97SToby Isaac /*@ 10659be51f97SToby Isaac DMForestSetGradeFactor - During the pre-setup phase, set the desired amount of grading in the mesh, e.g. give 2 to 1066*20f4b53cSBarry Smith indicate that the diameter of neighboring cells should differ by at most a factor of 2. Subtypes of `DMFOREST` may 10679be51f97SToby Isaac only support one particular choice of grading factor. 10689be51f97SToby Isaac 1069*20f4b53cSBarry Smith Logically Collective 10709be51f97SToby Isaac 10719be51f97SToby Isaac Input Parameters: 10729be51f97SToby Isaac + dm - the forest 10739be51f97SToby Isaac - grade - the grading factor 10749be51f97SToby Isaac 10759be51f97SToby Isaac Level: advanced 10769be51f97SToby Isaac 1077*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetGradeFactor()` 10789be51f97SToby Isaac @*/ 1079d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade) 1080d71ae5a4SJacob Faibussowitsch { 1081c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1082c7eeac06SToby Isaac 1083c7eeac06SToby Isaac PetscFunctionBegin; 1084c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 108528b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the grade factor after setup"); 1086c7eeac06SToby Isaac forest->gradeFactor = grade; 10873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1088c7eeac06SToby Isaac } 1089c7eeac06SToby Isaac 10909be51f97SToby Isaac /*@ 10919be51f97SToby Isaac DMForestGetGradeFactor - Get the desired amount of grading in the mesh, e.g. give 2 to indicate that the diameter of 1092*20f4b53cSBarry Smith neighboring cells should differ by at most a factor of 2. Subtypes of `DMFOREST` may only support one particular 10939be51f97SToby Isaac choice of grading factor. 10949be51f97SToby Isaac 1095*20f4b53cSBarry Smith Not Collective 10969be51f97SToby Isaac 10979be51f97SToby Isaac Input Parameter: 10989be51f97SToby Isaac . dm - the forest 10999be51f97SToby Isaac 11009be51f97SToby Isaac Output Parameter: 11019be51f97SToby Isaac . grade - the grading factor 11029be51f97SToby Isaac 11039be51f97SToby Isaac Level: advanced 11049be51f97SToby Isaac 1105*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetGradeFactor()` 11069be51f97SToby Isaac @*/ 1107d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade) 1108d71ae5a4SJacob Faibussowitsch { 1109c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1110c7eeac06SToby Isaac 1111c7eeac06SToby Isaac PetscFunctionBegin; 1112c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1113c7eeac06SToby Isaac PetscValidIntPointer(grade, 2); 1114c7eeac06SToby Isaac *grade = forest->gradeFactor; 11153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1116c7eeac06SToby Isaac } 1117c7eeac06SToby Isaac 11189be51f97SToby Isaac /*@ 11199be51f97SToby Isaac DMForestSetCellWeightFactor - During the pre-setup phase, set the factor by which the level of refinement changes 1120*20f4b53cSBarry Smith the cell weight (see `DMForestSetCellWeights()`) when calculating partitions. The final weight of a cell will be 11219be51f97SToby Isaac (cellWeight) * (weightFactor^refinementLevel). A factor of 1 indicates that the weight of a cell does not depend on 11229be51f97SToby Isaac its level; a factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the 11239be51f97SToby Isaac computation associated with a cell is multiplied by a factor of 2 for each additional level of refinement. 11249be51f97SToby Isaac 1125*20f4b53cSBarry Smith Logically Collective 11269be51f97SToby Isaac 11279be51f97SToby Isaac Input Parameters: 11289be51f97SToby Isaac + dm - the forest 11299be51f97SToby Isaac - weightsFactors - default 1. 11309be51f97SToby Isaac 11319be51f97SToby Isaac Level: advanced 11329be51f97SToby Isaac 1133*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetCellWeightFactor()`, `DMForestSetCellWeights()` 11349be51f97SToby Isaac @*/ 1135d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor) 1136d71ae5a4SJacob Faibussowitsch { 1137c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1138c7eeac06SToby Isaac 1139c7eeac06SToby Isaac PetscFunctionBegin; 1140c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 114128b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the weights factor after setup"); 1142c7eeac06SToby Isaac forest->weightsFactor = weightsFactor; 11433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1144c7eeac06SToby Isaac } 1145c7eeac06SToby Isaac 11469be51f97SToby Isaac /*@ 11479be51f97SToby Isaac DMForestGetCellWeightFactor - Get the factor by which the level of refinement changes the cell weight (see 1148*20f4b53cSBarry Smith `DMForestSetCellWeights()`) when calculating partitions. The final weight of a cell will be (cellWeight) * 11499be51f97SToby Isaac (weightFactor^refinementLevel). A factor of 1 indicates that the weight of a cell does not depend on its level; a 11509be51f97SToby Isaac factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the computation 11519be51f97SToby Isaac associated with a cell is multiplied by a factor of 2 for each additional level of refinement. 11529be51f97SToby Isaac 1153*20f4b53cSBarry Smith Not Collective 11549be51f97SToby Isaac 11559be51f97SToby Isaac Input Parameter: 11569be51f97SToby Isaac . dm - the forest 11579be51f97SToby Isaac 11589be51f97SToby Isaac Output Parameter: 11599be51f97SToby Isaac . weightsFactors - default 1. 11609be51f97SToby Isaac 11619be51f97SToby Isaac Level: advanced 11629be51f97SToby Isaac 1163*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetCellWeightFactor()`, `DMForestSetCellWeights()` 11649be51f97SToby Isaac @*/ 1165d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor) 1166d71ae5a4SJacob Faibussowitsch { 1167c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1168c7eeac06SToby Isaac 1169c7eeac06SToby Isaac PetscFunctionBegin; 1170c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1171c7eeac06SToby Isaac PetscValidRealPointer(weightsFactor, 2); 1172c7eeac06SToby Isaac *weightsFactor = forest->weightsFactor; 11733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1174c7eeac06SToby Isaac } 1175c7eeac06SToby Isaac 11769be51f97SToby Isaac /*@ 11779be51f97SToby Isaac DMForestGetCellChart - After the setup phase, get the local half-open interval of the chart of cells on this process 11789be51f97SToby Isaac 1179*20f4b53cSBarry Smith Not Collective 11809be51f97SToby Isaac 11819be51f97SToby Isaac Input Parameter: 11829be51f97SToby Isaac . dm - the forest 11839be51f97SToby Isaac 11849be51f97SToby Isaac Output Parameters: 11859be51f97SToby Isaac + cStart - the first cell on this process 11869be51f97SToby Isaac - cEnd - one after the final cell on this process 11879be51f97SToby Isaac 11881a244344SSatish Balay Level: intermediate 11899be51f97SToby Isaac 1190*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetCellSF()` 11919be51f97SToby Isaac @*/ 1192d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd) 1193d71ae5a4SJacob Faibussowitsch { 1194c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1195c7eeac06SToby Isaac 1196c7eeac06SToby Isaac PetscFunctionBegin; 1197c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1198c7eeac06SToby Isaac PetscValidIntPointer(cStart, 2); 1199064a246eSJacob Faibussowitsch PetscValidIntPointer(cEnd, 3); 120048a46eb9SPierre Jolivet if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) PetscCall(forest->createcellchart(dm, &forest->cStart, &forest->cEnd)); 1201c7eeac06SToby Isaac *cStart = forest->cStart; 1202c7eeac06SToby Isaac *cEnd = forest->cEnd; 12033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1204c7eeac06SToby Isaac } 1205c7eeac06SToby Isaac 12069be51f97SToby Isaac /*@ 1207*20f4b53cSBarry Smith DMForestGetCellSF - After the setup phase, get the `PetscSF` for overlapping cells between processes 12089be51f97SToby Isaac 1209*20f4b53cSBarry Smith Not Collective 12109be51f97SToby Isaac 12119be51f97SToby Isaac Input Parameter: 12129be51f97SToby Isaac . dm - the forest 12139be51f97SToby Isaac 12149be51f97SToby Isaac Output Parameter: 1215*20f4b53cSBarry Smith . cellSF - the `PetscSF` 12169be51f97SToby Isaac 12171a244344SSatish Balay Level: intermediate 12189be51f97SToby Isaac 1219*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetCellChart()` 12209be51f97SToby Isaac @*/ 1221d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF) 1222d71ae5a4SJacob Faibussowitsch { 1223c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1224c7eeac06SToby Isaac 1225c7eeac06SToby Isaac PetscFunctionBegin; 1226c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1227c7eeac06SToby Isaac PetscValidPointer(cellSF, 2); 122848a46eb9SPierre Jolivet if ((!forest->cellSF) && forest->createcellsf) PetscCall(forest->createcellsf(dm, &forest->cellSF)); 1229c7eeac06SToby Isaac *cellSF = forest->cellSF; 12303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1231c7eeac06SToby Isaac } 1232c7eeac06SToby Isaac 12339be51f97SToby Isaac /*@C 12349be51f97SToby Isaac DMForestSetAdaptivityLabel - During the pre-setup phase, set the label of the pre-adaptation forest (see 1235*20f4b53cSBarry Smith `DMForestGetAdaptivityForest()`) that holds the adaptation flags (refinement, coarsening, or some combination). The 1236*20f4b53cSBarry Smith interpretation of the label values is up to the subtype of `DMFOREST`, but `DM_ADAPT_DETERMINE`, `DM_ADAPT_KEEP`, 1237*20f4b53cSBarry Smith `DM_ADAPT_REFINE`, and `DM_ADAPT_COARSEN` have been reserved as choices that should be accepted by all subtypes. 12389be51f97SToby Isaac 1239*20f4b53cSBarry Smith Logically Collective 12409be51f97SToby Isaac 12419be51f97SToby Isaac Input Parameters: 12429be51f97SToby Isaac - dm - the forest 1243a1b0c543SToby Isaac + adaptLabel - the label in the pre-adaptation forest 12449be51f97SToby Isaac 12459be51f97SToby Isaac Level: intermediate 12469be51f97SToby Isaac 1247*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetAdaptivityLabel()` 12489be51f97SToby Isaac @*/ 1249d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetAdaptivityLabel(DM dm, DMLabel adaptLabel) 1250d71ae5a4SJacob Faibussowitsch { 1251c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1252c7eeac06SToby Isaac 1253c7eeac06SToby Isaac PetscFunctionBegin; 1254c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 12551fd50544SStefano Zampini if (adaptLabel) PetscValidHeaderSpecific(adaptLabel, DMLABEL_CLASSID, 2); 12569566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)adaptLabel)); 12579566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&forest->adaptLabel)); 12581fd50544SStefano Zampini forest->adaptLabel = adaptLabel; 12593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1260c7eeac06SToby Isaac } 1261c7eeac06SToby Isaac 12629be51f97SToby Isaac /*@C 1263*20f4b53cSBarry Smith DMForestGetAdaptivityLabel - Get the label of the pre-adaptation forest (see `DMForestGetAdaptivityForest()`) that 12649be51f97SToby Isaac holds the adaptation flags (refinement, coarsening, or some combination). The interpretation of the label values is 1265*20f4b53cSBarry Smith up to the subtype of `DMFOREST`, but `DM_ADAPT_DETERMINE`, `DM_ADAPT_KEEP`, `DM_ADAPT_REFINE`, and `DM_ADAPT_COARSEN` have 1266cd3c525cSToby Isaac been reserved as choices that should be accepted by all subtypes. 12679be51f97SToby Isaac 1268*20f4b53cSBarry Smith Not Collective 12699be51f97SToby Isaac 12709be51f97SToby Isaac Input Parameter: 12719be51f97SToby Isaac . dm - the forest 12729be51f97SToby Isaac 12739be51f97SToby Isaac Output Parameter: 12749be51f97SToby Isaac . adaptLabel - the name of the label in the pre-adaptation forest 12759be51f97SToby Isaac 12769be51f97SToby Isaac Level: intermediate 12779be51f97SToby Isaac 1278*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetAdaptivityLabel()` 12799be51f97SToby Isaac @*/ 1280d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetAdaptivityLabel(DM dm, DMLabel *adaptLabel) 1281d71ae5a4SJacob Faibussowitsch { 1282c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1283c7eeac06SToby Isaac 1284c7eeac06SToby Isaac PetscFunctionBegin; 1285c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1286ba936b91SToby Isaac *adaptLabel = forest->adaptLabel; 12873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1288c7eeac06SToby Isaac } 1289c7eeac06SToby Isaac 12909be51f97SToby Isaac /*@ 1291*20f4b53cSBarry Smith DMForestSetCellWeights - Set the weights assigned to each of the cells (see `DMForestGetCellChart()`) of the current 1292*20f4b53cSBarry Smith process: weights are used to determine parallel partitioning. 12939be51f97SToby Isaac 1294*20f4b53cSBarry Smith Logically Collective 12959be51f97SToby Isaac 12969be51f97SToby Isaac Input Parameters: 12979be51f97SToby Isaac + dm - the forest 1298*20f4b53cSBarry Smith . weights - the array of weights (see `DMForestSetWeightCapacity()`) for all cells, or `NULL` to indicate each cell has weight 1. 12999be51f97SToby Isaac - copyMode - how weights should reference weights 13009be51f97SToby Isaac 13019be51f97SToby Isaac Level: advanced 13029be51f97SToby Isaac 1303*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestGetCellWeights()`, `DMForestSetWeightCapacity()` 13049be51f97SToby Isaac @*/ 1305d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode) 1306d71ae5a4SJacob Faibussowitsch { 1307c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1308c7eeac06SToby Isaac PetscInt cStart, cEnd; 1309c7eeac06SToby Isaac 1310c7eeac06SToby Isaac PetscFunctionBegin; 1311c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 13129566063dSJacob Faibussowitsch PetscCall(DMForestGetCellChart(dm, &cStart, &cEnd)); 131363a3b9bcSJacob Faibussowitsch PetscCheck(cEnd >= cStart, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "cell chart [%" PetscInt_FMT ",%" PetscInt_FMT ") is not valid", cStart, cEnd); 1314c7eeac06SToby Isaac if (copyMode == PETSC_COPY_VALUES) { 131548a46eb9SPierre Jolivet if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) PetscCall(PetscMalloc1(cEnd - cStart, &forest->cellWeights)); 13169566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(forest->cellWeights, weights, cEnd - cStart)); 1317c7eeac06SToby Isaac forest->cellWeightsCopyMode = PETSC_OWN_POINTER; 13183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1319c7eeac06SToby Isaac } 132048a46eb9SPierre Jolivet if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) PetscCall(PetscFree(forest->cellWeights)); 1321c7eeac06SToby Isaac forest->cellWeights = weights; 1322c7eeac06SToby Isaac forest->cellWeightsCopyMode = copyMode; 13233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1324c7eeac06SToby Isaac } 1325c7eeac06SToby Isaac 13269be51f97SToby Isaac /*@ 1327*20f4b53cSBarry Smith DMForestGetCellWeights - Get the weights assigned to each of the cells (see `DMForestGetCellChart()`) of the current 1328*20f4b53cSBarry Smith process: weights are used to determine parallel partitioning. 13299be51f97SToby Isaac 1330*20f4b53cSBarry Smith Not Collective 13319be51f97SToby Isaac 13329be51f97SToby Isaac Input Parameter: 13339be51f97SToby Isaac . dm - the forest 13349be51f97SToby Isaac 13359be51f97SToby Isaac Output Parameter: 1336*20f4b53cSBarry Smith . weights - the array of weights for all cells, or `NULL` to indicate each cell has weight 1. 13379be51f97SToby Isaac 13389be51f97SToby Isaac Level: advanced 13399be51f97SToby Isaac 1340*20f4b53cSBarry Smith .seealso: `DM`, `DMFOREST`, `DMForestSetCellWeights()`, `DMForestSetWeightCapacity()` 13419be51f97SToby Isaac @*/ 1342d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights) 1343d71ae5a4SJacob Faibussowitsch { 1344c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1345c7eeac06SToby Isaac 1346c7eeac06SToby Isaac PetscFunctionBegin; 1347c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1348c7eeac06SToby Isaac PetscValidPointer(weights, 2); 1349c7eeac06SToby Isaac *weights = forest->cellWeights; 13503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1351c7eeac06SToby Isaac } 1352c7eeac06SToby Isaac 13539be51f97SToby Isaac /*@ 13549be51f97SToby Isaac DMForestSetWeightCapacity - During the pre-setup phase, set the capacity of the current process when repartitioning 1355*20f4b53cSBarry Smith a pre-adaptation forest (see `DMForestGetAdaptivityForest()`). After partitioning, the ratio of the weight of each 13569be51f97SToby Isaac process's cells to the process's capacity will be roughly equal for all processes. A capacity of 0 indicates that 13579be51f97SToby Isaac the current process should not have any cells after repartitioning. 13589be51f97SToby Isaac 1359*20f4b53cSBarry Smith Logically Collective 13609be51f97SToby Isaac 13619be51f97SToby Isaac Input parameters: 13629be51f97SToby Isaac + dm - the forest 13639be51f97SToby Isaac - capacity - this process's capacity 13649be51f97SToby Isaac 13659be51f97SToby Isaac Level: advanced 13669be51f97SToby Isaac 1367*20f4b53cSBarry Smith .seealso `DM`, `DMFOREST`, `DMForestGetWeightCapacity()`, `DMForestSetCellWeights()`, `DMForestSetCellWeightFactor()` 13689be51f97SToby Isaac @*/ 1369d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity) 1370d71ae5a4SJacob Faibussowitsch { 1371c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1372c7eeac06SToby Isaac 1373c7eeac06SToby Isaac PetscFunctionBegin; 1374c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 137528b400f6SJacob Faibussowitsch PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the weight capacity after setup"); 137663a3b9bcSJacob Faibussowitsch PetscCheck(capacity >= 0., PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have negative weight capacity; %g", (double)capacity); 1377c7eeac06SToby Isaac forest->weightCapacity = capacity; 13783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1379c7eeac06SToby Isaac } 1380c7eeac06SToby Isaac 13819be51f97SToby Isaac /*@ 13829be51f97SToby Isaac DMForestGetWeightCapacity - Set the capacity of the current process when repartitioning a pre-adaptation forest (see 1383*20f4b53cSBarry Smith `DMForestGetAdaptivityForest()`). After partitioning, the ratio of the weight of each process's cells to the 13849be51f97SToby Isaac process's capacity will be roughly equal for all processes. A capacity of 0 indicates that the current process 13859be51f97SToby Isaac should not have any cells after repartitioning. 13869be51f97SToby Isaac 1387*20f4b53cSBarry Smith Not Collective 13889be51f97SToby Isaac 13899be51f97SToby Isaac Input parameter: 13909be51f97SToby Isaac . dm - the forest 13919be51f97SToby Isaac 13929be51f97SToby Isaac Output parameter: 13939be51f97SToby Isaac . capacity - this process's capacity 13949be51f97SToby Isaac 13959be51f97SToby Isaac Level: advanced 13969be51f97SToby Isaac 1397*20f4b53cSBarry Smith .seealso `DM`, `DMFOREST`, `DMForestSetWeightCapacity()`, `DMForestSetCellWeights()`, `DMForestSetCellWeightFactor()` 13989be51f97SToby Isaac @*/ 1399d71ae5a4SJacob Faibussowitsch PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity) 1400d71ae5a4SJacob Faibussowitsch { 1401c7eeac06SToby Isaac DM_Forest *forest = (DM_Forest *)dm->data; 1402c7eeac06SToby Isaac 1403c7eeac06SToby Isaac PetscFunctionBegin; 1404c7eeac06SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1405c7eeac06SToby Isaac PetscValidRealPointer(capacity, 2); 1406c7eeac06SToby Isaac *capacity = forest->weightCapacity; 14073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1408c7eeac06SToby Isaac } 1409c7eeac06SToby Isaac 1410d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(DM dm, PetscOptionItems *PetscOptionsObject) 1411d71ae5a4SJacob Faibussowitsch { 141256ba9f64SToby Isaac PetscBool flg, flg1, flg2, flg3, flg4; 1413dd8e54a2SToby Isaac DMForestTopology oldTopo; 1414c7eeac06SToby Isaac char stringBuffer[256]; 1415dd8e54a2SToby Isaac PetscViewer viewer; 1416dd8e54a2SToby Isaac PetscViewerFormat format; 141756ba9f64SToby Isaac PetscInt adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade; 1418c7eeac06SToby Isaac PetscReal weightsFactor; 1419c7eeac06SToby Isaac DMForestAdaptivityStrategy adaptStrategy; 1420db4d5e8cSToby Isaac 1421db4d5e8cSToby Isaac PetscFunctionBegin; 14229566063dSJacob Faibussowitsch PetscCall(DMForestGetTopology(dm, &oldTopo)); 1423d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "DMForest Options"); 14249566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-dm_forest_topology", "the topology of the forest's base mesh", "DMForestSetTopology", oldTopo, stringBuffer, sizeof(stringBuffer), &flg1)); 14259566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-dm_forest_base_dm", "load the base DM from a viewer specification", "DMForestSetBaseDM", &viewer, &format, &flg2)); 14269566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-dm_forest_coarse_forest", "load the coarse forest from a viewer specification", "DMForestSetCoarseForest", &viewer, &format, &flg3)); 14279566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-dm_forest_fine_forest", "load the fine forest from a viewer specification", "DMForestSetFineForest", &viewer, &format, &flg4)); 14281dca8a05SBarry Smith PetscCheck((PetscInt)flg1 + (PetscInt)flg2 + (PetscInt)flg3 + (PetscInt)flg4 <= 1, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_INCOMP, "Specify only one of -dm_forest_{topology,base_dm,coarse_forest,fine_forest}"); 142956ba9f64SToby Isaac if (flg1) { 14309566063dSJacob Faibussowitsch PetscCall(DMForestSetTopology(dm, (DMForestTopology)stringBuffer)); 14319566063dSJacob Faibussowitsch PetscCall(DMForestSetBaseDM(dm, NULL)); 14329566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityForest(dm, NULL)); 143356ba9f64SToby Isaac } 143456ba9f64SToby Isaac if (flg2) { 1435dd8e54a2SToby Isaac DM base; 1436dd8e54a2SToby Isaac 14379566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &base)); 14389566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 14399566063dSJacob Faibussowitsch PetscCall(DMLoad(base, viewer)); 14409566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 14419566063dSJacob Faibussowitsch PetscCall(DMForestSetBaseDM(dm, base)); 14429566063dSJacob Faibussowitsch PetscCall(DMDestroy(&base)); 14439566063dSJacob Faibussowitsch PetscCall(DMForestSetTopology(dm, NULL)); 14449566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityForest(dm, NULL)); 1445dd8e54a2SToby Isaac } 144656ba9f64SToby Isaac if (flg3) { 1447dd8e54a2SToby Isaac DM coarse; 1448dd8e54a2SToby Isaac 14499566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &coarse)); 14509566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 14519566063dSJacob Faibussowitsch PetscCall(DMLoad(coarse, viewer)); 14529566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 14539566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityForest(dm, coarse)); 14549566063dSJacob Faibussowitsch PetscCall(DMDestroy(&coarse)); 14559566063dSJacob Faibussowitsch PetscCall(DMForestSetTopology(dm, NULL)); 14569566063dSJacob Faibussowitsch PetscCall(DMForestSetBaseDM(dm, NULL)); 1457dd8e54a2SToby Isaac } 145856ba9f64SToby Isaac if (flg4) { 1459dd8e54a2SToby Isaac DM fine; 1460dd8e54a2SToby Isaac 14619566063dSJacob Faibussowitsch PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &fine)); 14629566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 14639566063dSJacob Faibussowitsch PetscCall(DMLoad(fine, viewer)); 14649566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 14659566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityForest(dm, fine)); 14669566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 14679566063dSJacob Faibussowitsch PetscCall(DMForestSetTopology(dm, NULL)); 14689566063dSJacob Faibussowitsch PetscCall(DMForestSetBaseDM(dm, NULL)); 1469dd8e54a2SToby Isaac } 14709566063dSJacob Faibussowitsch PetscCall(DMForestGetAdjacencyDimension(dm, &adjDim)); 14719566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_forest_adjacency_dimension", "set the dimension of points that define adjacency in the forest", "DMForestSetAdjacencyDimension", adjDim, &adjDim, &flg, 0)); 1472dd8e54a2SToby Isaac if (flg) { 14739566063dSJacob Faibussowitsch PetscCall(DMForestSetAdjacencyDimension(dm, adjDim)); 1474f885a11aSToby Isaac } else { 14759566063dSJacob Faibussowitsch PetscCall(DMForestGetAdjacencyCodimension(dm, &adjCodim)); 14769566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_forest_adjacency_codimension", "set the codimension of points that define adjacency in the forest", "DMForestSetAdjacencyCodimension", adjCodim, &adjCodim, &flg, 1)); 14771baa6e33SBarry Smith if (flg) PetscCall(DMForestSetAdjacencyCodimension(dm, adjCodim)); 1478dd8e54a2SToby Isaac } 14799566063dSJacob Faibussowitsch PetscCall(DMForestGetPartitionOverlap(dm, &overlap)); 14809566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_forest_partition_overlap", "set the degree of partition overlap", "DMForestSetPartitionOverlap", overlap, &overlap, &flg, 0)); 14811baa6e33SBarry Smith if (flg) PetscCall(DMForestSetPartitionOverlap(dm, overlap)); 1482a6121fbdSMatthew G. Knepley #if 0 14839566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_refine","equivalent to -dm_forest_set_minimum_refinement and -dm_forest_set_initial_refinement with the same value",NULL,minRefinement,&minRefinement,&flg,0)); 1484a6121fbdSMatthew G. Knepley if (flg) { 14859566063dSJacob Faibussowitsch PetscCall(DMForestSetMinimumRefinement(dm,minRefinement)); 14869566063dSJacob Faibussowitsch PetscCall(DMForestSetInitialRefinement(dm,minRefinement)); 1487a6121fbdSMatthew G. Knepley } 14889566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_refine_hierarchy","equivalent to -dm_forest_set_minimum_refinement 0 and -dm_forest_set_initial_refinement",NULL,initRefinement,&initRefinement,&flg,0)); 1489a6121fbdSMatthew G. Knepley if (flg) { 14909566063dSJacob Faibussowitsch PetscCall(DMForestSetMinimumRefinement(dm,0)); 14919566063dSJacob Faibussowitsch PetscCall(DMForestSetInitialRefinement(dm,initRefinement)); 1492a6121fbdSMatthew G. Knepley } 1493a6121fbdSMatthew G. Knepley #endif 14949566063dSJacob Faibussowitsch PetscCall(DMForestGetMinimumRefinement(dm, &minRefinement)); 14959566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_forest_minimum_refinement", "set the minimum level of refinement in the forest", "DMForestSetMinimumRefinement", minRefinement, &minRefinement, &flg, 0)); 14961baa6e33SBarry Smith if (flg) PetscCall(DMForestSetMinimumRefinement(dm, minRefinement)); 14979566063dSJacob Faibussowitsch PetscCall(DMForestGetInitialRefinement(dm, &initRefinement)); 14989566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_forest_initial_refinement", "set the initial level of refinement in the forest", "DMForestSetInitialRefinement", initRefinement, &initRefinement, &flg, 0)); 14991baa6e33SBarry Smith if (flg) PetscCall(DMForestSetInitialRefinement(dm, initRefinement)); 15009566063dSJacob Faibussowitsch PetscCall(DMForestGetMaximumRefinement(dm, &maxRefinement)); 15019566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_forest_maximum_refinement", "set the maximum level of refinement in the forest", "DMForestSetMaximumRefinement", maxRefinement, &maxRefinement, &flg, 0)); 15021baa6e33SBarry Smith if (flg) PetscCall(DMForestSetMaximumRefinement(dm, maxRefinement)); 15039566063dSJacob Faibussowitsch PetscCall(DMForestGetAdaptivityStrategy(dm, &adaptStrategy)); 15049566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-dm_forest_adaptivity_strategy", "the forest's adaptivity-flag resolution strategy", "DMForestSetAdaptivityStrategy", adaptStrategy, stringBuffer, sizeof(stringBuffer), &flg)); 15051baa6e33SBarry Smith if (flg) PetscCall(DMForestSetAdaptivityStrategy(dm, (DMForestAdaptivityStrategy)stringBuffer)); 15069566063dSJacob Faibussowitsch PetscCall(DMForestGetGradeFactor(dm, &grade)); 15079566063dSJacob Faibussowitsch PetscCall(PetscOptionsBoundedInt("-dm_forest_grade_factor", "grade factor between neighboring cells", "DMForestSetGradeFactor", grade, &grade, &flg, 0)); 15081baa6e33SBarry Smith if (flg) PetscCall(DMForestSetGradeFactor(dm, grade)); 15099566063dSJacob Faibussowitsch PetscCall(DMForestGetCellWeightFactor(dm, &weightsFactor)); 15109566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-dm_forest_cell_weight_factor", "multiplying weight factor for cell refinement", "DMForestSetCellWeightFactor", weightsFactor, &weightsFactor, &flg)); 15111baa6e33SBarry Smith if (flg) PetscCall(DMForestSetCellWeightFactor(dm, weightsFactor)); 1512d0609cedSBarry Smith PetscOptionsHeadEnd(); 15133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1514db4d5e8cSToby Isaac } 1515db4d5e8cSToby Isaac 1516d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 1517d71ae5a4SJacob Faibussowitsch { 1518d8984e3bSMatthew G. Knepley PetscFunctionBegin; 15199566063dSJacob Faibussowitsch if (subdm) PetscCall(DMClone(dm, subdm)); 15209566063dSJacob Faibussowitsch PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm)); 15213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1522d8984e3bSMatthew G. Knepley } 1523d8984e3bSMatthew G. Knepley 1524d71ae5a4SJacob Faibussowitsch PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined) 1525d71ae5a4SJacob Faibussowitsch { 15265421bac9SToby Isaac DMLabel refine; 15275421bac9SToby Isaac DM fineDM; 15285421bac9SToby Isaac 15295421bac9SToby Isaac PetscFunctionBegin; 15309566063dSJacob Faibussowitsch PetscCall(DMGetFineDM(dm, &fineDM)); 15315421bac9SToby Isaac if (fineDM) { 15329566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)fineDM)); 15335421bac9SToby Isaac *dmRefined = fineDM; 15343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15355421bac9SToby Isaac } 15369566063dSJacob Faibussowitsch PetscCall(DMForestTemplate(dm, comm, dmRefined)); 15379566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "refine", &refine)); 15385421bac9SToby Isaac if (!refine) { 15399566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "refine", &refine)); 15409566063dSJacob Faibussowitsch PetscCall(DMLabelSetDefaultValue(refine, DM_ADAPT_REFINE)); 15411baa6e33SBarry Smith } else PetscCall(PetscObjectReference((PetscObject)refine)); 15429566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityLabel(*dmRefined, refine)); 15439566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&refine)); 15443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15455421bac9SToby Isaac } 15465421bac9SToby Isaac 1547d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened) 1548d71ae5a4SJacob Faibussowitsch { 15495421bac9SToby Isaac DMLabel coarsen; 15505421bac9SToby Isaac DM coarseDM; 15515421bac9SToby Isaac 15525421bac9SToby Isaac PetscFunctionBegin; 15534098eed7SToby Isaac { 15544098eed7SToby Isaac PetscMPIInt mpiComparison; 15554098eed7SToby Isaac MPI_Comm dmcomm = PetscObjectComm((PetscObject)dm); 15564098eed7SToby Isaac 15579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_compare(comm, dmcomm, &mpiComparison)); 15581dca8a05SBarry Smith PetscCheck(mpiComparison == MPI_IDENT || mpiComparison == MPI_CONGRUENT, dmcomm, PETSC_ERR_SUP, "No support for different communicators yet"); 15594098eed7SToby Isaac } 15609566063dSJacob Faibussowitsch PetscCall(DMGetCoarseDM(dm, &coarseDM)); 15615421bac9SToby Isaac if (coarseDM) { 15629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)coarseDM)); 15635421bac9SToby Isaac *dmCoarsened = coarseDM; 15643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15655421bac9SToby Isaac } 15669566063dSJacob Faibussowitsch PetscCall(DMForestTemplate(dm, comm, dmCoarsened)); 15679566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityPurpose(*dmCoarsened, DM_ADAPT_COARSEN)); 15689566063dSJacob Faibussowitsch PetscCall(DMGetLabel(dm, "coarsen", &coarsen)); 15695421bac9SToby Isaac if (!coarsen) { 15709566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PETSC_COMM_SELF, "coarsen", &coarsen)); 15719566063dSJacob Faibussowitsch PetscCall(DMLabelSetDefaultValue(coarsen, DM_ADAPT_COARSEN)); 15721baa6e33SBarry Smith } else PetscCall(PetscObjectReference((PetscObject)coarsen)); 15739566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityLabel(*dmCoarsened, coarsen)); 15749566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&coarsen)); 15753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15765421bac9SToby Isaac } 15775421bac9SToby Isaac 1578d71ae5a4SJacob Faibussowitsch PetscErrorCode DMAdaptLabel_Forest(DM dm, PETSC_UNUSED Vec metric, DMLabel label, PETSC_UNUSED DMLabel rgLabel, DM *adaptedDM) 1579d71ae5a4SJacob Faibussowitsch { 158009350103SToby Isaac PetscBool success; 158109350103SToby Isaac 158209350103SToby Isaac PetscFunctionBegin; 15839566063dSJacob Faibussowitsch PetscCall(DMForestTemplate(dm, PetscObjectComm((PetscObject)dm), adaptedDM)); 15849566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityLabel(*adaptedDM, label)); 15859566063dSJacob Faibussowitsch PetscCall(DMSetUp(*adaptedDM)); 15869566063dSJacob Faibussowitsch PetscCall(DMForestGetAdaptivitySuccess(*adaptedDM, &success)); 158709350103SToby Isaac if (!success) { 15889566063dSJacob Faibussowitsch PetscCall(DMDestroy(adaptedDM)); 158909350103SToby Isaac *adaptedDM = NULL; 159009350103SToby Isaac } 15913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 159209350103SToby Isaac } 159309350103SToby Isaac 1594d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMInitialize_Forest(DM dm) 1595d71ae5a4SJacob Faibussowitsch { 1596d222f98bSToby Isaac PetscFunctionBegin; 15979566063dSJacob Faibussowitsch PetscCall(PetscMemzero(dm->ops, sizeof(*(dm->ops)))); 1598d222f98bSToby Isaac 1599d222f98bSToby Isaac dm->ops->clone = DMClone_Forest; 1600d222f98bSToby Isaac dm->ops->setfromoptions = DMSetFromOptions_Forest; 1601d222f98bSToby Isaac dm->ops->destroy = DMDestroy_Forest; 1602d8984e3bSMatthew G. Knepley dm->ops->createsubdm = DMCreateSubDM_Forest; 16035421bac9SToby Isaac dm->ops->refine = DMRefine_Forest; 16045421bac9SToby Isaac dm->ops->coarsen = DMCoarsen_Forest; 16053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1606d222f98bSToby Isaac } 1607d222f98bSToby Isaac 16089be51f97SToby Isaac /*MC 16099be51f97SToby Isaac 1610*20f4b53cSBarry Smith DMFOREST = "forest" - A DM object that encapsulates a hierarchically refined mesh. Forests usually have a base `DM` 1611*20f4b53cSBarry Smith (see `DMForestGetBaseDM()`), from which it is refined. The refinement and partitioning of forests is considered 1612*20f4b53cSBarry Smith immutable after `DMSetUp()` is called. To adapt a mesh, one should call `DMForestTemplate()` to create a new mesh that 1613*20f4b53cSBarry Smith will default to being identical to it, specify how that mesh should differ, and then calling `DMSetUp()` on the new 1614bae1f979SBarry Smith mesh. 1615bae1f979SBarry Smith 1616bae1f979SBarry Smith To specify that a mesh should be refined or coarsened from the previous mesh, a label should be defined on the 1617*20f4b53cSBarry Smith previous mesh whose values indicate which cells should be refined (`DM_ADAPT_REFINE`) or coarsened (`DM_ADAPT_COARSEN`) 1618bae1f979SBarry Smith and how (subtypes are free to allow additional values for things like anisotropic refinement). The label should be 1619*20f4b53cSBarry Smith given to the *new* mesh with `DMForestSetAdaptivityLabel()`. 16209be51f97SToby Isaac 16219be51f97SToby Isaac Level: advanced 16229be51f97SToby Isaac 1623*20f4b53cSBarry Smith .seealso: `DMType`, `DM`, `DMCreate()`, `DMSetType()`, `DMForestGetBaseDM()`, `DMForestSetBaseDM()`, `DMForestTemplate()`, `DMForestSetAdaptivityLabel()` 16249be51f97SToby Isaac M*/ 16259be51f97SToby Isaac 1626d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm) 1627d71ae5a4SJacob Faibussowitsch { 1628db4d5e8cSToby Isaac DM_Forest *forest; 1629db4d5e8cSToby Isaac 1630db4d5e8cSToby Isaac PetscFunctionBegin; 1631db4d5e8cSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16324dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&forest)); 1633db4d5e8cSToby Isaac dm->dim = 0; 1634db4d5e8cSToby Isaac dm->data = forest; 1635db4d5e8cSToby Isaac forest->refct = 1; 1636db4d5e8cSToby Isaac forest->data = NULL; 1637db4d5e8cSToby Isaac forest->topology = NULL; 1638cd3c525cSToby Isaac forest->adapt = NULL; 1639db4d5e8cSToby Isaac forest->base = NULL; 16406a87ffbfSToby Isaac forest->adaptPurpose = DM_ADAPT_DETERMINE; 1641db4d5e8cSToby Isaac forest->adjDim = PETSC_DEFAULT; 1642db4d5e8cSToby Isaac forest->overlap = PETSC_DEFAULT; 1643db4d5e8cSToby Isaac forest->minRefinement = PETSC_DEFAULT; 1644db4d5e8cSToby Isaac forest->maxRefinement = PETSC_DEFAULT; 164556ba9f64SToby Isaac forest->initRefinement = PETSC_DEFAULT; 1646c7eeac06SToby Isaac forest->cStart = PETSC_DETERMINE; 1647c7eeac06SToby Isaac forest->cEnd = PETSC_DETERMINE; 1648cd3c525cSToby Isaac forest->cellSF = NULL; 1649ebdf65a2SToby Isaac forest->adaptLabel = NULL; 1650db4d5e8cSToby Isaac forest->gradeFactor = 2; 1651db4d5e8cSToby Isaac forest->cellWeights = NULL; 1652db4d5e8cSToby Isaac forest->cellWeightsCopyMode = PETSC_USE_POINTER; 1653db4d5e8cSToby Isaac forest->weightsFactor = 1.; 1654db4d5e8cSToby Isaac forest->weightCapacity = 1.; 16559566063dSJacob Faibussowitsch PetscCall(DMForestSetAdaptivityStrategy(dm, DMFORESTADAPTALL)); 16569566063dSJacob Faibussowitsch PetscCall(DMInitialize_Forest(dm)); 16573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1658db4d5e8cSToby Isaac } 1659