xref: /petsc/src/dm/impls/forest/forest.c (revision 20f4b53cbb5e9bd9ef12b76a8697d60d197cda17)
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