xref: /petsc/src/dm/impls/forest/forest.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
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 
179371c9d4SSatish Balay static PetscErrorCode DMForestPackageFinalize(void) {
1827d4645fSToby Isaac   DMForestTypeLink oldLink, link = DMForestTypeList;
1927d4645fSToby Isaac 
2027d4645fSToby Isaac   PetscFunctionBegin;
2127d4645fSToby Isaac   while (link) {
2227d4645fSToby Isaac     oldLink = link;
239566063dSJacob Faibussowitsch     PetscCall(PetscFree(oldLink->name));
2427d4645fSToby Isaac     link = oldLink->next;
259566063dSJacob Faibussowitsch     PetscCall(PetscFree(oldLink));
2627d4645fSToby Isaac   }
2727d4645fSToby Isaac   PetscFunctionReturn(0);
2827d4645fSToby Isaac }
2927d4645fSToby Isaac 
309371c9d4SSatish Balay static PetscErrorCode DMForestPackageInitialize(void) {
3127d4645fSToby Isaac   PetscFunctionBegin;
3227d4645fSToby Isaac   if (DMForestPackageInitialized) PetscFunctionReturn(0);
3327d4645fSToby Isaac   DMForestPackageInitialized = PETSC_TRUE;
34f885a11aSToby Isaac 
359566063dSJacob Faibussowitsch   PetscCall(DMForestRegisterType(DMFOREST));
369566063dSJacob Faibussowitsch   PetscCall(PetscRegisterFinalize(DMForestPackageFinalize));
3727d4645fSToby Isaac   PetscFunctionReturn(0);
3827d4645fSToby Isaac }
3927d4645fSToby Isaac 
409be51f97SToby Isaac /*@C
419be51f97SToby Isaac   DMForestRegisterType - Registers a DMType as a subtype of DMFOREST (so that DMIsForest() will be correct)
429be51f97SToby Isaac 
439be51f97SToby Isaac   Not Collective
449be51f97SToby Isaac 
459be51f97SToby Isaac   Input parameter:
469be51f97SToby Isaac . name - the name of the type
479be51f97SToby Isaac 
489be51f97SToby Isaac   Level: advanced
499be51f97SToby Isaac 
50db781477SPatrick Sanan .seealso: `DMFOREST`, `DMIsForest()`
519be51f97SToby Isaac @*/
529371c9d4SSatish Balay PetscErrorCode DMForestRegisterType(DMType name) {
5327d4645fSToby Isaac   DMForestTypeLink link;
5427d4645fSToby Isaac 
5527d4645fSToby Isaac   PetscFunctionBegin;
569566063dSJacob Faibussowitsch   PetscCall(DMForestPackageInitialize());
579566063dSJacob Faibussowitsch   PetscCall(PetscNew(&link));
589566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &link->name));
5927d4645fSToby Isaac   link->next       = DMForestTypeList;
6027d4645fSToby Isaac   DMForestTypeList = link;
6127d4645fSToby Isaac   PetscFunctionReturn(0);
6227d4645fSToby Isaac }
6327d4645fSToby Isaac 
649be51f97SToby Isaac /*@
659be51f97SToby Isaac   DMIsForest - Check whether a DM uses the DMFOREST interface for hierarchically-refined meshes
669be51f97SToby Isaac 
679be51f97SToby Isaac   Not Collective
689be51f97SToby Isaac 
699be51f97SToby Isaac   Input parameter:
709be51f97SToby Isaac . dm - the DM object
719be51f97SToby Isaac 
729be51f97SToby Isaac   Output parameter:
739be51f97SToby Isaac . isForest - whether dm is a subtype of DMFOREST
749be51f97SToby Isaac 
759be51f97SToby Isaac   Level: intermediate
769be51f97SToby Isaac 
77db781477SPatrick Sanan .seealso: `DMFOREST`, `DMForestRegisterType()`
789be51f97SToby Isaac @*/
799371c9d4SSatish Balay PetscErrorCode DMIsForest(DM dm, PetscBool *isForest) {
8027d4645fSToby Isaac   DMForestTypeLink link = DMForestTypeList;
8127d4645fSToby Isaac 
8227d4645fSToby Isaac   PetscFunctionBegin;
8327d4645fSToby Isaac   while (link) {
8427d4645fSToby Isaac     PetscBool sameType;
859566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dm, link->name, &sameType));
8627d4645fSToby Isaac     if (sameType) {
8727d4645fSToby Isaac       *isForest = PETSC_TRUE;
8827d4645fSToby Isaac       PetscFunctionReturn(0);
8927d4645fSToby Isaac     }
9027d4645fSToby Isaac     link = link->next;
9127d4645fSToby Isaac   }
9227d4645fSToby Isaac   *isForest = PETSC_FALSE;
9327d4645fSToby Isaac   PetscFunctionReturn(0);
9427d4645fSToby Isaac }
9527d4645fSToby Isaac 
969be51f97SToby Isaac /*@
979be51f97SToby Isaac   DMForestTemplate - Create a new DM that will be adapted from a source DM.  The new DM reproduces the configuration
989be51f97SToby Isaac   of the source, but is not yet setup, so that the user can then define only the ways that the new DM should differ
999be51f97SToby Isaac   (by, e.g., refinement or repartitioning).  The source DM is also set as the adaptivity source DM of the new DM (see
1009be51f97SToby Isaac   DMForestSetAdaptivityForest()).
1019be51f97SToby Isaac 
1029be51f97SToby Isaac   Collective on dm
1039be51f97SToby Isaac 
1049be51f97SToby Isaac   Input Parameters:
1059be51f97SToby Isaac + dm - the source DM object
1069be51f97SToby Isaac - comm - the communicator for the new DM (this communicator is currently ignored, but is present so that DMForestTemplate() can be used within DMCoarsen())
1079be51f97SToby Isaac 
1089be51f97SToby Isaac   Output Parameter:
1099be51f97SToby Isaac . tdm - the new DM object
1109be51f97SToby Isaac 
1119be51f97SToby Isaac   Level: intermediate
1129be51f97SToby Isaac 
113db781477SPatrick Sanan .seealso: `DMForestSetAdaptivityForest()`
1149be51f97SToby Isaac @*/
1159371c9d4SSatish Balay PetscErrorCode DMForestTemplate(DM dm, MPI_Comm comm, DM *tdm) {
116a0452a8eSToby Isaac   DM_Forest                 *forest = (DM_Forest *)dm->data;
11720e8089bSToby Isaac   DMType                     type;
118a0452a8eSToby Isaac   DM                         base;
119a0452a8eSToby Isaac   DMForestTopology           topology;
12005e99e11SStefano Zampini   MatType                    mtype;
121a0452a8eSToby Isaac   PetscInt                   dim, overlap, ref, factor;
122a0452a8eSToby Isaac   DMForestAdaptivityStrategy strat;
123795844e7SToby Isaac   void                      *ctx;
12449fc9a2fSToby Isaac   PetscErrorCode (*map)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void *);
1253e58adeeSToby Isaac   void *mapCtx;
126a0452a8eSToby Isaac 
127a0452a8eSToby Isaac   PetscFunctionBegin;
128a0452a8eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1299566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), tdm));
1309566063dSJacob Faibussowitsch   PetscCall(DMGetType(dm, &type));
1319566063dSJacob Faibussowitsch   PetscCall(DMSetType(*tdm, type));
1329566063dSJacob Faibussowitsch   PetscCall(DMForestGetBaseDM(dm, &base));
1339566063dSJacob Faibussowitsch   PetscCall(DMForestSetBaseDM(*tdm, base));
1349566063dSJacob Faibussowitsch   PetscCall(DMForestGetTopology(dm, &topology));
1359566063dSJacob Faibussowitsch   PetscCall(DMForestSetTopology(*tdm, topology));
1369566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdjacencyDimension(dm, &dim));
1379566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdjacencyDimension(*tdm, dim));
1389566063dSJacob Faibussowitsch   PetscCall(DMForestGetPartitionOverlap(dm, &overlap));
1399566063dSJacob Faibussowitsch   PetscCall(DMForestSetPartitionOverlap(*tdm, overlap));
1409566063dSJacob Faibussowitsch   PetscCall(DMForestGetMinimumRefinement(dm, &ref));
1419566063dSJacob Faibussowitsch   PetscCall(DMForestSetMinimumRefinement(*tdm, ref));
1429566063dSJacob Faibussowitsch   PetscCall(DMForestGetMaximumRefinement(dm, &ref));
1439566063dSJacob Faibussowitsch   PetscCall(DMForestSetMaximumRefinement(*tdm, ref));
1449566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivityStrategy(dm, &strat));
1459566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityStrategy(*tdm, strat));
1469566063dSJacob Faibussowitsch   PetscCall(DMForestGetGradeFactor(dm, &factor));
1479566063dSJacob Faibussowitsch   PetscCall(DMForestSetGradeFactor(*tdm, factor));
1489566063dSJacob Faibussowitsch   PetscCall(DMForestGetBaseCoordinateMapping(dm, &map, &mapCtx));
1499566063dSJacob Faibussowitsch   PetscCall(DMForestSetBaseCoordinateMapping(*tdm, map, mapCtx));
1501baa6e33SBarry Smith   if (forest->ftemplate) PetscCall((*forest->ftemplate)(dm, *tdm));
1519566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityForest(*tdm, dm));
1529566063dSJacob Faibussowitsch   PetscCall(DMCopyDisc(dm, *tdm));
1539566063dSJacob Faibussowitsch   PetscCall(DMGetApplicationContext(dm, &ctx));
1549566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(*tdm, &ctx));
15590b157c4SStefano Zampini   {
1564fb89dddSMatthew G. Knepley     const PetscReal *maxCell, *L, *Lstart;
157795844e7SToby Isaac 
1584fb89dddSMatthew G. Knepley     PetscCall(DMGetPeriodicity(dm, &maxCell, &Lstart, &L));
1594fb89dddSMatthew G. Knepley     PetscCall(DMSetPeriodicity(*tdm, maxCell, Lstart, L));
160795844e7SToby Isaac   }
1619566063dSJacob Faibussowitsch   PetscCall(DMGetMatType(dm, &mtype));
1629566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(*tdm, mtype));
163a0452a8eSToby Isaac   PetscFunctionReturn(0);
164a0452a8eSToby Isaac }
165a0452a8eSToby Isaac 
16601d9d024SToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm);
16701d9d024SToby Isaac 
1689371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm) {
169db4d5e8cSToby Isaac   DM_Forest  *forest = (DM_Forest *)dm->data;
170db4d5e8cSToby Isaac   const char *type;
171db4d5e8cSToby Isaac 
172db4d5e8cSToby Isaac   PetscFunctionBegin;
173db4d5e8cSToby Isaac   forest->refct++;
174db4d5e8cSToby Isaac   (*newdm)->data = forest;
1759566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetType((PetscObject)dm, &type));
1769566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)*newdm, type));
1779566063dSJacob Faibussowitsch   PetscCall(DMInitialize_Forest(*newdm));
178db4d5e8cSToby Isaac   PetscFunctionReturn(0);
179db4d5e8cSToby Isaac }
180db4d5e8cSToby Isaac 
1819371c9d4SSatish Balay static PetscErrorCode DMDestroy_Forest(DM dm) {
182db4d5e8cSToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
183db4d5e8cSToby Isaac 
184db4d5e8cSToby Isaac   PetscFunctionBegin;
185db4d5e8cSToby Isaac   if (--forest->refct > 0) PetscFunctionReturn(0);
1869566063dSJacob Faibussowitsch   if (forest->destroy) PetscCall((*forest->destroy)(dm));
1879566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&forest->cellSF));
1889566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&forest->preCoarseToFine));
1899566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&forest->coarseToPreFine));
1909566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&forest->adaptLabel));
1919566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->adaptStrategy));
1929566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&forest->base));
1939566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&forest->adapt));
1949566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->topology));
1959566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest));
196db4d5e8cSToby Isaac   PetscFunctionReturn(0);
197db4d5e8cSToby Isaac }
198db4d5e8cSToby Isaac 
1999be51f97SToby Isaac /*@C
2009be51f97SToby Isaac   DMForestSetTopology - Set the topology of a DMForest during the pre-setup phase.  The topology is a string (e.g.
20168d54884SBarry Smith   "cube", "shell") and can be interpreted by subtypes of DMFOREST) to construct the base DM of a forest during
2029be51f97SToby Isaac   DMSetUp().
2039be51f97SToby Isaac 
2049be51f97SToby Isaac   Logically collective on dm
2059be51f97SToby Isaac 
2069be51f97SToby Isaac   Input parameters:
2079be51f97SToby Isaac + dm - the forest
2089be51f97SToby Isaac - topology - the topology of the forest
2099be51f97SToby Isaac 
2109be51f97SToby Isaac   Level: intermediate
2119be51f97SToby Isaac 
212db781477SPatrick Sanan .seealso: `DMForestGetTopology()`, `DMForestSetBaseDM()`
2139be51f97SToby Isaac @*/
2149371c9d4SSatish Balay PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology) {
215db4d5e8cSToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
216db4d5e8cSToby Isaac 
217db4d5e8cSToby Isaac   PetscFunctionBegin;
218db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
21928b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the topology after setup");
2209566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->topology));
2219566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy((const char *)topology, (char **)&forest->topology));
222db4d5e8cSToby Isaac   PetscFunctionReturn(0);
223db4d5e8cSToby Isaac }
224db4d5e8cSToby Isaac 
2259be51f97SToby Isaac /*@C
2269be51f97SToby Isaac   DMForestGetTopology - Get a string describing the topology of a DMForest.
2279be51f97SToby Isaac 
2289be51f97SToby Isaac   Not collective
2299be51f97SToby Isaac 
2309be51f97SToby Isaac   Input parameter:
2319be51f97SToby Isaac . dm - the forest
2329be51f97SToby Isaac 
2339be51f97SToby Isaac   Output parameter:
2349be51f97SToby Isaac . topology - the topology of the forest (e.g., 'cube', 'shell')
2359be51f97SToby Isaac 
2369be51f97SToby Isaac   Level: intermediate
2379be51f97SToby Isaac 
238db781477SPatrick Sanan .seealso: `DMForestSetTopology()`
2399be51f97SToby Isaac @*/
2409371c9d4SSatish Balay PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology) {
241dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
242dd8e54a2SToby Isaac 
243dd8e54a2SToby Isaac   PetscFunctionBegin;
244dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
245dd8e54a2SToby Isaac   PetscValidPointer(topology, 2);
246dd8e54a2SToby Isaac   *topology = forest->topology;
247dd8e54a2SToby Isaac   PetscFunctionReturn(0);
248dd8e54a2SToby Isaac }
249dd8e54a2SToby Isaac 
2509be51f97SToby Isaac /*@
2519be51f97SToby Isaac   DMForestSetBaseDM - During the pre-setup phase, set the DM that defines the base mesh of a DMForest forest.  The
2529be51f97SToby Isaac   forest will be hierarchically refined from the base, and all refinements/coarsenings of the forest will share its
253765b024eSBarry Smith   base.  In general, two forest must share a base to be comparable, to do things like construct interpolators.
2549be51f97SToby Isaac 
2559be51f97SToby Isaac   Logically collective on dm
2569be51f97SToby Isaac 
2579be51f97SToby Isaac   Input Parameters:
2589be51f97SToby Isaac + dm - the forest
2599be51f97SToby Isaac - base - the base DM of the forest
2609be51f97SToby Isaac 
26195452b02SPatrick Sanan   Notes:
26295452b02SPatrick Sanan     Currently the base DM must be a DMPLEX
263765b024eSBarry Smith 
2649be51f97SToby Isaac   Level: intermediate
2659be51f97SToby Isaac 
266db781477SPatrick Sanan .seealso: `DMForestGetBaseDM()`
2679be51f97SToby Isaac @*/
2689371c9d4SSatish Balay PetscErrorCode DMForestSetBaseDM(DM dm, DM base) {
269dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
270dd8e54a2SToby Isaac   PetscInt   dim, dimEmbed;
271dd8e54a2SToby Isaac 
272dd8e54a2SToby Isaac   PetscFunctionBegin;
273dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
27428b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the base after setup");
2759566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)base));
2769566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&forest->base));
277dd8e54a2SToby Isaac   forest->base = base;
278a0452a8eSToby Isaac   if (base) {
2794fb89dddSMatthew G. Knepley     const PetscReal *maxCell, *Lstart, *L;
28028dfcf7cSStefano Zampini 
281a0452a8eSToby Isaac     PetscValidHeaderSpecific(base, DM_CLASSID, 2);
2829566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(base, &dim));
2839566063dSJacob Faibussowitsch     PetscCall(DMSetDimension(dm, dim));
2849566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDim(base, &dimEmbed));
2859566063dSJacob Faibussowitsch     PetscCall(DMSetCoordinateDim(dm, dimEmbed));
2864fb89dddSMatthew G. Knepley     PetscCall(DMGetPeriodicity(base, &maxCell, &Lstart, &L));
2874fb89dddSMatthew G. Knepley     PetscCall(DMSetPeriodicity(dm, maxCell, Lstart, L));
2884fb89dddSMatthew G. Knepley   } else PetscCall(DMSetPeriodicity(dm, NULL, NULL, NULL));
289dd8e54a2SToby Isaac   PetscFunctionReturn(0);
290dd8e54a2SToby Isaac }
291dd8e54a2SToby Isaac 
2929be51f97SToby Isaac /*@
2939be51f97SToby Isaac   DMForestGetBaseDM - Get the base DM of a DMForest forest.  The forest will be hierarchically refined from the base,
29468d54884SBarry Smith   and all refinements/coarsenings of the forest will share its base.  In general, two forest must share a base to be
2959be51f97SToby Isaac   comparable, to do things like construct interpolators.
2969be51f97SToby Isaac 
2979be51f97SToby Isaac   Not collective
2989be51f97SToby Isaac 
2999be51f97SToby Isaac   Input Parameter:
3009be51f97SToby Isaac . dm - the forest
3019be51f97SToby Isaac 
3029be51f97SToby Isaac   Output Parameter:
3039be51f97SToby Isaac . base - the base DM of the forest
3049be51f97SToby Isaac 
305367003a6SStefano Zampini   Notes:
306367003a6SStefano Zampini     After DMSetUp(), the base DM will be redundantly distributed across MPI processes
307367003a6SStefano Zampini 
3089be51f97SToby Isaac   Level: intermediate
3099be51f97SToby Isaac 
310db781477SPatrick Sanan .seealso: `DMForestSetBaseDM()`
3119be51f97SToby Isaac @*/
3129371c9d4SSatish Balay PetscErrorCode DMForestGetBaseDM(DM dm, DM *base) {
313dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
314dd8e54a2SToby Isaac 
315dd8e54a2SToby Isaac   PetscFunctionBegin;
316dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
317dd8e54a2SToby Isaac   PetscValidPointer(base, 2);
318dd8e54a2SToby Isaac   *base = forest->base;
319dd8e54a2SToby Isaac   PetscFunctionReturn(0);
320dd8e54a2SToby Isaac }
321dd8e54a2SToby Isaac 
3229371c9d4SSatish Balay PetscErrorCode DMForestSetBaseCoordinateMapping(DM dm, PetscErrorCode (*func)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void *), void *ctx) {
323cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
324cf38a08cSToby Isaac 
325cf38a08cSToby Isaac   PetscFunctionBegin;
326cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
327cf38a08cSToby Isaac   forest->mapcoordinates    = func;
328cf38a08cSToby Isaac   forest->mapcoordinatesctx = ctx;
329cf38a08cSToby Isaac   PetscFunctionReturn(0);
330cf38a08cSToby Isaac }
331cf38a08cSToby Isaac 
3329371c9d4SSatish Balay PetscErrorCode DMForestGetBaseCoordinateMapping(DM dm, PetscErrorCode (**func)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void *), void *ctx) {
333cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
334cf38a08cSToby Isaac 
335cf38a08cSToby Isaac   PetscFunctionBegin;
336cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
337cf38a08cSToby Isaac   if (func) *func = forest->mapcoordinates;
338cf38a08cSToby Isaac   if (ctx) *((void **)ctx) = forest->mapcoordinatesctx;
339cf38a08cSToby Isaac   PetscFunctionReturn(0);
340cf38a08cSToby Isaac }
341cf38a08cSToby Isaac 
3429be51f97SToby Isaac /*@
3439be51f97SToby Isaac   DMForestSetAdaptivityForest - During the pre-setup phase, set the forest from which the current forest will be
3449be51f97SToby Isaac   adapted (e.g., the current forest will be refined/coarsened/repartitioned from it) im DMSetUp().  Usually not needed
3459be51f97SToby Isaac   by users directly: DMForestTemplate() constructs a new forest to be adapted from an old forest and calls this
3469be51f97SToby Isaac   routine.
3479be51f97SToby Isaac 
348dffe73a3SToby Isaac   Note that this can be called after setup with adapt = NULL, which will clear all internal data related to the
349dffe73a3SToby Isaac   adaptivity forest from dm.  This way, repeatedly adapting does not leave stale DM objects in memory.
350dffe73a3SToby Isaac 
3519be51f97SToby Isaac   Logically collective on dm
3529be51f97SToby Isaac 
353d8d19677SJose E. Roman   Input Parameters:
3549be51f97SToby Isaac + dm - the new forest, which will be constructed from adapt
3559be51f97SToby Isaac - adapt - the old forest
3569be51f97SToby Isaac 
3579be51f97SToby Isaac   Level: intermediate
3589be51f97SToby Isaac 
359db781477SPatrick Sanan .seealso: `DMForestGetAdaptivityForest()`, `DMForestSetAdaptivityPurpose()`
3609be51f97SToby Isaac @*/
3619371c9d4SSatish Balay PetscErrorCode DMForestSetAdaptivityForest(DM dm, DM adapt) {
362dffe73a3SToby Isaac   DM_Forest *forest, *adaptForest, *oldAdaptForest;
363dffe73a3SToby Isaac   DM         oldAdapt;
364456cc5b7SMatthew G. Knepley   PetscBool  isForest;
365dd8e54a2SToby Isaac 
366dd8e54a2SToby Isaac   PetscFunctionBegin;
367dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3681fd50544SStefano Zampini   if (adapt) PetscValidHeaderSpecific(adapt, DM_CLASSID, 2);
3699566063dSJacob Faibussowitsch   PetscCall(DMIsForest(dm, &isForest));
370456cc5b7SMatthew G. Knepley   if (!isForest) PetscFunctionReturn(0);
3711dca8a05SBarry Smith   PetscCheck(adapt == NULL || !dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the adaptation forest after setup");
372ba936b91SToby Isaac   forest = (DM_Forest *)dm->data;
3739566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivityForest(dm, &oldAdapt));
374193eb951SToby Isaac   adaptForest    = (DM_Forest *)(adapt ? adapt->data : NULL);
375193eb951SToby Isaac   oldAdaptForest = (DM_Forest *)(oldAdapt ? oldAdapt->data : NULL);
376dffe73a3SToby Isaac   if (adaptForest != oldAdaptForest) {
3779566063dSJacob Faibussowitsch     PetscCall(PetscSFDestroy(&forest->preCoarseToFine));
3789566063dSJacob Faibussowitsch     PetscCall(PetscSFDestroy(&forest->coarseToPreFine));
3799566063dSJacob Faibussowitsch     if (forest->clearadaptivityforest) PetscCall((*forest->clearadaptivityforest)(dm));
380dffe73a3SToby Isaac   }
38126d9498aSToby Isaac   switch (forest->adaptPurpose) {
382cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
3839566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)adapt));
3849566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&(forest->adapt)));
385ba936b91SToby Isaac     forest->adapt = adapt;
38626d9498aSToby Isaac     break;
3879371c9d4SSatish Balay   case DM_ADAPT_REFINE: PetscCall(DMSetCoarseDM(dm, adapt)); break;
388a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
3899371c9d4SSatish Balay   case DM_ADAPT_COARSEN_LAST: PetscCall(DMSetFineDM(dm, adapt)); break;
3909371c9d4SSatish Balay   default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "invalid adaptivity purpose");
39126d9498aSToby Isaac   }
392dd8e54a2SToby Isaac   PetscFunctionReturn(0);
393dd8e54a2SToby Isaac }
394dd8e54a2SToby Isaac 
3959be51f97SToby Isaac /*@
3969be51f97SToby Isaac   DMForestGetAdaptivityForest - Get the forest from which the current forest is adapted.
3979be51f97SToby Isaac 
3989be51f97SToby Isaac   Not collective
3999be51f97SToby Isaac 
4009be51f97SToby Isaac   Input Parameter:
4019be51f97SToby Isaac . dm - the forest
4029be51f97SToby Isaac 
4039be51f97SToby Isaac   Output Parameter:
4049be51f97SToby Isaac . adapt - the forest from which dm is/was adapted
4059be51f97SToby Isaac 
4069be51f97SToby Isaac   Level: intermediate
4079be51f97SToby Isaac 
408db781477SPatrick Sanan .seealso: `DMForestSetAdaptivityForest()`, `DMForestSetAdaptivityPurpose()`
4099be51f97SToby Isaac @*/
4109371c9d4SSatish Balay PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt) {
411ba936b91SToby Isaac   DM_Forest *forest;
412dd8e54a2SToby Isaac 
413dd8e54a2SToby Isaac   PetscFunctionBegin;
414dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
415ba936b91SToby Isaac   forest = (DM_Forest *)dm->data;
41626d9498aSToby Isaac   switch (forest->adaptPurpose) {
4179371c9d4SSatish Balay   case DM_ADAPT_DETERMINE: *adapt = forest->adapt; break;
4189371c9d4SSatish Balay   case DM_ADAPT_REFINE: PetscCall(DMGetCoarseDM(dm, adapt)); break;
419a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
4209371c9d4SSatish Balay   case DM_ADAPT_COARSEN_LAST: PetscCall(DMGetFineDM(dm, adapt)); break;
4219371c9d4SSatish Balay   default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "invalid adaptivity purpose");
42226d9498aSToby Isaac   }
42326d9498aSToby Isaac   PetscFunctionReturn(0);
42426d9498aSToby Isaac }
42526d9498aSToby Isaac 
4269be51f97SToby Isaac /*@
4279be51f97SToby Isaac   DMForestSetAdaptivityPurpose - During the pre-setup phase, set whether the current DM is being adapted from its
428a1b0c543SToby Isaac   source (set with DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening
429cd3c525cSToby Isaac   (DM_ADAPT_COARSEN), or undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting:
4309be51f97SToby Isaac   during DMDestroy(), cyclic references can be found between DMs only if the cyclic reference is due to a fine/coarse
4319be51f97SToby Isaac   relationship (see DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does
4329be51f97SToby Isaac   not maintain a reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can
4339be51f97SToby Isaac   cause a memory leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
4349be51f97SToby Isaac 
4359be51f97SToby Isaac   Logically collective on dm
4369be51f97SToby Isaac 
4379be51f97SToby Isaac   Input Parameters:
4389be51f97SToby Isaac + dm - the forest
439bf2d5fbbSStefano Zampini - purpose - the adaptivity purpose
4409be51f97SToby Isaac 
4419be51f97SToby Isaac   Level: advanced
4429be51f97SToby Isaac 
443db781477SPatrick Sanan .seealso: `DMForestTemplate()`, `DMForestSetAdaptivityForest()`, `DMForestGetAdaptivityForest()`, `DMAdaptFlag`
4449be51f97SToby Isaac @*/
4459371c9d4SSatish Balay PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMAdaptFlag purpose) {
44626d9498aSToby Isaac   DM_Forest *forest;
44726d9498aSToby Isaac 
44826d9498aSToby Isaac   PetscFunctionBegin;
44926d9498aSToby Isaac   forest = (DM_Forest *)dm->data;
45028b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the adaptation forest after setup");
45126d9498aSToby Isaac   if (purpose != forest->adaptPurpose) {
45226d9498aSToby Isaac     DM adapt;
45326d9498aSToby Isaac 
4549566063dSJacob Faibussowitsch     PetscCall(DMForestGetAdaptivityForest(dm, &adapt));
4559566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)adapt));
4569566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm, NULL));
457f885a11aSToby Isaac 
45826d9498aSToby Isaac     forest->adaptPurpose = purpose;
459f885a11aSToby Isaac 
4609566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm, adapt));
4619566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&adapt));
46226d9498aSToby Isaac   }
463dd8e54a2SToby Isaac   PetscFunctionReturn(0);
464dd8e54a2SToby Isaac }
465dd8e54a2SToby Isaac 
46656c0450aSToby Isaac /*@
46756c0450aSToby Isaac   DMForestGetAdaptivityPurpose - Get whether the current DM is being adapted from its source (set with
468bf2d5fbbSStefano Zampini   DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening (DM_ADAPT_COARSEN),
469bf2d5fbbSStefano Zampini   coarsening only the last level (DM_ADAPT_COARSEN_LAST) or undefined (DM_ADAPT_DETERMINE).
470bf2d5fbbSStefano Zampini   This only matters for the purposes of reference counting: during DMDestroy(), cyclic
47156c0450aSToby Isaac   references can be found between DMs only if the cyclic reference is due to a fine/coarse relationship (see
47256c0450aSToby Isaac   DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does not maintain a
47356c0450aSToby Isaac   reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can cause a memory
47456c0450aSToby Isaac   leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
47556c0450aSToby Isaac 
47656c0450aSToby Isaac   Not collective
47756c0450aSToby Isaac 
47856c0450aSToby Isaac   Input Parameter:
47956c0450aSToby Isaac . dm - the forest
48056c0450aSToby Isaac 
48156c0450aSToby Isaac   Output Parameter:
482bf2d5fbbSStefano Zampini . purpose - the adaptivity purpose
48356c0450aSToby Isaac 
48456c0450aSToby Isaac   Level: advanced
48556c0450aSToby Isaac 
486db781477SPatrick Sanan .seealso: `DMForestTemplate()`, `DMForestSetAdaptivityForest()`, `DMForestGetAdaptivityForest()`, `DMAdaptFlag`
48756c0450aSToby Isaac @*/
4889371c9d4SSatish Balay PetscErrorCode DMForestGetAdaptivityPurpose(DM dm, DMAdaptFlag *purpose) {
48956c0450aSToby Isaac   DM_Forest *forest;
49056c0450aSToby Isaac 
49156c0450aSToby Isaac   PetscFunctionBegin;
49256c0450aSToby Isaac   forest   = (DM_Forest *)dm->data;
49356c0450aSToby Isaac   *purpose = forest->adaptPurpose;
49456c0450aSToby Isaac   PetscFunctionReturn(0);
49556c0450aSToby Isaac }
49656c0450aSToby Isaac 
4979be51f97SToby Isaac /*@
4989be51f97SToby Isaac   DMForestSetAdjacencyDimension - During the pre-setup phase, set the dimension of interface points that determine
4999be51f97SToby Isaac   cell adjacency (for the purposes of partitioning and overlap).
5009be51f97SToby Isaac 
5019be51f97SToby Isaac   Logically collective on dm
5029be51f97SToby Isaac 
5039be51f97SToby Isaac   Input Parameters:
5049be51f97SToby Isaac + dm - the forest
5059be51f97SToby Isaac - adjDim - default 0 (i.e., vertices determine adjacency)
5069be51f97SToby Isaac 
5079be51f97SToby Isaac   Level: intermediate
5089be51f97SToby Isaac 
509db781477SPatrick Sanan .seealso: `DMForestGetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()`, `DMForestSetPartitionOverlap()`
5109be51f97SToby Isaac @*/
5119371c9d4SSatish Balay PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim) {
512dd8e54a2SToby Isaac   PetscInt   dim;
513dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
514dd8e54a2SToby Isaac 
515dd8e54a2SToby Isaac   PetscFunctionBegin;
516dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
51728b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the adjacency dimension after setup");
51863a3b9bcSJacob Faibussowitsch   PetscCheck(adjDim >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "adjacency dim cannot be < 0: %" PetscInt_FMT, adjDim);
5199566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
52063a3b9bcSJacob Faibussowitsch   PetscCheck(adjDim <= dim, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "adjacency dim cannot be > %" PetscInt_FMT ": %" PetscInt_FMT, dim, adjDim);
521dd8e54a2SToby Isaac   forest->adjDim = adjDim;
522dd8e54a2SToby Isaac   PetscFunctionReturn(0);
523dd8e54a2SToby Isaac }
524dd8e54a2SToby Isaac 
5259be51f97SToby Isaac /*@
5269be51f97SToby Isaac   DMForestSetAdjacencyCodimension - Like DMForestSetAdjacencyDimension(), but specified as a co-dimension (so that,
5279be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
5289be51f97SToby Isaac 
5299be51f97SToby Isaac   Logically collective on dm
5309be51f97SToby Isaac 
5319be51f97SToby Isaac   Input Parameters:
5329be51f97SToby Isaac + dm - the forest
5339be51f97SToby Isaac - adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
5349be51f97SToby Isaac 
5359be51f97SToby Isaac   Level: intermediate
5369be51f97SToby Isaac 
537db781477SPatrick Sanan .seealso: `DMForestGetAdjacencyCodimension()`, `DMForestSetAdjacencyDimension()`
5389be51f97SToby Isaac @*/
5399371c9d4SSatish Balay PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim) {
540dd8e54a2SToby Isaac   PetscInt dim;
541dd8e54a2SToby Isaac 
542dd8e54a2SToby Isaac   PetscFunctionBegin;
543dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5449566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
5459566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdjacencyDimension(dm, dim - adjCodim));
546dd8e54a2SToby Isaac   PetscFunctionReturn(0);
547dd8e54a2SToby Isaac }
548dd8e54a2SToby Isaac 
5499be51f97SToby Isaac /*@
5509be51f97SToby Isaac   DMForestGetAdjacencyDimension - Get the dimension of interface points that determine cell adjacency (for the
5519be51f97SToby Isaac   purposes of partitioning and overlap).
5529be51f97SToby Isaac 
5539be51f97SToby Isaac   Not collective
5549be51f97SToby Isaac 
5559be51f97SToby Isaac   Input Parameter:
5569be51f97SToby Isaac . dm - the forest
5579be51f97SToby Isaac 
5589be51f97SToby Isaac   Output Parameter:
5599be51f97SToby Isaac . adjDim - default 0 (i.e., vertices determine adjacency)
5609be51f97SToby Isaac 
5619be51f97SToby Isaac   Level: intermediate
5629be51f97SToby Isaac 
563db781477SPatrick Sanan .seealso: `DMForestSetAdjacencyDimension()`, `DMForestGetAdjacencyCodimension()`, `DMForestSetPartitionOverlap()`
5649be51f97SToby Isaac @*/
5659371c9d4SSatish Balay PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim) {
566dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
567dd8e54a2SToby Isaac 
568dd8e54a2SToby Isaac   PetscFunctionBegin;
569dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
570dd8e54a2SToby Isaac   PetscValidIntPointer(adjDim, 2);
571dd8e54a2SToby Isaac   *adjDim = forest->adjDim;
572dd8e54a2SToby Isaac   PetscFunctionReturn(0);
573dd8e54a2SToby Isaac }
574dd8e54a2SToby Isaac 
5759be51f97SToby Isaac /*@
5769be51f97SToby Isaac   DMForestGetAdjacencyCodimension - Like DMForestGetAdjacencyDimension(), but specified as a co-dimension (so that,
5779be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
5789be51f97SToby Isaac 
5799be51f97SToby Isaac   Not collective
5809be51f97SToby Isaac 
5819be51f97SToby Isaac   Input Parameter:
5829be51f97SToby Isaac . dm - the forest
5839be51f97SToby Isaac 
5849be51f97SToby Isaac   Output Parameter:
5859be51f97SToby Isaac . adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
5869be51f97SToby Isaac 
5879be51f97SToby Isaac   Level: intermediate
5889be51f97SToby Isaac 
589db781477SPatrick Sanan .seealso: `DMForestSetAdjacencyCodimension()`, `DMForestGetAdjacencyDimension()`
5909be51f97SToby Isaac @*/
5919371c9d4SSatish Balay PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim) {
592dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
593dd8e54a2SToby Isaac   PetscInt   dim;
594dd8e54a2SToby Isaac 
595dd8e54a2SToby Isaac   PetscFunctionBegin;
596dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
597dd8e54a2SToby Isaac   PetscValidIntPointer(adjCodim, 2);
5989566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
599dd8e54a2SToby Isaac   *adjCodim = dim - forest->adjDim;
600dd8e54a2SToby Isaac   PetscFunctionReturn(0);
601dd8e54a2SToby Isaac }
602dd8e54a2SToby Isaac 
6039be51f97SToby Isaac /*@
6049be51f97SToby Isaac   DMForestSetPartitionOverlap - During the pre-setup phase, set the amount of cell-overlap present in parallel
6059be51f97SToby Isaac   partitions of a forest, with values > 0 indicating subdomains that are expanded by that many iterations of adding
6069be51f97SToby Isaac   adjacent cells
6079be51f97SToby Isaac 
6089be51f97SToby Isaac   Logically collective on dm
6099be51f97SToby Isaac 
6109be51f97SToby Isaac   Input Parameters:
6119be51f97SToby Isaac + dm - the forest
6129be51f97SToby Isaac - overlap - default 0
6139be51f97SToby Isaac 
6149be51f97SToby Isaac   Level: intermediate
6159be51f97SToby Isaac 
616db781477SPatrick Sanan .seealso: `DMForestGetPartitionOverlap()`, `DMForestSetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()`
6179be51f97SToby Isaac @*/
6189371c9d4SSatish Balay PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap) {
619dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
620dd8e54a2SToby Isaac 
621dd8e54a2SToby Isaac   PetscFunctionBegin;
622dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
62328b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the overlap after setup");
62463a3b9bcSJacob Faibussowitsch   PetscCheck(overlap >= 0, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "overlap cannot be < 0: %" PetscInt_FMT, overlap);
625dd8e54a2SToby Isaac   forest->overlap = overlap;
626dd8e54a2SToby Isaac   PetscFunctionReturn(0);
627dd8e54a2SToby Isaac }
628dd8e54a2SToby Isaac 
6299be51f97SToby Isaac /*@
6309be51f97SToby Isaac   DMForestGetPartitionOverlap - Get the amount of cell-overlap present in parallel partitions of a forest, with values
6319be51f97SToby Isaac   > 0 indicating subdomains that are expanded by that many iterations of adding adjacent cells
6329be51f97SToby Isaac 
6339be51f97SToby Isaac   Not collective
6349be51f97SToby Isaac 
6359be51f97SToby Isaac   Input Parameter:
6369be51f97SToby Isaac . dm - the forest
6379be51f97SToby Isaac 
6389be51f97SToby Isaac   Output Parameter:
6399be51f97SToby Isaac . overlap - default 0
6409be51f97SToby Isaac 
6419be51f97SToby Isaac   Level: intermediate
6429be51f97SToby Isaac 
643db781477SPatrick Sanan .seealso: `DMForestGetPartitionOverlap()`, `DMForestSetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()`
6449be51f97SToby Isaac @*/
6459371c9d4SSatish Balay PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap) {
646dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
647dd8e54a2SToby Isaac 
648dd8e54a2SToby Isaac   PetscFunctionBegin;
649dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
650dd8e54a2SToby Isaac   PetscValidIntPointer(overlap, 2);
651dd8e54a2SToby Isaac   *overlap = forest->overlap;
652dd8e54a2SToby Isaac   PetscFunctionReturn(0);
653dd8e54a2SToby Isaac }
654dd8e54a2SToby Isaac 
6559be51f97SToby Isaac /*@
6569be51f97SToby Isaac   DMForestSetMinimumRefinement - During the pre-setup phase, set the minimum level of refinement (relative to the base
6579be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest
6589be51f97SToby Isaac   (see DMForestGetAdaptivityForest()) this limits the amount of coarsening.
6599be51f97SToby Isaac 
6609be51f97SToby Isaac   Logically collective on dm
6619be51f97SToby Isaac 
6629be51f97SToby Isaac   Input Parameters:
6639be51f97SToby Isaac + dm - the forest
6649be51f97SToby Isaac - minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
6659be51f97SToby Isaac 
6669be51f97SToby Isaac   Level: intermediate
6679be51f97SToby Isaac 
668db781477SPatrick Sanan .seealso: `DMForestGetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestSetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()`
6699be51f97SToby Isaac @*/
6709371c9d4SSatish Balay PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement) {
671dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
672dd8e54a2SToby Isaac 
673dd8e54a2SToby Isaac   PetscFunctionBegin;
674dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
67528b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the minimum refinement after setup");
676dd8e54a2SToby Isaac   forest->minRefinement = minRefinement;
677dd8e54a2SToby Isaac   PetscFunctionReturn(0);
678dd8e54a2SToby Isaac }
679dd8e54a2SToby Isaac 
6809be51f97SToby Isaac /*@
6819be51f97SToby Isaac   DMForestGetMinimumRefinement - Get the minimum level of refinement (relative to the base DM, see
6829be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest (see
6839be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of coarsening.
6849be51f97SToby Isaac 
6859be51f97SToby Isaac   Not collective
6869be51f97SToby Isaac 
6879be51f97SToby Isaac   Input Parameter:
6889be51f97SToby Isaac . dm - the forest
6899be51f97SToby Isaac 
6909be51f97SToby Isaac   Output Parameter:
6919be51f97SToby Isaac . minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
6929be51f97SToby Isaac 
6939be51f97SToby Isaac   Level: intermediate
6949be51f97SToby Isaac 
695db781477SPatrick Sanan .seealso: `DMForestSetMinimumRefinement()`, `DMForestGetMaximumRefinement()`, `DMForestGetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()`
6969be51f97SToby Isaac @*/
6979371c9d4SSatish Balay PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement) {
698dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
699dd8e54a2SToby Isaac 
700dd8e54a2SToby Isaac   PetscFunctionBegin;
701dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
702dd8e54a2SToby Isaac   PetscValidIntPointer(minRefinement, 2);
703dd8e54a2SToby Isaac   *minRefinement = forest->minRefinement;
704dd8e54a2SToby Isaac   PetscFunctionReturn(0);
705dd8e54a2SToby Isaac }
706dd8e54a2SToby Isaac 
7079be51f97SToby Isaac /*@
7089be51f97SToby Isaac   DMForestSetInitialRefinement - During the pre-setup phase, set the initial level of refinement (relative to the base
7099be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.
7109be51f97SToby Isaac 
7119be51f97SToby Isaac   Logically collective on dm
7129be51f97SToby Isaac 
7139be51f97SToby Isaac   Input Parameters:
7149be51f97SToby Isaac + dm - the forest
7159be51f97SToby Isaac - initefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7169be51f97SToby Isaac 
7179be51f97SToby Isaac   Level: intermediate
7189be51f97SToby Isaac 
719db781477SPatrick Sanan .seealso: `DMForestSetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestGetBaseDM()`
7209be51f97SToby Isaac @*/
7219371c9d4SSatish Balay PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement) {
72256ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
72356ba9f64SToby Isaac 
72456ba9f64SToby Isaac   PetscFunctionBegin;
72556ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
72628b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the initial refinement after setup");
72756ba9f64SToby Isaac   forest->initRefinement = initRefinement;
72856ba9f64SToby Isaac   PetscFunctionReturn(0);
72956ba9f64SToby Isaac }
73056ba9f64SToby Isaac 
7319be51f97SToby Isaac /*@
7329be51f97SToby Isaac   DMForestGetInitialRefinement - Get the initial level of refinement (relative to the base DM, see
7339be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.
7349be51f97SToby Isaac 
7359be51f97SToby Isaac   Not collective
7369be51f97SToby Isaac 
7379be51f97SToby Isaac   Input Parameter:
7389be51f97SToby Isaac . dm - the forest
7399be51f97SToby Isaac 
74001d2d390SJose E. Roman   Output Parameter:
741bf2d5fbbSStefano Zampini . initRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7429be51f97SToby Isaac 
7439be51f97SToby Isaac   Level: intermediate
7449be51f97SToby Isaac 
745db781477SPatrick Sanan .seealso: `DMForestSetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestGetBaseDM()`
7469be51f97SToby Isaac @*/
7479371c9d4SSatish Balay PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement) {
74856ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
74956ba9f64SToby Isaac 
75056ba9f64SToby Isaac   PetscFunctionBegin;
75156ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
75256ba9f64SToby Isaac   PetscValidIntPointer(initRefinement, 2);
75356ba9f64SToby Isaac   *initRefinement = forest->initRefinement;
75456ba9f64SToby Isaac   PetscFunctionReturn(0);
75556ba9f64SToby Isaac }
75656ba9f64SToby Isaac 
7579be51f97SToby Isaac /*@
7589be51f97SToby Isaac   DMForestSetMaximumRefinement - During the pre-setup phase, set the maximum level of refinement (relative to the base
7599be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest
7609be51f97SToby Isaac   (see DMForestGetAdaptivityForest()), this limits the amount of refinement.
7619be51f97SToby Isaac 
7629be51f97SToby Isaac   Logically collective on dm
7639be51f97SToby Isaac 
7649be51f97SToby Isaac   Input Parameters:
7659be51f97SToby Isaac + dm - the forest
7669be51f97SToby Isaac - maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7679be51f97SToby Isaac 
7689be51f97SToby Isaac   Level: intermediate
7699be51f97SToby Isaac 
770db781477SPatrick Sanan .seealso: `DMForestGetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestSetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityDM()`
7719be51f97SToby Isaac @*/
7729371c9d4SSatish Balay PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement) {
773dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
774dd8e54a2SToby Isaac 
775dd8e54a2SToby Isaac   PetscFunctionBegin;
776dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77728b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the maximum refinement after setup");
778c7eeac06SToby Isaac   forest->maxRefinement = maxRefinement;
779dd8e54a2SToby Isaac   PetscFunctionReturn(0);
780dd8e54a2SToby Isaac }
781dd8e54a2SToby Isaac 
7829be51f97SToby Isaac /*@
7839be51f97SToby Isaac   DMForestGetMaximumRefinement - Get the maximum level of refinement (relative to the base DM, see
7849be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest (see
7859be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of refinement.
7869be51f97SToby Isaac 
7879be51f97SToby Isaac   Not collective
7889be51f97SToby Isaac 
7899be51f97SToby Isaac   Input Parameter:
7909be51f97SToby Isaac . dm - the forest
7919be51f97SToby Isaac 
7929be51f97SToby Isaac   Output Parameter:
7939be51f97SToby Isaac . maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7949be51f97SToby Isaac 
7959be51f97SToby Isaac   Level: intermediate
7969be51f97SToby Isaac 
797db781477SPatrick Sanan .seealso: `DMForestSetMaximumRefinement()`, `DMForestGetMinimumRefinement()`, `DMForestGetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()`
7989be51f97SToby Isaac @*/
7999371c9d4SSatish Balay PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement) {
800dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
801dd8e54a2SToby Isaac 
802dd8e54a2SToby Isaac   PetscFunctionBegin;
803dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
804c7eeac06SToby Isaac   PetscValidIntPointer(maxRefinement, 2);
805c7eeac06SToby Isaac   *maxRefinement = forest->maxRefinement;
806dd8e54a2SToby Isaac   PetscFunctionReturn(0);
807dd8e54a2SToby Isaac }
808c7eeac06SToby Isaac 
8099be51f97SToby Isaac /*@C
8109be51f97SToby Isaac   DMForestSetAdaptivityStrategy - During the pre-setup phase, set the strategy for combining adaptivity labels from multiple processes.
8119be51f97SToby Isaac   Subtypes of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all processes must agree
8129be51f97SToby Isaac   for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only one process needs to
8139be51f97SToby Isaac   specify refinement/coarsening.
8149be51f97SToby Isaac 
8159be51f97SToby Isaac   Logically collective on dm
8169be51f97SToby Isaac 
8179be51f97SToby Isaac   Input Parameters:
8189be51f97SToby Isaac + dm - the forest
8199be51f97SToby Isaac - adaptStrategy - default DMFORESTADAPTALL
8209be51f97SToby Isaac 
8219be51f97SToby Isaac   Level: advanced
8229be51f97SToby Isaac 
823db781477SPatrick Sanan .seealso: `DMForestGetAdaptivityStrategy()`
8249be51f97SToby Isaac @*/
8259371c9d4SSatish Balay PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy) {
826c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
827c7eeac06SToby Isaac 
828c7eeac06SToby Isaac   PetscFunctionBegin;
829c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8309566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->adaptStrategy));
8319566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy((const char *)adaptStrategy, (char **)&forest->adaptStrategy));
832c7eeac06SToby Isaac   PetscFunctionReturn(0);
833c7eeac06SToby Isaac }
834c7eeac06SToby Isaac 
8359be51f97SToby Isaac /*@C
8369be51f97SToby Isaac   DMForestSetAdaptivityStrategy - Get the strategy for combining adaptivity labels from multiple processes.  Subtypes
8379be51f97SToby Isaac   of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all
8389be51f97SToby Isaac   processes must agree for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only
8399be51f97SToby Isaac   one process needs to specify refinement/coarsening.
8409be51f97SToby Isaac 
8419be51f97SToby Isaac   Not collective
8429be51f97SToby Isaac 
8439be51f97SToby Isaac   Input Parameter:
8449be51f97SToby Isaac . dm - the forest
8459be51f97SToby Isaac 
8469be51f97SToby Isaac   Output Parameter:
8479be51f97SToby Isaac . adaptStrategy - the adaptivity strategy (default DMFORESTADAPTALL)
8489be51f97SToby Isaac 
8499be51f97SToby Isaac   Level: advanced
8509be51f97SToby Isaac 
851db781477SPatrick Sanan .seealso: `DMForestSetAdaptivityStrategy()`
8529be51f97SToby Isaac @*/
8539371c9d4SSatish Balay PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy) {
854c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
855c7eeac06SToby Isaac 
856c7eeac06SToby Isaac   PetscFunctionBegin;
857c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
858c7eeac06SToby Isaac   PetscValidPointer(adaptStrategy, 2);
859c7eeac06SToby Isaac   *adaptStrategy = forest->adaptStrategy;
860c7eeac06SToby Isaac   PetscFunctionReturn(0);
861c7eeac06SToby Isaac }
862c7eeac06SToby Isaac 
8632a133e43SToby Isaac /*@
8642a133e43SToby Isaac   DMForestGetAdaptivitySuccess - Return whether the requested adaptation (refinement, coarsening, repartitioning,
8652a133e43SToby Isaac   etc.) was successful.  PETSC_FALSE indicates that the post-adaptation forest is the same as the pre-adpatation
8662a133e43SToby Isaac   forest.  A requested adaptation may have been unsuccessful if, for example, the requested refinement would have
8672a133e43SToby Isaac   exceeded the maximum refinement level.
8682a133e43SToby Isaac 
8692a133e43SToby Isaac   Collective on dm
8702a133e43SToby Isaac 
8712a133e43SToby Isaac   Input Parameter:
8722a133e43SToby Isaac 
8732a133e43SToby Isaac . dm - the post-adaptation forest
8742a133e43SToby Isaac 
8752a133e43SToby Isaac   Output Parameter:
8762a133e43SToby Isaac 
8772a133e43SToby Isaac . success - PETSC_TRUE if the post-adaptation forest is different from the pre-adaptation forest.
8782a133e43SToby Isaac 
8792a133e43SToby Isaac   Level: intermediate
8802a133e43SToby Isaac 
8812a133e43SToby Isaac .see
8822a133e43SToby Isaac @*/
8839371c9d4SSatish Balay PetscErrorCode DMForestGetAdaptivitySuccess(DM dm, PetscBool *success) {
8842a133e43SToby Isaac   DM_Forest *forest;
8852a133e43SToby Isaac 
8862a133e43SToby Isaac   PetscFunctionBegin;
8872a133e43SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
88828b400f6SJacob Faibussowitsch   PetscCheck(dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DMSetUp() has not been called yet.");
8892a133e43SToby Isaac   forest = (DM_Forest *)dm->data;
8909566063dSJacob Faibussowitsch   PetscCall((forest->getadaptivitysuccess)(dm, success));
8912a133e43SToby Isaac   PetscFunctionReturn(0);
8922a133e43SToby Isaac }
8932a133e43SToby Isaac 
894bf9b5d84SToby Isaac /*@
895bf9b5d84SToby Isaac   DMForestSetComputeAdaptivitySF - During the pre-setup phase, set whether transfer PetscSFs should be computed
896bf9b5d84SToby Isaac   relating the cells of the pre-adaptation forest to the post-adaptiation forest.  After DMSetUp() is called, these transfer PetscSFs can be accessed with DMForestGetAdaptivitySF().
897bf9b5d84SToby Isaac 
898bf9b5d84SToby Isaac   Logically collective on dm
899bf9b5d84SToby Isaac 
900bf9b5d84SToby Isaac   Input Parameters:
901bf9b5d84SToby Isaac + dm - the post-adaptation forest
902bf9b5d84SToby Isaac - computeSF - default PETSC_TRUE
903bf9b5d84SToby Isaac 
904bf9b5d84SToby Isaac   Level: advanced
905bf9b5d84SToby Isaac 
906db781477SPatrick Sanan .seealso: `DMForestGetComputeAdaptivitySF()`, `DMForestGetAdaptivitySF()`
907bf9b5d84SToby Isaac @*/
9089371c9d4SSatish Balay PetscErrorCode DMForestSetComputeAdaptivitySF(DM dm, PetscBool computeSF) {
909bf9b5d84SToby Isaac   DM_Forest *forest;
910bf9b5d84SToby Isaac 
911bf9b5d84SToby Isaac   PetscFunctionBegin;
912bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
91328b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot compute adaptivity PetscSFs after setup is called");
914bf9b5d84SToby Isaac   forest                 = (DM_Forest *)dm->data;
915bf9b5d84SToby Isaac   forest->computeAdaptSF = computeSF;
916bf9b5d84SToby Isaac   PetscFunctionReturn(0);
917bf9b5d84SToby Isaac }
918bf9b5d84SToby Isaac 
9199371c9d4SSatish Balay PetscErrorCode DMForestTransferVec(DM dmIn, Vec vecIn, DM dmOut, Vec vecOut, PetscBool useBCs, PetscReal time) {
92080b27e07SToby Isaac   DM_Forest *forest;
92180b27e07SToby Isaac 
92280b27e07SToby Isaac   PetscFunctionBegin;
92380b27e07SToby Isaac   PetscValidHeaderSpecific(dmIn, DM_CLASSID, 1);
92480b27e07SToby Isaac   PetscValidHeaderSpecific(vecIn, VEC_CLASSID, 2);
92580b27e07SToby Isaac   PetscValidHeaderSpecific(dmOut, DM_CLASSID, 3);
92680b27e07SToby Isaac   PetscValidHeaderSpecific(vecOut, VEC_CLASSID, 4);
92780b27e07SToby Isaac   forest = (DM_Forest *)dmIn->data;
92828b400f6SJacob Faibussowitsch   PetscCheck(forest->transfervec, PetscObjectComm((PetscObject)dmIn), PETSC_ERR_SUP, "DMForestTransferVec() not implemented");
9299566063dSJacob Faibussowitsch   PetscCall((forest->transfervec)(dmIn, vecIn, dmOut, vecOut, useBCs, time));
93080b27e07SToby Isaac   PetscFunctionReturn(0);
93180b27e07SToby Isaac }
93280b27e07SToby Isaac 
9339371c9d4SSatish Balay PetscErrorCode DMForestTransferVecFromBase(DM dm, Vec vecIn, Vec vecOut) {
934ac34a06fSStefano Zampini   DM_Forest *forest;
935ac34a06fSStefano Zampini 
936ac34a06fSStefano Zampini   PetscFunctionBegin;
937ac34a06fSStefano Zampini   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
938ac34a06fSStefano Zampini   PetscValidHeaderSpecific(vecIn, VEC_CLASSID, 2);
939ac34a06fSStefano Zampini   PetscValidHeaderSpecific(vecOut, VEC_CLASSID, 3);
940ac34a06fSStefano Zampini   forest = (DM_Forest *)dm->data;
94128b400f6SJacob Faibussowitsch   PetscCheck(forest->transfervecfrombase, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "DMForestTransferVecFromBase() not implemented");
9429566063dSJacob Faibussowitsch   PetscCall((forest->transfervecfrombase)(dm, vecIn, vecOut));
943ac34a06fSStefano Zampini   PetscFunctionReturn(0);
944ac34a06fSStefano Zampini }
945ac34a06fSStefano Zampini 
946bf9b5d84SToby Isaac /*@
947bf9b5d84SToby Isaac   DMForestGetComputeAdaptivitySF - Get whether transfer PetscSFs should be computed relating the cells of the
948bf9b5d84SToby Isaac   pre-adaptation forest to the post-adaptiation forest.  After DMSetUp() is called, these transfer PetscSFs can be
949bf9b5d84SToby Isaac   accessed with DMForestGetAdaptivitySF().
950bf9b5d84SToby Isaac 
951bf9b5d84SToby Isaac   Not collective
952bf9b5d84SToby Isaac 
953bf9b5d84SToby Isaac   Input Parameter:
954bf9b5d84SToby Isaac . dm - the post-adaptation forest
955bf9b5d84SToby Isaac 
956bf9b5d84SToby Isaac   Output Parameter:
957bf9b5d84SToby Isaac . computeSF - default PETSC_TRUE
958bf9b5d84SToby Isaac 
959bf9b5d84SToby Isaac   Level: advanced
960bf9b5d84SToby Isaac 
961db781477SPatrick Sanan .seealso: `DMForestSetComputeAdaptivitySF()`, `DMForestGetAdaptivitySF()`
962bf9b5d84SToby Isaac @*/
9639371c9d4SSatish Balay PetscErrorCode DMForestGetComputeAdaptivitySF(DM dm, PetscBool *computeSF) {
964bf9b5d84SToby Isaac   DM_Forest *forest;
965bf9b5d84SToby Isaac 
966bf9b5d84SToby Isaac   PetscFunctionBegin;
967bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
968bf9b5d84SToby Isaac   forest     = (DM_Forest *)dm->data;
969bf9b5d84SToby Isaac   *computeSF = forest->computeAdaptSF;
970bf9b5d84SToby Isaac   PetscFunctionReturn(0);
971bf9b5d84SToby Isaac }
972bf9b5d84SToby Isaac 
973bf9b5d84SToby Isaac /*@
974bf9b5d84SToby Isaac   DMForestGetAdaptivitySF - Get PetscSFs that relate the pre-adaptation forest to the post-adaptation forest.
975bf9b5d84SToby Isaac   Adaptation can be any combination of refinement, coarsening, repartition, and change of overlap, so there may be
976bf9b5d84SToby Isaac   some cells of the pre-adaptation that are parents of post-adaptation cells, and vice versa.  Therefore there are two
977bf9b5d84SToby Isaac   PetscSFs: one that relates pre-adaptation coarse cells to post-adaptation fine cells, and one that relates
978bf9b5d84SToby Isaac   pre-adaptation fine cells to post-adaptation coarse cells.
979bf9b5d84SToby Isaac 
980bf9b5d84SToby Isaac   Not collective
981bf9b5d84SToby Isaac 
982bf9b5d84SToby Isaac   Input Parameter:
983bf9b5d84SToby Isaac   dm - the post-adaptation forest
984bf9b5d84SToby Isaac 
985bf9b5d84SToby Isaac   Output Parameter:
9860f17b9e3SToby Isaac   preCoarseToFine - pre-adaptation coarse cells to post-adaptation fine cells: BCast goes from pre- to post-
9870f17b9e3SToby Isaac   coarseToPreFine - post-adaptation coarse cells to pre-adaptation fine cells: BCast goes from post- to pre-
988bf9b5d84SToby Isaac 
989bf9b5d84SToby Isaac   Level: advanced
990bf9b5d84SToby Isaac 
991db781477SPatrick Sanan .seealso: `DMForestGetComputeAdaptivitySF()`, `DMForestSetComputeAdaptivitySF()`
992bf9b5d84SToby Isaac @*/
9939371c9d4SSatish Balay PetscErrorCode DMForestGetAdaptivitySF(DM dm, PetscSF *preCoarseToFine, PetscSF *coarseToPreFine) {
994bf9b5d84SToby Isaac   DM_Forest *forest;
995bf9b5d84SToby Isaac 
996bf9b5d84SToby Isaac   PetscFunctionBegin;
997bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9989566063dSJacob Faibussowitsch   PetscCall(DMSetUp(dm));
999bf9b5d84SToby Isaac   forest = (DM_Forest *)dm->data;
1000f885a11aSToby Isaac   if (preCoarseToFine) *preCoarseToFine = forest->preCoarseToFine;
1001f885a11aSToby Isaac   if (coarseToPreFine) *coarseToPreFine = forest->coarseToPreFine;
1002bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1003bf9b5d84SToby Isaac }
1004bf9b5d84SToby Isaac 
10059be51f97SToby Isaac /*@
10069be51f97SToby Isaac   DMForestSetGradeFactor - During the pre-setup phase, set the desired amount of grading in the mesh, e.g. give 2 to
10079be51f97SToby Isaac   indicate that the diameter of neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may
10089be51f97SToby Isaac   only support one particular choice of grading factor.
10099be51f97SToby Isaac 
10109be51f97SToby Isaac   Logically collective on dm
10119be51f97SToby Isaac 
10129be51f97SToby Isaac   Input Parameters:
10139be51f97SToby Isaac + dm - the forest
10149be51f97SToby Isaac - grade - the grading factor
10159be51f97SToby Isaac 
10169be51f97SToby Isaac   Level: advanced
10179be51f97SToby Isaac 
1018db781477SPatrick Sanan .seealso: `DMForestGetGradeFactor()`
10199be51f97SToby Isaac @*/
10209371c9d4SSatish Balay PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade) {
1021c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1022c7eeac06SToby Isaac 
1023c7eeac06SToby Isaac   PetscFunctionBegin;
1024c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
102528b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the grade factor after setup");
1026c7eeac06SToby Isaac   forest->gradeFactor = grade;
1027c7eeac06SToby Isaac   PetscFunctionReturn(0);
1028c7eeac06SToby Isaac }
1029c7eeac06SToby Isaac 
10309be51f97SToby Isaac /*@
10319be51f97SToby Isaac   DMForestGetGradeFactor - Get the desired amount of grading in the mesh, e.g. give 2 to indicate that the diameter of
10329be51f97SToby Isaac   neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may only support one particular
10339be51f97SToby Isaac   choice of grading factor.
10349be51f97SToby Isaac 
10359be51f97SToby Isaac   Not collective
10369be51f97SToby Isaac 
10379be51f97SToby Isaac   Input Parameter:
10389be51f97SToby Isaac . dm - the forest
10399be51f97SToby Isaac 
10409be51f97SToby Isaac   Output Parameter:
10419be51f97SToby Isaac . grade - the grading factor
10429be51f97SToby Isaac 
10439be51f97SToby Isaac   Level: advanced
10449be51f97SToby Isaac 
1045db781477SPatrick Sanan .seealso: `DMForestSetGradeFactor()`
10469be51f97SToby Isaac @*/
10479371c9d4SSatish Balay PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade) {
1048c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1049c7eeac06SToby Isaac 
1050c7eeac06SToby Isaac   PetscFunctionBegin;
1051c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1052c7eeac06SToby Isaac   PetscValidIntPointer(grade, 2);
1053c7eeac06SToby Isaac   *grade = forest->gradeFactor;
1054c7eeac06SToby Isaac   PetscFunctionReturn(0);
1055c7eeac06SToby Isaac }
1056c7eeac06SToby Isaac 
10579be51f97SToby Isaac /*@
10589be51f97SToby Isaac   DMForestSetCellWeightFactor - During the pre-setup phase, set the factor by which the level of refinement changes
10599be51f97SToby Isaac   the cell weight (see DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be
10609be51f97SToby Isaac   (cellWeight) * (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on
10619be51f97SToby Isaac   its level; a factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the
10629be51f97SToby Isaac   computation associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
10639be51f97SToby Isaac 
10649be51f97SToby Isaac   Logically collective on dm
10659be51f97SToby Isaac 
10669be51f97SToby Isaac   Input Parameters:
10679be51f97SToby Isaac + dm - the forest
10689be51f97SToby Isaac - weightsFactors - default 1.
10699be51f97SToby Isaac 
10709be51f97SToby Isaac   Level: advanced
10719be51f97SToby Isaac 
1072db781477SPatrick Sanan .seealso: `DMForestGetCellWeightFactor()`, `DMForestSetCellWeights()`
10739be51f97SToby Isaac @*/
10749371c9d4SSatish Balay PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor) {
1075c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1076c7eeac06SToby Isaac 
1077c7eeac06SToby Isaac   PetscFunctionBegin;
1078c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
107928b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the weights factor after setup");
1080c7eeac06SToby Isaac   forest->weightsFactor = weightsFactor;
1081c7eeac06SToby Isaac   PetscFunctionReturn(0);
1082c7eeac06SToby Isaac }
1083c7eeac06SToby Isaac 
10849be51f97SToby Isaac /*@
10859be51f97SToby Isaac   DMForestGetCellWeightFactor - Get the factor by which the level of refinement changes the cell weight (see
10869be51f97SToby Isaac   DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be (cellWeight) *
10879be51f97SToby Isaac   (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on its level; a
10889be51f97SToby Isaac   factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the computation
10899be51f97SToby Isaac   associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
10909be51f97SToby Isaac 
10919be51f97SToby Isaac   Not collective
10929be51f97SToby Isaac 
10939be51f97SToby Isaac   Input Parameter:
10949be51f97SToby Isaac . dm - the forest
10959be51f97SToby Isaac 
10969be51f97SToby Isaac   Output Parameter:
10979be51f97SToby Isaac . weightsFactors - default 1.
10989be51f97SToby Isaac 
10999be51f97SToby Isaac   Level: advanced
11009be51f97SToby Isaac 
1101db781477SPatrick Sanan .seealso: `DMForestSetCellWeightFactor()`, `DMForestSetCellWeights()`
11029be51f97SToby Isaac @*/
11039371c9d4SSatish Balay PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor) {
1104c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1105c7eeac06SToby Isaac 
1106c7eeac06SToby Isaac   PetscFunctionBegin;
1107c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1108c7eeac06SToby Isaac   PetscValidRealPointer(weightsFactor, 2);
1109c7eeac06SToby Isaac   *weightsFactor = forest->weightsFactor;
1110c7eeac06SToby Isaac   PetscFunctionReturn(0);
1111c7eeac06SToby Isaac }
1112c7eeac06SToby Isaac 
11139be51f97SToby Isaac /*@
11149be51f97SToby Isaac   DMForestGetCellChart - After the setup phase, get the local half-open interval of the chart of cells on this process
11159be51f97SToby Isaac 
11169be51f97SToby Isaac   Not collective
11179be51f97SToby Isaac 
11189be51f97SToby Isaac   Input Parameter:
11199be51f97SToby Isaac . dm - the forest
11209be51f97SToby Isaac 
11219be51f97SToby Isaac   Output Parameters:
11229be51f97SToby Isaac + cStart - the first cell on this process
11239be51f97SToby Isaac - cEnd - one after the final cell on this process
11249be51f97SToby Isaac 
11251a244344SSatish Balay   Level: intermediate
11269be51f97SToby Isaac 
1127db781477SPatrick Sanan .seealso: `DMForestGetCellSF()`
11289be51f97SToby Isaac @*/
11299371c9d4SSatish Balay PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd) {
1130c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1131c7eeac06SToby Isaac 
1132c7eeac06SToby Isaac   PetscFunctionBegin;
1133c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1134c7eeac06SToby Isaac   PetscValidIntPointer(cStart, 2);
1135064a246eSJacob Faibussowitsch   PetscValidIntPointer(cEnd, 3);
113648a46eb9SPierre Jolivet   if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) PetscCall(forest->createcellchart(dm, &forest->cStart, &forest->cEnd));
1137c7eeac06SToby Isaac   *cStart = forest->cStart;
1138c7eeac06SToby Isaac   *cEnd   = forest->cEnd;
1139c7eeac06SToby Isaac   PetscFunctionReturn(0);
1140c7eeac06SToby Isaac }
1141c7eeac06SToby Isaac 
11429be51f97SToby Isaac /*@
11439be51f97SToby Isaac   DMForestGetCellSF - After the setup phase, get the PetscSF for overlapping cells between processes
11449be51f97SToby Isaac 
11459be51f97SToby Isaac   Not collective
11469be51f97SToby Isaac 
11479be51f97SToby Isaac   Input Parameter:
11489be51f97SToby Isaac . dm - the forest
11499be51f97SToby Isaac 
11509be51f97SToby Isaac   Output Parameter:
11519be51f97SToby Isaac . cellSF - the PetscSF
11529be51f97SToby Isaac 
11531a244344SSatish Balay   Level: intermediate
11549be51f97SToby Isaac 
1155db781477SPatrick Sanan .seealso: `DMForestGetCellChart()`
11569be51f97SToby Isaac @*/
11579371c9d4SSatish Balay PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF) {
1158c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1159c7eeac06SToby Isaac 
1160c7eeac06SToby Isaac   PetscFunctionBegin;
1161c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1162c7eeac06SToby Isaac   PetscValidPointer(cellSF, 2);
116348a46eb9SPierre Jolivet   if ((!forest->cellSF) && forest->createcellsf) PetscCall(forest->createcellsf(dm, &forest->cellSF));
1164c7eeac06SToby Isaac   *cellSF = forest->cellSF;
1165c7eeac06SToby Isaac   PetscFunctionReturn(0);
1166c7eeac06SToby Isaac }
1167c7eeac06SToby Isaac 
11689be51f97SToby Isaac /*@C
11699be51f97SToby Isaac   DMForestSetAdaptivityLabel - During the pre-setup phase, set the label of the pre-adaptation forest (see
11709be51f97SToby Isaac   DMForestGetAdaptivityForest()) that holds the adaptation flags (refinement, coarsening, or some combination).  The
1171cd3c525cSToby Isaac   interpretation of the label values is up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP,
1172cd3c525cSToby Isaac   DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have been reserved as choices that should be accepted by all subtypes.
11739be51f97SToby Isaac 
11749be51f97SToby Isaac   Logically collective on dm
11759be51f97SToby Isaac 
11769be51f97SToby Isaac   Input Parameters:
11779be51f97SToby Isaac - dm - the forest
1178a1b0c543SToby Isaac + adaptLabel - the label in the pre-adaptation forest
11799be51f97SToby Isaac 
11809be51f97SToby Isaac   Level: intermediate
11819be51f97SToby Isaac 
1182db781477SPatrick Sanan .seealso `DMForestGetAdaptivityLabel()`
11839be51f97SToby Isaac @*/
11849371c9d4SSatish Balay PetscErrorCode DMForestSetAdaptivityLabel(DM dm, DMLabel adaptLabel) {
1185c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1186c7eeac06SToby Isaac 
1187c7eeac06SToby Isaac   PetscFunctionBegin;
1188c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
11891fd50544SStefano Zampini   if (adaptLabel) PetscValidHeaderSpecific(adaptLabel, DMLABEL_CLASSID, 2);
11909566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)adaptLabel));
11919566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&forest->adaptLabel));
11921fd50544SStefano Zampini   forest->adaptLabel = adaptLabel;
1193c7eeac06SToby Isaac   PetscFunctionReturn(0);
1194c7eeac06SToby Isaac }
1195c7eeac06SToby Isaac 
11969be51f97SToby Isaac /*@C
11979be51f97SToby Isaac   DMForestGetAdaptivityLabel - Get the label of the pre-adaptation forest (see DMForestGetAdaptivityForest()) that
11989be51f97SToby Isaac   holds the adaptation flags (refinement, coarsening, or some combination).  The interpretation of the label values is
1199cd3c525cSToby Isaac   up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have
1200cd3c525cSToby Isaac   been reserved as choices that should be accepted by all subtypes.
12019be51f97SToby Isaac 
12029be51f97SToby Isaac   Not collective
12039be51f97SToby Isaac 
12049be51f97SToby Isaac   Input Parameter:
12059be51f97SToby Isaac . dm - the forest
12069be51f97SToby Isaac 
12079be51f97SToby Isaac   Output Parameter:
12089be51f97SToby Isaac . adaptLabel - the name of the label in the pre-adaptation forest
12099be51f97SToby Isaac 
12109be51f97SToby Isaac   Level: intermediate
12119be51f97SToby Isaac 
1212db781477SPatrick Sanan .seealso `DMForestSetAdaptivityLabel()`
12139be51f97SToby Isaac @*/
12149371c9d4SSatish Balay PetscErrorCode DMForestGetAdaptivityLabel(DM dm, DMLabel *adaptLabel) {
1215c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1216c7eeac06SToby Isaac 
1217c7eeac06SToby Isaac   PetscFunctionBegin;
1218c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1219ba936b91SToby Isaac   *adaptLabel = forest->adaptLabel;
1220c7eeac06SToby Isaac   PetscFunctionReturn(0);
1221c7eeac06SToby Isaac }
1222c7eeac06SToby Isaac 
12239be51f97SToby Isaac /*@
12249be51f97SToby Isaac   DMForestSetCellWeights - Set the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
12259be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
12269be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
12279be51f97SToby Isaac   of 1.
12289be51f97SToby Isaac 
12299be51f97SToby Isaac   Logically collective on dm
12309be51f97SToby Isaac 
12319be51f97SToby Isaac   Input Parameters:
12329be51f97SToby Isaac + dm - the forest
12339be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
12349be51f97SToby Isaac - copyMode - how weights should reference weights
12359be51f97SToby Isaac 
12369be51f97SToby Isaac   Level: advanced
12379be51f97SToby Isaac 
1238db781477SPatrick Sanan .seealso: `DMForestGetCellWeights()`, `DMForestSetWeightCapacity()`
12399be51f97SToby Isaac @*/
12409371c9d4SSatish Balay PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode) {
1241c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1242c7eeac06SToby Isaac   PetscInt   cStart, cEnd;
1243c7eeac06SToby Isaac 
1244c7eeac06SToby Isaac   PetscFunctionBegin;
1245c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
12469566063dSJacob Faibussowitsch   PetscCall(DMForestGetCellChart(dm, &cStart, &cEnd));
124763a3b9bcSJacob Faibussowitsch   PetscCheck(cEnd >= cStart, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "cell chart [%" PetscInt_FMT ",%" PetscInt_FMT ") is not valid", cStart, cEnd);
1248c7eeac06SToby Isaac   if (copyMode == PETSC_COPY_VALUES) {
124948a46eb9SPierre Jolivet     if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) PetscCall(PetscMalloc1(cEnd - cStart, &forest->cellWeights));
12509566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(forest->cellWeights, weights, cEnd - cStart));
1251c7eeac06SToby Isaac     forest->cellWeightsCopyMode = PETSC_OWN_POINTER;
1252c7eeac06SToby Isaac     PetscFunctionReturn(0);
1253c7eeac06SToby Isaac   }
125448a46eb9SPierre Jolivet   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) PetscCall(PetscFree(forest->cellWeights));
1255c7eeac06SToby Isaac   forest->cellWeights         = weights;
1256c7eeac06SToby Isaac   forest->cellWeightsCopyMode = copyMode;
1257c7eeac06SToby Isaac   PetscFunctionReturn(0);
1258c7eeac06SToby Isaac }
1259c7eeac06SToby Isaac 
12609be51f97SToby Isaac /*@
12619be51f97SToby Isaac   DMForestGetCellWeights - Get the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
12629be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
12639be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
12649be51f97SToby Isaac   of 1.
12659be51f97SToby Isaac 
12669be51f97SToby Isaac   Not collective
12679be51f97SToby Isaac 
12689be51f97SToby Isaac   Input Parameter:
12699be51f97SToby Isaac . dm - the forest
12709be51f97SToby Isaac 
12719be51f97SToby Isaac   Output Parameter:
12729be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
12739be51f97SToby Isaac 
12749be51f97SToby Isaac   Level: advanced
12759be51f97SToby Isaac 
1276db781477SPatrick Sanan .seealso: `DMForestSetCellWeights()`, `DMForestSetWeightCapacity()`
12779be51f97SToby Isaac @*/
12789371c9d4SSatish Balay PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights) {
1279c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1280c7eeac06SToby Isaac 
1281c7eeac06SToby Isaac   PetscFunctionBegin;
1282c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1283c7eeac06SToby Isaac   PetscValidPointer(weights, 2);
1284c7eeac06SToby Isaac   *weights = forest->cellWeights;
1285c7eeac06SToby Isaac   PetscFunctionReturn(0);
1286c7eeac06SToby Isaac }
1287c7eeac06SToby Isaac 
12889be51f97SToby Isaac /*@
12899be51f97SToby Isaac   DMForestSetWeightCapacity - During the pre-setup phase, set the capacity of the current process when repartitioning
12909be51f97SToby Isaac   a pre-adaptation forest (see DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each
12919be51f97SToby Isaac   process's cells to the process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that
12929be51f97SToby Isaac   the current process should not have any cells after repartitioning.
12939be51f97SToby Isaac 
12949be51f97SToby Isaac   Logically Collective on dm
12959be51f97SToby Isaac 
12969be51f97SToby Isaac   Input parameters:
12979be51f97SToby Isaac + dm - the forest
12989be51f97SToby Isaac - capacity - this process's capacity
12999be51f97SToby Isaac 
13009be51f97SToby Isaac   Level: advanced
13019be51f97SToby Isaac 
1302db781477SPatrick Sanan .seealso `DMForestGetWeightCapacity()`, `DMForestSetCellWeights()`, `DMForestSetCellWeightFactor()`
13039be51f97SToby Isaac @*/
13049371c9d4SSatish Balay PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity) {
1305c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1306c7eeac06SToby Isaac 
1307c7eeac06SToby Isaac   PetscFunctionBegin;
1308c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
130928b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled, PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Cannot change the weight capacity after setup");
131063a3b9bcSJacob Faibussowitsch   PetscCheck(capacity >= 0., PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have negative weight capacity; %g", (double)capacity);
1311c7eeac06SToby Isaac   forest->weightCapacity = capacity;
1312c7eeac06SToby Isaac   PetscFunctionReturn(0);
1313c7eeac06SToby Isaac }
1314c7eeac06SToby Isaac 
13159be51f97SToby Isaac /*@
13169be51f97SToby Isaac   DMForestGetWeightCapacity - Set the capacity of the current process when repartitioning a pre-adaptation forest (see
13179be51f97SToby Isaac   DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each process's cells to the
13189be51f97SToby Isaac   process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that the current process
13199be51f97SToby Isaac   should not have any cells after repartitioning.
13209be51f97SToby Isaac 
13219be51f97SToby Isaac   Not collective
13229be51f97SToby Isaac 
13239be51f97SToby Isaac   Input parameter:
13249be51f97SToby Isaac . dm - the forest
13259be51f97SToby Isaac 
13269be51f97SToby Isaac   Output parameter:
13279be51f97SToby Isaac . capacity - this process's capacity
13289be51f97SToby Isaac 
13299be51f97SToby Isaac   Level: advanced
13309be51f97SToby Isaac 
1331db781477SPatrick Sanan .seealso `DMForestSetWeightCapacity()`, `DMForestSetCellWeights()`, `DMForestSetCellWeightFactor()`
13329be51f97SToby Isaac @*/
13339371c9d4SSatish Balay PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity) {
1334c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest *)dm->data;
1335c7eeac06SToby Isaac 
1336c7eeac06SToby Isaac   PetscFunctionBegin;
1337c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1338c7eeac06SToby Isaac   PetscValidRealPointer(capacity, 2);
1339c7eeac06SToby Isaac   *capacity = forest->weightCapacity;
1340c7eeac06SToby Isaac   PetscFunctionReturn(0);
1341c7eeac06SToby Isaac }
1342c7eeac06SToby Isaac 
13439371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(DM dm, PetscOptionItems *PetscOptionsObject) {
134456ba9f64SToby Isaac   PetscBool                  flg, flg1, flg2, flg3, flg4;
1345dd8e54a2SToby Isaac   DMForestTopology           oldTopo;
1346c7eeac06SToby Isaac   char                       stringBuffer[256];
1347dd8e54a2SToby Isaac   PetscViewer                viewer;
1348dd8e54a2SToby Isaac   PetscViewerFormat          format;
134956ba9f64SToby Isaac   PetscInt                   adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade;
1350c7eeac06SToby Isaac   PetscReal                  weightsFactor;
1351c7eeac06SToby Isaac   DMForestAdaptivityStrategy adaptStrategy;
1352db4d5e8cSToby Isaac 
1353db4d5e8cSToby Isaac   PetscFunctionBegin;
13549566063dSJacob Faibussowitsch   PetscCall(DMForestGetTopology(dm, &oldTopo));
1355d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "DMForest Options");
13569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-dm_forest_topology", "the topology of the forest's base mesh", "DMForestSetTopology", oldTopo, stringBuffer, sizeof(stringBuffer), &flg1));
13579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-dm_forest_base_dm", "load the base DM from a viewer specification", "DMForestSetBaseDM", &viewer, &format, &flg2));
13589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-dm_forest_coarse_forest", "load the coarse forest from a viewer specification", "DMForestSetCoarseForest", &viewer, &format, &flg3));
13599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-dm_forest_fine_forest", "load the fine forest from a viewer specification", "DMForestSetFineForest", &viewer, &format, &flg4));
13601dca8a05SBarry 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}");
136156ba9f64SToby Isaac   if (flg1) {
13629566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm, (DMForestTopology)stringBuffer));
13639566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm, NULL));
13649566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm, NULL));
136556ba9f64SToby Isaac   }
136656ba9f64SToby Isaac   if (flg2) {
1367dd8e54a2SToby Isaac     DM base;
1368dd8e54a2SToby Isaac 
13699566063dSJacob Faibussowitsch     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &base));
13709566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
13719566063dSJacob Faibussowitsch     PetscCall(DMLoad(base, viewer));
13729566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
13739566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm, base));
13749566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&base));
13759566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm, NULL));
13769566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm, NULL));
1377dd8e54a2SToby Isaac   }
137856ba9f64SToby Isaac   if (flg3) {
1379dd8e54a2SToby Isaac     DM coarse;
1380dd8e54a2SToby Isaac 
13819566063dSJacob Faibussowitsch     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &coarse));
13829566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
13839566063dSJacob Faibussowitsch     PetscCall(DMLoad(coarse, viewer));
13849566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
13859566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm, coarse));
13869566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&coarse));
13879566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm, NULL));
13889566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm, NULL));
1389dd8e54a2SToby Isaac   }
139056ba9f64SToby Isaac   if (flg4) {
1391dd8e54a2SToby Isaac     DM fine;
1392dd8e54a2SToby Isaac 
13939566063dSJacob Faibussowitsch     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), &fine));
13949566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
13959566063dSJacob Faibussowitsch     PetscCall(DMLoad(fine, viewer));
13969566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
13979566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm, fine));
13989566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&fine));
13999566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm, NULL));
14009566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm, NULL));
1401dd8e54a2SToby Isaac   }
14029566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdjacencyDimension(dm, &adjDim));
14039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_adjacency_dimension", "set the dimension of points that define adjacency in the forest", "DMForestSetAdjacencyDimension", adjDim, &adjDim, &flg, 0));
1404dd8e54a2SToby Isaac   if (flg) {
14059566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdjacencyDimension(dm, adjDim));
1406f885a11aSToby Isaac   } else {
14079566063dSJacob Faibussowitsch     PetscCall(DMForestGetAdjacencyCodimension(dm, &adjCodim));
14089566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBoundedInt("-dm_forest_adjacency_codimension", "set the codimension of points that define adjacency in the forest", "DMForestSetAdjacencyCodimension", adjCodim, &adjCodim, &flg, 1));
14091baa6e33SBarry Smith     if (flg) PetscCall(DMForestSetAdjacencyCodimension(dm, adjCodim));
1410dd8e54a2SToby Isaac   }
14119566063dSJacob Faibussowitsch   PetscCall(DMForestGetPartitionOverlap(dm, &overlap));
14129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_partition_overlap", "set the degree of partition overlap", "DMForestSetPartitionOverlap", overlap, &overlap, &flg, 0));
14131baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetPartitionOverlap(dm, overlap));
1414a6121fbdSMatthew G. Knepley #if 0
14159566063dSJacob 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));
1416a6121fbdSMatthew G. Knepley   if (flg) {
14179566063dSJacob Faibussowitsch     PetscCall(DMForestSetMinimumRefinement(dm,minRefinement));
14189566063dSJacob Faibussowitsch     PetscCall(DMForestSetInitialRefinement(dm,minRefinement));
1419a6121fbdSMatthew G. Knepley   }
14209566063dSJacob 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));
1421a6121fbdSMatthew G. Knepley   if (flg) {
14229566063dSJacob Faibussowitsch     PetscCall(DMForestSetMinimumRefinement(dm,0));
14239566063dSJacob Faibussowitsch     PetscCall(DMForestSetInitialRefinement(dm,initRefinement));
1424a6121fbdSMatthew G. Knepley   }
1425a6121fbdSMatthew G. Knepley #endif
14269566063dSJacob Faibussowitsch   PetscCall(DMForestGetMinimumRefinement(dm, &minRefinement));
14279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_minimum_refinement", "set the minimum level of refinement in the forest", "DMForestSetMinimumRefinement", minRefinement, &minRefinement, &flg, 0));
14281baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetMinimumRefinement(dm, minRefinement));
14299566063dSJacob Faibussowitsch   PetscCall(DMForestGetInitialRefinement(dm, &initRefinement));
14309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_initial_refinement", "set the initial level of refinement in the forest", "DMForestSetInitialRefinement", initRefinement, &initRefinement, &flg, 0));
14311baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetInitialRefinement(dm, initRefinement));
14329566063dSJacob Faibussowitsch   PetscCall(DMForestGetMaximumRefinement(dm, &maxRefinement));
14339566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_maximum_refinement", "set the maximum level of refinement in the forest", "DMForestSetMaximumRefinement", maxRefinement, &maxRefinement, &flg, 0));
14341baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetMaximumRefinement(dm, maxRefinement));
14359566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivityStrategy(dm, &adaptStrategy));
14369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-dm_forest_adaptivity_strategy", "the forest's adaptivity-flag resolution strategy", "DMForestSetAdaptivityStrategy", adaptStrategy, stringBuffer, sizeof(stringBuffer), &flg));
14371baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetAdaptivityStrategy(dm, (DMForestAdaptivityStrategy)stringBuffer));
14389566063dSJacob Faibussowitsch   PetscCall(DMForestGetGradeFactor(dm, &grade));
14399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_grade_factor", "grade factor between neighboring cells", "DMForestSetGradeFactor", grade, &grade, &flg, 0));
14401baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetGradeFactor(dm, grade));
14419566063dSJacob Faibussowitsch   PetscCall(DMForestGetCellWeightFactor(dm, &weightsFactor));
14429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-dm_forest_cell_weight_factor", "multiplying weight factor for cell refinement", "DMForestSetCellWeightFactor", weightsFactor, &weightsFactor, &flg));
14431baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetCellWeightFactor(dm, weightsFactor));
1444d0609cedSBarry Smith   PetscOptionsHeadEnd();
1445db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1446db4d5e8cSToby Isaac }
1447db4d5e8cSToby Isaac 
14489371c9d4SSatish Balay PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) {
1449d8984e3bSMatthew G. Knepley   PetscFunctionBegin;
14509566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMClone(dm, subdm));
14519566063dSJacob Faibussowitsch   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm));
1452d8984e3bSMatthew G. Knepley   PetscFunctionReturn(0);
1453d8984e3bSMatthew G. Knepley }
1454d8984e3bSMatthew G. Knepley 
14559371c9d4SSatish Balay PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined) {
14565421bac9SToby Isaac   DMLabel refine;
14575421bac9SToby Isaac   DM      fineDM;
14585421bac9SToby Isaac 
14595421bac9SToby Isaac   PetscFunctionBegin;
14609566063dSJacob Faibussowitsch   PetscCall(DMGetFineDM(dm, &fineDM));
14615421bac9SToby Isaac   if (fineDM) {
14629566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)fineDM));
14635421bac9SToby Isaac     *dmRefined = fineDM;
14645421bac9SToby Isaac     PetscFunctionReturn(0);
14655421bac9SToby Isaac   }
14669566063dSJacob Faibussowitsch   PetscCall(DMForestTemplate(dm, comm, dmRefined));
14679566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "refine", &refine));
14685421bac9SToby Isaac   if (!refine) {
14699566063dSJacob Faibussowitsch     PetscCall(DMLabelCreate(PETSC_COMM_SELF, "refine", &refine));
14709566063dSJacob Faibussowitsch     PetscCall(DMLabelSetDefaultValue(refine, DM_ADAPT_REFINE));
14711baa6e33SBarry Smith   } else PetscCall(PetscObjectReference((PetscObject)refine));
14729566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityLabel(*dmRefined, refine));
14739566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&refine));
14745421bac9SToby Isaac   PetscFunctionReturn(0);
14755421bac9SToby Isaac }
14765421bac9SToby Isaac 
14779371c9d4SSatish Balay PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened) {
14785421bac9SToby Isaac   DMLabel coarsen;
14795421bac9SToby Isaac   DM      coarseDM;
14805421bac9SToby Isaac 
14815421bac9SToby Isaac   PetscFunctionBegin;
14824098eed7SToby Isaac   {
14834098eed7SToby Isaac     PetscMPIInt mpiComparison;
14844098eed7SToby Isaac     MPI_Comm    dmcomm = PetscObjectComm((PetscObject)dm);
14854098eed7SToby Isaac 
14869566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_compare(comm, dmcomm, &mpiComparison));
14871dca8a05SBarry Smith     PetscCheck(mpiComparison == MPI_IDENT || mpiComparison == MPI_CONGRUENT, dmcomm, PETSC_ERR_SUP, "No support for different communicators yet");
14884098eed7SToby Isaac   }
14899566063dSJacob Faibussowitsch   PetscCall(DMGetCoarseDM(dm, &coarseDM));
14905421bac9SToby Isaac   if (coarseDM) {
14919566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)coarseDM));
14925421bac9SToby Isaac     *dmCoarsened = coarseDM;
14935421bac9SToby Isaac     PetscFunctionReturn(0);
14945421bac9SToby Isaac   }
14959566063dSJacob Faibussowitsch   PetscCall(DMForestTemplate(dm, comm, dmCoarsened));
14969566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityPurpose(*dmCoarsened, DM_ADAPT_COARSEN));
14979566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "coarsen", &coarsen));
14985421bac9SToby Isaac   if (!coarsen) {
14999566063dSJacob Faibussowitsch     PetscCall(DMLabelCreate(PETSC_COMM_SELF, "coarsen", &coarsen));
15009566063dSJacob Faibussowitsch     PetscCall(DMLabelSetDefaultValue(coarsen, DM_ADAPT_COARSEN));
15011baa6e33SBarry Smith   } else PetscCall(PetscObjectReference((PetscObject)coarsen));
15029566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityLabel(*dmCoarsened, coarsen));
15039566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&coarsen));
15045421bac9SToby Isaac   PetscFunctionReturn(0);
15055421bac9SToby Isaac }
15065421bac9SToby Isaac 
15079371c9d4SSatish Balay PetscErrorCode DMAdaptLabel_Forest(DM dm, PETSC_UNUSED Vec metric, DMLabel label, PETSC_UNUSED DMLabel rgLabel, DM *adaptedDM) {
150809350103SToby Isaac   PetscBool success;
150909350103SToby Isaac 
151009350103SToby Isaac   PetscFunctionBegin;
15119566063dSJacob Faibussowitsch   PetscCall(DMForestTemplate(dm, PetscObjectComm((PetscObject)dm), adaptedDM));
15129566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityLabel(*adaptedDM, label));
15139566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*adaptedDM));
15149566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivitySuccess(*adaptedDM, &success));
151509350103SToby Isaac   if (!success) {
15169566063dSJacob Faibussowitsch     PetscCall(DMDestroy(adaptedDM));
151709350103SToby Isaac     *adaptedDM = NULL;
151809350103SToby Isaac   }
151909350103SToby Isaac   PetscFunctionReturn(0);
152009350103SToby Isaac }
152109350103SToby Isaac 
15229371c9d4SSatish Balay static PetscErrorCode DMInitialize_Forest(DM dm) {
1523d222f98bSToby Isaac   PetscFunctionBegin;
15249566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(dm->ops, sizeof(*(dm->ops))));
1525d222f98bSToby Isaac 
1526d222f98bSToby Isaac   dm->ops->clone          = DMClone_Forest;
1527d222f98bSToby Isaac   dm->ops->setfromoptions = DMSetFromOptions_Forest;
1528d222f98bSToby Isaac   dm->ops->destroy        = DMDestroy_Forest;
1529d8984e3bSMatthew G. Knepley   dm->ops->createsubdm    = DMCreateSubDM_Forest;
15305421bac9SToby Isaac   dm->ops->refine         = DMRefine_Forest;
15315421bac9SToby Isaac   dm->ops->coarsen        = DMCoarsen_Forest;
1532d222f98bSToby Isaac   PetscFunctionReturn(0);
1533d222f98bSToby Isaac }
1534d222f98bSToby Isaac 
15359be51f97SToby Isaac /*MC
15369be51f97SToby Isaac 
1537bae1f979SBarry Smith      DMFOREST = "forest" - A DM object that encapsulates a hierarchically refined mesh.  Forests usually have a base DM
1538bae1f979SBarry Smith   (see DMForestGetBaseDM()), from which it is refined.  The refinement and partitioning of forests is considered
1539bae1f979SBarry Smith   immutable after DMSetUp() is called.  To adapt a mesh, one should call DMForestTemplate() to create a new mesh that
1540bae1f979SBarry Smith   will default to being identical to it, specify how that mesh should differ, and then calling DMSetUp() on the new
1541bae1f979SBarry Smith   mesh.
1542bae1f979SBarry Smith 
1543bae1f979SBarry Smith   To specify that a mesh should be refined or coarsened from the previous mesh, a label should be defined on the
1544bae1f979SBarry Smith   previous mesh whose values indicate which cells should be refined (DM_ADAPT_REFINE) or coarsened (DM_ADAPT_COARSEN)
1545bae1f979SBarry Smith   and how (subtypes are free to allow additional values for things like anisotropic refinement).  The label should be
1546bae1f979SBarry Smith   given to the *new* mesh with DMForestSetAdaptivityLabel().
15479be51f97SToby Isaac 
15489be51f97SToby Isaac   Level: advanced
15499be51f97SToby Isaac 
1550db781477SPatrick Sanan .seealso: `DMType`, `DMCreate()`, `DMSetType()`, `DMForestGetBaseDM()`, `DMForestSetBaseDM()`, `DMForestTemplate()`, `DMForestSetAdaptivityLabel()`
15519be51f97SToby Isaac M*/
15529be51f97SToby Isaac 
15539371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm) {
1554db4d5e8cSToby Isaac   DM_Forest *forest;
1555db4d5e8cSToby Isaac 
1556db4d5e8cSToby Isaac   PetscFunctionBegin;
1557db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1558*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&forest));
1559db4d5e8cSToby Isaac   dm->dim                     = 0;
1560db4d5e8cSToby Isaac   dm->data                    = forest;
1561db4d5e8cSToby Isaac   forest->refct               = 1;
1562db4d5e8cSToby Isaac   forest->data                = NULL;
1563db4d5e8cSToby Isaac   forest->topology            = NULL;
1564cd3c525cSToby Isaac   forest->adapt               = NULL;
1565db4d5e8cSToby Isaac   forest->base                = NULL;
15666a87ffbfSToby Isaac   forest->adaptPurpose        = DM_ADAPT_DETERMINE;
1567db4d5e8cSToby Isaac   forest->adjDim              = PETSC_DEFAULT;
1568db4d5e8cSToby Isaac   forest->overlap             = PETSC_DEFAULT;
1569db4d5e8cSToby Isaac   forest->minRefinement       = PETSC_DEFAULT;
1570db4d5e8cSToby Isaac   forest->maxRefinement       = PETSC_DEFAULT;
157156ba9f64SToby Isaac   forest->initRefinement      = PETSC_DEFAULT;
1572c7eeac06SToby Isaac   forest->cStart              = PETSC_DETERMINE;
1573c7eeac06SToby Isaac   forest->cEnd                = PETSC_DETERMINE;
1574cd3c525cSToby Isaac   forest->cellSF              = NULL;
1575ebdf65a2SToby Isaac   forest->adaptLabel          = NULL;
1576db4d5e8cSToby Isaac   forest->gradeFactor         = 2;
1577db4d5e8cSToby Isaac   forest->cellWeights         = NULL;
1578db4d5e8cSToby Isaac   forest->cellWeightsCopyMode = PETSC_USE_POINTER;
1579db4d5e8cSToby Isaac   forest->weightsFactor       = 1.;
1580db4d5e8cSToby Isaac   forest->weightCapacity      = 1.;
15819566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityStrategy(dm, DMFORESTADAPTALL));
15829566063dSJacob Faibussowitsch   PetscCall(DMInitialize_Forest(dm));
1583db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1584db4d5e8cSToby Isaac }
1585