xref: /petsc/src/dm/impls/forest/forest.c (revision 1baa6e3354bfe224b33a0c158f482508792a8a6e)
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 
1027d4645fSToby Isaac struct _DMForestTypeLink
1127d4645fSToby Isaac {
1227d4645fSToby Isaac   char             *name;
1327d4645fSToby Isaac   DMForestTypeLink next;
1427d4645fSToby Isaac };
1527d4645fSToby Isaac 
1627d4645fSToby Isaac DMForestTypeLink DMForestTypeList;
1727d4645fSToby Isaac 
1827d4645fSToby Isaac static PetscErrorCode DMForestPackageFinalize(void)
1927d4645fSToby Isaac {
2027d4645fSToby Isaac   DMForestTypeLink oldLink, link = DMForestTypeList;
2127d4645fSToby Isaac 
2227d4645fSToby Isaac   PetscFunctionBegin;
2327d4645fSToby Isaac   while (link) {
2427d4645fSToby Isaac     oldLink = link;
259566063dSJacob Faibussowitsch     PetscCall(PetscFree(oldLink->name));
2627d4645fSToby Isaac     link    = oldLink->next;
279566063dSJacob Faibussowitsch     PetscCall(PetscFree(oldLink));
2827d4645fSToby Isaac   }
2927d4645fSToby Isaac   PetscFunctionReturn(0);
3027d4645fSToby Isaac }
3127d4645fSToby Isaac 
3227d4645fSToby Isaac static PetscErrorCode DMForestPackageInitialize(void)
3327d4645fSToby Isaac {
3427d4645fSToby Isaac   PetscFunctionBegin;
3527d4645fSToby Isaac   if (DMForestPackageInitialized) PetscFunctionReturn(0);
3627d4645fSToby Isaac   DMForestPackageInitialized = PETSC_TRUE;
37f885a11aSToby Isaac 
389566063dSJacob Faibussowitsch   PetscCall(DMForestRegisterType(DMFOREST));
399566063dSJacob Faibussowitsch   PetscCall(PetscRegisterFinalize(DMForestPackageFinalize));
4027d4645fSToby Isaac   PetscFunctionReturn(0);
4127d4645fSToby Isaac }
4227d4645fSToby Isaac 
439be51f97SToby Isaac /*@C
449be51f97SToby Isaac   DMForestRegisterType - Registers a DMType as a subtype of DMFOREST (so that DMIsForest() will be correct)
459be51f97SToby Isaac 
469be51f97SToby Isaac   Not Collective
479be51f97SToby Isaac 
489be51f97SToby Isaac   Input parameter:
499be51f97SToby Isaac . name - the name of the type
509be51f97SToby Isaac 
519be51f97SToby Isaac   Level: advanced
529be51f97SToby Isaac 
53db781477SPatrick Sanan .seealso: `DMFOREST`, `DMIsForest()`
549be51f97SToby Isaac @*/
5527d4645fSToby Isaac PetscErrorCode DMForestRegisterType(DMType name)
5627d4645fSToby Isaac {
5727d4645fSToby Isaac   DMForestTypeLink link;
5827d4645fSToby Isaac 
5927d4645fSToby Isaac   PetscFunctionBegin;
609566063dSJacob Faibussowitsch   PetscCall(DMForestPackageInitialize());
619566063dSJacob Faibussowitsch   PetscCall(PetscNew(&link));
629566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name,&link->name));
6327d4645fSToby Isaac   link->next       = DMForestTypeList;
6427d4645fSToby Isaac   DMForestTypeList = link;
6527d4645fSToby Isaac   PetscFunctionReturn(0);
6627d4645fSToby Isaac }
6727d4645fSToby Isaac 
689be51f97SToby Isaac /*@
699be51f97SToby Isaac   DMIsForest - Check whether a DM uses the DMFOREST interface for hierarchically-refined meshes
709be51f97SToby Isaac 
719be51f97SToby Isaac   Not Collective
729be51f97SToby Isaac 
739be51f97SToby Isaac   Input parameter:
749be51f97SToby Isaac . dm - the DM object
759be51f97SToby Isaac 
769be51f97SToby Isaac   Output parameter:
779be51f97SToby Isaac . isForest - whether dm is a subtype of DMFOREST
789be51f97SToby Isaac 
799be51f97SToby Isaac   Level: intermediate
809be51f97SToby Isaac 
81db781477SPatrick Sanan .seealso: `DMFOREST`, `DMForestRegisterType()`
829be51f97SToby Isaac @*/
8327d4645fSToby Isaac PetscErrorCode DMIsForest(DM dm, PetscBool *isForest)
8427d4645fSToby Isaac {
8527d4645fSToby Isaac   DMForestTypeLink link = DMForestTypeList;
8627d4645fSToby Isaac 
8727d4645fSToby Isaac   PetscFunctionBegin;
8827d4645fSToby Isaac   while (link) {
8927d4645fSToby Isaac     PetscBool sameType;
909566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dm,link->name,&sameType));
9127d4645fSToby Isaac     if (sameType) {
9227d4645fSToby Isaac       *isForest = PETSC_TRUE;
9327d4645fSToby Isaac       PetscFunctionReturn(0);
9427d4645fSToby Isaac     }
9527d4645fSToby Isaac     link = link->next;
9627d4645fSToby Isaac   }
9727d4645fSToby Isaac   *isForest = PETSC_FALSE;
9827d4645fSToby Isaac   PetscFunctionReturn(0);
9927d4645fSToby Isaac }
10027d4645fSToby Isaac 
1019be51f97SToby Isaac /*@
1029be51f97SToby Isaac   DMForestTemplate - Create a new DM that will be adapted from a source DM.  The new DM reproduces the configuration
1039be51f97SToby 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
1049be51f97SToby Isaac   (by, e.g., refinement or repartitioning).  The source DM is also set as the adaptivity source DM of the new DM (see
1059be51f97SToby Isaac   DMForestSetAdaptivityForest()).
1069be51f97SToby Isaac 
1079be51f97SToby Isaac   Collective on dm
1089be51f97SToby Isaac 
1099be51f97SToby Isaac   Input Parameters:
1109be51f97SToby Isaac + dm - the source DM object
1119be51f97SToby Isaac - comm - the communicator for the new DM (this communicator is currently ignored, but is present so that DMForestTemplate() can be used within DMCoarsen())
1129be51f97SToby Isaac 
1139be51f97SToby Isaac   Output Parameter:
1149be51f97SToby Isaac . tdm - the new DM object
1159be51f97SToby Isaac 
1169be51f97SToby Isaac   Level: intermediate
1179be51f97SToby Isaac 
118db781477SPatrick Sanan .seealso: `DMForestSetAdaptivityForest()`
1199be51f97SToby Isaac @*/
1209be51f97SToby Isaac PetscErrorCode DMForestTemplate(DM dm, MPI_Comm comm, DM *tdm)
121a0452a8eSToby Isaac {
122a0452a8eSToby Isaac   DM_Forest                  *forest = (DM_Forest*) dm->data;
12320e8089bSToby Isaac   DMType                     type;
124a0452a8eSToby Isaac   DM                         base;
125a0452a8eSToby Isaac   DMForestTopology           topology;
12605e99e11SStefano Zampini   MatType                    mtype;
127a0452a8eSToby Isaac   PetscInt                   dim, overlap, ref, factor;
128a0452a8eSToby Isaac   DMForestAdaptivityStrategy strat;
129795844e7SToby Isaac   void                       *ctx;
13049fc9a2fSToby Isaac   PetscErrorCode             (*map)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void*);
1313e58adeeSToby Isaac   void                       *mapCtx;
132a0452a8eSToby Isaac 
133a0452a8eSToby Isaac   PetscFunctionBegin;
134a0452a8eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1359566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)dm),tdm));
1369566063dSJacob Faibussowitsch   PetscCall(DMGetType(dm,&type));
1379566063dSJacob Faibussowitsch   PetscCall(DMSetType(*tdm,type));
1389566063dSJacob Faibussowitsch   PetscCall(DMForestGetBaseDM(dm,&base));
1399566063dSJacob Faibussowitsch   PetscCall(DMForestSetBaseDM(*tdm,base));
1409566063dSJacob Faibussowitsch   PetscCall(DMForestGetTopology(dm,&topology));
1419566063dSJacob Faibussowitsch   PetscCall(DMForestSetTopology(*tdm,topology));
1429566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdjacencyDimension(dm,&dim));
1439566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdjacencyDimension(*tdm,dim));
1449566063dSJacob Faibussowitsch   PetscCall(DMForestGetPartitionOverlap(dm,&overlap));
1459566063dSJacob Faibussowitsch   PetscCall(DMForestSetPartitionOverlap(*tdm,overlap));
1469566063dSJacob Faibussowitsch   PetscCall(DMForestGetMinimumRefinement(dm,&ref));
1479566063dSJacob Faibussowitsch   PetscCall(DMForestSetMinimumRefinement(*tdm,ref));
1489566063dSJacob Faibussowitsch   PetscCall(DMForestGetMaximumRefinement(dm,&ref));
1499566063dSJacob Faibussowitsch   PetscCall(DMForestSetMaximumRefinement(*tdm,ref));
1509566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivityStrategy(dm,&strat));
1519566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityStrategy(*tdm,strat));
1529566063dSJacob Faibussowitsch   PetscCall(DMForestGetGradeFactor(dm,&factor));
1539566063dSJacob Faibussowitsch   PetscCall(DMForestSetGradeFactor(*tdm,factor));
1549566063dSJacob Faibussowitsch   PetscCall(DMForestGetBaseCoordinateMapping(dm,&map,&mapCtx));
1559566063dSJacob Faibussowitsch   PetscCall(DMForestSetBaseCoordinateMapping(*tdm,map,mapCtx));
156*1baa6e33SBarry Smith   if (forest->ftemplate) PetscCall((*forest->ftemplate)(dm, *tdm));
1579566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityForest(*tdm,dm));
1589566063dSJacob Faibussowitsch   PetscCall(DMCopyDisc(dm,*tdm));
1599566063dSJacob Faibussowitsch   PetscCall(DMGetApplicationContext(dm,&ctx));
1609566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(*tdm,&ctx));
16190b157c4SStefano Zampini   {
16290b157c4SStefano Zampini     PetscBool            isper;
163795844e7SToby Isaac     const PetscReal      *maxCell, *L;
164795844e7SToby Isaac     const DMBoundaryType *bd;
165795844e7SToby Isaac 
1669566063dSJacob Faibussowitsch     PetscCall(DMGetPeriodicity(dm,&isper,&maxCell,&L,&bd));
1679566063dSJacob Faibussowitsch     PetscCall(DMSetPeriodicity(*tdm,isper,maxCell,L,bd));
168795844e7SToby Isaac   }
1699566063dSJacob Faibussowitsch   PetscCall(DMGetMatType(dm,&mtype));
1709566063dSJacob Faibussowitsch   PetscCall(DMSetMatType(*tdm,mtype));
171a0452a8eSToby Isaac   PetscFunctionReturn(0);
172a0452a8eSToby Isaac }
173a0452a8eSToby Isaac 
17401d9d024SToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm);
17501d9d024SToby Isaac 
176db4d5e8cSToby Isaac PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm)
177db4d5e8cSToby Isaac {
178db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
179db4d5e8cSToby Isaac   const char     *type;
180db4d5e8cSToby Isaac 
181db4d5e8cSToby Isaac   PetscFunctionBegin;
182db4d5e8cSToby Isaac   forest->refct++;
183db4d5e8cSToby Isaac   (*newdm)->data = forest;
1849566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetType((PetscObject) dm, &type));
1859566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject) *newdm, type));
1869566063dSJacob Faibussowitsch   PetscCall(DMInitialize_Forest(*newdm));
187db4d5e8cSToby Isaac   PetscFunctionReturn(0);
188db4d5e8cSToby Isaac }
189db4d5e8cSToby Isaac 
190d222f98bSToby Isaac static PetscErrorCode DMDestroy_Forest(DM dm)
191db4d5e8cSToby Isaac {
192db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
193db4d5e8cSToby Isaac 
194db4d5e8cSToby Isaac   PetscFunctionBegin;
195db4d5e8cSToby Isaac   if (--forest->refct > 0) PetscFunctionReturn(0);
1969566063dSJacob Faibussowitsch   if (forest->destroy) PetscCall((*forest->destroy)(dm));
1979566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&forest->cellSF));
1989566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&forest->preCoarseToFine));
1999566063dSJacob Faibussowitsch   PetscCall(PetscSFDestroy(&forest->coarseToPreFine));
2009566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&forest->adaptLabel));
2019566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->adaptStrategy));
2029566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&forest->base));
2039566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&forest->adapt));
2049566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->topology));
2059566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest));
206db4d5e8cSToby Isaac   PetscFunctionReturn(0);
207db4d5e8cSToby Isaac }
208db4d5e8cSToby Isaac 
2099be51f97SToby Isaac /*@C
2109be51f97SToby Isaac   DMForestSetTopology - Set the topology of a DMForest during the pre-setup phase.  The topology is a string (e.g.
21168d54884SBarry Smith   "cube", "shell") and can be interpreted by subtypes of DMFOREST) to construct the base DM of a forest during
2129be51f97SToby Isaac   DMSetUp().
2139be51f97SToby Isaac 
2149be51f97SToby Isaac   Logically collective on dm
2159be51f97SToby Isaac 
2169be51f97SToby Isaac   Input parameters:
2179be51f97SToby Isaac + dm - the forest
2189be51f97SToby Isaac - topology - the topology of the forest
2199be51f97SToby Isaac 
2209be51f97SToby Isaac   Level: intermediate
2219be51f97SToby Isaac 
222db781477SPatrick Sanan .seealso: `DMForestGetTopology()`, `DMForestSetBaseDM()`
2239be51f97SToby Isaac @*/
224dd8e54a2SToby Isaac PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology)
225db4d5e8cSToby Isaac {
226db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
227db4d5e8cSToby Isaac 
228db4d5e8cSToby Isaac   PetscFunctionBegin;
229db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
23028b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup");
2319566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->topology));
2329566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy((const char*)topology,(char**) &forest->topology));
233db4d5e8cSToby Isaac   PetscFunctionReturn(0);
234db4d5e8cSToby Isaac }
235db4d5e8cSToby Isaac 
2369be51f97SToby Isaac /*@C
2379be51f97SToby Isaac   DMForestGetTopology - Get a string describing the topology of a DMForest.
2389be51f97SToby Isaac 
2399be51f97SToby Isaac   Not collective
2409be51f97SToby Isaac 
2419be51f97SToby Isaac   Input parameter:
2429be51f97SToby Isaac . dm - the forest
2439be51f97SToby Isaac 
2449be51f97SToby Isaac   Output parameter:
2459be51f97SToby Isaac . topology - the topology of the forest (e.g., 'cube', 'shell')
2469be51f97SToby Isaac 
2479be51f97SToby Isaac   Level: intermediate
2489be51f97SToby Isaac 
249db781477SPatrick Sanan .seealso: `DMForestSetTopology()`
2509be51f97SToby Isaac @*/
251dd8e54a2SToby Isaac PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology)
252dd8e54a2SToby Isaac {
253dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
254dd8e54a2SToby Isaac 
255dd8e54a2SToby Isaac   PetscFunctionBegin;
256dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
257dd8e54a2SToby Isaac   PetscValidPointer(topology,2);
258dd8e54a2SToby Isaac   *topology = forest->topology;
259dd8e54a2SToby Isaac   PetscFunctionReturn(0);
260dd8e54a2SToby Isaac }
261dd8e54a2SToby Isaac 
2629be51f97SToby Isaac /*@
2639be51f97SToby Isaac   DMForestSetBaseDM - During the pre-setup phase, set the DM that defines the base mesh of a DMForest forest.  The
2649be51f97SToby Isaac   forest will be hierarchically refined from the base, and all refinements/coarsenings of the forest will share its
265765b024eSBarry Smith   base.  In general, two forest must share a base to be comparable, to do things like construct interpolators.
2669be51f97SToby Isaac 
2679be51f97SToby Isaac   Logically collective on dm
2689be51f97SToby Isaac 
2699be51f97SToby Isaac   Input Parameters:
2709be51f97SToby Isaac + dm - the forest
2719be51f97SToby Isaac - base - the base DM of the forest
2729be51f97SToby Isaac 
27395452b02SPatrick Sanan   Notes:
27495452b02SPatrick Sanan     Currently the base DM must be a DMPLEX
275765b024eSBarry Smith 
2769be51f97SToby Isaac   Level: intermediate
2779be51f97SToby Isaac 
278db781477SPatrick Sanan .seealso: `DMForestGetBaseDM()`
2799be51f97SToby Isaac @*/
280dd8e54a2SToby Isaac PetscErrorCode DMForestSetBaseDM(DM dm, DM base)
281dd8e54a2SToby Isaac {
282dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
283dd8e54a2SToby Isaac   PetscInt       dim, dimEmbed;
284dd8e54a2SToby Isaac 
285dd8e54a2SToby Isaac   PetscFunctionBegin;
286dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
28728b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup");
2889566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)base));
2899566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&forest->base));
290dd8e54a2SToby Isaac   forest->base = base;
291a0452a8eSToby Isaac   if (base) {
29228dfcf7cSStefano Zampini     PetscBool        isper;
29328dfcf7cSStefano Zampini     const PetscReal *maxCell, *L;
29428dfcf7cSStefano Zampini     const DMBoundaryType *bd;
29528dfcf7cSStefano Zampini 
296a0452a8eSToby Isaac     PetscValidHeaderSpecific(base, DM_CLASSID, 2);
2979566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(base,&dim));
2989566063dSJacob Faibussowitsch     PetscCall(DMSetDimension(dm,dim));
2999566063dSJacob Faibussowitsch     PetscCall(DMGetCoordinateDim(base,&dimEmbed));
3009566063dSJacob Faibussowitsch     PetscCall(DMSetCoordinateDim(dm,dimEmbed));
3019566063dSJacob Faibussowitsch     PetscCall(DMGetPeriodicity(base,&isper,&maxCell,&L,&bd));
3029566063dSJacob Faibussowitsch     PetscCall(DMSetPeriodicity(dm,isper,maxCell,L,bd));
303*1baa6e33SBarry Smith   } else PetscCall(DMSetPeriodicity(dm,PETSC_FALSE,NULL,NULL,NULL));
304dd8e54a2SToby Isaac   PetscFunctionReturn(0);
305dd8e54a2SToby Isaac }
306dd8e54a2SToby Isaac 
3079be51f97SToby Isaac /*@
3089be51f97SToby Isaac   DMForestGetBaseDM - Get the base DM of a DMForest forest.  The forest will be hierarchically refined from the base,
30968d54884SBarry Smith   and all refinements/coarsenings of the forest will share its base.  In general, two forest must share a base to be
3109be51f97SToby Isaac   comparable, to do things like construct interpolators.
3119be51f97SToby Isaac 
3129be51f97SToby Isaac   Not collective
3139be51f97SToby Isaac 
3149be51f97SToby Isaac   Input Parameter:
3159be51f97SToby Isaac . dm - the forest
3169be51f97SToby Isaac 
3179be51f97SToby Isaac   Output Parameter:
3189be51f97SToby Isaac . base - the base DM of the forest
3199be51f97SToby Isaac 
320367003a6SStefano Zampini   Notes:
321367003a6SStefano Zampini     After DMSetUp(), the base DM will be redundantly distributed across MPI processes
322367003a6SStefano Zampini 
3239be51f97SToby Isaac   Level: intermediate
3249be51f97SToby Isaac 
325db781477SPatrick Sanan .seealso: `DMForestSetBaseDM()`
3269be51f97SToby Isaac @*/
327dd8e54a2SToby Isaac PetscErrorCode DMForestGetBaseDM(DM dm, DM *base)
328dd8e54a2SToby Isaac {
329dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
330dd8e54a2SToby Isaac 
331dd8e54a2SToby Isaac   PetscFunctionBegin;
332dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
333dd8e54a2SToby Isaac   PetscValidPointer(base, 2);
334dd8e54a2SToby Isaac   *base = forest->base;
335dd8e54a2SToby Isaac   PetscFunctionReturn(0);
336dd8e54a2SToby Isaac }
337dd8e54a2SToby Isaac 
33899478f86SToby Isaac PetscErrorCode DMForestSetBaseCoordinateMapping(DM dm, PetscErrorCode (*func)(DM,PetscInt,PetscInt,const PetscReal [],PetscReal [],void*),void *ctx)
339cf38a08cSToby Isaac {
340cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
341cf38a08cSToby Isaac 
342cf38a08cSToby Isaac   PetscFunctionBegin;
343cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
344cf38a08cSToby Isaac   forest->mapcoordinates    = func;
345cf38a08cSToby Isaac   forest->mapcoordinatesctx = ctx;
346cf38a08cSToby Isaac   PetscFunctionReturn(0);
347cf38a08cSToby Isaac }
348cf38a08cSToby Isaac 
34999478f86SToby Isaac PetscErrorCode DMForestGetBaseCoordinateMapping(DM dm, PetscErrorCode (**func) (DM,PetscInt,PetscInt,const PetscReal [],PetscReal [],void*),void *ctx)
350cf38a08cSToby Isaac {
351cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
352cf38a08cSToby Isaac 
353cf38a08cSToby Isaac   PetscFunctionBegin;
354cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
355cf38a08cSToby Isaac   if (func) *func = forest->mapcoordinates;
356cf38a08cSToby Isaac   if (ctx) *((void**) ctx) = forest->mapcoordinatesctx;
357cf38a08cSToby Isaac   PetscFunctionReturn(0);
358cf38a08cSToby Isaac }
359cf38a08cSToby Isaac 
3609be51f97SToby Isaac /*@
3619be51f97SToby Isaac   DMForestSetAdaptivityForest - During the pre-setup phase, set the forest from which the current forest will be
3629be51f97SToby Isaac   adapted (e.g., the current forest will be refined/coarsened/repartitioned from it) im DMSetUp().  Usually not needed
3639be51f97SToby Isaac   by users directly: DMForestTemplate() constructs a new forest to be adapted from an old forest and calls this
3649be51f97SToby Isaac   routine.
3659be51f97SToby Isaac 
366dffe73a3SToby Isaac   Note that this can be called after setup with adapt = NULL, which will clear all internal data related to the
367dffe73a3SToby Isaac   adaptivity forest from dm.  This way, repeatedly adapting does not leave stale DM objects in memory.
368dffe73a3SToby Isaac 
3699be51f97SToby Isaac   Logically collective on dm
3709be51f97SToby Isaac 
371d8d19677SJose E. Roman   Input Parameters:
3729be51f97SToby Isaac + dm - the new forest, which will be constructed from adapt
3739be51f97SToby Isaac - adapt - the old forest
3749be51f97SToby Isaac 
3759be51f97SToby Isaac   Level: intermediate
3769be51f97SToby Isaac 
377db781477SPatrick Sanan .seealso: `DMForestGetAdaptivityForest()`, `DMForestSetAdaptivityPurpose()`
3789be51f97SToby Isaac @*/
379ba936b91SToby Isaac PetscErrorCode DMForestSetAdaptivityForest(DM dm,DM adapt)
380dd8e54a2SToby Isaac {
381dffe73a3SToby Isaac   DM_Forest      *forest, *adaptForest, *oldAdaptForest;
382dffe73a3SToby Isaac   DM             oldAdapt;
383456cc5b7SMatthew G. Knepley   PetscBool      isForest;
384dd8e54a2SToby Isaac 
385dd8e54a2SToby Isaac   PetscFunctionBegin;
386dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3871fd50544SStefano Zampini   if (adapt) PetscValidHeaderSpecific(adapt, DM_CLASSID, 2);
3889566063dSJacob Faibussowitsch   PetscCall(DMIsForest(dm, &isForest));
389456cc5b7SMatthew G. Knepley   if (!isForest) PetscFunctionReturn(0);
3901dca8a05SBarry Smith   PetscCheck(adapt == NULL || !dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
391ba936b91SToby Isaac   forest         = (DM_Forest*) dm->data;
3929566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivityForest(dm,&oldAdapt));
393193eb951SToby Isaac   adaptForest    = (DM_Forest*) (adapt ? adapt->data : NULL);
394193eb951SToby Isaac   oldAdaptForest = (DM_Forest*) (oldAdapt ? oldAdapt->data : NULL);
395dffe73a3SToby Isaac   if (adaptForest != oldAdaptForest) {
3969566063dSJacob Faibussowitsch     PetscCall(PetscSFDestroy(&forest->preCoarseToFine));
3979566063dSJacob Faibussowitsch     PetscCall(PetscSFDestroy(&forest->coarseToPreFine));
3989566063dSJacob Faibussowitsch     if (forest->clearadaptivityforest) PetscCall((*forest->clearadaptivityforest)(dm));
399dffe73a3SToby Isaac   }
40026d9498aSToby Isaac   switch (forest->adaptPurpose) {
401cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
4029566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)adapt));
4039566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&(forest->adapt)));
404ba936b91SToby Isaac     forest->adapt = adapt;
40526d9498aSToby Isaac     break;
406a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
4079566063dSJacob Faibussowitsch     PetscCall(DMSetCoarseDM(dm,adapt));
40826d9498aSToby Isaac     break;
409a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
410bf2d5fbbSStefano Zampini   case DM_ADAPT_COARSEN_LAST:
4119566063dSJacob Faibussowitsch     PetscCall(DMSetFineDM(dm,adapt));
41226d9498aSToby Isaac     break;
41326d9498aSToby Isaac   default:
41426d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
41526d9498aSToby Isaac   }
416dd8e54a2SToby Isaac   PetscFunctionReturn(0);
417dd8e54a2SToby Isaac }
418dd8e54a2SToby Isaac 
4199be51f97SToby Isaac /*@
4209be51f97SToby Isaac   DMForestGetAdaptivityForest - Get the forest from which the current forest is adapted.
4219be51f97SToby Isaac 
4229be51f97SToby Isaac   Not collective
4239be51f97SToby Isaac 
4249be51f97SToby Isaac   Input Parameter:
4259be51f97SToby Isaac . dm - the forest
4269be51f97SToby Isaac 
4279be51f97SToby Isaac   Output Parameter:
4289be51f97SToby Isaac . adapt - the forest from which dm is/was adapted
4299be51f97SToby Isaac 
4309be51f97SToby Isaac   Level: intermediate
4319be51f97SToby Isaac 
432db781477SPatrick Sanan .seealso: `DMForestSetAdaptivityForest()`, `DMForestSetAdaptivityPurpose()`
4339be51f97SToby Isaac @*/
434ba936b91SToby Isaac PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt)
435dd8e54a2SToby Isaac {
436ba936b91SToby Isaac   DM_Forest      *forest;
437dd8e54a2SToby Isaac 
438dd8e54a2SToby Isaac   PetscFunctionBegin;
439dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
440ba936b91SToby Isaac   forest = (DM_Forest*) dm->data;
44126d9498aSToby Isaac   switch (forest->adaptPurpose) {
442cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
443ba936b91SToby Isaac     *adapt = forest->adapt;
44426d9498aSToby Isaac     break;
445a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
4469566063dSJacob Faibussowitsch     PetscCall(DMGetCoarseDM(dm,adapt));
44726d9498aSToby Isaac     break;
448a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
449bf2d5fbbSStefano Zampini   case DM_ADAPT_COARSEN_LAST:
4509566063dSJacob Faibussowitsch     PetscCall(DMGetFineDM(dm,adapt));
45126d9498aSToby Isaac     break;
45226d9498aSToby Isaac   default:
45326d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
45426d9498aSToby Isaac   }
45526d9498aSToby Isaac   PetscFunctionReturn(0);
45626d9498aSToby Isaac }
45726d9498aSToby Isaac 
4589be51f97SToby Isaac /*@
4599be51f97SToby Isaac   DMForestSetAdaptivityPurpose - During the pre-setup phase, set whether the current DM is being adapted from its
460a1b0c543SToby Isaac   source (set with DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening
461cd3c525cSToby Isaac   (DM_ADAPT_COARSEN), or undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting:
4629be51f97SToby Isaac   during DMDestroy(), cyclic references can be found between DMs only if the cyclic reference is due to a fine/coarse
4639be51f97SToby Isaac   relationship (see DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does
4649be51f97SToby Isaac   not maintain a reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can
4659be51f97SToby Isaac   cause a memory leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
4669be51f97SToby Isaac 
4679be51f97SToby Isaac   Logically collective on dm
4689be51f97SToby Isaac 
4699be51f97SToby Isaac   Input Parameters:
4709be51f97SToby Isaac + dm - the forest
471bf2d5fbbSStefano Zampini - purpose - the adaptivity purpose
4729be51f97SToby Isaac 
4739be51f97SToby Isaac   Level: advanced
4749be51f97SToby Isaac 
475db781477SPatrick Sanan .seealso: `DMForestTemplate()`, `DMForestSetAdaptivityForest()`, `DMForestGetAdaptivityForest()`, `DMAdaptFlag`
4769be51f97SToby Isaac @*/
477a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMAdaptFlag purpose)
47826d9498aSToby Isaac {
47926d9498aSToby Isaac   DM_Forest      *forest;
48026d9498aSToby Isaac 
48126d9498aSToby Isaac   PetscFunctionBegin;
48226d9498aSToby Isaac   forest = (DM_Forest*) dm->data;
48328b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
48426d9498aSToby Isaac   if (purpose != forest->adaptPurpose) {
48526d9498aSToby Isaac     DM adapt;
48626d9498aSToby Isaac 
4879566063dSJacob Faibussowitsch     PetscCall(DMForestGetAdaptivityForest(dm,&adapt));
4889566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)adapt));
4899566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm,NULL));
490f885a11aSToby Isaac 
49126d9498aSToby Isaac     forest->adaptPurpose = purpose;
492f885a11aSToby Isaac 
4939566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm,adapt));
4949566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&adapt));
49526d9498aSToby Isaac   }
496dd8e54a2SToby Isaac   PetscFunctionReturn(0);
497dd8e54a2SToby Isaac }
498dd8e54a2SToby Isaac 
49956c0450aSToby Isaac /*@
50056c0450aSToby Isaac   DMForestGetAdaptivityPurpose - Get whether the current DM is being adapted from its source (set with
501bf2d5fbbSStefano Zampini   DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening (DM_ADAPT_COARSEN),
502bf2d5fbbSStefano Zampini   coarsening only the last level (DM_ADAPT_COARSEN_LAST) or undefined (DM_ADAPT_DETERMINE).
503bf2d5fbbSStefano Zampini   This only matters for the purposes of reference counting: during DMDestroy(), cyclic
50456c0450aSToby Isaac   references can be found between DMs only if the cyclic reference is due to a fine/coarse relationship (see
50556c0450aSToby Isaac   DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does not maintain a
50656c0450aSToby Isaac   reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can cause a memory
50756c0450aSToby Isaac   leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
50856c0450aSToby Isaac 
50956c0450aSToby Isaac   Not collective
51056c0450aSToby Isaac 
51156c0450aSToby Isaac   Input Parameter:
51256c0450aSToby Isaac . dm - the forest
51356c0450aSToby Isaac 
51456c0450aSToby Isaac   Output Parameter:
515bf2d5fbbSStefano Zampini . purpose - the adaptivity purpose
51656c0450aSToby Isaac 
51756c0450aSToby Isaac   Level: advanced
51856c0450aSToby Isaac 
519db781477SPatrick Sanan .seealso: `DMForestTemplate()`, `DMForestSetAdaptivityForest()`, `DMForestGetAdaptivityForest()`, `DMAdaptFlag`
52056c0450aSToby Isaac @*/
521a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityPurpose(DM dm, DMAdaptFlag *purpose)
52256c0450aSToby Isaac {
52356c0450aSToby Isaac   DM_Forest *forest;
52456c0450aSToby Isaac 
52556c0450aSToby Isaac   PetscFunctionBegin;
52656c0450aSToby Isaac   forest   = (DM_Forest*) dm->data;
52756c0450aSToby Isaac   *purpose = forest->adaptPurpose;
52856c0450aSToby Isaac   PetscFunctionReturn(0);
52956c0450aSToby Isaac }
53056c0450aSToby Isaac 
5319be51f97SToby Isaac /*@
5329be51f97SToby Isaac   DMForestSetAdjacencyDimension - During the pre-setup phase, set the dimension of interface points that determine
5339be51f97SToby Isaac   cell adjacency (for the purposes of partitioning and overlap).
5349be51f97SToby Isaac 
5359be51f97SToby Isaac   Logically collective on dm
5369be51f97SToby Isaac 
5379be51f97SToby Isaac   Input Parameters:
5389be51f97SToby Isaac + dm - the forest
5399be51f97SToby Isaac - adjDim - default 0 (i.e., vertices determine adjacency)
5409be51f97SToby Isaac 
5419be51f97SToby Isaac   Level: intermediate
5429be51f97SToby Isaac 
543db781477SPatrick Sanan .seealso: `DMForestGetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()`, `DMForestSetPartitionOverlap()`
5449be51f97SToby Isaac @*/
545dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim)
546dd8e54a2SToby Isaac {
547dd8e54a2SToby Isaac   PetscInt       dim;
548dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
549dd8e54a2SToby Isaac 
550dd8e54a2SToby Isaac   PetscFunctionBegin;
551dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
55228b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup");
55363a3b9bcSJacob Faibussowitsch   PetscCheck(adjDim >= 0,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %" PetscInt_FMT, adjDim);
5549566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm,&dim));
55563a3b9bcSJacob Faibussowitsch   PetscCheck(adjDim <= dim,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %" PetscInt_FMT ": %" PetscInt_FMT, dim, adjDim);
556dd8e54a2SToby Isaac   forest->adjDim = adjDim;
557dd8e54a2SToby Isaac   PetscFunctionReturn(0);
558dd8e54a2SToby Isaac }
559dd8e54a2SToby Isaac 
5609be51f97SToby Isaac /*@
5619be51f97SToby Isaac   DMForestSetAdjacencyCodimension - Like DMForestSetAdjacencyDimension(), but specified as a co-dimension (so that,
5629be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
5639be51f97SToby Isaac 
5649be51f97SToby Isaac   Logically collective on dm
5659be51f97SToby Isaac 
5669be51f97SToby Isaac   Input Parameters:
5679be51f97SToby Isaac + dm - the forest
5689be51f97SToby Isaac - adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
5699be51f97SToby Isaac 
5709be51f97SToby Isaac   Level: intermediate
5719be51f97SToby Isaac 
572db781477SPatrick Sanan .seealso: `DMForestGetAdjacencyCodimension()`, `DMForestSetAdjacencyDimension()`
5739be51f97SToby Isaac @*/
574dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim)
575dd8e54a2SToby Isaac {
576dd8e54a2SToby Isaac   PetscInt       dim;
577dd8e54a2SToby Isaac 
578dd8e54a2SToby Isaac   PetscFunctionBegin;
579dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5809566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm,&dim));
5819566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdjacencyDimension(dm,dim-adjCodim));
582dd8e54a2SToby Isaac   PetscFunctionReturn(0);
583dd8e54a2SToby Isaac }
584dd8e54a2SToby Isaac 
5859be51f97SToby Isaac /*@
5869be51f97SToby Isaac   DMForestGetAdjacencyDimension - Get the dimension of interface points that determine cell adjacency (for the
5879be51f97SToby Isaac   purposes of partitioning and overlap).
5889be51f97SToby Isaac 
5899be51f97SToby Isaac   Not collective
5909be51f97SToby Isaac 
5919be51f97SToby Isaac   Input Parameter:
5929be51f97SToby Isaac . dm - the forest
5939be51f97SToby Isaac 
5949be51f97SToby Isaac   Output Parameter:
5959be51f97SToby Isaac . adjDim - default 0 (i.e., vertices determine adjacency)
5969be51f97SToby Isaac 
5979be51f97SToby Isaac   Level: intermediate
5989be51f97SToby Isaac 
599db781477SPatrick Sanan .seealso: `DMForestSetAdjacencyDimension()`, `DMForestGetAdjacencyCodimension()`, `DMForestSetPartitionOverlap()`
6009be51f97SToby Isaac @*/
601dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim)
602dd8e54a2SToby Isaac {
603dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
604dd8e54a2SToby Isaac 
605dd8e54a2SToby Isaac   PetscFunctionBegin;
606dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
607dd8e54a2SToby Isaac   PetscValidIntPointer(adjDim,2);
608dd8e54a2SToby Isaac   *adjDim = forest->adjDim;
609dd8e54a2SToby Isaac   PetscFunctionReturn(0);
610dd8e54a2SToby Isaac }
611dd8e54a2SToby Isaac 
6129be51f97SToby Isaac /*@
6139be51f97SToby Isaac   DMForestGetAdjacencyCodimension - Like DMForestGetAdjacencyDimension(), but specified as a co-dimension (so that,
6149be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
6159be51f97SToby Isaac 
6169be51f97SToby Isaac   Not collective
6179be51f97SToby Isaac 
6189be51f97SToby Isaac   Input Parameter:
6199be51f97SToby Isaac . dm - the forest
6209be51f97SToby Isaac 
6219be51f97SToby Isaac   Output Parameter:
6229be51f97SToby Isaac . adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
6239be51f97SToby Isaac 
6249be51f97SToby Isaac   Level: intermediate
6259be51f97SToby Isaac 
626db781477SPatrick Sanan .seealso: `DMForestSetAdjacencyCodimension()`, `DMForestGetAdjacencyDimension()`
6279be51f97SToby Isaac @*/
628dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim)
629dd8e54a2SToby Isaac {
630dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
631dd8e54a2SToby Isaac   PetscInt       dim;
632dd8e54a2SToby Isaac 
633dd8e54a2SToby Isaac   PetscFunctionBegin;
634dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
635dd8e54a2SToby Isaac   PetscValidIntPointer(adjCodim,2);
6369566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm,&dim));
637dd8e54a2SToby Isaac   *adjCodim = dim - forest->adjDim;
638dd8e54a2SToby Isaac   PetscFunctionReturn(0);
639dd8e54a2SToby Isaac }
640dd8e54a2SToby Isaac 
6419be51f97SToby Isaac /*@
6429be51f97SToby Isaac   DMForestSetPartitionOverlap - During the pre-setup phase, set the amount of cell-overlap present in parallel
6439be51f97SToby Isaac   partitions of a forest, with values > 0 indicating subdomains that are expanded by that many iterations of adding
6449be51f97SToby Isaac   adjacent cells
6459be51f97SToby Isaac 
6469be51f97SToby Isaac   Logically collective on dm
6479be51f97SToby Isaac 
6489be51f97SToby Isaac   Input Parameters:
6499be51f97SToby Isaac + dm - the forest
6509be51f97SToby Isaac - overlap - default 0
6519be51f97SToby Isaac 
6529be51f97SToby Isaac   Level: intermediate
6539be51f97SToby Isaac 
654db781477SPatrick Sanan .seealso: `DMForestGetPartitionOverlap()`, `DMForestSetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()`
6559be51f97SToby Isaac @*/
656dd8e54a2SToby Isaac PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap)
657dd8e54a2SToby Isaac {
658dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
659dd8e54a2SToby Isaac 
660dd8e54a2SToby Isaac   PetscFunctionBegin;
661dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
66228b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup");
66363a3b9bcSJacob Faibussowitsch   PetscCheck(overlap >= 0,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %" PetscInt_FMT, overlap);
664dd8e54a2SToby Isaac   forest->overlap = overlap;
665dd8e54a2SToby Isaac   PetscFunctionReturn(0);
666dd8e54a2SToby Isaac }
667dd8e54a2SToby Isaac 
6689be51f97SToby Isaac /*@
6699be51f97SToby Isaac   DMForestGetPartitionOverlap - Get the amount of cell-overlap present in parallel partitions of a forest, with values
6709be51f97SToby Isaac   > 0 indicating subdomains that are expanded by that many iterations of adding adjacent cells
6719be51f97SToby Isaac 
6729be51f97SToby Isaac   Not collective
6739be51f97SToby Isaac 
6749be51f97SToby Isaac   Input Parameter:
6759be51f97SToby Isaac . dm - the forest
6769be51f97SToby Isaac 
6779be51f97SToby Isaac   Output Parameter:
6789be51f97SToby Isaac . overlap - default 0
6799be51f97SToby Isaac 
6809be51f97SToby Isaac   Level: intermediate
6819be51f97SToby Isaac 
682db781477SPatrick Sanan .seealso: `DMForestGetPartitionOverlap()`, `DMForestSetAdjacencyDimension()`, `DMForestSetAdjacencyCodimension()`
6839be51f97SToby Isaac @*/
684dd8e54a2SToby Isaac PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap)
685dd8e54a2SToby Isaac {
686dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
687dd8e54a2SToby Isaac 
688dd8e54a2SToby Isaac   PetscFunctionBegin;
689dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
690dd8e54a2SToby Isaac   PetscValidIntPointer(overlap,2);
691dd8e54a2SToby Isaac   *overlap = forest->overlap;
692dd8e54a2SToby Isaac   PetscFunctionReturn(0);
693dd8e54a2SToby Isaac }
694dd8e54a2SToby Isaac 
6959be51f97SToby Isaac /*@
6969be51f97SToby Isaac   DMForestSetMinimumRefinement - During the pre-setup phase, set the minimum level of refinement (relative to the base
6979be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest
6989be51f97SToby Isaac   (see DMForestGetAdaptivityForest()) this limits the amount of coarsening.
6999be51f97SToby Isaac 
7009be51f97SToby Isaac   Logically collective on dm
7019be51f97SToby Isaac 
7029be51f97SToby Isaac   Input Parameters:
7039be51f97SToby Isaac + dm - the forest
7049be51f97SToby Isaac - minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7059be51f97SToby Isaac 
7069be51f97SToby Isaac   Level: intermediate
7079be51f97SToby Isaac 
708db781477SPatrick Sanan .seealso: `DMForestGetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestSetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()`
7099be51f97SToby Isaac @*/
710dd8e54a2SToby Isaac PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement)
711dd8e54a2SToby Isaac {
712dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
713dd8e54a2SToby Isaac 
714dd8e54a2SToby Isaac   PetscFunctionBegin;
715dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
71628b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup");
717dd8e54a2SToby Isaac   forest->minRefinement = minRefinement;
718dd8e54a2SToby Isaac   PetscFunctionReturn(0);
719dd8e54a2SToby Isaac }
720dd8e54a2SToby Isaac 
7219be51f97SToby Isaac /*@
7229be51f97SToby Isaac   DMForestGetMinimumRefinement - Get the minimum level of refinement (relative to the base DM, see
7239be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest (see
7249be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of coarsening.
7259be51f97SToby Isaac 
7269be51f97SToby Isaac   Not collective
7279be51f97SToby Isaac 
7289be51f97SToby Isaac   Input Parameter:
7299be51f97SToby Isaac . dm - the forest
7309be51f97SToby Isaac 
7319be51f97SToby Isaac   Output Parameter:
7329be51f97SToby Isaac . minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7339be51f97SToby Isaac 
7349be51f97SToby Isaac   Level: intermediate
7359be51f97SToby Isaac 
736db781477SPatrick Sanan .seealso: `DMForestSetMinimumRefinement()`, `DMForestGetMaximumRefinement()`, `DMForestGetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()`
7379be51f97SToby Isaac @*/
738dd8e54a2SToby Isaac PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement)
739dd8e54a2SToby Isaac {
740dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
741dd8e54a2SToby Isaac 
742dd8e54a2SToby Isaac   PetscFunctionBegin;
743dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
744dd8e54a2SToby Isaac   PetscValidIntPointer(minRefinement,2);
745dd8e54a2SToby Isaac   *minRefinement = forest->minRefinement;
746dd8e54a2SToby Isaac   PetscFunctionReturn(0);
747dd8e54a2SToby Isaac }
748dd8e54a2SToby Isaac 
7499be51f97SToby Isaac /*@
7509be51f97SToby Isaac   DMForestSetInitialRefinement - During the pre-setup phase, set the initial level of refinement (relative to the base
7519be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.
7529be51f97SToby Isaac 
7539be51f97SToby Isaac   Logically collective on dm
7549be51f97SToby Isaac 
7559be51f97SToby Isaac   Input Parameters:
7569be51f97SToby Isaac + dm - the forest
7579be51f97SToby Isaac - initefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7589be51f97SToby Isaac 
7599be51f97SToby Isaac   Level: intermediate
7609be51f97SToby Isaac 
761db781477SPatrick Sanan .seealso: `DMForestSetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestGetBaseDM()`
7629be51f97SToby Isaac @*/
76356ba9f64SToby Isaac PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement)
76456ba9f64SToby Isaac {
76556ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
76656ba9f64SToby Isaac 
76756ba9f64SToby Isaac   PetscFunctionBegin;
76856ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
76928b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the initial refinement after setup");
77056ba9f64SToby Isaac   forest->initRefinement = initRefinement;
77156ba9f64SToby Isaac   PetscFunctionReturn(0);
77256ba9f64SToby Isaac }
77356ba9f64SToby Isaac 
7749be51f97SToby Isaac /*@
7759be51f97SToby Isaac   DMForestGetInitialRefinement - Get the initial level of refinement (relative to the base DM, see
7769be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.
7779be51f97SToby Isaac 
7789be51f97SToby Isaac   Not collective
7799be51f97SToby Isaac 
7809be51f97SToby Isaac   Input Parameter:
7819be51f97SToby Isaac . dm - the forest
7829be51f97SToby Isaac 
78301d2d390SJose E. Roman   Output Parameter:
784bf2d5fbbSStefano Zampini . initRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7859be51f97SToby Isaac 
7869be51f97SToby Isaac   Level: intermediate
7879be51f97SToby Isaac 
788db781477SPatrick Sanan .seealso: `DMForestSetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestGetBaseDM()`
7899be51f97SToby Isaac @*/
79056ba9f64SToby Isaac PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement)
79156ba9f64SToby Isaac {
79256ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
79356ba9f64SToby Isaac 
79456ba9f64SToby Isaac   PetscFunctionBegin;
79556ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
79656ba9f64SToby Isaac   PetscValidIntPointer(initRefinement,2);
79756ba9f64SToby Isaac   *initRefinement = forest->initRefinement;
79856ba9f64SToby Isaac   PetscFunctionReturn(0);
79956ba9f64SToby Isaac }
80056ba9f64SToby Isaac 
8019be51f97SToby Isaac /*@
8029be51f97SToby Isaac   DMForestSetMaximumRefinement - During the pre-setup phase, set the maximum level of refinement (relative to the base
8039be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest
8049be51f97SToby Isaac   (see DMForestGetAdaptivityForest()), this limits the amount of refinement.
8059be51f97SToby Isaac 
8069be51f97SToby Isaac   Logically collective on dm
8079be51f97SToby Isaac 
8089be51f97SToby Isaac   Input Parameters:
8099be51f97SToby Isaac + dm - the forest
8109be51f97SToby Isaac - maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
8119be51f97SToby Isaac 
8129be51f97SToby Isaac   Level: intermediate
8139be51f97SToby Isaac 
814db781477SPatrick Sanan .seealso: `DMForestGetMinimumRefinement()`, `DMForestSetMaximumRefinement()`, `DMForestSetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityDM()`
8159be51f97SToby Isaac @*/
816c7eeac06SToby Isaac PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement)
817dd8e54a2SToby Isaac {
818dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
819dd8e54a2SToby Isaac 
820dd8e54a2SToby Isaac   PetscFunctionBegin;
821dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
82228b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup");
823c7eeac06SToby Isaac   forest->maxRefinement = maxRefinement;
824dd8e54a2SToby Isaac   PetscFunctionReturn(0);
825dd8e54a2SToby Isaac }
826dd8e54a2SToby Isaac 
8279be51f97SToby Isaac /*@
8289be51f97SToby Isaac   DMForestGetMaximumRefinement - Get the maximum level of refinement (relative to the base DM, see
8299be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest (see
8309be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of refinement.
8319be51f97SToby Isaac 
8329be51f97SToby Isaac   Not collective
8339be51f97SToby Isaac 
8349be51f97SToby Isaac   Input Parameter:
8359be51f97SToby Isaac . dm - the forest
8369be51f97SToby Isaac 
8379be51f97SToby Isaac   Output Parameter:
8389be51f97SToby Isaac . maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
8399be51f97SToby Isaac 
8409be51f97SToby Isaac   Level: intermediate
8419be51f97SToby Isaac 
842db781477SPatrick Sanan .seealso: `DMForestSetMaximumRefinement()`, `DMForestGetMinimumRefinement()`, `DMForestGetInitialRefinement()`, `DMForestGetBaseDM()`, `DMForestGetAdaptivityForest()`
8439be51f97SToby Isaac @*/
844c7eeac06SToby Isaac PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement)
845dd8e54a2SToby Isaac {
846dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
847dd8e54a2SToby Isaac 
848dd8e54a2SToby Isaac   PetscFunctionBegin;
849dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
850c7eeac06SToby Isaac   PetscValidIntPointer(maxRefinement,2);
851c7eeac06SToby Isaac   *maxRefinement = forest->maxRefinement;
852dd8e54a2SToby Isaac   PetscFunctionReturn(0);
853dd8e54a2SToby Isaac }
854c7eeac06SToby Isaac 
8559be51f97SToby Isaac /*@C
8569be51f97SToby Isaac   DMForestSetAdaptivityStrategy - During the pre-setup phase, set the strategy for combining adaptivity labels from multiple processes.
8579be51f97SToby Isaac   Subtypes of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all processes must agree
8589be51f97SToby Isaac   for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only one process needs to
8599be51f97SToby Isaac   specify refinement/coarsening.
8609be51f97SToby Isaac 
8619be51f97SToby Isaac   Logically collective on dm
8629be51f97SToby Isaac 
8639be51f97SToby Isaac   Input Parameters:
8649be51f97SToby Isaac + dm - the forest
8659be51f97SToby Isaac - adaptStrategy - default DMFORESTADAPTALL
8669be51f97SToby Isaac 
8679be51f97SToby Isaac   Level: advanced
8689be51f97SToby Isaac 
869db781477SPatrick Sanan .seealso: `DMForestGetAdaptivityStrategy()`
8709be51f97SToby Isaac @*/
871c7eeac06SToby Isaac PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy)
872c7eeac06SToby Isaac {
873c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
874c7eeac06SToby Isaac 
875c7eeac06SToby Isaac   PetscFunctionBegin;
876c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
8779566063dSJacob Faibussowitsch   PetscCall(PetscFree(forest->adaptStrategy));
8789566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy((const char*) adaptStrategy,(char**)&forest->adaptStrategy));
879c7eeac06SToby Isaac   PetscFunctionReturn(0);
880c7eeac06SToby Isaac }
881c7eeac06SToby Isaac 
8829be51f97SToby Isaac /*@C
8839be51f97SToby Isaac   DMForestSetAdaptivityStrategy - Get the strategy for combining adaptivity labels from multiple processes.  Subtypes
8849be51f97SToby Isaac   of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all
8859be51f97SToby Isaac   processes must agree for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only
8869be51f97SToby Isaac   one process needs to specify refinement/coarsening.
8879be51f97SToby Isaac 
8889be51f97SToby Isaac   Not collective
8899be51f97SToby Isaac 
8909be51f97SToby Isaac   Input Parameter:
8919be51f97SToby Isaac . dm - the forest
8929be51f97SToby Isaac 
8939be51f97SToby Isaac   Output Parameter:
8949be51f97SToby Isaac . adaptStrategy - the adaptivity strategy (default DMFORESTADAPTALL)
8959be51f97SToby Isaac 
8969be51f97SToby Isaac   Level: advanced
8979be51f97SToby Isaac 
898db781477SPatrick Sanan .seealso: `DMForestSetAdaptivityStrategy()`
8999be51f97SToby Isaac @*/
900c7eeac06SToby Isaac PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy)
901c7eeac06SToby Isaac {
902c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
903c7eeac06SToby Isaac 
904c7eeac06SToby Isaac   PetscFunctionBegin;
905c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
906c7eeac06SToby Isaac   PetscValidPointer(adaptStrategy,2);
907c7eeac06SToby Isaac   *adaptStrategy = forest->adaptStrategy;
908c7eeac06SToby Isaac   PetscFunctionReturn(0);
909c7eeac06SToby Isaac }
910c7eeac06SToby Isaac 
9112a133e43SToby Isaac /*@
9122a133e43SToby Isaac   DMForestGetAdaptivitySuccess - Return whether the requested adaptation (refinement, coarsening, repartitioning,
9132a133e43SToby Isaac   etc.) was successful.  PETSC_FALSE indicates that the post-adaptation forest is the same as the pre-adpatation
9142a133e43SToby Isaac   forest.  A requested adaptation may have been unsuccessful if, for example, the requested refinement would have
9152a133e43SToby Isaac   exceeded the maximum refinement level.
9162a133e43SToby Isaac 
9172a133e43SToby Isaac   Collective on dm
9182a133e43SToby Isaac 
9192a133e43SToby Isaac   Input Parameter:
9202a133e43SToby Isaac 
9212a133e43SToby Isaac . dm - the post-adaptation forest
9222a133e43SToby Isaac 
9232a133e43SToby Isaac   Output Parameter:
9242a133e43SToby Isaac 
9252a133e43SToby Isaac . success - PETSC_TRUE if the post-adaptation forest is different from the pre-adaptation forest.
9262a133e43SToby Isaac 
9272a133e43SToby Isaac   Level: intermediate
9282a133e43SToby Isaac 
9292a133e43SToby Isaac .see
9302a133e43SToby Isaac @*/
9312a133e43SToby Isaac PetscErrorCode DMForestGetAdaptivitySuccess(DM dm, PetscBool *success)
9322a133e43SToby Isaac {
9332a133e43SToby Isaac   DM_Forest      *forest;
9342a133e43SToby Isaac 
9352a133e43SToby Isaac   PetscFunctionBegin;
9362a133e43SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
93728b400f6SJacob Faibussowitsch   PetscCheck(dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() has not been called yet.");
9382a133e43SToby Isaac   forest = (DM_Forest *) dm->data;
9399566063dSJacob Faibussowitsch   PetscCall((forest->getadaptivitysuccess)(dm,success));
9402a133e43SToby Isaac   PetscFunctionReturn(0);
9412a133e43SToby Isaac }
9422a133e43SToby Isaac 
943bf9b5d84SToby Isaac /*@
944bf9b5d84SToby Isaac   DMForestSetComputeAdaptivitySF - During the pre-setup phase, set whether transfer PetscSFs should be computed
945bf9b5d84SToby 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().
946bf9b5d84SToby Isaac 
947bf9b5d84SToby Isaac   Logically collective on dm
948bf9b5d84SToby Isaac 
949bf9b5d84SToby Isaac   Input Parameters:
950bf9b5d84SToby Isaac + dm - the post-adaptation forest
951bf9b5d84SToby Isaac - computeSF - default PETSC_TRUE
952bf9b5d84SToby Isaac 
953bf9b5d84SToby Isaac   Level: advanced
954bf9b5d84SToby Isaac 
955db781477SPatrick Sanan .seealso: `DMForestGetComputeAdaptivitySF()`, `DMForestGetAdaptivitySF()`
956bf9b5d84SToby Isaac @*/
957bf9b5d84SToby Isaac PetscErrorCode DMForestSetComputeAdaptivitySF(DM dm, PetscBool computeSF)
958bf9b5d84SToby Isaac {
959bf9b5d84SToby Isaac   DM_Forest *forest;
960bf9b5d84SToby Isaac 
961bf9b5d84SToby Isaac   PetscFunctionBegin;
962bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
96328b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot compute adaptivity PetscSFs after setup is called");
964bf9b5d84SToby Isaac   forest                 = (DM_Forest*) dm->data;
965bf9b5d84SToby Isaac   forest->computeAdaptSF = computeSF;
966bf9b5d84SToby Isaac   PetscFunctionReturn(0);
967bf9b5d84SToby Isaac }
968bf9b5d84SToby Isaac 
9690eb7e1eaSToby Isaac PetscErrorCode DMForestTransferVec(DM dmIn, Vec vecIn, DM dmOut, Vec vecOut, PetscBool useBCs, PetscReal time)
97080b27e07SToby Isaac {
97180b27e07SToby Isaac   DM_Forest      *forest;
97280b27e07SToby Isaac 
97380b27e07SToby Isaac   PetscFunctionBegin;
97480b27e07SToby Isaac   PetscValidHeaderSpecific(dmIn   ,DM_CLASSID  ,1);
97580b27e07SToby Isaac   PetscValidHeaderSpecific(vecIn  ,VEC_CLASSID ,2);
97680b27e07SToby Isaac   PetscValidHeaderSpecific(dmOut  ,DM_CLASSID  ,3);
97780b27e07SToby Isaac   PetscValidHeaderSpecific(vecOut ,VEC_CLASSID ,4);
97880b27e07SToby Isaac   forest = (DM_Forest *) dmIn->data;
97928b400f6SJacob Faibussowitsch   PetscCheck(forest->transfervec,PetscObjectComm((PetscObject)dmIn),PETSC_ERR_SUP,"DMForestTransferVec() not implemented");
9809566063dSJacob Faibussowitsch   PetscCall((forest->transfervec)(dmIn,vecIn,dmOut,vecOut,useBCs,time));
98180b27e07SToby Isaac   PetscFunctionReturn(0);
98280b27e07SToby Isaac }
98380b27e07SToby Isaac 
984ac34a06fSStefano Zampini PetscErrorCode DMForestTransferVecFromBase(DM dm, Vec vecIn, Vec vecOut)
985ac34a06fSStefano Zampini {
986ac34a06fSStefano Zampini   DM_Forest      *forest;
987ac34a06fSStefano Zampini 
988ac34a06fSStefano Zampini   PetscFunctionBegin;
989ac34a06fSStefano Zampini   PetscValidHeaderSpecific(dm   ,DM_CLASSID  ,1);
990ac34a06fSStefano Zampini   PetscValidHeaderSpecific(vecIn  ,VEC_CLASSID ,2);
991ac34a06fSStefano Zampini   PetscValidHeaderSpecific(vecOut ,VEC_CLASSID ,3);
992ac34a06fSStefano Zampini   forest = (DM_Forest *) dm->data;
99328b400f6SJacob Faibussowitsch   PetscCheck(forest->transfervecfrombase,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"DMForestTransferVecFromBase() not implemented");
9949566063dSJacob Faibussowitsch   PetscCall((forest->transfervecfrombase)(dm,vecIn,vecOut));
995ac34a06fSStefano Zampini   PetscFunctionReturn(0);
996ac34a06fSStefano Zampini }
997ac34a06fSStefano Zampini 
998bf9b5d84SToby Isaac /*@
999bf9b5d84SToby Isaac   DMForestGetComputeAdaptivitySF - Get whether transfer PetscSFs should be computed relating the cells of the
1000bf9b5d84SToby Isaac   pre-adaptation forest to the post-adaptiation forest.  After DMSetUp() is called, these transfer PetscSFs can be
1001bf9b5d84SToby Isaac   accessed with DMForestGetAdaptivitySF().
1002bf9b5d84SToby Isaac 
1003bf9b5d84SToby Isaac   Not collective
1004bf9b5d84SToby Isaac 
1005bf9b5d84SToby Isaac   Input Parameter:
1006bf9b5d84SToby Isaac . dm - the post-adaptation forest
1007bf9b5d84SToby Isaac 
1008bf9b5d84SToby Isaac   Output Parameter:
1009bf9b5d84SToby Isaac . computeSF - default PETSC_TRUE
1010bf9b5d84SToby Isaac 
1011bf9b5d84SToby Isaac   Level: advanced
1012bf9b5d84SToby Isaac 
1013db781477SPatrick Sanan .seealso: `DMForestSetComputeAdaptivitySF()`, `DMForestGetAdaptivitySF()`
1014bf9b5d84SToby Isaac @*/
1015bf9b5d84SToby Isaac PetscErrorCode DMForestGetComputeAdaptivitySF(DM dm, PetscBool *computeSF)
1016bf9b5d84SToby Isaac {
1017bf9b5d84SToby Isaac   DM_Forest *forest;
1018bf9b5d84SToby Isaac 
1019bf9b5d84SToby Isaac   PetscFunctionBegin;
1020bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1021bf9b5d84SToby Isaac   forest     = (DM_Forest*) dm->data;
1022bf9b5d84SToby Isaac   *computeSF = forest->computeAdaptSF;
1023bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1024bf9b5d84SToby Isaac }
1025bf9b5d84SToby Isaac 
1026bf9b5d84SToby Isaac /*@
1027bf9b5d84SToby Isaac   DMForestGetAdaptivitySF - Get PetscSFs that relate the pre-adaptation forest to the post-adaptation forest.
1028bf9b5d84SToby Isaac   Adaptation can be any combination of refinement, coarsening, repartition, and change of overlap, so there may be
1029bf9b5d84SToby Isaac   some cells of the pre-adaptation that are parents of post-adaptation cells, and vice versa.  Therefore there are two
1030bf9b5d84SToby Isaac   PetscSFs: one that relates pre-adaptation coarse cells to post-adaptation fine cells, and one that relates
1031bf9b5d84SToby Isaac   pre-adaptation fine cells to post-adaptation coarse cells.
1032bf9b5d84SToby Isaac 
1033bf9b5d84SToby Isaac   Not collective
1034bf9b5d84SToby Isaac 
1035bf9b5d84SToby Isaac   Input Parameter:
1036bf9b5d84SToby Isaac   dm - the post-adaptation forest
1037bf9b5d84SToby Isaac 
1038bf9b5d84SToby Isaac   Output Parameter:
10390f17b9e3SToby Isaac   preCoarseToFine - pre-adaptation coarse cells to post-adaptation fine cells: BCast goes from pre- to post-
10400f17b9e3SToby Isaac   coarseToPreFine - post-adaptation coarse cells to pre-adaptation fine cells: BCast goes from post- to pre-
1041bf9b5d84SToby Isaac 
1042bf9b5d84SToby Isaac   Level: advanced
1043bf9b5d84SToby Isaac 
1044db781477SPatrick Sanan .seealso: `DMForestGetComputeAdaptivitySF()`, `DMForestSetComputeAdaptivitySF()`
1045bf9b5d84SToby Isaac @*/
10460f17b9e3SToby Isaac PetscErrorCode DMForestGetAdaptivitySF(DM dm, PetscSF *preCoarseToFine, PetscSF *coarseToPreFine)
1047bf9b5d84SToby Isaac {
1048bf9b5d84SToby Isaac   DM_Forest      *forest;
1049bf9b5d84SToby Isaac 
1050bf9b5d84SToby Isaac   PetscFunctionBegin;
1051bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
10529566063dSJacob Faibussowitsch   PetscCall(DMSetUp(dm));
1053bf9b5d84SToby Isaac   forest = (DM_Forest*) dm->data;
1054f885a11aSToby Isaac   if (preCoarseToFine) *preCoarseToFine = forest->preCoarseToFine;
1055f885a11aSToby Isaac   if (coarseToPreFine) *coarseToPreFine = forest->coarseToPreFine;
1056bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1057bf9b5d84SToby Isaac }
1058bf9b5d84SToby Isaac 
10599be51f97SToby Isaac /*@
10609be51f97SToby Isaac   DMForestSetGradeFactor - During the pre-setup phase, set the desired amount of grading in the mesh, e.g. give 2 to
10619be51f97SToby Isaac   indicate that the diameter of neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may
10629be51f97SToby Isaac   only support one particular choice of grading factor.
10639be51f97SToby Isaac 
10649be51f97SToby Isaac   Logically collective on dm
10659be51f97SToby Isaac 
10669be51f97SToby Isaac   Input Parameters:
10679be51f97SToby Isaac + dm - the forest
10689be51f97SToby Isaac - grade - the grading factor
10699be51f97SToby Isaac 
10709be51f97SToby Isaac   Level: advanced
10719be51f97SToby Isaac 
1072db781477SPatrick Sanan .seealso: `DMForestGetGradeFactor()`
10739be51f97SToby Isaac @*/
1074c7eeac06SToby Isaac PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade)
1075c7eeac06SToby Isaac {
1076c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1077c7eeac06SToby Isaac 
1078c7eeac06SToby Isaac   PetscFunctionBegin;
1079c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
108028b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup");
1081c7eeac06SToby Isaac   forest->gradeFactor = grade;
1082c7eeac06SToby Isaac   PetscFunctionReturn(0);
1083c7eeac06SToby Isaac }
1084c7eeac06SToby Isaac 
10859be51f97SToby Isaac /*@
10869be51f97SToby Isaac   DMForestGetGradeFactor - Get the desired amount of grading in the mesh, e.g. give 2 to indicate that the diameter of
10879be51f97SToby Isaac   neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may only support one particular
10889be51f97SToby Isaac   choice of grading factor.
10899be51f97SToby Isaac 
10909be51f97SToby Isaac   Not collective
10919be51f97SToby Isaac 
10929be51f97SToby Isaac   Input Parameter:
10939be51f97SToby Isaac . dm - the forest
10949be51f97SToby Isaac 
10959be51f97SToby Isaac   Output Parameter:
10969be51f97SToby Isaac . grade - the grading factor
10979be51f97SToby Isaac 
10989be51f97SToby Isaac   Level: advanced
10999be51f97SToby Isaac 
1100db781477SPatrick Sanan .seealso: `DMForestSetGradeFactor()`
11019be51f97SToby Isaac @*/
1102c7eeac06SToby Isaac PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade)
1103c7eeac06SToby Isaac {
1104c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1105c7eeac06SToby Isaac 
1106c7eeac06SToby Isaac   PetscFunctionBegin;
1107c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1108c7eeac06SToby Isaac   PetscValidIntPointer(grade,2);
1109c7eeac06SToby Isaac   *grade = forest->gradeFactor;
1110c7eeac06SToby Isaac   PetscFunctionReturn(0);
1111c7eeac06SToby Isaac }
1112c7eeac06SToby Isaac 
11139be51f97SToby Isaac /*@
11149be51f97SToby Isaac   DMForestSetCellWeightFactor - During the pre-setup phase, set the factor by which the level of refinement changes
11159be51f97SToby Isaac   the cell weight (see DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be
11169be51f97SToby Isaac   (cellWeight) * (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on
11179be51f97SToby Isaac   its level; a factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the
11189be51f97SToby Isaac   computation associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11199be51f97SToby Isaac 
11209be51f97SToby Isaac   Logically collective on dm
11219be51f97SToby Isaac 
11229be51f97SToby Isaac   Input Parameters:
11239be51f97SToby Isaac + dm - the forest
11249be51f97SToby Isaac - weightsFactors - default 1.
11259be51f97SToby Isaac 
11269be51f97SToby Isaac   Level: advanced
11279be51f97SToby Isaac 
1128db781477SPatrick Sanan .seealso: `DMForestGetCellWeightFactor()`, `DMForestSetCellWeights()`
11299be51f97SToby Isaac @*/
1130ef51cf95SToby Isaac PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor)
1131c7eeac06SToby Isaac {
1132c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1133c7eeac06SToby Isaac 
1134c7eeac06SToby Isaac   PetscFunctionBegin;
1135c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
113628b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup");
1137c7eeac06SToby Isaac   forest->weightsFactor = weightsFactor;
1138c7eeac06SToby Isaac   PetscFunctionReturn(0);
1139c7eeac06SToby Isaac }
1140c7eeac06SToby Isaac 
11419be51f97SToby Isaac /*@
11429be51f97SToby Isaac   DMForestGetCellWeightFactor - Get the factor by which the level of refinement changes the cell weight (see
11439be51f97SToby Isaac   DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be (cellWeight) *
11449be51f97SToby Isaac   (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on its level; a
11459be51f97SToby Isaac   factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the computation
11469be51f97SToby Isaac   associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11479be51f97SToby Isaac 
11489be51f97SToby Isaac   Not collective
11499be51f97SToby Isaac 
11509be51f97SToby Isaac   Input Parameter:
11519be51f97SToby Isaac . dm - the forest
11529be51f97SToby Isaac 
11539be51f97SToby Isaac   Output Parameter:
11549be51f97SToby Isaac . weightsFactors - default 1.
11559be51f97SToby Isaac 
11569be51f97SToby Isaac   Level: advanced
11579be51f97SToby Isaac 
1158db781477SPatrick Sanan .seealso: `DMForestSetCellWeightFactor()`, `DMForestSetCellWeights()`
11599be51f97SToby Isaac @*/
1160ef51cf95SToby Isaac PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor)
1161c7eeac06SToby Isaac {
1162c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1163c7eeac06SToby Isaac 
1164c7eeac06SToby Isaac   PetscFunctionBegin;
1165c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1166c7eeac06SToby Isaac   PetscValidRealPointer(weightsFactor,2);
1167c7eeac06SToby Isaac   *weightsFactor = forest->weightsFactor;
1168c7eeac06SToby Isaac   PetscFunctionReturn(0);
1169c7eeac06SToby Isaac }
1170c7eeac06SToby Isaac 
11719be51f97SToby Isaac /*@
11729be51f97SToby Isaac   DMForestGetCellChart - After the setup phase, get the local half-open interval of the chart of cells on this process
11739be51f97SToby Isaac 
11749be51f97SToby Isaac   Not collective
11759be51f97SToby Isaac 
11769be51f97SToby Isaac   Input Parameter:
11779be51f97SToby Isaac . dm - the forest
11789be51f97SToby Isaac 
11799be51f97SToby Isaac   Output Parameters:
11809be51f97SToby Isaac + cStart - the first cell on this process
11819be51f97SToby Isaac - cEnd - one after the final cell on this process
11829be51f97SToby Isaac 
11831a244344SSatish Balay   Level: intermediate
11849be51f97SToby Isaac 
1185db781477SPatrick Sanan .seealso: `DMForestGetCellSF()`
11869be51f97SToby Isaac @*/
1187c7eeac06SToby Isaac PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd)
1188c7eeac06SToby Isaac {
1189c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1190c7eeac06SToby Isaac 
1191c7eeac06SToby Isaac   PetscFunctionBegin;
1192c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1193c7eeac06SToby Isaac   PetscValidIntPointer(cStart,2);
1194064a246eSJacob Faibussowitsch   PetscValidIntPointer(cEnd,3);
1195c7eeac06SToby Isaac   if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) {
11969566063dSJacob Faibussowitsch     PetscCall(forest->createcellchart(dm,&forest->cStart,&forest->cEnd));
1197c7eeac06SToby Isaac   }
1198c7eeac06SToby Isaac   *cStart =  forest->cStart;
1199c7eeac06SToby Isaac   *cEnd   =  forest->cEnd;
1200c7eeac06SToby Isaac   PetscFunctionReturn(0);
1201c7eeac06SToby Isaac }
1202c7eeac06SToby Isaac 
12039be51f97SToby Isaac /*@
12049be51f97SToby Isaac   DMForestGetCellSF - After the setup phase, get the PetscSF for overlapping cells between processes
12059be51f97SToby Isaac 
12069be51f97SToby Isaac   Not collective
12079be51f97SToby Isaac 
12089be51f97SToby Isaac   Input Parameter:
12099be51f97SToby Isaac . dm - the forest
12109be51f97SToby Isaac 
12119be51f97SToby Isaac   Output Parameter:
12129be51f97SToby Isaac . cellSF - the PetscSF
12139be51f97SToby Isaac 
12141a244344SSatish Balay   Level: intermediate
12159be51f97SToby Isaac 
1216db781477SPatrick Sanan .seealso: `DMForestGetCellChart()`
12179be51f97SToby Isaac @*/
1218c7eeac06SToby Isaac PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF)
1219c7eeac06SToby Isaac {
1220c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1221c7eeac06SToby Isaac 
1222c7eeac06SToby Isaac   PetscFunctionBegin;
1223c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1224c7eeac06SToby Isaac   PetscValidPointer(cellSF,2);
1225c7eeac06SToby Isaac   if ((!forest->cellSF) && forest->createcellsf) {
12269566063dSJacob Faibussowitsch     PetscCall(forest->createcellsf(dm,&forest->cellSF));
1227c7eeac06SToby Isaac   }
1228c7eeac06SToby Isaac   *cellSF = forest->cellSF;
1229c7eeac06SToby Isaac   PetscFunctionReturn(0);
1230c7eeac06SToby Isaac }
1231c7eeac06SToby Isaac 
12329be51f97SToby Isaac /*@C
12339be51f97SToby Isaac   DMForestSetAdaptivityLabel - During the pre-setup phase, set the label of the pre-adaptation forest (see
12349be51f97SToby Isaac   DMForestGetAdaptivityForest()) that holds the adaptation flags (refinement, coarsening, or some combination).  The
1235cd3c525cSToby Isaac   interpretation of the label values is up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP,
1236cd3c525cSToby Isaac   DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have been reserved as choices that should be accepted by all subtypes.
12379be51f97SToby Isaac 
12389be51f97SToby Isaac   Logically collective on dm
12399be51f97SToby Isaac 
12409be51f97SToby Isaac   Input Parameters:
12419be51f97SToby Isaac - dm - the forest
1242a1b0c543SToby Isaac + adaptLabel - the label in the pre-adaptation forest
12439be51f97SToby Isaac 
12449be51f97SToby Isaac   Level: intermediate
12459be51f97SToby Isaac 
1246db781477SPatrick Sanan .seealso `DMForestGetAdaptivityLabel()`
12479be51f97SToby Isaac @*/
1248a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityLabel(DM dm, DMLabel adaptLabel)
1249c7eeac06SToby Isaac {
1250c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1251c7eeac06SToby Isaac 
1252c7eeac06SToby Isaac   PetscFunctionBegin;
1253c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12541fd50544SStefano Zampini   if (adaptLabel) PetscValidHeaderSpecific(adaptLabel,DMLABEL_CLASSID,2);
12559566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)adaptLabel));
12569566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&forest->adaptLabel));
12571fd50544SStefano Zampini   forest->adaptLabel = adaptLabel;
1258c7eeac06SToby Isaac   PetscFunctionReturn(0);
1259c7eeac06SToby Isaac }
1260c7eeac06SToby Isaac 
12619be51f97SToby Isaac /*@C
12629be51f97SToby Isaac   DMForestGetAdaptivityLabel - Get the label of the pre-adaptation forest (see DMForestGetAdaptivityForest()) that
12639be51f97SToby Isaac   holds the adaptation flags (refinement, coarsening, or some combination).  The interpretation of the label values is
1264cd3c525cSToby Isaac   up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have
1265cd3c525cSToby Isaac   been reserved as choices that should be accepted by all subtypes.
12669be51f97SToby Isaac 
12679be51f97SToby Isaac   Not collective
12689be51f97SToby Isaac 
12699be51f97SToby Isaac   Input Parameter:
12709be51f97SToby Isaac . dm - the forest
12719be51f97SToby Isaac 
12729be51f97SToby Isaac   Output Parameter:
12739be51f97SToby Isaac . adaptLabel - the name of the label in the pre-adaptation forest
12749be51f97SToby Isaac 
12759be51f97SToby Isaac   Level: intermediate
12769be51f97SToby Isaac 
1277db781477SPatrick Sanan .seealso `DMForestSetAdaptivityLabel()`
12789be51f97SToby Isaac @*/
1279a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityLabel(DM dm, DMLabel *adaptLabel)
1280c7eeac06SToby Isaac {
1281c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1282c7eeac06SToby Isaac 
1283c7eeac06SToby Isaac   PetscFunctionBegin;
1284c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1285ba936b91SToby Isaac   *adaptLabel = forest->adaptLabel;
1286c7eeac06SToby Isaac   PetscFunctionReturn(0);
1287c7eeac06SToby Isaac }
1288c7eeac06SToby Isaac 
12899be51f97SToby Isaac /*@
12909be51f97SToby Isaac   DMForestSetCellWeights - Set the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
12919be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
12929be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
12939be51f97SToby Isaac   of 1.
12949be51f97SToby Isaac 
12959be51f97SToby Isaac   Logically collective on dm
12969be51f97SToby Isaac 
12979be51f97SToby Isaac   Input Parameters:
12989be51f97SToby Isaac + dm - the forest
12999be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
13009be51f97SToby Isaac - copyMode - how weights should reference weights
13019be51f97SToby Isaac 
13029be51f97SToby Isaac   Level: advanced
13039be51f97SToby Isaac 
1304db781477SPatrick Sanan .seealso: `DMForestGetCellWeights()`, `DMForestSetWeightCapacity()`
13059be51f97SToby Isaac @*/
1306c7eeac06SToby Isaac PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode)
1307c7eeac06SToby Isaac {
1308c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1309c7eeac06SToby Isaac   PetscInt       cStart, cEnd;
1310c7eeac06SToby Isaac 
1311c7eeac06SToby Isaac   PetscFunctionBegin;
1312c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
13139566063dSJacob Faibussowitsch   PetscCall(DMForestGetCellChart(dm,&cStart,&cEnd));
131463a3b9bcSJacob Faibussowitsch   PetscCheck(cEnd >= cStart,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%" PetscInt_FMT ",%" PetscInt_FMT ") is not valid",cStart,cEnd);
1315c7eeac06SToby Isaac   if (copyMode == PETSC_COPY_VALUES) {
1316c7eeac06SToby Isaac     if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) {
13179566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(cEnd-cStart,&forest->cellWeights));
1318c7eeac06SToby Isaac     }
13199566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(forest->cellWeights,weights,cEnd-cStart));
1320c7eeac06SToby Isaac     forest->cellWeightsCopyMode = PETSC_OWN_POINTER;
1321c7eeac06SToby Isaac     PetscFunctionReturn(0);
1322c7eeac06SToby Isaac   }
1323c7eeac06SToby Isaac   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) {
13249566063dSJacob Faibussowitsch     PetscCall(PetscFree(forest->cellWeights));
1325c7eeac06SToby Isaac   }
1326c7eeac06SToby Isaac   forest->cellWeights         = weights;
1327c7eeac06SToby Isaac   forest->cellWeightsCopyMode = copyMode;
1328c7eeac06SToby Isaac   PetscFunctionReturn(0);
1329c7eeac06SToby Isaac }
1330c7eeac06SToby Isaac 
13319be51f97SToby Isaac /*@
13329be51f97SToby Isaac   DMForestGetCellWeights - Get the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
13339be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
13349be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
13359be51f97SToby Isaac   of 1.
13369be51f97SToby Isaac 
13379be51f97SToby Isaac   Not collective
13389be51f97SToby Isaac 
13399be51f97SToby Isaac   Input Parameter:
13409be51f97SToby Isaac . dm - the forest
13419be51f97SToby Isaac 
13429be51f97SToby Isaac   Output Parameter:
13439be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
13449be51f97SToby Isaac 
13459be51f97SToby Isaac   Level: advanced
13469be51f97SToby Isaac 
1347db781477SPatrick Sanan .seealso: `DMForestSetCellWeights()`, `DMForestSetWeightCapacity()`
13489be51f97SToby Isaac @*/
1349c7eeac06SToby Isaac PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights)
1350c7eeac06SToby Isaac {
1351c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1352c7eeac06SToby Isaac 
1353c7eeac06SToby Isaac   PetscFunctionBegin;
1354c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1355c7eeac06SToby Isaac   PetscValidPointer(weights,2);
1356c7eeac06SToby Isaac   *weights = forest->cellWeights;
1357c7eeac06SToby Isaac   PetscFunctionReturn(0);
1358c7eeac06SToby Isaac }
1359c7eeac06SToby Isaac 
13609be51f97SToby Isaac /*@
13619be51f97SToby Isaac   DMForestSetWeightCapacity - During the pre-setup phase, set the capacity of the current process when repartitioning
13629be51f97SToby Isaac   a pre-adaptation forest (see DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each
13639be51f97SToby Isaac   process's cells to the process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that
13649be51f97SToby Isaac   the current process should not have any cells after repartitioning.
13659be51f97SToby Isaac 
13669be51f97SToby Isaac   Logically Collective on dm
13679be51f97SToby Isaac 
13689be51f97SToby Isaac   Input parameters:
13699be51f97SToby Isaac + dm - the forest
13709be51f97SToby Isaac - capacity - this process's capacity
13719be51f97SToby Isaac 
13729be51f97SToby Isaac   Level: advanced
13739be51f97SToby Isaac 
1374db781477SPatrick Sanan .seealso `DMForestGetWeightCapacity()`, `DMForestSetCellWeights()`, `DMForestSetCellWeightFactor()`
13759be51f97SToby Isaac @*/
1376c7eeac06SToby Isaac PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity)
1377c7eeac06SToby Isaac {
1378c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1379c7eeac06SToby Isaac 
1380c7eeac06SToby Isaac   PetscFunctionBegin;
1381c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
138228b400f6SJacob Faibussowitsch   PetscCheck(!dm->setupcalled,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup");
138363a3b9bcSJacob Faibussowitsch   PetscCheck(capacity >= 0.,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %g",(double)capacity);
1384c7eeac06SToby Isaac   forest->weightCapacity = capacity;
1385c7eeac06SToby Isaac   PetscFunctionReturn(0);
1386c7eeac06SToby Isaac }
1387c7eeac06SToby Isaac 
13889be51f97SToby Isaac /*@
13899be51f97SToby Isaac   DMForestGetWeightCapacity - Set the capacity of the current process when repartitioning a pre-adaptation forest (see
13909be51f97SToby Isaac   DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each process's cells to the
13919be51f97SToby Isaac   process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that the current process
13929be51f97SToby Isaac   should not have any cells after repartitioning.
13939be51f97SToby Isaac 
13949be51f97SToby Isaac   Not collective
13959be51f97SToby Isaac 
13969be51f97SToby Isaac   Input parameter:
13979be51f97SToby Isaac . dm - the forest
13989be51f97SToby Isaac 
13999be51f97SToby Isaac   Output parameter:
14009be51f97SToby Isaac . capacity - this process's capacity
14019be51f97SToby Isaac 
14029be51f97SToby Isaac   Level: advanced
14039be51f97SToby Isaac 
1404db781477SPatrick Sanan .seealso `DMForestSetWeightCapacity()`, `DMForestSetCellWeights()`, `DMForestSetCellWeightFactor()`
14059be51f97SToby Isaac @*/
1406c7eeac06SToby Isaac PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity)
1407c7eeac06SToby Isaac {
1408c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1409c7eeac06SToby Isaac 
1410c7eeac06SToby Isaac   PetscFunctionBegin;
1411c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1412c7eeac06SToby Isaac   PetscValidRealPointer(capacity,2);
1413c7eeac06SToby Isaac   *capacity = forest->weightCapacity;
1414c7eeac06SToby Isaac   PetscFunctionReturn(0);
1415c7eeac06SToby Isaac }
1416c7eeac06SToby Isaac 
14170709b2feSToby Isaac PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptionItems *PetscOptionsObject,DM dm)
1418db4d5e8cSToby Isaac {
141956ba9f64SToby Isaac   PetscBool                  flg, flg1, flg2, flg3, flg4;
1420dd8e54a2SToby Isaac   DMForestTopology           oldTopo;
1421c7eeac06SToby Isaac   char                       stringBuffer[256];
1422dd8e54a2SToby Isaac   PetscViewer                viewer;
1423dd8e54a2SToby Isaac   PetscViewerFormat          format;
142456ba9f64SToby Isaac   PetscInt                   adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade;
1425c7eeac06SToby Isaac   PetscReal                  weightsFactor;
1426c7eeac06SToby Isaac   DMForestAdaptivityStrategy adaptStrategy;
1427db4d5e8cSToby Isaac 
1428db4d5e8cSToby Isaac   PetscFunctionBegin;
1429db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
14309566063dSJacob Faibussowitsch   PetscCall(DMForestGetTopology(dm, &oldTopo));
1431d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject,"DMForest Options");
14329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,sizeof(stringBuffer),&flg1));
14339566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg2));
14349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg3));
14359566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg4));
14361dca8a05SBarry 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}");
143756ba9f64SToby Isaac   if (flg1) {
14389566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm,(DMForestTopology)stringBuffer));
14399566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm,NULL));
14409566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm,NULL));
144156ba9f64SToby Isaac   }
144256ba9f64SToby Isaac   if (flg2) {
1443dd8e54a2SToby Isaac     DM base;
1444dd8e54a2SToby Isaac 
14459566063dSJacob Faibussowitsch     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm),&base));
14469566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer,format));
14479566063dSJacob Faibussowitsch     PetscCall(DMLoad(base,viewer));
14489566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
14499566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm,base));
14509566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&base));
14519566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm,NULL));
14529566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm,NULL));
1453dd8e54a2SToby Isaac   }
145456ba9f64SToby Isaac   if (flg3) {
1455dd8e54a2SToby Isaac     DM coarse;
1456dd8e54a2SToby Isaac 
14579566063dSJacob Faibussowitsch     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm),&coarse));
14589566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer,format));
14599566063dSJacob Faibussowitsch     PetscCall(DMLoad(coarse,viewer));
14609566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
14619566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm,coarse));
14629566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&coarse));
14639566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm,NULL));
14649566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm,NULL));
1465dd8e54a2SToby Isaac   }
146656ba9f64SToby Isaac   if (flg4) {
1467dd8e54a2SToby Isaac     DM fine;
1468dd8e54a2SToby Isaac 
14699566063dSJacob Faibussowitsch     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm),&fine));
14709566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer,format));
14719566063dSJacob Faibussowitsch     PetscCall(DMLoad(fine,viewer));
14729566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
14739566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdaptivityForest(dm,fine));
14749566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&fine));
14759566063dSJacob Faibussowitsch     PetscCall(DMForestSetTopology(dm,NULL));
14769566063dSJacob Faibussowitsch     PetscCall(DMForestSetBaseDM(dm,NULL));
1477dd8e54a2SToby Isaac   }
14789566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdjacencyDimension(dm,&adjDim));
14799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg,0));
1480dd8e54a2SToby Isaac   if (flg) {
14819566063dSJacob Faibussowitsch     PetscCall(DMForestSetAdjacencyDimension(dm,adjDim));
1482f885a11aSToby Isaac   } else {
14839566063dSJacob Faibussowitsch     PetscCall(DMForestGetAdjacencyCodimension(dm,&adjCodim));
14849566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBoundedInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg,1));
1485*1baa6e33SBarry Smith     if (flg) PetscCall(DMForestSetAdjacencyCodimension(dm,adjCodim));
1486dd8e54a2SToby Isaac   }
14879566063dSJacob Faibussowitsch   PetscCall(DMForestGetPartitionOverlap(dm,&overlap));
14889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg,0));
1489*1baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetPartitionOverlap(dm,overlap));
1490a6121fbdSMatthew G. Knepley #if 0
14919566063dSJacob 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));
1492a6121fbdSMatthew G. Knepley   if (flg) {
14939566063dSJacob Faibussowitsch     PetscCall(DMForestSetMinimumRefinement(dm,minRefinement));
14949566063dSJacob Faibussowitsch     PetscCall(DMForestSetInitialRefinement(dm,minRefinement));
1495a6121fbdSMatthew G. Knepley   }
14969566063dSJacob 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));
1497a6121fbdSMatthew G. Knepley   if (flg) {
14989566063dSJacob Faibussowitsch     PetscCall(DMForestSetMinimumRefinement(dm,0));
14999566063dSJacob Faibussowitsch     PetscCall(DMForestSetInitialRefinement(dm,initRefinement));
1500a6121fbdSMatthew G. Knepley   }
1501a6121fbdSMatthew G. Knepley #endif
15029566063dSJacob Faibussowitsch   PetscCall(DMForestGetMinimumRefinement(dm,&minRefinement));
15039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg,0));
1504*1baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetMinimumRefinement(dm,minRefinement));
15059566063dSJacob Faibussowitsch   PetscCall(DMForestGetInitialRefinement(dm,&initRefinement));
15069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_initial_refinement","set the initial level of refinement in the forest","DMForestSetInitialRefinement",initRefinement,&initRefinement,&flg,0));
1507*1baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetInitialRefinement(dm,initRefinement));
15089566063dSJacob Faibussowitsch   PetscCall(DMForestGetMaximumRefinement(dm,&maxRefinement));
15099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg,0));
1510*1baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetMaximumRefinement(dm,maxRefinement));
15119566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivityStrategy(dm,&adaptStrategy));
15129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,sizeof(stringBuffer),&flg));
1513*1baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer));
15149566063dSJacob Faibussowitsch   PetscCall(DMForestGetGradeFactor(dm,&grade));
15159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg,0));
1516*1baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetGradeFactor(dm,grade));
15179566063dSJacob Faibussowitsch   PetscCall(DMForestGetCellWeightFactor(dm,&weightsFactor));
15189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg));
1519*1baa6e33SBarry Smith   if (flg) PetscCall(DMForestSetCellWeightFactor(dm,weightsFactor));
1520d0609cedSBarry Smith   PetscOptionsHeadEnd();
1521db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1522db4d5e8cSToby Isaac }
1523db4d5e8cSToby Isaac 
1524276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1525d8984e3bSMatthew G. Knepley {
1526d8984e3bSMatthew G. Knepley   PetscFunctionBegin;
15279566063dSJacob Faibussowitsch   if (subdm) PetscCall(DMClone(dm, subdm));
15289566063dSJacob Faibussowitsch   PetscCall(DMCreateSectionSubDM(dm, numFields, fields, is, subdm));
1529d8984e3bSMatthew G. Knepley   PetscFunctionReturn(0);
1530d8984e3bSMatthew G. Knepley }
1531d8984e3bSMatthew G. Knepley 
15325421bac9SToby Isaac PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined)
15335421bac9SToby Isaac {
15345421bac9SToby Isaac   DMLabel        refine;
15355421bac9SToby Isaac   DM             fineDM;
15365421bac9SToby Isaac 
15375421bac9SToby Isaac   PetscFunctionBegin;
15389566063dSJacob Faibussowitsch   PetscCall(DMGetFineDM(dm,&fineDM));
15395421bac9SToby Isaac   if (fineDM) {
15409566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)fineDM));
15415421bac9SToby Isaac     *dmRefined = fineDM;
15425421bac9SToby Isaac     PetscFunctionReturn(0);
15435421bac9SToby Isaac   }
15449566063dSJacob Faibussowitsch   PetscCall(DMForestTemplate(dm,comm,dmRefined));
15459566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm,"refine",&refine));
15465421bac9SToby Isaac   if (!refine) {
15479566063dSJacob Faibussowitsch     PetscCall(DMLabelCreate(PETSC_COMM_SELF, "refine",&refine));
15489566063dSJacob Faibussowitsch     PetscCall(DMLabelSetDefaultValue(refine,DM_ADAPT_REFINE));
1549*1baa6e33SBarry Smith   } else PetscCall(PetscObjectReference((PetscObject) refine));
15509566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityLabel(*dmRefined,refine));
15519566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&refine));
15525421bac9SToby Isaac   PetscFunctionReturn(0);
15535421bac9SToby Isaac }
15545421bac9SToby Isaac 
15555421bac9SToby Isaac PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened)
15565421bac9SToby Isaac {
15575421bac9SToby Isaac   DMLabel        coarsen;
15585421bac9SToby Isaac   DM             coarseDM;
15595421bac9SToby Isaac 
15605421bac9SToby Isaac   PetscFunctionBegin;
15614098eed7SToby Isaac   {
15624098eed7SToby Isaac     PetscMPIInt mpiComparison;
15634098eed7SToby Isaac     MPI_Comm    dmcomm = PetscObjectComm((PetscObject)dm);
15644098eed7SToby Isaac 
15659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_compare(comm, dmcomm, &mpiComparison));
15661dca8a05SBarry Smith     PetscCheck(mpiComparison == MPI_IDENT || mpiComparison == MPI_CONGRUENT,dmcomm,PETSC_ERR_SUP,"No support for different communicators yet");
15674098eed7SToby Isaac   }
15689566063dSJacob Faibussowitsch   PetscCall(DMGetCoarseDM(dm,&coarseDM));
15695421bac9SToby Isaac   if (coarseDM) {
15709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)coarseDM));
15715421bac9SToby Isaac     *dmCoarsened = coarseDM;
15725421bac9SToby Isaac     PetscFunctionReturn(0);
15735421bac9SToby Isaac   }
15749566063dSJacob Faibussowitsch   PetscCall(DMForestTemplate(dm,comm,dmCoarsened));
15759566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityPurpose(*dmCoarsened,DM_ADAPT_COARSEN));
15769566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm,"coarsen",&coarsen));
15775421bac9SToby Isaac   if (!coarsen) {
15789566063dSJacob Faibussowitsch     PetscCall(DMLabelCreate(PETSC_COMM_SELF, "coarsen",&coarsen));
15799566063dSJacob Faibussowitsch     PetscCall(DMLabelSetDefaultValue(coarsen,DM_ADAPT_COARSEN));
1580*1baa6e33SBarry Smith   } else PetscCall(PetscObjectReference((PetscObject) coarsen));
15819566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityLabel(*dmCoarsened,coarsen));
15829566063dSJacob Faibussowitsch   PetscCall(DMLabelDestroy(&coarsen));
15835421bac9SToby Isaac   PetscFunctionReturn(0);
15845421bac9SToby Isaac }
15855421bac9SToby Isaac 
15869fe9e680SJoe Wallwork PetscErrorCode DMAdaptLabel_Forest(DM dm, PETSC_UNUSED Vec metric, DMLabel label, PETSC_UNUSED DMLabel rgLabel, DM *adaptedDM)
158709350103SToby Isaac {
158809350103SToby Isaac   PetscBool      success;
158909350103SToby Isaac 
159009350103SToby Isaac   PetscFunctionBegin;
15919566063dSJacob Faibussowitsch   PetscCall(DMForestTemplate(dm,PetscObjectComm((PetscObject)dm),adaptedDM));
15929566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityLabel(*adaptedDM,label));
15939566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*adaptedDM));
15949566063dSJacob Faibussowitsch   PetscCall(DMForestGetAdaptivitySuccess(*adaptedDM,&success));
159509350103SToby Isaac   if (!success) {
15969566063dSJacob Faibussowitsch     PetscCall(DMDestroy(adaptedDM));
159709350103SToby Isaac     *adaptedDM = NULL;
159809350103SToby Isaac   }
159909350103SToby Isaac   PetscFunctionReturn(0);
160009350103SToby Isaac }
160109350103SToby Isaac 
1602d222f98bSToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm)
1603d222f98bSToby Isaac {
1604d222f98bSToby Isaac   PetscFunctionBegin;
16059566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(dm->ops,sizeof(*(dm->ops))));
1606d222f98bSToby Isaac 
1607d222f98bSToby Isaac   dm->ops->clone          = DMClone_Forest;
1608d222f98bSToby Isaac   dm->ops->setfromoptions = DMSetFromOptions_Forest;
1609d222f98bSToby Isaac   dm->ops->destroy        = DMDestroy_Forest;
1610d8984e3bSMatthew G. Knepley   dm->ops->createsubdm    = DMCreateSubDM_Forest;
16115421bac9SToby Isaac   dm->ops->refine         = DMRefine_Forest;
16125421bac9SToby Isaac   dm->ops->coarsen        = DMCoarsen_Forest;
1613d222f98bSToby Isaac   PetscFunctionReturn(0);
1614d222f98bSToby Isaac }
1615d222f98bSToby Isaac 
16169be51f97SToby Isaac /*MC
16179be51f97SToby Isaac 
1618bae1f979SBarry Smith      DMFOREST = "forest" - A DM object that encapsulates a hierarchically refined mesh.  Forests usually have a base DM
1619bae1f979SBarry Smith   (see DMForestGetBaseDM()), from which it is refined.  The refinement and partitioning of forests is considered
1620bae1f979SBarry Smith   immutable after DMSetUp() is called.  To adapt a mesh, one should call DMForestTemplate() to create a new mesh that
1621bae1f979SBarry Smith   will default to being identical to it, specify how that mesh should differ, and then calling DMSetUp() on the new
1622bae1f979SBarry Smith   mesh.
1623bae1f979SBarry Smith 
1624bae1f979SBarry Smith   To specify that a mesh should be refined or coarsened from the previous mesh, a label should be defined on the
1625bae1f979SBarry Smith   previous mesh whose values indicate which cells should be refined (DM_ADAPT_REFINE) or coarsened (DM_ADAPT_COARSEN)
1626bae1f979SBarry Smith   and how (subtypes are free to allow additional values for things like anisotropic refinement).  The label should be
1627bae1f979SBarry Smith   given to the *new* mesh with DMForestSetAdaptivityLabel().
16289be51f97SToby Isaac 
16299be51f97SToby Isaac   Level: advanced
16309be51f97SToby Isaac 
1631db781477SPatrick Sanan .seealso: `DMType`, `DMCreate()`, `DMSetType()`, `DMForestGetBaseDM()`, `DMForestSetBaseDM()`, `DMForestTemplate()`, `DMForestSetAdaptivityLabel()`
16329be51f97SToby Isaac M*/
16339be51f97SToby Isaac 
1634db4d5e8cSToby Isaac PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm)
1635db4d5e8cSToby Isaac {
1636db4d5e8cSToby Isaac   DM_Forest      *forest;
1637db4d5e8cSToby Isaac 
1638db4d5e8cSToby Isaac   PetscFunctionBegin;
1639db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
16409566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(dm,&forest));
1641db4d5e8cSToby Isaac   dm->dim                      = 0;
1642db4d5e8cSToby Isaac   dm->data                     = forest;
1643db4d5e8cSToby Isaac   forest->refct                = 1;
1644db4d5e8cSToby Isaac   forest->data                 = NULL;
1645db4d5e8cSToby Isaac   forest->topology             = NULL;
1646cd3c525cSToby Isaac   forest->adapt                = NULL;
1647db4d5e8cSToby Isaac   forest->base                 = NULL;
16486a87ffbfSToby Isaac   forest->adaptPurpose         = DM_ADAPT_DETERMINE;
1649db4d5e8cSToby Isaac   forest->adjDim               = PETSC_DEFAULT;
1650db4d5e8cSToby Isaac   forest->overlap              = PETSC_DEFAULT;
1651db4d5e8cSToby Isaac   forest->minRefinement        = PETSC_DEFAULT;
1652db4d5e8cSToby Isaac   forest->maxRefinement        = PETSC_DEFAULT;
165356ba9f64SToby Isaac   forest->initRefinement       = PETSC_DEFAULT;
1654c7eeac06SToby Isaac   forest->cStart               = PETSC_DETERMINE;
1655c7eeac06SToby Isaac   forest->cEnd                 = PETSC_DETERMINE;
1656cd3c525cSToby Isaac   forest->cellSF               = NULL;
1657ebdf65a2SToby Isaac   forest->adaptLabel           = NULL;
1658db4d5e8cSToby Isaac   forest->gradeFactor          = 2;
1659db4d5e8cSToby Isaac   forest->cellWeights          = NULL;
1660db4d5e8cSToby Isaac   forest->cellWeightsCopyMode  = PETSC_USE_POINTER;
1661db4d5e8cSToby Isaac   forest->weightsFactor        = 1.;
1662db4d5e8cSToby Isaac   forest->weightCapacity       = 1.;
16639566063dSJacob Faibussowitsch   PetscCall(DMForestSetAdaptivityStrategy(dm,DMFORESTADAPTALL));
16649566063dSJacob Faibussowitsch   PetscCall(DMInitialize_Forest(dm));
1665db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1666db4d5e8cSToby Isaac }
1667