xref: /petsc/src/dm/impls/forest/forest.c (revision bae1f97911a89d59967a173bf6b8ac3a703a52ee)
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   PetscErrorCode   ierr;
2227d4645fSToby Isaac 
2327d4645fSToby Isaac   PetscFunctionBegin;
2427d4645fSToby Isaac   while (link) {
2527d4645fSToby Isaac     oldLink = link;
26f416af30SBarry Smith     ierr    = PetscFree(oldLink->name);CHKERRQ(ierr);
2727d4645fSToby Isaac     link    = oldLink->next;
2827d4645fSToby Isaac     ierr    = PetscFree(oldLink);CHKERRQ(ierr);
2927d4645fSToby Isaac   }
3027d4645fSToby Isaac   PetscFunctionReturn(0);
3127d4645fSToby Isaac }
3227d4645fSToby Isaac 
3327d4645fSToby Isaac static PetscErrorCode DMForestPackageInitialize(void)
3427d4645fSToby Isaac {
3527d4645fSToby Isaac   PetscErrorCode ierr;
3627d4645fSToby Isaac 
3727d4645fSToby Isaac   PetscFunctionBegin;
3827d4645fSToby Isaac   if (DMForestPackageInitialized) PetscFunctionReturn(0);
3927d4645fSToby Isaac   DMForestPackageInitialized = PETSC_TRUE;
40f885a11aSToby Isaac 
4127d4645fSToby Isaac   ierr = DMForestRegisterType(DMFOREST);CHKERRQ(ierr);
4227d4645fSToby Isaac   ierr = PetscRegisterFinalize(DMForestPackageFinalize);CHKERRQ(ierr);
4327d4645fSToby Isaac   PetscFunctionReturn(0);
4427d4645fSToby Isaac }
4527d4645fSToby Isaac 
469be51f97SToby Isaac /*@C
479be51f97SToby Isaac   DMForestRegisterType - Registers a DMType as a subtype of DMFOREST (so that DMIsForest() will be correct)
489be51f97SToby Isaac 
499be51f97SToby Isaac   Not Collective
509be51f97SToby Isaac 
519be51f97SToby Isaac   Input parameter:
529be51f97SToby Isaac . name - the name of the type
539be51f97SToby Isaac 
549be51f97SToby Isaac   Level: advanced
559be51f97SToby Isaac 
569be51f97SToby Isaac .seealso: DMFOREST, DMIsForest()
579be51f97SToby Isaac @*/
5827d4645fSToby Isaac PetscErrorCode DMForestRegisterType(DMType name)
5927d4645fSToby Isaac {
6027d4645fSToby Isaac   DMForestTypeLink link;
6127d4645fSToby Isaac   PetscErrorCode   ierr;
6227d4645fSToby Isaac 
6327d4645fSToby Isaac   PetscFunctionBegin;
6427d4645fSToby Isaac   ierr             = DMForestPackageInitialize();CHKERRQ(ierr);
6527d4645fSToby Isaac   ierr             = PetscNew(&link);CHKERRQ(ierr);
6627d4645fSToby Isaac   ierr             = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
6727d4645fSToby Isaac   link->next       = DMForestTypeList;
6827d4645fSToby Isaac   DMForestTypeList = link;
6927d4645fSToby Isaac   PetscFunctionReturn(0);
7027d4645fSToby Isaac }
7127d4645fSToby Isaac 
729be51f97SToby Isaac /*@
739be51f97SToby Isaac   DMIsForest - Check whether a DM uses the DMFOREST interface for hierarchically-refined meshes
749be51f97SToby Isaac 
759be51f97SToby Isaac   Not Collective
769be51f97SToby Isaac 
779be51f97SToby Isaac   Input parameter:
789be51f97SToby Isaac . dm - the DM object
799be51f97SToby Isaac 
809be51f97SToby Isaac   Output parameter:
819be51f97SToby Isaac . isForest - whether dm is a subtype of DMFOREST
829be51f97SToby Isaac 
839be51f97SToby Isaac   Level: intermediate
849be51f97SToby Isaac 
859be51f97SToby Isaac .seealso: DMFOREST, DMForestRegisterType()
869be51f97SToby Isaac @*/
8727d4645fSToby Isaac PetscErrorCode DMIsForest(DM dm, PetscBool *isForest)
8827d4645fSToby Isaac {
8927d4645fSToby Isaac   DMForestTypeLink link = DMForestTypeList;
9027d4645fSToby Isaac   PetscErrorCode   ierr;
9127d4645fSToby Isaac 
9227d4645fSToby Isaac   PetscFunctionBegin;
9327d4645fSToby Isaac   while (link) {
9427d4645fSToby Isaac     PetscBool sameType;
9527d4645fSToby Isaac     ierr = PetscObjectTypeCompare((PetscObject)dm,link->name,&sameType);CHKERRQ(ierr);
9627d4645fSToby Isaac     if (sameType) {
9727d4645fSToby Isaac       *isForest = PETSC_TRUE;
9827d4645fSToby Isaac       PetscFunctionReturn(0);
9927d4645fSToby Isaac     }
10027d4645fSToby Isaac     link = link->next;
10127d4645fSToby Isaac   }
10227d4645fSToby Isaac   *isForest = PETSC_FALSE;
10327d4645fSToby Isaac   PetscFunctionReturn(0);
10427d4645fSToby Isaac }
10527d4645fSToby Isaac 
1069be51f97SToby Isaac /*@
1079be51f97SToby Isaac   DMForestTemplate - Create a new DM that will be adapted from a source DM.  The new DM reproduces the configuration
1089be51f97SToby 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
1099be51f97SToby Isaac   (by, e.g., refinement or repartitioning).  The source DM is also set as the adaptivity source DM of the new DM (see
1109be51f97SToby Isaac   DMForestSetAdaptivityForest()).
1119be51f97SToby Isaac 
1129be51f97SToby Isaac   Collective on dm
1139be51f97SToby Isaac 
1149be51f97SToby Isaac   Input Parameters:
1159be51f97SToby Isaac + dm - the source DM object
1169be51f97SToby Isaac - comm - the communicator for the new DM (this communicator is currently ignored, but is present so that DMForestTemplate() can be used within DMCoarsen())
1179be51f97SToby Isaac 
1189be51f97SToby Isaac   Output Parameter:
1199be51f97SToby Isaac . tdm - the new DM object
1209be51f97SToby Isaac 
1219be51f97SToby Isaac   Level: intermediate
1229be51f97SToby Isaac 
1239be51f97SToby Isaac .seealso: DMForestSetAdaptivityForest()
1249be51f97SToby Isaac @*/
1259be51f97SToby Isaac PetscErrorCode DMForestTemplate(DM dm, MPI_Comm comm, DM *tdm)
126a0452a8eSToby Isaac {
127a0452a8eSToby Isaac   DM_Forest                  *forest = (DM_Forest*) dm->data;
12820e8089bSToby Isaac   DMType                     type;
129a0452a8eSToby Isaac   DM                         base;
130a0452a8eSToby Isaac   DMForestTopology           topology;
131a0452a8eSToby Isaac   PetscInt                   dim, overlap, ref, factor;
132a0452a8eSToby Isaac   DMForestAdaptivityStrategy strat;
133795844e7SToby Isaac   PetscDS                    ds;
134795844e7SToby Isaac   void                       *ctx;
13549fc9a2fSToby Isaac   PetscErrorCode             (*map)(DM, PetscInt, PetscInt, const PetscReal[], PetscReal[], void*);
1363e58adeeSToby Isaac   void                       *mapCtx;
137a0452a8eSToby Isaac   PetscErrorCode             ierr;
138a0452a8eSToby Isaac 
139a0452a8eSToby Isaac   PetscFunctionBegin;
140a0452a8eSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
14120e8089bSToby Isaac   ierr = DMCreate(PetscObjectComm((PetscObject)dm),tdm);CHKERRQ(ierr);
14220e8089bSToby Isaac   ierr = DMGetType(dm,&type);CHKERRQ(ierr);
14320e8089bSToby Isaac   ierr = DMSetType(*tdm,type);CHKERRQ(ierr);
144a0452a8eSToby Isaac   ierr = DMForestGetBaseDM(dm,&base);CHKERRQ(ierr);
14520e8089bSToby Isaac   ierr = DMForestSetBaseDM(*tdm,base);CHKERRQ(ierr);
146a0452a8eSToby Isaac   ierr = DMForestGetTopology(dm,&topology);CHKERRQ(ierr);
14720e8089bSToby Isaac   ierr = DMForestSetTopology(*tdm,topology);CHKERRQ(ierr);
148a0452a8eSToby Isaac   ierr = DMForestGetAdjacencyDimension(dm,&dim);CHKERRQ(ierr);
14920e8089bSToby Isaac   ierr = DMForestSetAdjacencyDimension(*tdm,dim);CHKERRQ(ierr);
150a0452a8eSToby Isaac   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
15120e8089bSToby Isaac   ierr = DMForestSetPartitionOverlap(*tdm,overlap);CHKERRQ(ierr);
152a0452a8eSToby Isaac   ierr = DMForestGetMinimumRefinement(dm,&ref);CHKERRQ(ierr);
15320e8089bSToby Isaac   ierr = DMForestSetMinimumRefinement(*tdm,ref);CHKERRQ(ierr);
154a0452a8eSToby Isaac   ierr = DMForestGetMaximumRefinement(dm,&ref);CHKERRQ(ierr);
15520e8089bSToby Isaac   ierr = DMForestSetMaximumRefinement(*tdm,ref);CHKERRQ(ierr);
156a0452a8eSToby Isaac   ierr = DMForestGetAdaptivityStrategy(dm,&strat);CHKERRQ(ierr);
15720e8089bSToby Isaac   ierr = DMForestSetAdaptivityStrategy(*tdm,strat);CHKERRQ(ierr);
158a0452a8eSToby Isaac   ierr = DMForestGetGradeFactor(dm,&factor);CHKERRQ(ierr);
15920e8089bSToby Isaac   ierr = DMForestSetGradeFactor(*tdm,factor);CHKERRQ(ierr);
1603e58adeeSToby Isaac   ierr = DMForestGetBaseCoordinateMapping(dm,&map,&mapCtx);CHKERRQ(ierr);
1615e8c540aSToby Isaac   ierr = DMForestSetBaseCoordinateMapping(*tdm,map,mapCtx);CHKERRQ(ierr);
162a0452a8eSToby Isaac   if (forest->ftemplate) {
16320e8089bSToby Isaac     ierr = (forest->ftemplate)(dm, *tdm);CHKERRQ(ierr);
164a0452a8eSToby Isaac   }
16520e8089bSToby Isaac   ierr = DMForestSetAdaptivityForest(*tdm,dm);CHKERRQ(ierr);
166795844e7SToby Isaac   ierr = DMGetDS(dm,&ds);CHKERRQ(ierr);
167795844e7SToby Isaac   ierr = DMSetDS(*tdm,ds);CHKERRQ(ierr);
168795844e7SToby Isaac   ierr = DMGetApplicationContext(dm,&ctx);CHKERRQ(ierr);
169795844e7SToby Isaac   ierr = DMSetApplicationContext(*tdm,&ctx);CHKERRQ(ierr);
170795844e7SToby Isaac   if (dm->maxCell) {
171795844e7SToby Isaac     const PetscReal      *maxCell, *L;
172795844e7SToby Isaac     const DMBoundaryType *bd;
173795844e7SToby Isaac 
174795844e7SToby Isaac     ierr = DMGetPeriodicity(dm,&maxCell,&L,&bd);CHKERRQ(ierr);
175795844e7SToby Isaac     ierr = DMSetPeriodicity(*tdm,maxCell,L,bd);CHKERRQ(ierr);
176795844e7SToby Isaac   }
177bff67a9bSToby Isaac   ierr = DMCopyBoundary(dm,*tdm);CHKERRQ(ierr);
178a0452a8eSToby Isaac   PetscFunctionReturn(0);
179a0452a8eSToby Isaac }
180a0452a8eSToby Isaac 
18101d9d024SToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm);
18201d9d024SToby Isaac 
183db4d5e8cSToby Isaac PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm)
184db4d5e8cSToby Isaac {
185db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
186db4d5e8cSToby Isaac   const char     *type;
187db4d5e8cSToby Isaac   PetscErrorCode ierr;
188db4d5e8cSToby Isaac 
189db4d5e8cSToby Isaac   PetscFunctionBegin;
190db4d5e8cSToby Isaac   forest->refct++;
191db4d5e8cSToby Isaac   (*newdm)->data = forest;
192db4d5e8cSToby Isaac   ierr           = PetscObjectGetType((PetscObject) dm, &type);CHKERRQ(ierr);
193db4d5e8cSToby Isaac   ierr           = PetscObjectChangeTypeName((PetscObject) *newdm, type);CHKERRQ(ierr);
19401d9d024SToby Isaac   ierr           = DMInitialize_Forest(*newdm);CHKERRQ(ierr);
195db4d5e8cSToby Isaac   PetscFunctionReturn(0);
196db4d5e8cSToby Isaac }
197db4d5e8cSToby Isaac 
198d222f98bSToby Isaac static PetscErrorCode DMDestroy_Forest(DM dm)
199db4d5e8cSToby Isaac {
200db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
201db4d5e8cSToby Isaac   PetscErrorCode ierr;
202db4d5e8cSToby Isaac 
203db4d5e8cSToby Isaac   PetscFunctionBegin;
204db4d5e8cSToby Isaac   if (--forest->refct > 0) PetscFunctionReturn(0);
205d222f98bSToby Isaac   if (forest->destroy) {ierr = forest->destroy(dm);CHKERRQ(ierr);}
206db4d5e8cSToby Isaac   ierr = PetscSFDestroy(&forest->cellSF);CHKERRQ(ierr);
2070f17b9e3SToby Isaac   ierr = PetscSFDestroy(&forest->preCoarseToFine);CHKERRQ(ierr);
2080f17b9e3SToby Isaac   ierr = PetscSFDestroy(&forest->coarseToPreFine);CHKERRQ(ierr);
209a1b0c543SToby Isaac   ierr = DMLabelDestroy(&forest->adaptLabel);CHKERRQ(ierr);
2109a81d013SToby Isaac   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
21156ba9f64SToby Isaac   ierr = DMDestroy(&forest->base);CHKERRQ(ierr);
212ba936b91SToby Isaac   ierr = DMDestroy(&forest->adapt);CHKERRQ(ierr);
21330f902e7SToby Isaac   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
21430f902e7SToby Isaac   ierr = PetscFree(forest);CHKERRQ(ierr);
215a1b0c543SToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMAdaptLabel_C",NULL);CHKERRQ(ierr);
216db4d5e8cSToby Isaac   PetscFunctionReturn(0);
217db4d5e8cSToby Isaac }
218db4d5e8cSToby Isaac 
2199be51f97SToby Isaac /*@C
2209be51f97SToby Isaac   DMForestSetTopology - Set the topology of a DMForest during the pre-setup phase.  The topology is a string (e.g.
2219be51f97SToby Isaac   "cube", "shell") and can be interpreted by subtypes of DMFOREST) to construct the base DM of a forest durint
2229be51f97SToby Isaac   DMSetUp().
2239be51f97SToby Isaac 
2249be51f97SToby Isaac   Logically collective on dm
2259be51f97SToby Isaac 
2269be51f97SToby Isaac   Input parameters:
2279be51f97SToby Isaac + dm - the forest
2289be51f97SToby Isaac - topology - the topology of the forest
2299be51f97SToby Isaac 
2309be51f97SToby Isaac   Level: intermediate
2319be51f97SToby Isaac 
2329be51f97SToby Isaac .seealso(): DMForestGetTopology(), DMForestSetBaseDM()
2339be51f97SToby Isaac @*/
234dd8e54a2SToby Isaac PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology)
235db4d5e8cSToby Isaac {
236db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
237db4d5e8cSToby Isaac   PetscErrorCode ierr;
238db4d5e8cSToby Isaac 
239db4d5e8cSToby Isaac   PetscFunctionBegin;
240db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
241ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup");
242dd8e54a2SToby Isaac   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
243dd8e54a2SToby Isaac   ierr = PetscStrallocpy((const char*)topology,(char**) &forest->topology);CHKERRQ(ierr);
244db4d5e8cSToby Isaac   PetscFunctionReturn(0);
245db4d5e8cSToby Isaac }
246db4d5e8cSToby Isaac 
2479be51f97SToby Isaac /*@C
2489be51f97SToby Isaac   DMForestGetTopology - Get a string describing the topology of a DMForest.
2499be51f97SToby Isaac 
2509be51f97SToby Isaac   Not collective
2519be51f97SToby Isaac 
2529be51f97SToby Isaac   Input parameter:
2539be51f97SToby Isaac . dm - the forest
2549be51f97SToby Isaac 
2559be51f97SToby Isaac   Output parameter:
2569be51f97SToby Isaac . topology - the topology of the forest (e.g., 'cube', 'shell')
2579be51f97SToby Isaac 
2589be51f97SToby Isaac   Level: intermediate
2599be51f97SToby Isaac 
2609be51f97SToby Isaac .seealso: DMForestSetTopology()
2619be51f97SToby Isaac @*/
262dd8e54a2SToby Isaac PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology)
263dd8e54a2SToby Isaac {
264dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
265dd8e54a2SToby Isaac 
266dd8e54a2SToby Isaac   PetscFunctionBegin;
267dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
268dd8e54a2SToby Isaac   PetscValidPointer(topology,2);
269dd8e54a2SToby Isaac   *topology = forest->topology;
270dd8e54a2SToby Isaac   PetscFunctionReturn(0);
271dd8e54a2SToby Isaac }
272dd8e54a2SToby Isaac 
2739be51f97SToby Isaac /*@
2749be51f97SToby Isaac   DMForestSetBaseDM - During the pre-setup phase, set the DM that defines the base mesh of a DMForest forest.  The
2759be51f97SToby Isaac   forest will be hierarchically refined from the base, and all refinements/coarsenings of the forest will share its
2769be51f97SToby Isaac   base.  In general, two forest must share a bse to be comparable, to do things like construct interpolators.
2779be51f97SToby Isaac 
2789be51f97SToby Isaac   Logically collective on dm
2799be51f97SToby Isaac 
2809be51f97SToby Isaac   Input Parameters:
2819be51f97SToby Isaac + dm - the forest
2829be51f97SToby Isaac - base - the base DM of the forest
2839be51f97SToby Isaac 
2849be51f97SToby Isaac   Level: intermediate
2859be51f97SToby Isaac 
2869be51f97SToby Isaac .seealso(): DMForestGetBaseDM()
2879be51f97SToby Isaac @*/
288dd8e54a2SToby Isaac PetscErrorCode DMForestSetBaseDM(DM dm, DM base)
289dd8e54a2SToby Isaac {
290dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
291dd8e54a2SToby Isaac   PetscInt       dim, dimEmbed;
292dd8e54a2SToby Isaac   PetscErrorCode ierr;
293dd8e54a2SToby Isaac 
294dd8e54a2SToby Isaac   PetscFunctionBegin;
295dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
296ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup");
297dd8e54a2SToby Isaac   ierr         = PetscObjectReference((PetscObject)base);CHKERRQ(ierr);
298dd8e54a2SToby Isaac   ierr         = DMDestroy(&forest->base);CHKERRQ(ierr);
299dd8e54a2SToby Isaac   forest->base = base;
300a0452a8eSToby Isaac   if (base) {
301a0452a8eSToby Isaac     PetscValidHeaderSpecific(base, DM_CLASSID, 2);
302dd8e54a2SToby Isaac     ierr = DMGetDimension(base,&dim);CHKERRQ(ierr);
303dd8e54a2SToby Isaac     ierr = DMSetDimension(dm,dim);CHKERRQ(ierr);
304dd8e54a2SToby Isaac     ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr);
305dd8e54a2SToby Isaac     ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr);
306a0452a8eSToby Isaac   }
307dd8e54a2SToby Isaac   PetscFunctionReturn(0);
308dd8e54a2SToby Isaac }
309dd8e54a2SToby Isaac 
3109be51f97SToby Isaac /*@
3119be51f97SToby Isaac   DMForestGetBaseDM - Get the base DM of a DMForest forest.  The forest will be hierarchically refined from the base,
3129be51f97SToby Isaac   and all refinements/coarsenings of the forest will share its base.  In general, two forest must share a bse to be
3139be51f97SToby Isaac   comparable, to do things like construct interpolators.
3149be51f97SToby Isaac 
3159be51f97SToby Isaac   Not collective
3169be51f97SToby Isaac 
3179be51f97SToby Isaac   Input Parameter:
3189be51f97SToby Isaac . dm - the forest
3199be51f97SToby Isaac 
3209be51f97SToby Isaac   Output Parameter:
3219be51f97SToby Isaac . base - the base DM of the forest
3229be51f97SToby Isaac 
3239be51f97SToby Isaac   Level: intermediate
3249be51f97SToby Isaac 
3259be51f97SToby Isaac .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 
3719be51f97SToby Isaac   Input Parameter:
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 
3779be51f97SToby Isaac .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;
383dd8e54a2SToby Isaac   PetscErrorCode ierr;
384dd8e54a2SToby Isaac 
385dd8e54a2SToby Isaac   PetscFunctionBegin;
386dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
387ba936b91SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
388ba936b91SToby Isaac   forest   = (DM_Forest*) dm->data;
389dffe73a3SToby Isaac   ierr     = DMForestGetAdaptivityForest(dm,&oldAdapt);CHKERRQ(ierr);
390dffe73a3SToby Isaac   if (adapt != NULL && dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
391193eb951SToby Isaac   adaptForest    = (DM_Forest*) (adapt ? adapt->data : NULL);
392193eb951SToby Isaac   oldAdaptForest = (DM_Forest*) (oldAdapt ? oldAdapt->data : NULL);
393dffe73a3SToby Isaac   if (adaptForest != oldAdaptForest) {
394dffe73a3SToby Isaac     ierr = PetscSFDestroy(&forest->preCoarseToFine);CHKERRQ(ierr);
395dffe73a3SToby Isaac     ierr = PetscSFDestroy(&forest->coarseToPreFine);CHKERRQ(ierr);
396dffe73a3SToby Isaac     if (forest->clearadaptivityforest) {ierr = (forest->clearadaptivityforest)(dm);CHKERRQ(ierr);}
397dffe73a3SToby Isaac   }
39826d9498aSToby Isaac   switch (forest->adaptPurpose) {
399cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
400ba936b91SToby Isaac     ierr          = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
401ba936b91SToby Isaac     ierr          = DMDestroy(&(forest->adapt));CHKERRQ(ierr);
402ba936b91SToby Isaac     forest->adapt = adapt;
40326d9498aSToby Isaac     break;
404a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
40526d9498aSToby Isaac     ierr = DMSetCoarseDM(dm,adapt);CHKERRQ(ierr);
40626d9498aSToby Isaac     break;
407a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
40826d9498aSToby Isaac     ierr = DMSetFineDM(dm,adapt);CHKERRQ(ierr);
40926d9498aSToby Isaac     break;
41026d9498aSToby Isaac   default:
41126d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
41226d9498aSToby Isaac   }
413dd8e54a2SToby Isaac   PetscFunctionReturn(0);
414dd8e54a2SToby Isaac }
415dd8e54a2SToby Isaac 
4169be51f97SToby Isaac /*@
4179be51f97SToby Isaac   DMForestGetAdaptivityForest - Get the forest from which the current forest is adapted.
4189be51f97SToby Isaac 
4199be51f97SToby Isaac   Not collective
4209be51f97SToby Isaac 
4219be51f97SToby Isaac   Input Parameter:
4229be51f97SToby Isaac . dm - the forest
4239be51f97SToby Isaac 
4249be51f97SToby Isaac   Output Parameter:
4259be51f97SToby Isaac . adapt - the forest from which dm is/was adapted
4269be51f97SToby Isaac 
4279be51f97SToby Isaac   Level: intermediate
4289be51f97SToby Isaac 
4299be51f97SToby Isaac .seealso: DMForestSetAdaptivityForest(), DMForestSetAdaptivityPurpose()
4309be51f97SToby Isaac @*/
431ba936b91SToby Isaac PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt)
432dd8e54a2SToby Isaac {
433ba936b91SToby Isaac   DM_Forest      *forest;
43426d9498aSToby Isaac   PetscErrorCode ierr;
435dd8e54a2SToby Isaac 
436dd8e54a2SToby Isaac   PetscFunctionBegin;
437dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
438ba936b91SToby Isaac   forest = (DM_Forest*) dm->data;
43926d9498aSToby Isaac   switch (forest->adaptPurpose) {
440cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
441ba936b91SToby Isaac     *adapt = forest->adapt;
44226d9498aSToby Isaac     break;
443a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
44426d9498aSToby Isaac     ierr = DMGetCoarseDM(dm,adapt);CHKERRQ(ierr);
44526d9498aSToby Isaac     break;
446a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
44726d9498aSToby Isaac     ierr = DMGetFineDM(dm,adapt);CHKERRQ(ierr);
44826d9498aSToby Isaac     break;
44926d9498aSToby Isaac   default:
45026d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
45126d9498aSToby Isaac   }
45226d9498aSToby Isaac   PetscFunctionReturn(0);
45326d9498aSToby Isaac }
45426d9498aSToby Isaac 
4559be51f97SToby Isaac /*@
4569be51f97SToby Isaac   DMForestSetAdaptivityPurpose - During the pre-setup phase, set whether the current DM is being adapted from its
457a1b0c543SToby Isaac   source (set with DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening
458cd3c525cSToby Isaac   (DM_ADAPT_COARSEN), or undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting:
4599be51f97SToby Isaac   during DMDestroy(), cyclic references can be found between DMs only if the cyclic reference is due to a fine/coarse
4609be51f97SToby Isaac   relationship (see DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does
4619be51f97SToby Isaac   not maintain a reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can
4629be51f97SToby Isaac   cause a memory leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
4639be51f97SToby Isaac 
4649be51f97SToby Isaac   Logically collective on dm
4659be51f97SToby Isaac 
4669be51f97SToby Isaac   Input Parameters:
4679be51f97SToby Isaac + dm - the forest
468cd3c525cSToby Isaac - purpose - the adaptivity purpose (DM_ADAPT_DETERMINE/DM_ADAPT_REFINE/DM_ADAPT_COARSEN)
4699be51f97SToby Isaac 
4709be51f97SToby Isaac   Level: advanced
4719be51f97SToby Isaac 
4729be51f97SToby Isaac .seealso: DMForestTemplate(), DMForestSetAdaptivityForest(), DMForestGetAdaptivityForest()
4739be51f97SToby Isaac @*/
474a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMAdaptFlag purpose)
47526d9498aSToby Isaac {
47626d9498aSToby Isaac   DM_Forest      *forest;
47726d9498aSToby Isaac   PetscErrorCode ierr;
47826d9498aSToby Isaac 
47926d9498aSToby Isaac   PetscFunctionBegin;
48026d9498aSToby Isaac   forest = (DM_Forest*) dm->data;
4819be51f97SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
48226d9498aSToby Isaac   if (purpose != forest->adaptPurpose) {
48326d9498aSToby Isaac     DM adapt;
48426d9498aSToby Isaac 
48526d9498aSToby Isaac     ierr = DMForestGetAdaptivityForest(dm,&adapt);CHKERRQ(ierr);
48626d9498aSToby Isaac     ierr = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
48726d9498aSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
488f885a11aSToby Isaac 
48926d9498aSToby Isaac     forest->adaptPurpose = purpose;
490f885a11aSToby Isaac 
49126d9498aSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,adapt);CHKERRQ(ierr);
49226d9498aSToby Isaac     ierr = DMDestroy(&adapt);CHKERRQ(ierr);
49326d9498aSToby Isaac   }
494dd8e54a2SToby Isaac   PetscFunctionReturn(0);
495dd8e54a2SToby Isaac }
496dd8e54a2SToby Isaac 
49756c0450aSToby Isaac /*@
49856c0450aSToby Isaac   DMForestGetAdaptivityPurpose - Get whether the current DM is being adapted from its source (set with
499a1b0c543SToby Isaac   DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening (DM_ADAPT_COARSEN), or
500cd3c525cSToby Isaac   undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting: during DMDestroy(), cyclic
50156c0450aSToby Isaac   references can be found between DMs only if the cyclic reference is due to a fine/coarse relationship (see
50256c0450aSToby Isaac   DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does not maintain a
50356c0450aSToby Isaac   reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can cause a memory
50456c0450aSToby Isaac   leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
50556c0450aSToby Isaac 
50656c0450aSToby Isaac   Not collective
50756c0450aSToby Isaac 
50856c0450aSToby Isaac   Input Parameter:
50956c0450aSToby Isaac . dm - the forest
51056c0450aSToby Isaac 
51156c0450aSToby Isaac   Output Parameter:
512cd3c525cSToby Isaac . purpose - the adaptivity purpose (DM_ADAPT_DETERMINE/DM_ADAPT_REFINE/DM_ADAPT_COARSEN)
51356c0450aSToby Isaac 
51456c0450aSToby Isaac   Level: advanced
51556c0450aSToby Isaac 
51656c0450aSToby Isaac .seealso: DMForestTemplate(), DMForestSetAdaptivityForest(), DMForestGetAdaptivityForest()
51756c0450aSToby Isaac @*/
518a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityPurpose(DM dm, DMAdaptFlag *purpose)
51956c0450aSToby Isaac {
52056c0450aSToby Isaac   DM_Forest *forest;
52156c0450aSToby Isaac 
52256c0450aSToby Isaac   PetscFunctionBegin;
52356c0450aSToby Isaac   forest   = (DM_Forest*) dm->data;
52456c0450aSToby Isaac   *purpose = forest->adaptPurpose;
52556c0450aSToby Isaac   PetscFunctionReturn(0);
52656c0450aSToby Isaac }
52756c0450aSToby Isaac 
5289be51f97SToby Isaac /*@
5299be51f97SToby Isaac   DMForestSetAdjacencyDimension - During the pre-setup phase, set the dimension of interface points that determine
5309be51f97SToby Isaac   cell adjacency (for the purposes of partitioning and overlap).
5319be51f97SToby Isaac 
5329be51f97SToby Isaac   Logically collective on dm
5339be51f97SToby Isaac 
5349be51f97SToby Isaac   Input Parameters:
5359be51f97SToby Isaac + dm - the forest
5369be51f97SToby Isaac - adjDim - default 0 (i.e., vertices determine adjacency)
5379be51f97SToby Isaac 
5389be51f97SToby Isaac   Level: intermediate
5399be51f97SToby Isaac 
5409be51f97SToby Isaac .seealso: DMForestGetAdjacencyDimension(), DMForestSetAdjacencyCodimension(), DMForestSetPartitionOverlap()
5419be51f97SToby Isaac @*/
542dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim)
543dd8e54a2SToby Isaac {
544dd8e54a2SToby Isaac   PetscInt       dim;
545dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
546dd8e54a2SToby Isaac   PetscErrorCode ierr;
547dd8e54a2SToby Isaac 
548dd8e54a2SToby Isaac   PetscFunctionBegin;
549dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
550ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup");
551dd8e54a2SToby Isaac   if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim);
552dd8e54a2SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
553dd8e54a2SToby Isaac   if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim);
554dd8e54a2SToby Isaac   forest->adjDim = adjDim;
555dd8e54a2SToby Isaac   PetscFunctionReturn(0);
556dd8e54a2SToby Isaac }
557dd8e54a2SToby Isaac 
5589be51f97SToby Isaac /*@
5599be51f97SToby Isaac   DMForestSetAdjacencyCodimension - Like DMForestSetAdjacencyDimension(), but specified as a co-dimension (so that,
5609be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
5619be51f97SToby Isaac 
5629be51f97SToby Isaac   Logically collective on dm
5639be51f97SToby Isaac 
5649be51f97SToby Isaac   Input Parameters:
5659be51f97SToby Isaac + dm - the forest
5669be51f97SToby Isaac - adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
5679be51f97SToby Isaac 
5689be51f97SToby Isaac   Level: intermediate
5699be51f97SToby Isaac 
5709be51f97SToby Isaac .seealso: DMForestGetAdjacencyCodimension(), DMForestSetAdjacencyDimension()
5719be51f97SToby Isaac @*/
572dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim)
573dd8e54a2SToby Isaac {
574dd8e54a2SToby Isaac   PetscInt       dim;
575dd8e54a2SToby Isaac   PetscErrorCode ierr;
576dd8e54a2SToby Isaac 
577dd8e54a2SToby Isaac   PetscFunctionBegin;
578dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
579dd8e54a2SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
580dd8e54a2SToby Isaac   ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr);
581dd8e54a2SToby Isaac   PetscFunctionReturn(0);
582dd8e54a2SToby Isaac }
583dd8e54a2SToby Isaac 
5849be51f97SToby Isaac /*@
5859be51f97SToby Isaac   DMForestGetAdjacencyDimension - Get the dimension of interface points that determine cell adjacency (for the
5869be51f97SToby Isaac   purposes of partitioning and overlap).
5879be51f97SToby Isaac 
5889be51f97SToby Isaac   Not collective
5899be51f97SToby Isaac 
5909be51f97SToby Isaac   Input Parameter:
5919be51f97SToby Isaac . dm - the forest
5929be51f97SToby Isaac 
5939be51f97SToby Isaac   Output Parameter:
5949be51f97SToby Isaac . adjDim - default 0 (i.e., vertices determine adjacency)
5959be51f97SToby Isaac 
5969be51f97SToby Isaac   Level: intermediate
5979be51f97SToby Isaac 
5989be51f97SToby Isaac .seealso: DMForestSetAdjacencyDimension(), DMForestGetAdjacencyCodimension(), DMForestSetPartitionOverlap()
5999be51f97SToby Isaac @*/
600dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim)
601dd8e54a2SToby Isaac {
602dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
603dd8e54a2SToby Isaac 
604dd8e54a2SToby Isaac   PetscFunctionBegin;
605dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
606dd8e54a2SToby Isaac   PetscValidIntPointer(adjDim,2);
607dd8e54a2SToby Isaac   *adjDim = forest->adjDim;
608dd8e54a2SToby Isaac   PetscFunctionReturn(0);
609dd8e54a2SToby Isaac }
610dd8e54a2SToby Isaac 
6119be51f97SToby Isaac /*@
6129be51f97SToby Isaac   DMForestGetAdjacencyCodimension - Like DMForestGetAdjacencyDimension(), but specified as a co-dimension (so that,
6139be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
6149be51f97SToby Isaac 
6159be51f97SToby Isaac   Not collective
6169be51f97SToby Isaac 
6179be51f97SToby Isaac   Input Parameter:
6189be51f97SToby Isaac . dm - the forest
6199be51f97SToby Isaac 
6209be51f97SToby Isaac   Output Parameter:
6219be51f97SToby Isaac . adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
6229be51f97SToby Isaac 
6239be51f97SToby Isaac   Level: intermediate
6249be51f97SToby Isaac 
6259be51f97SToby Isaac .seealso: DMForestSetAdjacencyCodimension(), DMForestGetAdjacencyDimension()
6269be51f97SToby Isaac @*/
627dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim)
628dd8e54a2SToby Isaac {
629dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
630dd8e54a2SToby Isaac   PetscInt       dim;
631dd8e54a2SToby Isaac   PetscErrorCode ierr;
632dd8e54a2SToby Isaac 
633dd8e54a2SToby Isaac   PetscFunctionBegin;
634dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
635dd8e54a2SToby Isaac   PetscValidIntPointer(adjCodim,2);
636dd8e54a2SToby Isaac   ierr      = DMGetDimension(dm,&dim);CHKERRQ(ierr);
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 
6549be51f97SToby Isaac .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);
662ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup");
663dd8e54a2SToby Isaac   if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", 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 
6829be51f97SToby Isaac .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 
7089be51f97SToby Isaac .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);
716ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(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 
7369be51f97SToby Isaac .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 
7619be51f97SToby Isaac .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);
76956ba9f64SToby Isaac   if (dm->setupcalled) SETERRQ(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 
7839be51f97SToby Isaac   Output Paramater:
7849be51f97SToby Isaac . initefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7859be51f97SToby Isaac 
7869be51f97SToby Isaac   Level: intermediate
7879be51f97SToby Isaac 
7889be51f97SToby Isaac .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 
8149be51f97SToby Isaac .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);
822ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(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 
8429be51f97SToby Isaac .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 
8699be51f97SToby Isaac .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   PetscErrorCode ierr;
875c7eeac06SToby Isaac 
876c7eeac06SToby Isaac   PetscFunctionBegin;
877c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
878c7eeac06SToby Isaac   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
879a73e2921SToby Isaac   ierr = PetscStrallocpy((const char*) adaptStrategy,(char**)&forest->adaptStrategy);CHKERRQ(ierr);
880c7eeac06SToby Isaac   PetscFunctionReturn(0);
881c7eeac06SToby Isaac }
882c7eeac06SToby Isaac 
8839be51f97SToby Isaac /*@C
8849be51f97SToby Isaac   DMForestSetAdaptivityStrategy - Get the strategy for combining adaptivity labels from multiple processes.  Subtypes
8859be51f97SToby Isaac   of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all
8869be51f97SToby Isaac   processes must agree for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only
8879be51f97SToby Isaac   one process needs to specify refinement/coarsening.
8889be51f97SToby Isaac 
8899be51f97SToby Isaac   Not collective
8909be51f97SToby Isaac 
8919be51f97SToby Isaac   Input Parameter:
8929be51f97SToby Isaac . dm - the forest
8939be51f97SToby Isaac 
8949be51f97SToby Isaac   Output Parameter:
8959be51f97SToby Isaac . adaptStrategy - the adaptivity strategy (default DMFORESTADAPTALL)
8969be51f97SToby Isaac 
8979be51f97SToby Isaac   Level: advanced
8989be51f97SToby Isaac 
8999be51f97SToby Isaac .seealso: DMForestSetAdaptivityStrategy()
9009be51f97SToby Isaac @*/
901c7eeac06SToby Isaac PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy)
902c7eeac06SToby Isaac {
903c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
904c7eeac06SToby Isaac 
905c7eeac06SToby Isaac   PetscFunctionBegin;
906c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
907c7eeac06SToby Isaac   PetscValidPointer(adaptStrategy,2);
908c7eeac06SToby Isaac   *adaptStrategy = forest->adaptStrategy;
909c7eeac06SToby Isaac   PetscFunctionReturn(0);
910c7eeac06SToby Isaac }
911c7eeac06SToby Isaac 
9122a133e43SToby Isaac /*@
9132a133e43SToby Isaac   DMForestGetAdaptivitySuccess - Return whether the requested adaptation (refinement, coarsening, repartitioning,
9142a133e43SToby Isaac   etc.) was successful.  PETSC_FALSE indicates that the post-adaptation forest is the same as the pre-adpatation
9152a133e43SToby Isaac   forest.  A requested adaptation may have been unsuccessful if, for example, the requested refinement would have
9162a133e43SToby Isaac   exceeded the maximum refinement level.
9172a133e43SToby Isaac 
9182a133e43SToby Isaac   Collective on dm
9192a133e43SToby Isaac 
9202a133e43SToby Isaac   Input Parameter:
9212a133e43SToby Isaac 
9222a133e43SToby Isaac . dm - the post-adaptation forest
9232a133e43SToby Isaac 
9242a133e43SToby Isaac   Output Parameter:
9252a133e43SToby Isaac 
9262a133e43SToby Isaac . success - PETSC_TRUE if the post-adaptation forest is different from the pre-adaptation forest.
9272a133e43SToby Isaac 
9282a133e43SToby Isaac   Level: intermediate
9292a133e43SToby Isaac 
9302a133e43SToby Isaac .see
9312a133e43SToby Isaac @*/
9322a133e43SToby Isaac PetscErrorCode DMForestGetAdaptivitySuccess(DM dm, PetscBool *success)
9332a133e43SToby Isaac {
9342a133e43SToby Isaac   DM_Forest      *forest;
9352a133e43SToby Isaac   PetscErrorCode ierr;
9362a133e43SToby Isaac 
9372a133e43SToby Isaac   PetscFunctionBegin;
9382a133e43SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9392a133e43SToby Isaac   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() has not been called yet.");
9402a133e43SToby Isaac   forest = (DM_Forest *) dm->data;
9412a133e43SToby Isaac   ierr = (forest->getadaptivitysuccess)(dm,success);CHKERRQ(ierr);
9422a133e43SToby Isaac   PetscFunctionReturn(0);
9432a133e43SToby Isaac }
9442a133e43SToby Isaac 
945bf9b5d84SToby Isaac /*@
946bf9b5d84SToby Isaac   DMForestSetComputeAdaptivitySF - During the pre-setup phase, set whether transfer PetscSFs should be computed
947bf9b5d84SToby 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().
948bf9b5d84SToby Isaac 
949bf9b5d84SToby Isaac   Logically collective on dm
950bf9b5d84SToby Isaac 
951bf9b5d84SToby Isaac   Input Parameters:
952bf9b5d84SToby Isaac + dm - the post-adaptation forest
953bf9b5d84SToby Isaac - computeSF - default PETSC_TRUE
954bf9b5d84SToby Isaac 
955bf9b5d84SToby Isaac   Level: advanced
956bf9b5d84SToby Isaac 
957bf9b5d84SToby Isaac .seealso: DMForestGetComputeAdaptivitySF(), DMForestGetAdaptivitySF()
958bf9b5d84SToby Isaac @*/
959bf9b5d84SToby Isaac PetscErrorCode DMForestSetComputeAdaptivitySF(DM dm, PetscBool computeSF)
960bf9b5d84SToby Isaac {
961bf9b5d84SToby Isaac   DM_Forest *forest;
962bf9b5d84SToby Isaac 
963bf9b5d84SToby Isaac   PetscFunctionBegin;
964bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
965bf9b5d84SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot compute adaptivity PetscSFs after setup is called");
966bf9b5d84SToby Isaac   forest                 = (DM_Forest*) dm->data;
967bf9b5d84SToby Isaac   forest->computeAdaptSF = computeSF;
968bf9b5d84SToby Isaac   PetscFunctionReturn(0);
969bf9b5d84SToby Isaac }
970bf9b5d84SToby Isaac 
9710eb7e1eaSToby Isaac PetscErrorCode DMForestTransferVec(DM dmIn, Vec vecIn, DM dmOut, Vec vecOut, PetscBool useBCs, PetscReal time)
97280b27e07SToby Isaac {
97380b27e07SToby Isaac   DM_Forest      *forest;
97480b27e07SToby Isaac   PetscErrorCode ierr;
97580b27e07SToby Isaac 
97680b27e07SToby Isaac   PetscFunctionBegin;
97780b27e07SToby Isaac   PetscValidHeaderSpecific(dmIn   ,DM_CLASSID  ,1);
97880b27e07SToby Isaac   PetscValidHeaderSpecific(vecIn  ,VEC_CLASSID ,2);
97980b27e07SToby Isaac   PetscValidHeaderSpecific(dmOut  ,DM_CLASSID  ,3);
98080b27e07SToby Isaac   PetscValidHeaderSpecific(vecOut ,VEC_CLASSID ,4);
98180b27e07SToby Isaac   forest = (DM_Forest *) dmIn->data;
98280b27e07SToby Isaac   if (!forest->transfervec) SETERRQ(PetscObjectComm((PetscObject)dmIn),PETSC_ERR_SUP,"DMForestTransferVec() not implemented");
9830eb7e1eaSToby Isaac   ierr = (forest->transfervec)(dmIn,vecIn,dmOut,vecOut,useBCs,time);CHKERRQ(ierr);
98480b27e07SToby Isaac   PetscFunctionReturn(0);
98580b27e07SToby Isaac }
98680b27e07SToby Isaac 
987bf9b5d84SToby Isaac /*@
988bf9b5d84SToby Isaac   DMForestGetComputeAdaptivitySF - Get whether transfer PetscSFs should be computed relating the cells of the
989bf9b5d84SToby Isaac   pre-adaptation forest to the post-adaptiation forest.  After DMSetUp() is called, these transfer PetscSFs can be
990bf9b5d84SToby Isaac   accessed with DMForestGetAdaptivitySF().
991bf9b5d84SToby Isaac 
992bf9b5d84SToby Isaac   Not collective
993bf9b5d84SToby Isaac 
994bf9b5d84SToby Isaac   Input Parameter:
995bf9b5d84SToby Isaac . dm - the post-adaptation forest
996bf9b5d84SToby Isaac 
997bf9b5d84SToby Isaac   Output Parameter:
998bf9b5d84SToby Isaac . computeSF - default PETSC_TRUE
999bf9b5d84SToby Isaac 
1000bf9b5d84SToby Isaac   Level: advanced
1001bf9b5d84SToby Isaac 
1002bf9b5d84SToby Isaac .seealso: DMForestSetComputeAdaptivitySF(), DMForestGetAdaptivitySF()
1003bf9b5d84SToby Isaac @*/
1004bf9b5d84SToby Isaac PetscErrorCode DMForestGetComputeAdaptivitySF(DM dm, PetscBool *computeSF)
1005bf9b5d84SToby Isaac {
1006bf9b5d84SToby Isaac   DM_Forest *forest;
1007bf9b5d84SToby Isaac 
1008bf9b5d84SToby Isaac   PetscFunctionBegin;
1009bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1010bf9b5d84SToby Isaac   forest     = (DM_Forest*) dm->data;
1011bf9b5d84SToby Isaac   *computeSF = forest->computeAdaptSF;
1012bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1013bf9b5d84SToby Isaac }
1014bf9b5d84SToby Isaac 
1015bf9b5d84SToby Isaac /*@
1016bf9b5d84SToby Isaac   DMForestGetAdaptivitySF - Get PetscSFs that relate the pre-adaptation forest to the post-adaptation forest.
1017bf9b5d84SToby Isaac   Adaptation can be any combination of refinement, coarsening, repartition, and change of overlap, so there may be
1018bf9b5d84SToby Isaac   some cells of the pre-adaptation that are parents of post-adaptation cells, and vice versa.  Therefore there are two
1019bf9b5d84SToby Isaac   PetscSFs: one that relates pre-adaptation coarse cells to post-adaptation fine cells, and one that relates
1020bf9b5d84SToby Isaac   pre-adaptation fine cells to post-adaptation coarse cells.
1021bf9b5d84SToby Isaac 
1022bf9b5d84SToby Isaac   Not collective
1023bf9b5d84SToby Isaac 
1024bf9b5d84SToby Isaac   Input Parameter:
1025bf9b5d84SToby Isaac   dm - the post-adaptation forest
1026bf9b5d84SToby Isaac 
1027bf9b5d84SToby Isaac   Output Parameter:
10280f17b9e3SToby Isaac   preCoarseToFine - pre-adaptation coarse cells to post-adaptation fine cells: BCast goes from pre- to post-
10290f17b9e3SToby Isaac   coarseToPreFine - post-adaptation coarse cells to pre-adaptation fine cells: BCast goes from post- to pre-
1030bf9b5d84SToby Isaac 
1031bf9b5d84SToby Isaac   Level: advanced
1032bf9b5d84SToby Isaac 
1033bf9b5d84SToby Isaac .seealso: DMForestGetComputeAdaptivitySF(), DMForestSetComputeAdaptivitySF()
1034bf9b5d84SToby Isaac @*/
10350f17b9e3SToby Isaac PetscErrorCode DMForestGetAdaptivitySF(DM dm, PetscSF *preCoarseToFine, PetscSF *coarseToPreFine)
1036bf9b5d84SToby Isaac {
1037bf9b5d84SToby Isaac   DM_Forest      *forest;
1038bf9b5d84SToby Isaac   PetscErrorCode ierr;
1039bf9b5d84SToby Isaac 
1040bf9b5d84SToby Isaac   PetscFunctionBegin;
1041bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1042bf9b5d84SToby Isaac   ierr   = DMSetUp(dm);CHKERRQ(ierr);
1043bf9b5d84SToby Isaac   forest = (DM_Forest*) dm->data;
1044f885a11aSToby Isaac   if (preCoarseToFine) *preCoarseToFine = forest->preCoarseToFine;
1045f885a11aSToby Isaac   if (coarseToPreFine) *coarseToPreFine = forest->coarseToPreFine;
1046bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1047bf9b5d84SToby Isaac }
1048bf9b5d84SToby Isaac 
10499be51f97SToby Isaac /*@
10509be51f97SToby Isaac   DMForestSetGradeFactor - During the pre-setup phase, set the desired amount of grading in the mesh, e.g. give 2 to
10519be51f97SToby Isaac   indicate that the diameter of neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may
10529be51f97SToby Isaac   only support one particular choice of grading factor.
10539be51f97SToby Isaac 
10549be51f97SToby Isaac   Logically collective on dm
10559be51f97SToby Isaac 
10569be51f97SToby Isaac   Input Parameters:
10579be51f97SToby Isaac + dm - the forest
10589be51f97SToby Isaac - grade - the grading factor
10599be51f97SToby Isaac 
10609be51f97SToby Isaac   Level: advanced
10619be51f97SToby Isaac 
10629be51f97SToby Isaac .seealso: DMForestGetGradeFactor()
10639be51f97SToby Isaac @*/
1064c7eeac06SToby Isaac PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade)
1065c7eeac06SToby Isaac {
1066c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1067c7eeac06SToby Isaac 
1068c7eeac06SToby Isaac   PetscFunctionBegin;
1069c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1070ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup");
1071c7eeac06SToby Isaac   forest->gradeFactor = grade;
1072c7eeac06SToby Isaac   PetscFunctionReturn(0);
1073c7eeac06SToby Isaac }
1074c7eeac06SToby Isaac 
10759be51f97SToby Isaac /*@
10769be51f97SToby Isaac   DMForestGetGradeFactor - Get the desired amount of grading in the mesh, e.g. give 2 to indicate that the diameter of
10779be51f97SToby Isaac   neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may only support one particular
10789be51f97SToby Isaac   choice of grading factor.
10799be51f97SToby Isaac 
10809be51f97SToby Isaac   Not collective
10819be51f97SToby Isaac 
10829be51f97SToby Isaac   Input Parameter:
10839be51f97SToby Isaac . dm - the forest
10849be51f97SToby Isaac 
10859be51f97SToby Isaac   Output Parameter:
10869be51f97SToby Isaac . grade - the grading factor
10879be51f97SToby Isaac 
10889be51f97SToby Isaac   Level: advanced
10899be51f97SToby Isaac 
10909be51f97SToby Isaac .seealso: DMForestSetGradeFactor()
10919be51f97SToby Isaac @*/
1092c7eeac06SToby Isaac PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade)
1093c7eeac06SToby Isaac {
1094c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1095c7eeac06SToby Isaac 
1096c7eeac06SToby Isaac   PetscFunctionBegin;
1097c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1098c7eeac06SToby Isaac   PetscValidIntPointer(grade,2);
1099c7eeac06SToby Isaac   *grade = forest->gradeFactor;
1100c7eeac06SToby Isaac   PetscFunctionReturn(0);
1101c7eeac06SToby Isaac }
1102c7eeac06SToby Isaac 
11039be51f97SToby Isaac /*@
11049be51f97SToby Isaac   DMForestSetCellWeightFactor - During the pre-setup phase, set the factor by which the level of refinement changes
11059be51f97SToby Isaac   the cell weight (see DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be
11069be51f97SToby Isaac   (cellWeight) * (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on
11079be51f97SToby Isaac   its level; a factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the
11089be51f97SToby Isaac   computation associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11099be51f97SToby Isaac 
11109be51f97SToby Isaac   Logically collective on dm
11119be51f97SToby Isaac 
11129be51f97SToby Isaac   Input Parameters:
11139be51f97SToby Isaac + dm - the forest
11149be51f97SToby Isaac - weightsFactors - default 1.
11159be51f97SToby Isaac 
11169be51f97SToby Isaac   Level: advanced
11179be51f97SToby Isaac 
11189be51f97SToby Isaac .seealso: DMForestGetCellWeightFactor(), DMForestSetCellWeights()
11199be51f97SToby Isaac @*/
1120ef51cf95SToby Isaac PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor)
1121c7eeac06SToby Isaac {
1122c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1123c7eeac06SToby Isaac 
1124c7eeac06SToby Isaac   PetscFunctionBegin;
1125c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1126ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup");
1127c7eeac06SToby Isaac   forest->weightsFactor = weightsFactor;
1128c7eeac06SToby Isaac   PetscFunctionReturn(0);
1129c7eeac06SToby Isaac }
1130c7eeac06SToby Isaac 
11319be51f97SToby Isaac /*@
11329be51f97SToby Isaac   DMForestGetCellWeightFactor - Get the factor by which the level of refinement changes the cell weight (see
11339be51f97SToby Isaac   DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be (cellWeight) *
11349be51f97SToby Isaac   (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on its level; a
11359be51f97SToby Isaac   factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the computation
11369be51f97SToby Isaac   associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11379be51f97SToby Isaac 
11389be51f97SToby Isaac   Not collective
11399be51f97SToby Isaac 
11409be51f97SToby Isaac   Input Parameter:
11419be51f97SToby Isaac . dm - the forest
11429be51f97SToby Isaac 
11439be51f97SToby Isaac   Output Parameter:
11449be51f97SToby Isaac . weightsFactors - default 1.
11459be51f97SToby Isaac 
11469be51f97SToby Isaac   Level: advanced
11479be51f97SToby Isaac 
11489be51f97SToby Isaac .seealso: DMForestSetCellWeightFactor(), DMForestSetCellWeights()
11499be51f97SToby Isaac @*/
1150ef51cf95SToby Isaac PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor)
1151c7eeac06SToby Isaac {
1152c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1153c7eeac06SToby Isaac 
1154c7eeac06SToby Isaac   PetscFunctionBegin;
1155c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1156c7eeac06SToby Isaac   PetscValidRealPointer(weightsFactor,2);
1157c7eeac06SToby Isaac   *weightsFactor = forest->weightsFactor;
1158c7eeac06SToby Isaac   PetscFunctionReturn(0);
1159c7eeac06SToby Isaac }
1160c7eeac06SToby Isaac 
11619be51f97SToby Isaac /*@
11629be51f97SToby Isaac   DMForestGetCellChart - After the setup phase, get the local half-open interval of the chart of cells on this process
11639be51f97SToby Isaac 
11649be51f97SToby Isaac   Not collective
11659be51f97SToby Isaac 
11669be51f97SToby Isaac   Input Parameter:
11679be51f97SToby Isaac . dm - the forest
11689be51f97SToby Isaac 
11699be51f97SToby Isaac   Output Parameters:
11709be51f97SToby Isaac + cStart - the first cell on this process
11719be51f97SToby Isaac - cEnd - one after the final cell on this process
11729be51f97SToby Isaac 
11731a244344SSatish Balay   Level: intermediate
11749be51f97SToby Isaac 
11759be51f97SToby Isaac .seealso: DMForestGetCellSF()
11769be51f97SToby Isaac @*/
1177c7eeac06SToby Isaac PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd)
1178c7eeac06SToby Isaac {
1179c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1180c7eeac06SToby Isaac   PetscErrorCode ierr;
1181c7eeac06SToby Isaac 
1182c7eeac06SToby Isaac   PetscFunctionBegin;
1183c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1184c7eeac06SToby Isaac   PetscValidIntPointer(cStart,2);
1185c7eeac06SToby Isaac   PetscValidIntPointer(cEnd,2);
1186c7eeac06SToby Isaac   if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) {
1187c7eeac06SToby Isaac     ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr);
1188c7eeac06SToby Isaac   }
1189c7eeac06SToby Isaac   *cStart =  forest->cStart;
1190c7eeac06SToby Isaac   *cEnd   =  forest->cEnd;
1191c7eeac06SToby Isaac   PetscFunctionReturn(0);
1192c7eeac06SToby Isaac }
1193c7eeac06SToby Isaac 
11949be51f97SToby Isaac /*@
11959be51f97SToby Isaac   DMForestGetCellSF - After the setup phase, get the PetscSF for overlapping cells between processes
11969be51f97SToby Isaac 
11979be51f97SToby Isaac   Not collective
11989be51f97SToby Isaac 
11999be51f97SToby Isaac   Input Parameter:
12009be51f97SToby Isaac . dm - the forest
12019be51f97SToby Isaac 
12029be51f97SToby Isaac   Output Parameter:
12039be51f97SToby Isaac . cellSF - the PetscSF
12049be51f97SToby Isaac 
12051a244344SSatish Balay   Level: intermediate
12069be51f97SToby Isaac 
12079be51f97SToby Isaac .seealso: DMForestGetCellChart()
12089be51f97SToby Isaac @*/
1209c7eeac06SToby Isaac PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF)
1210c7eeac06SToby Isaac {
1211c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1212c7eeac06SToby Isaac   PetscErrorCode ierr;
1213c7eeac06SToby Isaac 
1214c7eeac06SToby Isaac   PetscFunctionBegin;
1215c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1216c7eeac06SToby Isaac   PetscValidPointer(cellSF,2);
1217c7eeac06SToby Isaac   if ((!forest->cellSF) && forest->createcellsf) {
1218c7eeac06SToby Isaac     ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr);
1219c7eeac06SToby Isaac   }
1220c7eeac06SToby Isaac   *cellSF = forest->cellSF;
1221c7eeac06SToby Isaac   PetscFunctionReturn(0);
1222c7eeac06SToby Isaac }
1223c7eeac06SToby Isaac 
12249be51f97SToby Isaac /*@C
12259be51f97SToby Isaac   DMForestSetAdaptivityLabel - During the pre-setup phase, set the label of the pre-adaptation forest (see
12269be51f97SToby Isaac   DMForestGetAdaptivityForest()) that holds the adaptation flags (refinement, coarsening, or some combination).  The
1227cd3c525cSToby Isaac   interpretation of the label values is up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP,
1228cd3c525cSToby Isaac   DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have been reserved as choices that should be accepted by all subtypes.
12299be51f97SToby Isaac 
12309be51f97SToby Isaac   Logically collective on dm
12319be51f97SToby Isaac 
12329be51f97SToby Isaac   Input Parameters:
12339be51f97SToby Isaac - dm - the forest
1234a1b0c543SToby Isaac + adaptLabel - the label in the pre-adaptation forest
12359be51f97SToby Isaac 
12369be51f97SToby Isaac   Level: intermediate
12379be51f97SToby Isaac 
12389be51f97SToby Isaac .seealso DMForestGetAdaptivityLabel()
12399be51f97SToby Isaac @*/
1240a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityLabel(DM dm, DMLabel adaptLabel)
1241c7eeac06SToby Isaac {
1242c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1243c7eeac06SToby Isaac   PetscErrorCode ierr;
1244c7eeac06SToby Isaac 
1245c7eeac06SToby Isaac   PetscFunctionBegin;
1246c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1247a1b0c543SToby Isaac   adaptLabel->refct++;
1248a1b0c543SToby Isaac   if (forest->adaptLabel) {ierr = DMLabelDestroy(&forest->adaptLabel);CHKERRQ(ierr);}
1249a1b0c543SToby Isaac   forest->adaptLabel = adaptLabel;
1250c7eeac06SToby Isaac   PetscFunctionReturn(0);
1251c7eeac06SToby Isaac }
1252c7eeac06SToby Isaac 
12539be51f97SToby Isaac /*@C
12549be51f97SToby Isaac   DMForestGetAdaptivityLabel - Get the label of the pre-adaptation forest (see DMForestGetAdaptivityForest()) that
12559be51f97SToby Isaac   holds the adaptation flags (refinement, coarsening, or some combination).  The interpretation of the label values is
1256cd3c525cSToby Isaac   up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have
1257cd3c525cSToby Isaac   been reserved as choices that should be accepted by all subtypes.
12589be51f97SToby Isaac 
12599be51f97SToby Isaac   Not collective
12609be51f97SToby Isaac 
12619be51f97SToby Isaac   Input Parameter:
12629be51f97SToby Isaac . dm - the forest
12639be51f97SToby Isaac 
12649be51f97SToby Isaac   Output Parameter:
12659be51f97SToby Isaac . adaptLabel - the name of the label in the pre-adaptation forest
12669be51f97SToby Isaac 
12679be51f97SToby Isaac   Level: intermediate
12689be51f97SToby Isaac 
12699be51f97SToby Isaac .seealso DMForestSetAdaptivityLabel()
12709be51f97SToby Isaac @*/
1271a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityLabel(DM dm, DMLabel *adaptLabel)
1272c7eeac06SToby Isaac {
1273c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1274c7eeac06SToby Isaac 
1275c7eeac06SToby Isaac   PetscFunctionBegin;
1276c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1277ba936b91SToby Isaac   *adaptLabel = forest->adaptLabel;
1278c7eeac06SToby Isaac   PetscFunctionReturn(0);
1279c7eeac06SToby Isaac }
1280c7eeac06SToby Isaac 
12819be51f97SToby Isaac /*@
12829be51f97SToby Isaac   DMForestSetCellWeights - Set the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
12839be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
12849be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
12859be51f97SToby Isaac   of 1.
12869be51f97SToby Isaac 
12879be51f97SToby Isaac   Logically collective on dm
12889be51f97SToby Isaac 
12899be51f97SToby Isaac   Input Parameters:
12909be51f97SToby Isaac + dm - the forest
12919be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
12929be51f97SToby Isaac - copyMode - how weights should reference weights
12939be51f97SToby Isaac 
12949be51f97SToby Isaac   Level: advanced
12959be51f97SToby Isaac 
12969be51f97SToby Isaac .seealso: DMForestGetCellWeights(), DMForestSetWeightCapacity()
12979be51f97SToby Isaac @*/
1298c7eeac06SToby Isaac PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode)
1299c7eeac06SToby Isaac {
1300c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1301c7eeac06SToby Isaac   PetscInt       cStart, cEnd;
1302c7eeac06SToby Isaac   PetscErrorCode ierr;
1303c7eeac06SToby Isaac 
1304c7eeac06SToby Isaac   PetscFunctionBegin;
1305c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1306c7eeac06SToby Isaac   ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr);
1307c7eeac06SToby Isaac   if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd);
1308c7eeac06SToby Isaac   if (copyMode == PETSC_COPY_VALUES) {
1309c7eeac06SToby Isaac     if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) {
1310c7eeac06SToby Isaac       ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr);
1311c7eeac06SToby Isaac     }
1312c7eeac06SToby Isaac     ierr                        = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr);
1313c7eeac06SToby Isaac     forest->cellWeightsCopyMode = PETSC_OWN_POINTER;
1314c7eeac06SToby Isaac     PetscFunctionReturn(0);
1315c7eeac06SToby Isaac   }
1316c7eeac06SToby Isaac   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) {
1317c7eeac06SToby Isaac     ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr);
1318c7eeac06SToby Isaac   }
1319c7eeac06SToby Isaac   forest->cellWeights         = weights;
1320c7eeac06SToby Isaac   forest->cellWeightsCopyMode = copyMode;
1321c7eeac06SToby Isaac   PetscFunctionReturn(0);
1322c7eeac06SToby Isaac }
1323c7eeac06SToby Isaac 
13249be51f97SToby Isaac /*@
13259be51f97SToby Isaac   DMForestGetCellWeights - Get the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
13269be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
13279be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
13289be51f97SToby Isaac   of 1.
13299be51f97SToby Isaac 
13309be51f97SToby Isaac   Not collective
13319be51f97SToby Isaac 
13329be51f97SToby Isaac   Input Parameter:
13339be51f97SToby Isaac . dm - the forest
13349be51f97SToby Isaac 
13359be51f97SToby Isaac   Output Parameter:
13369be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
13379be51f97SToby Isaac 
13389be51f97SToby Isaac   Level: advanced
13399be51f97SToby Isaac 
13409be51f97SToby Isaac .seealso: DMForestSetCellWeights(), DMForestSetWeightCapacity()
13419be51f97SToby Isaac @*/
1342c7eeac06SToby Isaac PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights)
1343c7eeac06SToby Isaac {
1344c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1345c7eeac06SToby Isaac 
1346c7eeac06SToby Isaac   PetscFunctionBegin;
1347c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1348c7eeac06SToby Isaac   PetscValidPointer(weights,2);
1349c7eeac06SToby Isaac   *weights = forest->cellWeights;
1350c7eeac06SToby Isaac   PetscFunctionReturn(0);
1351c7eeac06SToby Isaac }
1352c7eeac06SToby Isaac 
13539be51f97SToby Isaac /*@
13549be51f97SToby Isaac   DMForestSetWeightCapacity - During the pre-setup phase, set the capacity of the current process when repartitioning
13559be51f97SToby Isaac   a pre-adaptation forest (see DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each
13569be51f97SToby Isaac   process's cells to the process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that
13579be51f97SToby Isaac   the current process should not have any cells after repartitioning.
13589be51f97SToby Isaac 
13599be51f97SToby Isaac   Logically Collective on dm
13609be51f97SToby Isaac 
13619be51f97SToby Isaac   Input parameters:
13629be51f97SToby Isaac + dm - the forest
13639be51f97SToby Isaac - capacity - this process's capacity
13649be51f97SToby Isaac 
13659be51f97SToby Isaac   Level: advanced
13669be51f97SToby Isaac 
13679be51f97SToby Isaac .seealso DMForestGetWeightCapacity(), DMForestSetCellWeights(), DMForestSetCellWeightFactor()
13689be51f97SToby Isaac @*/
1369c7eeac06SToby Isaac PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity)
1370c7eeac06SToby Isaac {
1371c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1372c7eeac06SToby Isaac 
1373c7eeac06SToby Isaac   PetscFunctionBegin;
1374c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1375ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup");
1376c7eeac06SToby Isaac   if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity);
1377c7eeac06SToby Isaac   forest->weightCapacity = capacity;
1378c7eeac06SToby Isaac   PetscFunctionReturn(0);
1379c7eeac06SToby Isaac }
1380c7eeac06SToby Isaac 
13819be51f97SToby Isaac /*@
13829be51f97SToby Isaac   DMForestGetWeightCapacity - Set the capacity of the current process when repartitioning a pre-adaptation forest (see
13839be51f97SToby Isaac   DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each process's cells to the
13849be51f97SToby Isaac   process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that the current process
13859be51f97SToby Isaac   should not have any cells after repartitioning.
13869be51f97SToby Isaac 
13879be51f97SToby Isaac   Not collective
13889be51f97SToby Isaac 
13899be51f97SToby Isaac   Input parameter:
13909be51f97SToby Isaac . dm - the forest
13919be51f97SToby Isaac 
13929be51f97SToby Isaac   Output parameter:
13939be51f97SToby Isaac . capacity - this process's capacity
13949be51f97SToby Isaac 
13959be51f97SToby Isaac   Level: advanced
13969be51f97SToby Isaac 
13979be51f97SToby Isaac .seealso DMForestSetWeightCapacity(), DMForestSetCellWeights(), DMForestSetCellWeightFactor()
13989be51f97SToby Isaac @*/
1399c7eeac06SToby Isaac PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity)
1400c7eeac06SToby Isaac {
1401c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1402c7eeac06SToby Isaac 
1403c7eeac06SToby Isaac   PetscFunctionBegin;
1404c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1405c7eeac06SToby Isaac   PetscValidRealPointer(capacity,2);
1406c7eeac06SToby Isaac   *capacity = forest->weightCapacity;
1407c7eeac06SToby Isaac   PetscFunctionReturn(0);
1408c7eeac06SToby Isaac }
1409c7eeac06SToby Isaac 
14100709b2feSToby Isaac PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptionItems *PetscOptionsObject,DM dm)
1411db4d5e8cSToby Isaac {
1412db4d5e8cSToby Isaac   DM_Forest                  *forest = (DM_Forest*) dm->data;
141356ba9f64SToby Isaac   PetscBool                  flg, flg1, flg2, flg3, flg4;
1414dd8e54a2SToby Isaac   DMForestTopology           oldTopo;
1415c7eeac06SToby Isaac   char                       stringBuffer[256];
1416dd8e54a2SToby Isaac   PetscViewer                viewer;
1417dd8e54a2SToby Isaac   PetscViewerFormat          format;
141856ba9f64SToby Isaac   PetscInt                   adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade;
1419c7eeac06SToby Isaac   PetscReal                  weightsFactor;
1420c7eeac06SToby Isaac   DMForestAdaptivityStrategy adaptStrategy;
1421db4d5e8cSToby Isaac   PetscErrorCode             ierr;
1422db4d5e8cSToby Isaac 
1423db4d5e8cSToby Isaac   PetscFunctionBegin;
1424db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
142558762b62SToby Isaac   forest->setfromoptionscalled = PETSC_TRUE;
1426dd8e54a2SToby Isaac   ierr                         = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr);
1427a3eda1eaSToby Isaac   ierr                         = PetscOptionsHead(PetscOptionsObject,"DMForest Options");CHKERRQ(ierr);
142856ba9f64SToby Isaac   ierr                         = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg1);CHKERRQ(ierr);
142956ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg2);CHKERRQ(ierr);
143056ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg3);CHKERRQ(ierr);
143156ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg4);CHKERRQ(ierr);
1432f885a11aSToby Isaac   if ((PetscInt) flg1 + (PetscInt) flg2 + (PetscInt) flg3 + (PetscInt) flg4 > 1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Specify only one of -dm_forest_{topology,base_dm,coarse_forest,fine_forest}");
143356ba9f64SToby Isaac   if (flg1) {
143456ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr);
143556ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
143620e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
143756ba9f64SToby Isaac   }
143856ba9f64SToby Isaac   if (flg2) {
1439dd8e54a2SToby Isaac     DM base;
1440dd8e54a2SToby Isaac 
1441dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr);
1442dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1443dd8e54a2SToby Isaac     ierr = DMLoad(base,viewer);CHKERRQ(ierr);
1444dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1445dd8e54a2SToby Isaac     ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
1446dd8e54a2SToby Isaac     ierr = DMDestroy(&base);CHKERRQ(ierr);
144756ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
144820e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
1449dd8e54a2SToby Isaac   }
145056ba9f64SToby Isaac   if (flg3) {
1451dd8e54a2SToby Isaac     DM coarse;
1452dd8e54a2SToby Isaac 
1453dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr);
1454dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1455dd8e54a2SToby Isaac     ierr = DMLoad(coarse,viewer);CHKERRQ(ierr);
1456dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
145720e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,coarse);CHKERRQ(ierr);
1458dd8e54a2SToby Isaac     ierr = DMDestroy(&coarse);CHKERRQ(ierr);
145956ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
146056ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
1461dd8e54a2SToby Isaac   }
146256ba9f64SToby Isaac   if (flg4) {
1463dd8e54a2SToby Isaac     DM fine;
1464dd8e54a2SToby Isaac 
1465dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr);
1466dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1467dd8e54a2SToby Isaac     ierr = DMLoad(fine,viewer);CHKERRQ(ierr);
1468dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
146920e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,fine);CHKERRQ(ierr);
1470dd8e54a2SToby Isaac     ierr = DMDestroy(&fine);CHKERRQ(ierr);
147156ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
147256ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
1473dd8e54a2SToby Isaac   }
1474dd8e54a2SToby Isaac   ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr);
1475dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr);
1476dd8e54a2SToby Isaac   if (flg) {
1477dd8e54a2SToby Isaac     ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr);
1478f885a11aSToby Isaac   } else {
1479dd8e54a2SToby Isaac     ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr);
1480dd8e54a2SToby Isaac     ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr);
1481dd8e54a2SToby Isaac     if (flg) {
1482dd8e54a2SToby Isaac       ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr);
1483dd8e54a2SToby Isaac     }
1484dd8e54a2SToby Isaac   }
1485dd8e54a2SToby Isaac   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
1486dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr);
1487dd8e54a2SToby Isaac   if (flg) {
1488dd8e54a2SToby Isaac     ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr);
1489dd8e54a2SToby Isaac   }
1490a6121fbdSMatthew G. Knepley #if 0
1491a6121fbdSMatthew G. Knepley   ierr = PetscOptionsInt("-dm_refine","equivalent to -dm_forest_set_minimum_refinement and -dm_forest_set_initial_refinement with the same value",NULL,minRefinement,&minRefinement,&flg);CHKERRQ(ierr);
1492a6121fbdSMatthew G. Knepley   if (flg) {
1493a6121fbdSMatthew G. Knepley     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
1494a6121fbdSMatthew G. Knepley     ierr = DMForestSetInitialRefinement(dm,minRefinement);CHKERRQ(ierr);
1495a6121fbdSMatthew G. Knepley   }
1496a6121fbdSMatthew G. Knepley   ierr = PetscOptionsInt("-dm_refine_hierarchy","equivalent to -dm_forest_set_minimum_refinement 0 and -dm_forest_set_initial_refinement",NULL,initRefinement,&initRefinement,&flg);CHKERRQ(ierr);
1497a6121fbdSMatthew G. Knepley   if (flg) {
1498a6121fbdSMatthew G. Knepley     ierr = DMForestSetMinimumRefinement(dm,0);CHKERRQ(ierr);
1499a6121fbdSMatthew G. Knepley     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
1500a6121fbdSMatthew G. Knepley   }
1501a6121fbdSMatthew G. Knepley #endif
1502dd8e54a2SToby Isaac   ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr);
1503dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr);
1504dd8e54a2SToby Isaac   if (flg) {
1505dd8e54a2SToby Isaac     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
1506db4d5e8cSToby Isaac   }
150756ba9f64SToby Isaac   ierr = DMForestGetInitialRefinement(dm,&initRefinement);CHKERRQ(ierr);
150856ba9f64SToby Isaac   ierr = PetscOptionsInt("-dm_forest_initial_refinement","set the initial level of refinement in the forest","DMForestSetInitialRefinement",initRefinement,&initRefinement,&flg);CHKERRQ(ierr);
150956ba9f64SToby Isaac   if (flg) {
151056ba9f64SToby Isaac     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
151156ba9f64SToby Isaac   }
1512c7eeac06SToby Isaac   ierr = DMForestGetMaximumRefinement(dm,&maxRefinement);CHKERRQ(ierr);
1513c7eeac06SToby Isaac   ierr = PetscOptionsInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg);CHKERRQ(ierr);
1514c7eeac06SToby Isaac   if (flg) {
1515c7eeac06SToby Isaac     ierr = DMForestSetMaximumRefinement(dm,maxRefinement);CHKERRQ(ierr);
1516c7eeac06SToby Isaac   }
1517c7eeac06SToby Isaac   ierr = DMForestGetAdaptivityStrategy(dm,&adaptStrategy);CHKERRQ(ierr);
1518c7eeac06SToby Isaac   ierr = PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,256,&flg);CHKERRQ(ierr);
1519c7eeac06SToby Isaac   if (flg) {
1520c7eeac06SToby Isaac     ierr = DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer);CHKERRQ(ierr);
1521c7eeac06SToby Isaac   }
1522c7eeac06SToby Isaac   ierr = DMForestGetGradeFactor(dm,&grade);CHKERRQ(ierr);
1523c7eeac06SToby Isaac   ierr = PetscOptionsInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg);CHKERRQ(ierr);
1524c7eeac06SToby Isaac   if (flg) {
1525c7eeac06SToby Isaac     ierr = DMForestSetGradeFactor(dm,grade);CHKERRQ(ierr);
1526c7eeac06SToby Isaac   }
1527c7eeac06SToby Isaac   ierr = DMForestGetCellWeightFactor(dm,&weightsFactor);CHKERRQ(ierr);
1528c7eeac06SToby Isaac   ierr = PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg);CHKERRQ(ierr);
1529c7eeac06SToby Isaac   if (flg) {
1530c7eeac06SToby Isaac     ierr = DMForestSetCellWeightFactor(dm,weightsFactor);CHKERRQ(ierr);
1531c7eeac06SToby Isaac   }
1532db4d5e8cSToby Isaac   ierr = PetscOptionsTail();CHKERRQ(ierr);
1533db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1534db4d5e8cSToby Isaac }
1535db4d5e8cSToby Isaac 
1536d8984e3bSMatthew G. Knepley PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1537d8984e3bSMatthew G. Knepley {
1538d8984e3bSMatthew G. Knepley   PetscErrorCode ierr;
1539d8984e3bSMatthew G. Knepley 
1540d8984e3bSMatthew G. Knepley   PetscFunctionBegin;
1541d8984e3bSMatthew G. Knepley   if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);}
1542d8984e3bSMatthew G. Knepley   ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
1543d8984e3bSMatthew G. Knepley   PetscFunctionReturn(0);
1544d8984e3bSMatthew G. Knepley }
1545d8984e3bSMatthew G. Knepley 
15465421bac9SToby Isaac PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined)
15475421bac9SToby Isaac {
15485421bac9SToby Isaac   DMLabel        refine;
15495421bac9SToby Isaac   DM             fineDM;
15505421bac9SToby Isaac   PetscErrorCode ierr;
15515421bac9SToby Isaac 
15525421bac9SToby Isaac   PetscFunctionBegin;
15535421bac9SToby Isaac   ierr = DMGetFineDM(dm,&fineDM);CHKERRQ(ierr);
15545421bac9SToby Isaac   if (fineDM) {
15555421bac9SToby Isaac     ierr       = PetscObjectReference((PetscObject)fineDM);CHKERRQ(ierr);
15565421bac9SToby Isaac     *dmRefined = fineDM;
15575421bac9SToby Isaac     PetscFunctionReturn(0);
15585421bac9SToby Isaac   }
15595421bac9SToby Isaac   ierr = DMForestTemplate(dm,comm,dmRefined);CHKERRQ(ierr);
15605421bac9SToby Isaac   ierr = DMGetLabel(dm,"refine",&refine);CHKERRQ(ierr);
15615421bac9SToby Isaac   if (!refine) {
1562a1b0c543SToby Isaac     ierr = DMLabelCreate("refine",&refine);CHKERRQ(ierr);
1563a1b0c543SToby Isaac     ierr = DMLabelSetDefaultValue(refine,DM_ADAPT_REFINE);CHKERRQ(ierr);
15645421bac9SToby Isaac   }
1565a1b0c543SToby Isaac   else {
1566a1b0c543SToby Isaac     refine->refct++;
1567a1b0c543SToby Isaac   }
1568a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*dmRefined,refine);CHKERRQ(ierr);
1569a1b0c543SToby Isaac   ierr = DMLabelDestroy(&refine);CHKERRQ(ierr);
15705421bac9SToby Isaac   PetscFunctionReturn(0);
15715421bac9SToby Isaac }
15725421bac9SToby Isaac 
15735421bac9SToby Isaac PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened)
15745421bac9SToby Isaac {
15755421bac9SToby Isaac   DMLabel        coarsen;
15765421bac9SToby Isaac   DM             coarseDM;
15775421bac9SToby Isaac   PetscErrorCode ierr;
15785421bac9SToby Isaac 
15795421bac9SToby Isaac   PetscFunctionBegin;
15804098eed7SToby Isaac   {
15814098eed7SToby Isaac     PetscMPIInt mpiComparison;
15824098eed7SToby Isaac     MPI_Comm    dmcomm = PetscObjectComm((PetscObject)dm);
15834098eed7SToby Isaac 
15844098eed7SToby Isaac     ierr = MPI_Comm_compare(comm, dmcomm, &mpiComparison);CHKERRQ(ierr);
1585f885a11aSToby Isaac     if (mpiComparison != MPI_IDENT && mpiComparison != MPI_CONGRUENT) SETERRQ(dmcomm,PETSC_ERR_SUP,"No support for different communicators yet");
15864098eed7SToby Isaac   }
15875421bac9SToby Isaac   ierr = DMGetCoarseDM(dm,&coarseDM);CHKERRQ(ierr);
15885421bac9SToby Isaac   if (coarseDM) {
15895421bac9SToby Isaac     ierr         = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr);
15905421bac9SToby Isaac     *dmCoarsened = coarseDM;
15915421bac9SToby Isaac     PetscFunctionReturn(0);
15925421bac9SToby Isaac   }
15935421bac9SToby Isaac   ierr = DMForestTemplate(dm,comm,dmCoarsened);CHKERRQ(ierr);
1594a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityPurpose(coarseDM,DM_ADAPT_COARSEN);CHKERRQ(ierr);
15955421bac9SToby Isaac   ierr = DMGetLabel(dm,"coarsen",&coarsen);CHKERRQ(ierr);
15965421bac9SToby Isaac   if (!coarsen) {
1597a1b0c543SToby Isaac     ierr = DMLabelCreate("coarsen",&coarsen);CHKERRQ(ierr);
1598a1b0c543SToby Isaac     ierr = DMLabelSetDefaultValue(coarsen,DM_ADAPT_COARSEN);CHKERRQ(ierr);
1599a1b0c543SToby Isaac   } else {
1600a1b0c543SToby Isaac     coarsen->refct++;
16015421bac9SToby Isaac   }
1602a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*dmCoarsened,coarsen);CHKERRQ(ierr);
1603a1b0c543SToby Isaac   ierr = DMLabelDestroy(&coarsen);CHKERRQ(ierr);
16045421bac9SToby Isaac   PetscFunctionReturn(0);
16055421bac9SToby Isaac }
16065421bac9SToby Isaac 
1607a1b0c543SToby Isaac static PetscErrorCode DMAdaptLabel_Forest(DM dm, DMLabel label, DM *adaptedDM)
160809350103SToby Isaac {
160909350103SToby Isaac   PetscBool      success;
161009350103SToby Isaac   PetscErrorCode ierr;
161109350103SToby Isaac 
161209350103SToby Isaac   PetscFunctionBegin;
161309350103SToby Isaac   ierr = DMForestTemplate(dm,PetscObjectComm((PetscObject)dm),adaptedDM);CHKERRQ(ierr);
1614a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*adaptedDM,label);CHKERRQ(ierr);
161509350103SToby Isaac   ierr = DMSetUp(*adaptedDM);CHKERRQ(ierr);
161609350103SToby Isaac   ierr = DMForestGetAdaptivitySuccess(*adaptedDM,&success);CHKERRQ(ierr);
161709350103SToby Isaac   if (!success) {
161809350103SToby Isaac     ierr = DMDestroy(adaptedDM);CHKERRQ(ierr);
161909350103SToby Isaac     *adaptedDM = NULL;
162009350103SToby Isaac   }
162109350103SToby Isaac   PetscFunctionReturn(0);
162209350103SToby Isaac }
162309350103SToby Isaac 
1624d222f98bSToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm)
1625d222f98bSToby Isaac {
1626d222f98bSToby Isaac   PetscErrorCode ierr;
1627d222f98bSToby Isaac 
1628d222f98bSToby Isaac   PetscFunctionBegin;
1629d222f98bSToby Isaac   ierr = PetscMemzero(dm->ops,sizeof(*(dm->ops)));CHKERRQ(ierr);
1630d222f98bSToby Isaac 
1631d222f98bSToby Isaac   dm->ops->clone          = DMClone_Forest;
1632d222f98bSToby Isaac   dm->ops->setfromoptions = DMSetFromOptions_Forest;
1633d222f98bSToby Isaac   dm->ops->destroy        = DMDestroy_Forest;
1634d8984e3bSMatthew G. Knepley   dm->ops->createsubdm    = DMCreateSubDM_Forest;
16355421bac9SToby Isaac   dm->ops->refine         = DMRefine_Forest;
16365421bac9SToby Isaac   dm->ops->coarsen        = DMCoarsen_Forest;
1637a1b0c543SToby Isaac   ierr                    = PetscObjectComposeFunction((PetscObject)dm,"DMAdaptLabel_C",DMAdaptLabel_Forest);CHKERRQ(ierr);
1638d222f98bSToby Isaac   PetscFunctionReturn(0);
1639d222f98bSToby Isaac }
1640d222f98bSToby Isaac 
16419be51f97SToby Isaac /*MC
16429be51f97SToby Isaac 
1643*bae1f979SBarry Smith      DMFOREST = "forest" - A DM object that encapsulates a hierarchically refined mesh.  Forests usually have a base DM
1644*bae1f979SBarry Smith   (see DMForestGetBaseDM()), from which it is refined.  The refinement and partitioning of forests is considered
1645*bae1f979SBarry Smith   immutable after DMSetUp() is called.  To adapt a mesh, one should call DMForestTemplate() to create a new mesh that
1646*bae1f979SBarry Smith   will default to being identical to it, specify how that mesh should differ, and then calling DMSetUp() on the new
1647*bae1f979SBarry Smith   mesh.
1648*bae1f979SBarry Smith 
1649*bae1f979SBarry Smith   To specify that a mesh should be refined or coarsened from the previous mesh, a label should be defined on the
1650*bae1f979SBarry Smith   previous mesh whose values indicate which cells should be refined (DM_ADAPT_REFINE) or coarsened (DM_ADAPT_COARSEN)
1651*bae1f979SBarry Smith   and how (subtypes are free to allow additional values for things like anisotropic refinement).  The label should be
1652*bae1f979SBarry Smith   given to the *new* mesh with DMForestSetAdaptivityLabel().
16539be51f97SToby Isaac 
16549be51f97SToby Isaac   Level: advanced
16559be51f97SToby Isaac 
16569be51f97SToby Isaac .seealso: DMType, DMCreate(), DMSetType(), DMForestGetBaseDM(), DMForestSetBaseDM(), DMForestTemplate(), DMForestSetAdaptivityLabel()
16579be51f97SToby Isaac M*/
16589be51f97SToby Isaac 
1659db4d5e8cSToby Isaac PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm)
1660db4d5e8cSToby Isaac {
1661db4d5e8cSToby Isaac   DM_Forest      *forest;
1662db4d5e8cSToby Isaac   PetscErrorCode ierr;
1663db4d5e8cSToby Isaac 
1664db4d5e8cSToby Isaac   PetscFunctionBegin;
1665db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1666db4d5e8cSToby Isaac   ierr                         = PetscNewLog(dm,&forest);CHKERRQ(ierr);
1667db4d5e8cSToby Isaac   dm->dim                      = 0;
1668db4d5e8cSToby Isaac   dm->data                     = forest;
1669db4d5e8cSToby Isaac   forest->refct                = 1;
1670db4d5e8cSToby Isaac   forest->data                 = NULL;
167158762b62SToby Isaac   forest->setfromoptionscalled = PETSC_FALSE;
1672db4d5e8cSToby Isaac   forest->topology             = NULL;
1673cd3c525cSToby Isaac   forest->adapt                = NULL;
1674db4d5e8cSToby Isaac   forest->base                 = NULL;
16756a87ffbfSToby Isaac   forest->adaptPurpose         = DM_ADAPT_DETERMINE;
1676db4d5e8cSToby Isaac   forest->adjDim               = PETSC_DEFAULT;
1677db4d5e8cSToby Isaac   forest->overlap              = PETSC_DEFAULT;
1678db4d5e8cSToby Isaac   forest->minRefinement        = PETSC_DEFAULT;
1679db4d5e8cSToby Isaac   forest->maxRefinement        = PETSC_DEFAULT;
168056ba9f64SToby Isaac   forest->initRefinement       = PETSC_DEFAULT;
1681c7eeac06SToby Isaac   forest->cStart               = PETSC_DETERMINE;
1682c7eeac06SToby Isaac   forest->cEnd                 = PETSC_DETERMINE;
1683cd3c525cSToby Isaac   forest->cellSF               = NULL;
1684ebdf65a2SToby Isaac   forest->adaptLabel           = NULL;
1685db4d5e8cSToby Isaac   forest->gradeFactor          = 2;
1686db4d5e8cSToby Isaac   forest->cellWeights          = NULL;
1687db4d5e8cSToby Isaac   forest->cellWeightsCopyMode  = PETSC_USE_POINTER;
1688db4d5e8cSToby Isaac   forest->weightsFactor        = 1.;
1689db4d5e8cSToby Isaac   forest->weightCapacity       = 1.;
1690a73e2921SToby Isaac   ierr                         = DMForestSetAdaptivityStrategy(dm,DMFORESTADAPTALL);CHKERRQ(ierr);
1691d222f98bSToby Isaac   ierr                         = DMInitialize_Forest(dm);CHKERRQ(ierr);
1692db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1693db4d5e8cSToby Isaac }
1694db4d5e8cSToby Isaac 
1695