xref: /petsc/src/dm/impls/forest/forest.c (revision 90b157c44842f659fe30172b3ce8b86a412dec46)
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);
170*90b157c4SStefano Zampini   {
171*90b157c4SStefano Zampini     PetscBool            isper;
172795844e7SToby Isaac     const PetscReal      *maxCell, *L;
173795844e7SToby Isaac     const DMBoundaryType *bd;
174795844e7SToby Isaac 
175*90b157c4SStefano Zampini     ierr = DMGetPeriodicity(dm,&isper,&maxCell,&L,&bd);CHKERRQ(ierr);
176*90b157c4SStefano Zampini     ierr = DMSetPeriodicity(*tdm,isper,maxCell,L,bd);CHKERRQ(ierr);
177795844e7SToby Isaac   }
178bff67a9bSToby Isaac   ierr = DMCopyBoundary(dm,*tdm);CHKERRQ(ierr);
179a0452a8eSToby Isaac   PetscFunctionReturn(0);
180a0452a8eSToby Isaac }
181a0452a8eSToby Isaac 
18201d9d024SToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm);
18301d9d024SToby Isaac 
184db4d5e8cSToby Isaac PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm)
185db4d5e8cSToby Isaac {
186db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
187db4d5e8cSToby Isaac   const char     *type;
188db4d5e8cSToby Isaac   PetscErrorCode ierr;
189db4d5e8cSToby Isaac 
190db4d5e8cSToby Isaac   PetscFunctionBegin;
191db4d5e8cSToby Isaac   forest->refct++;
192db4d5e8cSToby Isaac   (*newdm)->data = forest;
193db4d5e8cSToby Isaac   ierr           = PetscObjectGetType((PetscObject) dm, &type);CHKERRQ(ierr);
194db4d5e8cSToby Isaac   ierr           = PetscObjectChangeTypeName((PetscObject) *newdm, type);CHKERRQ(ierr);
19501d9d024SToby Isaac   ierr           = DMInitialize_Forest(*newdm);CHKERRQ(ierr);
196db4d5e8cSToby Isaac   PetscFunctionReturn(0);
197db4d5e8cSToby Isaac }
198db4d5e8cSToby Isaac 
199d222f98bSToby Isaac static PetscErrorCode DMDestroy_Forest(DM dm)
200db4d5e8cSToby Isaac {
201db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
202db4d5e8cSToby Isaac   PetscErrorCode ierr;
203db4d5e8cSToby Isaac 
204db4d5e8cSToby Isaac   PetscFunctionBegin;
205db4d5e8cSToby Isaac   if (--forest->refct > 0) PetscFunctionReturn(0);
206d222f98bSToby Isaac   if (forest->destroy) {ierr = forest->destroy(dm);CHKERRQ(ierr);}
207db4d5e8cSToby Isaac   ierr = PetscSFDestroy(&forest->cellSF);CHKERRQ(ierr);
2080f17b9e3SToby Isaac   ierr = PetscSFDestroy(&forest->preCoarseToFine);CHKERRQ(ierr);
2090f17b9e3SToby Isaac   ierr = PetscSFDestroy(&forest->coarseToPreFine);CHKERRQ(ierr);
210a1b0c543SToby Isaac   ierr = DMLabelDestroy(&forest->adaptLabel);CHKERRQ(ierr);
2119a81d013SToby Isaac   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
21256ba9f64SToby Isaac   ierr = DMDestroy(&forest->base);CHKERRQ(ierr);
213ba936b91SToby Isaac   ierr = DMDestroy(&forest->adapt);CHKERRQ(ierr);
21430f902e7SToby Isaac   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
21530f902e7SToby Isaac   ierr = PetscFree(forest);CHKERRQ(ierr);
216a1b0c543SToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)dm,"DMAdaptLabel_C",NULL);CHKERRQ(ierr);
217db4d5e8cSToby Isaac   PetscFunctionReturn(0);
218db4d5e8cSToby Isaac }
219db4d5e8cSToby Isaac 
2209be51f97SToby Isaac /*@C
2219be51f97SToby Isaac   DMForestSetTopology - Set the topology of a DMForest during the pre-setup phase.  The topology is a string (e.g.
22268d54884SBarry Smith   "cube", "shell") and can be interpreted by subtypes of DMFOREST) to construct the base DM of a forest during
2239be51f97SToby Isaac   DMSetUp().
2249be51f97SToby Isaac 
2259be51f97SToby Isaac   Logically collective on dm
2269be51f97SToby Isaac 
2279be51f97SToby Isaac   Input parameters:
2289be51f97SToby Isaac + dm - the forest
2299be51f97SToby Isaac - topology - the topology of the forest
2309be51f97SToby Isaac 
2319be51f97SToby Isaac   Level: intermediate
2329be51f97SToby Isaac 
2339be51f97SToby Isaac .seealso(): DMForestGetTopology(), DMForestSetBaseDM()
2349be51f97SToby Isaac @*/
235dd8e54a2SToby Isaac PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology)
236db4d5e8cSToby Isaac {
237db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
238db4d5e8cSToby Isaac   PetscErrorCode ierr;
239db4d5e8cSToby Isaac 
240db4d5e8cSToby Isaac   PetscFunctionBegin;
241db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
242ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup");
243dd8e54a2SToby Isaac   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
244dd8e54a2SToby Isaac   ierr = PetscStrallocpy((const char*)topology,(char**) &forest->topology);CHKERRQ(ierr);
245db4d5e8cSToby Isaac   PetscFunctionReturn(0);
246db4d5e8cSToby Isaac }
247db4d5e8cSToby Isaac 
2489be51f97SToby Isaac /*@C
2499be51f97SToby Isaac   DMForestGetTopology - Get a string describing the topology of a DMForest.
2509be51f97SToby Isaac 
2519be51f97SToby Isaac   Not collective
2529be51f97SToby Isaac 
2539be51f97SToby Isaac   Input parameter:
2549be51f97SToby Isaac . dm - the forest
2559be51f97SToby Isaac 
2569be51f97SToby Isaac   Output parameter:
2579be51f97SToby Isaac . topology - the topology of the forest (e.g., 'cube', 'shell')
2589be51f97SToby Isaac 
2599be51f97SToby Isaac   Level: intermediate
2609be51f97SToby Isaac 
2619be51f97SToby Isaac .seealso: DMForestSetTopology()
2629be51f97SToby Isaac @*/
263dd8e54a2SToby Isaac PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology)
264dd8e54a2SToby Isaac {
265dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
266dd8e54a2SToby Isaac 
267dd8e54a2SToby Isaac   PetscFunctionBegin;
268dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
269dd8e54a2SToby Isaac   PetscValidPointer(topology,2);
270dd8e54a2SToby Isaac   *topology = forest->topology;
271dd8e54a2SToby Isaac   PetscFunctionReturn(0);
272dd8e54a2SToby Isaac }
273dd8e54a2SToby Isaac 
2749be51f97SToby Isaac /*@
2759be51f97SToby Isaac   DMForestSetBaseDM - During the pre-setup phase, set the DM that defines the base mesh of a DMForest forest.  The
2769be51f97SToby Isaac   forest will be hierarchically refined from the base, and all refinements/coarsenings of the forest will share its
277765b024eSBarry Smith   base.  In general, two forest must share a base to be comparable, to do things like construct interpolators.
2789be51f97SToby Isaac 
2799be51f97SToby Isaac   Logically collective on dm
2809be51f97SToby Isaac 
2819be51f97SToby Isaac   Input Parameters:
2829be51f97SToby Isaac + dm - the forest
2839be51f97SToby Isaac - base - the base DM of the forest
2849be51f97SToby Isaac 
285765b024eSBarry Smith   Notes: Currently the base DM must be a DMPLEX
286765b024eSBarry Smith 
2879be51f97SToby Isaac   Level: intermediate
2889be51f97SToby Isaac 
2899be51f97SToby Isaac .seealso(): DMForestGetBaseDM()
2909be51f97SToby Isaac @*/
291dd8e54a2SToby Isaac PetscErrorCode DMForestSetBaseDM(DM dm, DM base)
292dd8e54a2SToby Isaac {
293dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
294dd8e54a2SToby Isaac   PetscInt       dim, dimEmbed;
295dd8e54a2SToby Isaac   PetscErrorCode ierr;
296dd8e54a2SToby Isaac 
297dd8e54a2SToby Isaac   PetscFunctionBegin;
298dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
299ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup");
300dd8e54a2SToby Isaac   ierr         = PetscObjectReference((PetscObject)base);CHKERRQ(ierr);
301dd8e54a2SToby Isaac   ierr         = DMDestroy(&forest->base);CHKERRQ(ierr);
302dd8e54a2SToby Isaac   forest->base = base;
303a0452a8eSToby Isaac   if (base) {
304a0452a8eSToby Isaac     PetscValidHeaderSpecific(base, DM_CLASSID, 2);
305dd8e54a2SToby Isaac     ierr = DMGetDimension(base,&dim);CHKERRQ(ierr);
306dd8e54a2SToby Isaac     ierr = DMSetDimension(dm,dim);CHKERRQ(ierr);
307dd8e54a2SToby Isaac     ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr);
308dd8e54a2SToby Isaac     ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr);
309a0452a8eSToby Isaac   }
310dd8e54a2SToby Isaac   PetscFunctionReturn(0);
311dd8e54a2SToby Isaac }
312dd8e54a2SToby Isaac 
3139be51f97SToby Isaac /*@
3149be51f97SToby Isaac   DMForestGetBaseDM - Get the base DM of a DMForest forest.  The forest will be hierarchically refined from the base,
31568d54884SBarry Smith   and all refinements/coarsenings of the forest will share its base.  In general, two forest must share a base to be
3169be51f97SToby Isaac   comparable, to do things like construct interpolators.
3179be51f97SToby Isaac 
3189be51f97SToby Isaac   Not collective
3199be51f97SToby Isaac 
3209be51f97SToby Isaac   Input Parameter:
3219be51f97SToby Isaac . dm - the forest
3229be51f97SToby Isaac 
3239be51f97SToby Isaac   Output Parameter:
3249be51f97SToby Isaac . base - the base DM of the forest
3259be51f97SToby Isaac 
3269be51f97SToby Isaac   Level: intermediate
3279be51f97SToby Isaac 
3289be51f97SToby Isaac .seealso(); DMForestSetBaseDM()
3299be51f97SToby Isaac @*/
330dd8e54a2SToby Isaac PetscErrorCode DMForestGetBaseDM(DM dm, DM *base)
331dd8e54a2SToby Isaac {
332dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
333dd8e54a2SToby Isaac 
334dd8e54a2SToby Isaac   PetscFunctionBegin;
335dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
336dd8e54a2SToby Isaac   PetscValidPointer(base, 2);
337dd8e54a2SToby Isaac   *base = forest->base;
338dd8e54a2SToby Isaac   PetscFunctionReturn(0);
339dd8e54a2SToby Isaac }
340dd8e54a2SToby Isaac 
34199478f86SToby Isaac PetscErrorCode DMForestSetBaseCoordinateMapping(DM dm, PetscErrorCode (*func)(DM,PetscInt,PetscInt,const PetscReal [],PetscReal [],void*),void *ctx)
342cf38a08cSToby Isaac {
343cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
344cf38a08cSToby Isaac 
345cf38a08cSToby Isaac   PetscFunctionBegin;
346cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
347cf38a08cSToby Isaac   forest->mapcoordinates    = func;
348cf38a08cSToby Isaac   forest->mapcoordinatesctx = ctx;
349cf38a08cSToby Isaac   PetscFunctionReturn(0);
350cf38a08cSToby Isaac }
351cf38a08cSToby Isaac 
35299478f86SToby Isaac PetscErrorCode DMForestGetBaseCoordinateMapping(DM dm, PetscErrorCode (**func) (DM,PetscInt,PetscInt,const PetscReal [],PetscReal [],void*),void *ctx)
353cf38a08cSToby Isaac {
354cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
355cf38a08cSToby Isaac 
356cf38a08cSToby Isaac   PetscFunctionBegin;
357cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
358cf38a08cSToby Isaac   if (func) *func = forest->mapcoordinates;
359cf38a08cSToby Isaac   if (ctx) *((void**) ctx) = forest->mapcoordinatesctx;
360cf38a08cSToby Isaac   PetscFunctionReturn(0);
361cf38a08cSToby Isaac }
362cf38a08cSToby Isaac 
3639be51f97SToby Isaac /*@
3649be51f97SToby Isaac   DMForestSetAdaptivityForest - During the pre-setup phase, set the forest from which the current forest will be
3659be51f97SToby Isaac   adapted (e.g., the current forest will be refined/coarsened/repartitioned from it) im DMSetUp().  Usually not needed
3669be51f97SToby Isaac   by users directly: DMForestTemplate() constructs a new forest to be adapted from an old forest and calls this
3679be51f97SToby Isaac   routine.
3689be51f97SToby Isaac 
369dffe73a3SToby Isaac   Note that this can be called after setup with adapt = NULL, which will clear all internal data related to the
370dffe73a3SToby Isaac   adaptivity forest from dm.  This way, repeatedly adapting does not leave stale DM objects in memory.
371dffe73a3SToby Isaac 
3729be51f97SToby Isaac   Logically collective on dm
3739be51f97SToby Isaac 
3749be51f97SToby Isaac   Input Parameter:
3759be51f97SToby Isaac + dm - the new forest, which will be constructed from adapt
3769be51f97SToby Isaac - adapt - the old forest
3779be51f97SToby Isaac 
3789be51f97SToby Isaac   Level: intermediate
3799be51f97SToby Isaac 
3809be51f97SToby Isaac .seealso: DMForestGetAdaptivityForest(), DMForestSetAdaptivityPurpose()
3819be51f97SToby Isaac @*/
382ba936b91SToby Isaac PetscErrorCode DMForestSetAdaptivityForest(DM dm,DM adapt)
383dd8e54a2SToby Isaac {
384dffe73a3SToby Isaac   DM_Forest      *forest, *adaptForest, *oldAdaptForest;
385dffe73a3SToby Isaac   DM             oldAdapt;
386dd8e54a2SToby Isaac   PetscErrorCode ierr;
387dd8e54a2SToby Isaac 
388dd8e54a2SToby Isaac   PetscFunctionBegin;
389dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
390ba936b91SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
391ba936b91SToby Isaac   forest   = (DM_Forest*) dm->data;
392dffe73a3SToby Isaac   ierr     = DMForestGetAdaptivityForest(dm,&oldAdapt);CHKERRQ(ierr);
393dffe73a3SToby Isaac   if (adapt != NULL && dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
394193eb951SToby Isaac   adaptForest    = (DM_Forest*) (adapt ? adapt->data : NULL);
395193eb951SToby Isaac   oldAdaptForest = (DM_Forest*) (oldAdapt ? oldAdapt->data : NULL);
396dffe73a3SToby Isaac   if (adaptForest != oldAdaptForest) {
397dffe73a3SToby Isaac     ierr = PetscSFDestroy(&forest->preCoarseToFine);CHKERRQ(ierr);
398dffe73a3SToby Isaac     ierr = PetscSFDestroy(&forest->coarseToPreFine);CHKERRQ(ierr);
399dffe73a3SToby Isaac     if (forest->clearadaptivityforest) {ierr = (forest->clearadaptivityforest)(dm);CHKERRQ(ierr);}
400dffe73a3SToby Isaac   }
40126d9498aSToby Isaac   switch (forest->adaptPurpose) {
402cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
403ba936b91SToby Isaac     ierr          = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
404ba936b91SToby Isaac     ierr          = DMDestroy(&(forest->adapt));CHKERRQ(ierr);
405ba936b91SToby Isaac     forest->adapt = adapt;
40626d9498aSToby Isaac     break;
407a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
40826d9498aSToby Isaac     ierr = DMSetCoarseDM(dm,adapt);CHKERRQ(ierr);
40926d9498aSToby Isaac     break;
410a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
41126d9498aSToby Isaac     ierr = DMSetFineDM(dm,adapt);CHKERRQ(ierr);
41226d9498aSToby Isaac     break;
41326d9498aSToby Isaac   default:
41426d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
41526d9498aSToby Isaac   }
416dd8e54a2SToby Isaac   PetscFunctionReturn(0);
417dd8e54a2SToby Isaac }
418dd8e54a2SToby Isaac 
4199be51f97SToby Isaac /*@
4209be51f97SToby Isaac   DMForestGetAdaptivityForest - Get the forest from which the current forest is adapted.
4219be51f97SToby Isaac 
4229be51f97SToby Isaac   Not collective
4239be51f97SToby Isaac 
4249be51f97SToby Isaac   Input Parameter:
4259be51f97SToby Isaac . dm - the forest
4269be51f97SToby Isaac 
4279be51f97SToby Isaac   Output Parameter:
4289be51f97SToby Isaac . adapt - the forest from which dm is/was adapted
4299be51f97SToby Isaac 
4309be51f97SToby Isaac   Level: intermediate
4319be51f97SToby Isaac 
4329be51f97SToby Isaac .seealso: DMForestSetAdaptivityForest(), DMForestSetAdaptivityPurpose()
4339be51f97SToby Isaac @*/
434ba936b91SToby Isaac PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt)
435dd8e54a2SToby Isaac {
436ba936b91SToby Isaac   DM_Forest      *forest;
43726d9498aSToby Isaac   PetscErrorCode ierr;
438dd8e54a2SToby Isaac 
439dd8e54a2SToby Isaac   PetscFunctionBegin;
440dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
441ba936b91SToby Isaac   forest = (DM_Forest*) dm->data;
44226d9498aSToby Isaac   switch (forest->adaptPurpose) {
443cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
444ba936b91SToby Isaac     *adapt = forest->adapt;
44526d9498aSToby Isaac     break;
446a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
44726d9498aSToby Isaac     ierr = DMGetCoarseDM(dm,adapt);CHKERRQ(ierr);
44826d9498aSToby Isaac     break;
449a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
45026d9498aSToby Isaac     ierr = DMGetFineDM(dm,adapt);CHKERRQ(ierr);
45126d9498aSToby Isaac     break;
45226d9498aSToby Isaac   default:
45326d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
45426d9498aSToby Isaac   }
45526d9498aSToby Isaac   PetscFunctionReturn(0);
45626d9498aSToby Isaac }
45726d9498aSToby Isaac 
4589be51f97SToby Isaac /*@
4599be51f97SToby Isaac   DMForestSetAdaptivityPurpose - During the pre-setup phase, set whether the current DM is being adapted from its
460a1b0c543SToby Isaac   source (set with DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening
461cd3c525cSToby Isaac   (DM_ADAPT_COARSEN), or undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting:
4629be51f97SToby Isaac   during DMDestroy(), cyclic references can be found between DMs only if the cyclic reference is due to a fine/coarse
4639be51f97SToby Isaac   relationship (see DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does
4649be51f97SToby Isaac   not maintain a reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can
4659be51f97SToby Isaac   cause a memory leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
4669be51f97SToby Isaac 
4679be51f97SToby Isaac   Logically collective on dm
4689be51f97SToby Isaac 
4699be51f97SToby Isaac   Input Parameters:
4709be51f97SToby Isaac + dm - the forest
471cd3c525cSToby Isaac - purpose - the adaptivity purpose (DM_ADAPT_DETERMINE/DM_ADAPT_REFINE/DM_ADAPT_COARSEN)
4729be51f97SToby Isaac 
4739be51f97SToby Isaac   Level: advanced
4749be51f97SToby Isaac 
4759be51f97SToby Isaac .seealso: DMForestTemplate(), DMForestSetAdaptivityForest(), DMForestGetAdaptivityForest()
4769be51f97SToby Isaac @*/
477a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMAdaptFlag purpose)
47826d9498aSToby Isaac {
47926d9498aSToby Isaac   DM_Forest      *forest;
48026d9498aSToby Isaac   PetscErrorCode ierr;
48126d9498aSToby Isaac 
48226d9498aSToby Isaac   PetscFunctionBegin;
48326d9498aSToby Isaac   forest = (DM_Forest*) dm->data;
4849be51f97SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
48526d9498aSToby Isaac   if (purpose != forest->adaptPurpose) {
48626d9498aSToby Isaac     DM adapt;
48726d9498aSToby Isaac 
48826d9498aSToby Isaac     ierr = DMForestGetAdaptivityForest(dm,&adapt);CHKERRQ(ierr);
48926d9498aSToby Isaac     ierr = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
49026d9498aSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
491f885a11aSToby Isaac 
49226d9498aSToby Isaac     forest->adaptPurpose = purpose;
493f885a11aSToby Isaac 
49426d9498aSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,adapt);CHKERRQ(ierr);
49526d9498aSToby Isaac     ierr = DMDestroy(&adapt);CHKERRQ(ierr);
49626d9498aSToby Isaac   }
497dd8e54a2SToby Isaac   PetscFunctionReturn(0);
498dd8e54a2SToby Isaac }
499dd8e54a2SToby Isaac 
50056c0450aSToby Isaac /*@
50156c0450aSToby Isaac   DMForestGetAdaptivityPurpose - Get whether the current DM is being adapted from its source (set with
502a1b0c543SToby Isaac   DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening (DM_ADAPT_COARSEN), or
503cd3c525cSToby Isaac   undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting: during DMDestroy(), cyclic
50456c0450aSToby Isaac   references can be found between DMs only if the cyclic reference is due to a fine/coarse relationship (see
50556c0450aSToby Isaac   DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does not maintain a
50656c0450aSToby Isaac   reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can cause a memory
50756c0450aSToby Isaac   leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
50856c0450aSToby Isaac 
50956c0450aSToby Isaac   Not collective
51056c0450aSToby Isaac 
51156c0450aSToby Isaac   Input Parameter:
51256c0450aSToby Isaac . dm - the forest
51356c0450aSToby Isaac 
51456c0450aSToby Isaac   Output Parameter:
515cd3c525cSToby Isaac . purpose - the adaptivity purpose (DM_ADAPT_DETERMINE/DM_ADAPT_REFINE/DM_ADAPT_COARSEN)
51656c0450aSToby Isaac 
51756c0450aSToby Isaac   Level: advanced
51856c0450aSToby Isaac 
51956c0450aSToby Isaac .seealso: DMForestTemplate(), DMForestSetAdaptivityForest(), DMForestGetAdaptivityForest()
52056c0450aSToby Isaac @*/
521a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityPurpose(DM dm, DMAdaptFlag *purpose)
52256c0450aSToby Isaac {
52356c0450aSToby Isaac   DM_Forest *forest;
52456c0450aSToby Isaac 
52556c0450aSToby Isaac   PetscFunctionBegin;
52656c0450aSToby Isaac   forest   = (DM_Forest*) dm->data;
52756c0450aSToby Isaac   *purpose = forest->adaptPurpose;
52856c0450aSToby Isaac   PetscFunctionReturn(0);
52956c0450aSToby Isaac }
53056c0450aSToby Isaac 
5319be51f97SToby Isaac /*@
5329be51f97SToby Isaac   DMForestSetAdjacencyDimension - During the pre-setup phase, set the dimension of interface points that determine
5339be51f97SToby Isaac   cell adjacency (for the purposes of partitioning and overlap).
5349be51f97SToby Isaac 
5359be51f97SToby Isaac   Logically collective on dm
5369be51f97SToby Isaac 
5379be51f97SToby Isaac   Input Parameters:
5389be51f97SToby Isaac + dm - the forest
5399be51f97SToby Isaac - adjDim - default 0 (i.e., vertices determine adjacency)
5409be51f97SToby Isaac 
5419be51f97SToby Isaac   Level: intermediate
5429be51f97SToby Isaac 
5439be51f97SToby Isaac .seealso: DMForestGetAdjacencyDimension(), DMForestSetAdjacencyCodimension(), DMForestSetPartitionOverlap()
5449be51f97SToby Isaac @*/
545dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim)
546dd8e54a2SToby Isaac {
547dd8e54a2SToby Isaac   PetscInt       dim;
548dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
549dd8e54a2SToby Isaac   PetscErrorCode ierr;
550dd8e54a2SToby Isaac 
551dd8e54a2SToby Isaac   PetscFunctionBegin;
552dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
553ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup");
554dd8e54a2SToby Isaac   if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim);
555dd8e54a2SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
556dd8e54a2SToby Isaac   if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim);
557dd8e54a2SToby Isaac   forest->adjDim = adjDim;
558dd8e54a2SToby Isaac   PetscFunctionReturn(0);
559dd8e54a2SToby Isaac }
560dd8e54a2SToby Isaac 
5619be51f97SToby Isaac /*@
5629be51f97SToby Isaac   DMForestSetAdjacencyCodimension - Like DMForestSetAdjacencyDimension(), but specified as a co-dimension (so that,
5639be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
5649be51f97SToby Isaac 
5659be51f97SToby Isaac   Logically collective on dm
5669be51f97SToby Isaac 
5679be51f97SToby Isaac   Input Parameters:
5689be51f97SToby Isaac + dm - the forest
5699be51f97SToby Isaac - adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
5709be51f97SToby Isaac 
5719be51f97SToby Isaac   Level: intermediate
5729be51f97SToby Isaac 
5739be51f97SToby Isaac .seealso: DMForestGetAdjacencyCodimension(), DMForestSetAdjacencyDimension()
5749be51f97SToby Isaac @*/
575dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim)
576dd8e54a2SToby Isaac {
577dd8e54a2SToby Isaac   PetscInt       dim;
578dd8e54a2SToby Isaac   PetscErrorCode ierr;
579dd8e54a2SToby Isaac 
580dd8e54a2SToby Isaac   PetscFunctionBegin;
581dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
582dd8e54a2SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
583dd8e54a2SToby Isaac   ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr);
584dd8e54a2SToby Isaac   PetscFunctionReturn(0);
585dd8e54a2SToby Isaac }
586dd8e54a2SToby Isaac 
5879be51f97SToby Isaac /*@
5889be51f97SToby Isaac   DMForestGetAdjacencyDimension - Get the dimension of interface points that determine cell adjacency (for the
5899be51f97SToby Isaac   purposes of partitioning and overlap).
5909be51f97SToby Isaac 
5919be51f97SToby Isaac   Not collective
5929be51f97SToby Isaac 
5939be51f97SToby Isaac   Input Parameter:
5949be51f97SToby Isaac . dm - the forest
5959be51f97SToby Isaac 
5969be51f97SToby Isaac   Output Parameter:
5979be51f97SToby Isaac . adjDim - default 0 (i.e., vertices determine adjacency)
5989be51f97SToby Isaac 
5999be51f97SToby Isaac   Level: intermediate
6009be51f97SToby Isaac 
6019be51f97SToby Isaac .seealso: DMForestSetAdjacencyDimension(), DMForestGetAdjacencyCodimension(), DMForestSetPartitionOverlap()
6029be51f97SToby Isaac @*/
603dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim)
604dd8e54a2SToby Isaac {
605dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
606dd8e54a2SToby Isaac 
607dd8e54a2SToby Isaac   PetscFunctionBegin;
608dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
609dd8e54a2SToby Isaac   PetscValidIntPointer(adjDim,2);
610dd8e54a2SToby Isaac   *adjDim = forest->adjDim;
611dd8e54a2SToby Isaac   PetscFunctionReturn(0);
612dd8e54a2SToby Isaac }
613dd8e54a2SToby Isaac 
6149be51f97SToby Isaac /*@
6159be51f97SToby Isaac   DMForestGetAdjacencyCodimension - Like DMForestGetAdjacencyDimension(), but specified as a co-dimension (so that,
6169be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
6179be51f97SToby Isaac 
6189be51f97SToby Isaac   Not collective
6199be51f97SToby Isaac 
6209be51f97SToby Isaac   Input Parameter:
6219be51f97SToby Isaac . dm - the forest
6229be51f97SToby Isaac 
6239be51f97SToby Isaac   Output Parameter:
6249be51f97SToby Isaac . adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
6259be51f97SToby Isaac 
6269be51f97SToby Isaac   Level: intermediate
6279be51f97SToby Isaac 
6289be51f97SToby Isaac .seealso: DMForestSetAdjacencyCodimension(), DMForestGetAdjacencyDimension()
6299be51f97SToby Isaac @*/
630dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim)
631dd8e54a2SToby Isaac {
632dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
633dd8e54a2SToby Isaac   PetscInt       dim;
634dd8e54a2SToby Isaac   PetscErrorCode ierr;
635dd8e54a2SToby Isaac 
636dd8e54a2SToby Isaac   PetscFunctionBegin;
637dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
638dd8e54a2SToby Isaac   PetscValidIntPointer(adjCodim,2);
639dd8e54a2SToby Isaac   ierr      = DMGetDimension(dm,&dim);CHKERRQ(ierr);
640dd8e54a2SToby Isaac   *adjCodim = dim - forest->adjDim;
641dd8e54a2SToby Isaac   PetscFunctionReturn(0);
642dd8e54a2SToby Isaac }
643dd8e54a2SToby Isaac 
6449be51f97SToby Isaac /*@
6459be51f97SToby Isaac   DMForestSetPartitionOverlap - During the pre-setup phase, set the amount of cell-overlap present in parallel
6469be51f97SToby Isaac   partitions of a forest, with values > 0 indicating subdomains that are expanded by that many iterations of adding
6479be51f97SToby Isaac   adjacent cells
6489be51f97SToby Isaac 
6499be51f97SToby Isaac   Logically collective on dm
6509be51f97SToby Isaac 
6519be51f97SToby Isaac   Input Parameters:
6529be51f97SToby Isaac + dm - the forest
6539be51f97SToby Isaac - overlap - default 0
6549be51f97SToby Isaac 
6559be51f97SToby Isaac   Level: intermediate
6569be51f97SToby Isaac 
6579be51f97SToby Isaac .seealso: DMForestGetPartitionOverlap(), DMForestSetAdjacencyDimension(), DMForestSetAdjacencyCodimension()
6589be51f97SToby Isaac @*/
659dd8e54a2SToby Isaac PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap)
660dd8e54a2SToby Isaac {
661dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
662dd8e54a2SToby Isaac 
663dd8e54a2SToby Isaac   PetscFunctionBegin;
664dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
665ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup");
666dd8e54a2SToby Isaac   if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap);
667dd8e54a2SToby Isaac   forest->overlap = overlap;
668dd8e54a2SToby Isaac   PetscFunctionReturn(0);
669dd8e54a2SToby Isaac }
670dd8e54a2SToby Isaac 
6719be51f97SToby Isaac /*@
6729be51f97SToby Isaac   DMForestGetPartitionOverlap - Get the amount of cell-overlap present in parallel partitions of a forest, with values
6739be51f97SToby Isaac   > 0 indicating subdomains that are expanded by that many iterations of adding adjacent cells
6749be51f97SToby Isaac 
6759be51f97SToby Isaac   Not collective
6769be51f97SToby Isaac 
6779be51f97SToby Isaac   Input Parameter:
6789be51f97SToby Isaac . dm - the forest
6799be51f97SToby Isaac 
6809be51f97SToby Isaac   Output Parameter:
6819be51f97SToby Isaac . overlap - default 0
6829be51f97SToby Isaac 
6839be51f97SToby Isaac   Level: intermediate
6849be51f97SToby Isaac 
6859be51f97SToby Isaac .seealso: DMForestGetPartitionOverlap(), DMForestSetAdjacencyDimension(), DMForestSetAdjacencyCodimension()
6869be51f97SToby Isaac @*/
687dd8e54a2SToby Isaac PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap)
688dd8e54a2SToby Isaac {
689dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
690dd8e54a2SToby Isaac 
691dd8e54a2SToby Isaac   PetscFunctionBegin;
692dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
693dd8e54a2SToby Isaac   PetscValidIntPointer(overlap,2);
694dd8e54a2SToby Isaac   *overlap = forest->overlap;
695dd8e54a2SToby Isaac   PetscFunctionReturn(0);
696dd8e54a2SToby Isaac }
697dd8e54a2SToby Isaac 
6989be51f97SToby Isaac /*@
6999be51f97SToby Isaac   DMForestSetMinimumRefinement - During the pre-setup phase, set the minimum level of refinement (relative to the base
7009be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest
7019be51f97SToby Isaac   (see DMForestGetAdaptivityForest()) this limits the amount of coarsening.
7029be51f97SToby Isaac 
7039be51f97SToby Isaac   Logically collective on dm
7049be51f97SToby Isaac 
7059be51f97SToby Isaac   Input Parameters:
7069be51f97SToby Isaac + dm - the forest
7079be51f97SToby Isaac - minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7089be51f97SToby Isaac 
7099be51f97SToby Isaac   Level: intermediate
7109be51f97SToby Isaac 
7119be51f97SToby Isaac .seealso: DMForestGetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestSetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityForest()
7129be51f97SToby Isaac @*/
713dd8e54a2SToby Isaac PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement)
714dd8e54a2SToby Isaac {
715dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
716dd8e54a2SToby Isaac 
717dd8e54a2SToby Isaac   PetscFunctionBegin;
718dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
719ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup");
720dd8e54a2SToby Isaac   forest->minRefinement = minRefinement;
721dd8e54a2SToby Isaac   PetscFunctionReturn(0);
722dd8e54a2SToby Isaac }
723dd8e54a2SToby Isaac 
7249be51f97SToby Isaac /*@
7259be51f97SToby Isaac   DMForestGetMinimumRefinement - Get the minimum level of refinement (relative to the base DM, see
7269be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest (see
7279be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of coarsening.
7289be51f97SToby Isaac 
7299be51f97SToby Isaac   Not collective
7309be51f97SToby Isaac 
7319be51f97SToby Isaac   Input Parameter:
7329be51f97SToby Isaac . dm - the forest
7339be51f97SToby Isaac 
7349be51f97SToby Isaac   Output Parameter:
7359be51f97SToby Isaac . minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7369be51f97SToby Isaac 
7379be51f97SToby Isaac   Level: intermediate
7389be51f97SToby Isaac 
7399be51f97SToby Isaac .seealso: DMForestSetMinimumRefinement(), DMForestGetMaximumRefinement(), DMForestGetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityForest()
7409be51f97SToby Isaac @*/
741dd8e54a2SToby Isaac PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement)
742dd8e54a2SToby Isaac {
743dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
744dd8e54a2SToby Isaac 
745dd8e54a2SToby Isaac   PetscFunctionBegin;
746dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
747dd8e54a2SToby Isaac   PetscValidIntPointer(minRefinement,2);
748dd8e54a2SToby Isaac   *minRefinement = forest->minRefinement;
749dd8e54a2SToby Isaac   PetscFunctionReturn(0);
750dd8e54a2SToby Isaac }
751dd8e54a2SToby Isaac 
7529be51f97SToby Isaac /*@
7539be51f97SToby Isaac   DMForestSetInitialRefinement - During the pre-setup phase, set the initial level of refinement (relative to the base
7549be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.
7559be51f97SToby Isaac 
7569be51f97SToby Isaac   Logically collective on dm
7579be51f97SToby Isaac 
7589be51f97SToby Isaac   Input Parameters:
7599be51f97SToby Isaac + dm - the forest
7609be51f97SToby Isaac - initefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7619be51f97SToby Isaac 
7629be51f97SToby Isaac   Level: intermediate
7639be51f97SToby Isaac 
7649be51f97SToby Isaac .seealso: DMForestSetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestGetBaseDM()
7659be51f97SToby Isaac @*/
76656ba9f64SToby Isaac PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement)
76756ba9f64SToby Isaac {
76856ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
76956ba9f64SToby Isaac 
77056ba9f64SToby Isaac   PetscFunctionBegin;
77156ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77256ba9f64SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the initial refinement after setup");
77356ba9f64SToby Isaac   forest->initRefinement = initRefinement;
77456ba9f64SToby Isaac   PetscFunctionReturn(0);
77556ba9f64SToby Isaac }
77656ba9f64SToby Isaac 
7779be51f97SToby Isaac /*@
7789be51f97SToby Isaac   DMForestGetInitialRefinement - Get the initial level of refinement (relative to the base DM, see
7799be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.
7809be51f97SToby Isaac 
7819be51f97SToby Isaac   Not collective
7829be51f97SToby Isaac 
7839be51f97SToby Isaac   Input Parameter:
7849be51f97SToby Isaac . dm - the forest
7859be51f97SToby Isaac 
7869be51f97SToby Isaac   Output Paramater:
7879be51f97SToby Isaac . initefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7889be51f97SToby Isaac 
7899be51f97SToby Isaac   Level: intermediate
7909be51f97SToby Isaac 
7919be51f97SToby Isaac .seealso: DMForestSetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestGetBaseDM()
7929be51f97SToby Isaac @*/
79356ba9f64SToby Isaac PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement)
79456ba9f64SToby Isaac {
79556ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
79656ba9f64SToby Isaac 
79756ba9f64SToby Isaac   PetscFunctionBegin;
79856ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
79956ba9f64SToby Isaac   PetscValidIntPointer(initRefinement,2);
80056ba9f64SToby Isaac   *initRefinement = forest->initRefinement;
80156ba9f64SToby Isaac   PetscFunctionReturn(0);
80256ba9f64SToby Isaac }
80356ba9f64SToby Isaac 
8049be51f97SToby Isaac /*@
8059be51f97SToby Isaac   DMForestSetMaximumRefinement - During the pre-setup phase, set the maximum level of refinement (relative to the base
8069be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest
8079be51f97SToby Isaac   (see DMForestGetAdaptivityForest()), this limits the amount of refinement.
8089be51f97SToby Isaac 
8099be51f97SToby Isaac   Logically collective on dm
8109be51f97SToby Isaac 
8119be51f97SToby Isaac   Input Parameters:
8129be51f97SToby Isaac + dm - the forest
8139be51f97SToby Isaac - maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
8149be51f97SToby Isaac 
8159be51f97SToby Isaac   Level: intermediate
8169be51f97SToby Isaac 
8179be51f97SToby Isaac .seealso: DMForestGetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestSetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityDM()
8189be51f97SToby Isaac @*/
819c7eeac06SToby Isaac PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement)
820dd8e54a2SToby Isaac {
821dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
822dd8e54a2SToby Isaac 
823dd8e54a2SToby Isaac   PetscFunctionBegin;
824dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
825ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup");
826c7eeac06SToby Isaac   forest->maxRefinement = maxRefinement;
827dd8e54a2SToby Isaac   PetscFunctionReturn(0);
828dd8e54a2SToby Isaac }
829dd8e54a2SToby Isaac 
8309be51f97SToby Isaac /*@
8319be51f97SToby Isaac   DMForestGetMaximumRefinement - Get the maximum level of refinement (relative to the base DM, see
8329be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest (see
8339be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of refinement.
8349be51f97SToby Isaac 
8359be51f97SToby Isaac   Not collective
8369be51f97SToby Isaac 
8379be51f97SToby Isaac   Input Parameter:
8389be51f97SToby Isaac . dm - the forest
8399be51f97SToby Isaac 
8409be51f97SToby Isaac   Output Parameter:
8419be51f97SToby Isaac . maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
8429be51f97SToby Isaac 
8439be51f97SToby Isaac   Level: intermediate
8449be51f97SToby Isaac 
8459be51f97SToby Isaac .seealso: DMForestSetMaximumRefinement(), DMForestGetMinimumRefinement(), DMForestGetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityForest()
8469be51f97SToby Isaac @*/
847c7eeac06SToby Isaac PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement)
848dd8e54a2SToby Isaac {
849dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
850dd8e54a2SToby Isaac 
851dd8e54a2SToby Isaac   PetscFunctionBegin;
852dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
853c7eeac06SToby Isaac   PetscValidIntPointer(maxRefinement,2);
854c7eeac06SToby Isaac   *maxRefinement = forest->maxRefinement;
855dd8e54a2SToby Isaac   PetscFunctionReturn(0);
856dd8e54a2SToby Isaac }
857c7eeac06SToby Isaac 
8589be51f97SToby Isaac /*@C
8599be51f97SToby Isaac   DMForestSetAdaptivityStrategy - During the pre-setup phase, set the strategy for combining adaptivity labels from multiple processes.
8609be51f97SToby Isaac   Subtypes of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all processes must agree
8619be51f97SToby Isaac   for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only one process needs to
8629be51f97SToby Isaac   specify refinement/coarsening.
8639be51f97SToby Isaac 
8649be51f97SToby Isaac   Logically collective on dm
8659be51f97SToby Isaac 
8669be51f97SToby Isaac   Input Parameters:
8679be51f97SToby Isaac + dm - the forest
8689be51f97SToby Isaac - adaptStrategy - default DMFORESTADAPTALL
8699be51f97SToby Isaac 
8709be51f97SToby Isaac   Level: advanced
8719be51f97SToby Isaac 
8729be51f97SToby Isaac .seealso: DMForestGetAdaptivityStrategy()
8739be51f97SToby Isaac @*/
874c7eeac06SToby Isaac PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy)
875c7eeac06SToby Isaac {
876c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
877c7eeac06SToby Isaac   PetscErrorCode ierr;
878c7eeac06SToby Isaac 
879c7eeac06SToby Isaac   PetscFunctionBegin;
880c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
881c7eeac06SToby Isaac   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
882a73e2921SToby Isaac   ierr = PetscStrallocpy((const char*) adaptStrategy,(char**)&forest->adaptStrategy);CHKERRQ(ierr);
883c7eeac06SToby Isaac   PetscFunctionReturn(0);
884c7eeac06SToby Isaac }
885c7eeac06SToby Isaac 
8869be51f97SToby Isaac /*@C
8879be51f97SToby Isaac   DMForestSetAdaptivityStrategy - Get the strategy for combining adaptivity labels from multiple processes.  Subtypes
8889be51f97SToby Isaac   of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all
8899be51f97SToby Isaac   processes must agree for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only
8909be51f97SToby Isaac   one process needs to specify refinement/coarsening.
8919be51f97SToby Isaac 
8929be51f97SToby Isaac   Not collective
8939be51f97SToby Isaac 
8949be51f97SToby Isaac   Input Parameter:
8959be51f97SToby Isaac . dm - the forest
8969be51f97SToby Isaac 
8979be51f97SToby Isaac   Output Parameter:
8989be51f97SToby Isaac . adaptStrategy - the adaptivity strategy (default DMFORESTADAPTALL)
8999be51f97SToby Isaac 
9009be51f97SToby Isaac   Level: advanced
9019be51f97SToby Isaac 
9029be51f97SToby Isaac .seealso: DMForestSetAdaptivityStrategy()
9039be51f97SToby Isaac @*/
904c7eeac06SToby Isaac PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy)
905c7eeac06SToby Isaac {
906c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
907c7eeac06SToby Isaac 
908c7eeac06SToby Isaac   PetscFunctionBegin;
909c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
910c7eeac06SToby Isaac   PetscValidPointer(adaptStrategy,2);
911c7eeac06SToby Isaac   *adaptStrategy = forest->adaptStrategy;
912c7eeac06SToby Isaac   PetscFunctionReturn(0);
913c7eeac06SToby Isaac }
914c7eeac06SToby Isaac 
9152a133e43SToby Isaac /*@
9162a133e43SToby Isaac   DMForestGetAdaptivitySuccess - Return whether the requested adaptation (refinement, coarsening, repartitioning,
9172a133e43SToby Isaac   etc.) was successful.  PETSC_FALSE indicates that the post-adaptation forest is the same as the pre-adpatation
9182a133e43SToby Isaac   forest.  A requested adaptation may have been unsuccessful if, for example, the requested refinement would have
9192a133e43SToby Isaac   exceeded the maximum refinement level.
9202a133e43SToby Isaac 
9212a133e43SToby Isaac   Collective on dm
9222a133e43SToby Isaac 
9232a133e43SToby Isaac   Input Parameter:
9242a133e43SToby Isaac 
9252a133e43SToby Isaac . dm - the post-adaptation forest
9262a133e43SToby Isaac 
9272a133e43SToby Isaac   Output Parameter:
9282a133e43SToby Isaac 
9292a133e43SToby Isaac . success - PETSC_TRUE if the post-adaptation forest is different from the pre-adaptation forest.
9302a133e43SToby Isaac 
9312a133e43SToby Isaac   Level: intermediate
9322a133e43SToby Isaac 
9332a133e43SToby Isaac .see
9342a133e43SToby Isaac @*/
9352a133e43SToby Isaac PetscErrorCode DMForestGetAdaptivitySuccess(DM dm, PetscBool *success)
9362a133e43SToby Isaac {
9372a133e43SToby Isaac   DM_Forest      *forest;
9382a133e43SToby Isaac   PetscErrorCode ierr;
9392a133e43SToby Isaac 
9402a133e43SToby Isaac   PetscFunctionBegin;
9412a133e43SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9422a133e43SToby Isaac   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() has not been called yet.");
9432a133e43SToby Isaac   forest = (DM_Forest *) dm->data;
9442a133e43SToby Isaac   ierr = (forest->getadaptivitysuccess)(dm,success);CHKERRQ(ierr);
9452a133e43SToby Isaac   PetscFunctionReturn(0);
9462a133e43SToby Isaac }
9472a133e43SToby Isaac 
948bf9b5d84SToby Isaac /*@
949bf9b5d84SToby Isaac   DMForestSetComputeAdaptivitySF - During the pre-setup phase, set whether transfer PetscSFs should be computed
950bf9b5d84SToby 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().
951bf9b5d84SToby Isaac 
952bf9b5d84SToby Isaac   Logically collective on dm
953bf9b5d84SToby Isaac 
954bf9b5d84SToby Isaac   Input Parameters:
955bf9b5d84SToby Isaac + dm - the post-adaptation forest
956bf9b5d84SToby Isaac - computeSF - default PETSC_TRUE
957bf9b5d84SToby Isaac 
958bf9b5d84SToby Isaac   Level: advanced
959bf9b5d84SToby Isaac 
960bf9b5d84SToby Isaac .seealso: DMForestGetComputeAdaptivitySF(), DMForestGetAdaptivitySF()
961bf9b5d84SToby Isaac @*/
962bf9b5d84SToby Isaac PetscErrorCode DMForestSetComputeAdaptivitySF(DM dm, PetscBool computeSF)
963bf9b5d84SToby Isaac {
964bf9b5d84SToby Isaac   DM_Forest *forest;
965bf9b5d84SToby Isaac 
966bf9b5d84SToby Isaac   PetscFunctionBegin;
967bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
968bf9b5d84SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot compute adaptivity PetscSFs after setup is called");
969bf9b5d84SToby Isaac   forest                 = (DM_Forest*) dm->data;
970bf9b5d84SToby Isaac   forest->computeAdaptSF = computeSF;
971bf9b5d84SToby Isaac   PetscFunctionReturn(0);
972bf9b5d84SToby Isaac }
973bf9b5d84SToby Isaac 
9740eb7e1eaSToby Isaac PetscErrorCode DMForestTransferVec(DM dmIn, Vec vecIn, DM dmOut, Vec vecOut, PetscBool useBCs, PetscReal time)
97580b27e07SToby Isaac {
97680b27e07SToby Isaac   DM_Forest      *forest;
97780b27e07SToby Isaac   PetscErrorCode ierr;
97880b27e07SToby Isaac 
97980b27e07SToby Isaac   PetscFunctionBegin;
98080b27e07SToby Isaac   PetscValidHeaderSpecific(dmIn   ,DM_CLASSID  ,1);
98180b27e07SToby Isaac   PetscValidHeaderSpecific(vecIn  ,VEC_CLASSID ,2);
98280b27e07SToby Isaac   PetscValidHeaderSpecific(dmOut  ,DM_CLASSID  ,3);
98380b27e07SToby Isaac   PetscValidHeaderSpecific(vecOut ,VEC_CLASSID ,4);
98480b27e07SToby Isaac   forest = (DM_Forest *) dmIn->data;
98580b27e07SToby Isaac   if (!forest->transfervec) SETERRQ(PetscObjectComm((PetscObject)dmIn),PETSC_ERR_SUP,"DMForestTransferVec() not implemented");
9860eb7e1eaSToby Isaac   ierr = (forest->transfervec)(dmIn,vecIn,dmOut,vecOut,useBCs,time);CHKERRQ(ierr);
98780b27e07SToby Isaac   PetscFunctionReturn(0);
98880b27e07SToby Isaac }
98980b27e07SToby Isaac 
990bf9b5d84SToby Isaac /*@
991bf9b5d84SToby Isaac   DMForestGetComputeAdaptivitySF - Get whether transfer PetscSFs should be computed relating the cells of the
992bf9b5d84SToby Isaac   pre-adaptation forest to the post-adaptiation forest.  After DMSetUp() is called, these transfer PetscSFs can be
993bf9b5d84SToby Isaac   accessed with DMForestGetAdaptivitySF().
994bf9b5d84SToby Isaac 
995bf9b5d84SToby Isaac   Not collective
996bf9b5d84SToby Isaac 
997bf9b5d84SToby Isaac   Input Parameter:
998bf9b5d84SToby Isaac . dm - the post-adaptation forest
999bf9b5d84SToby Isaac 
1000bf9b5d84SToby Isaac   Output Parameter:
1001bf9b5d84SToby Isaac . computeSF - default PETSC_TRUE
1002bf9b5d84SToby Isaac 
1003bf9b5d84SToby Isaac   Level: advanced
1004bf9b5d84SToby Isaac 
1005bf9b5d84SToby Isaac .seealso: DMForestSetComputeAdaptivitySF(), DMForestGetAdaptivitySF()
1006bf9b5d84SToby Isaac @*/
1007bf9b5d84SToby Isaac PetscErrorCode DMForestGetComputeAdaptivitySF(DM dm, PetscBool *computeSF)
1008bf9b5d84SToby Isaac {
1009bf9b5d84SToby Isaac   DM_Forest *forest;
1010bf9b5d84SToby Isaac 
1011bf9b5d84SToby Isaac   PetscFunctionBegin;
1012bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1013bf9b5d84SToby Isaac   forest     = (DM_Forest*) dm->data;
1014bf9b5d84SToby Isaac   *computeSF = forest->computeAdaptSF;
1015bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1016bf9b5d84SToby Isaac }
1017bf9b5d84SToby Isaac 
1018bf9b5d84SToby Isaac /*@
1019bf9b5d84SToby Isaac   DMForestGetAdaptivitySF - Get PetscSFs that relate the pre-adaptation forest to the post-adaptation forest.
1020bf9b5d84SToby Isaac   Adaptation can be any combination of refinement, coarsening, repartition, and change of overlap, so there may be
1021bf9b5d84SToby Isaac   some cells of the pre-adaptation that are parents of post-adaptation cells, and vice versa.  Therefore there are two
1022bf9b5d84SToby Isaac   PetscSFs: one that relates pre-adaptation coarse cells to post-adaptation fine cells, and one that relates
1023bf9b5d84SToby Isaac   pre-adaptation fine cells to post-adaptation coarse cells.
1024bf9b5d84SToby Isaac 
1025bf9b5d84SToby Isaac   Not collective
1026bf9b5d84SToby Isaac 
1027bf9b5d84SToby Isaac   Input Parameter:
1028bf9b5d84SToby Isaac   dm - the post-adaptation forest
1029bf9b5d84SToby Isaac 
1030bf9b5d84SToby Isaac   Output Parameter:
10310f17b9e3SToby Isaac   preCoarseToFine - pre-adaptation coarse cells to post-adaptation fine cells: BCast goes from pre- to post-
10320f17b9e3SToby Isaac   coarseToPreFine - post-adaptation coarse cells to pre-adaptation fine cells: BCast goes from post- to pre-
1033bf9b5d84SToby Isaac 
1034bf9b5d84SToby Isaac   Level: advanced
1035bf9b5d84SToby Isaac 
1036bf9b5d84SToby Isaac .seealso: DMForestGetComputeAdaptivitySF(), DMForestSetComputeAdaptivitySF()
1037bf9b5d84SToby Isaac @*/
10380f17b9e3SToby Isaac PetscErrorCode DMForestGetAdaptivitySF(DM dm, PetscSF *preCoarseToFine, PetscSF *coarseToPreFine)
1039bf9b5d84SToby Isaac {
1040bf9b5d84SToby Isaac   DM_Forest      *forest;
1041bf9b5d84SToby Isaac   PetscErrorCode ierr;
1042bf9b5d84SToby Isaac 
1043bf9b5d84SToby Isaac   PetscFunctionBegin;
1044bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1045bf9b5d84SToby Isaac   ierr   = DMSetUp(dm);CHKERRQ(ierr);
1046bf9b5d84SToby Isaac   forest = (DM_Forest*) dm->data;
1047f885a11aSToby Isaac   if (preCoarseToFine) *preCoarseToFine = forest->preCoarseToFine;
1048f885a11aSToby Isaac   if (coarseToPreFine) *coarseToPreFine = forest->coarseToPreFine;
1049bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1050bf9b5d84SToby Isaac }
1051bf9b5d84SToby Isaac 
10529be51f97SToby Isaac /*@
10539be51f97SToby Isaac   DMForestSetGradeFactor - During the pre-setup phase, set the desired amount of grading in the mesh, e.g. give 2 to
10549be51f97SToby Isaac   indicate that the diameter of neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may
10559be51f97SToby Isaac   only support one particular choice of grading factor.
10569be51f97SToby Isaac 
10579be51f97SToby Isaac   Logically collective on dm
10589be51f97SToby Isaac 
10599be51f97SToby Isaac   Input Parameters:
10609be51f97SToby Isaac + dm - the forest
10619be51f97SToby Isaac - grade - the grading factor
10629be51f97SToby Isaac 
10639be51f97SToby Isaac   Level: advanced
10649be51f97SToby Isaac 
10659be51f97SToby Isaac .seealso: DMForestGetGradeFactor()
10669be51f97SToby Isaac @*/
1067c7eeac06SToby Isaac PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade)
1068c7eeac06SToby Isaac {
1069c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1070c7eeac06SToby Isaac 
1071c7eeac06SToby Isaac   PetscFunctionBegin;
1072c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1073ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup");
1074c7eeac06SToby Isaac   forest->gradeFactor = grade;
1075c7eeac06SToby Isaac   PetscFunctionReturn(0);
1076c7eeac06SToby Isaac }
1077c7eeac06SToby Isaac 
10789be51f97SToby Isaac /*@
10799be51f97SToby Isaac   DMForestGetGradeFactor - Get the desired amount of grading in the mesh, e.g. give 2 to indicate that the diameter of
10809be51f97SToby Isaac   neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may only support one particular
10819be51f97SToby Isaac   choice of grading factor.
10829be51f97SToby Isaac 
10839be51f97SToby Isaac   Not collective
10849be51f97SToby Isaac 
10859be51f97SToby Isaac   Input Parameter:
10869be51f97SToby Isaac . dm - the forest
10879be51f97SToby Isaac 
10889be51f97SToby Isaac   Output Parameter:
10899be51f97SToby Isaac . grade - the grading factor
10909be51f97SToby Isaac 
10919be51f97SToby Isaac   Level: advanced
10929be51f97SToby Isaac 
10939be51f97SToby Isaac .seealso: DMForestSetGradeFactor()
10949be51f97SToby Isaac @*/
1095c7eeac06SToby Isaac PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade)
1096c7eeac06SToby Isaac {
1097c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1098c7eeac06SToby Isaac 
1099c7eeac06SToby Isaac   PetscFunctionBegin;
1100c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1101c7eeac06SToby Isaac   PetscValidIntPointer(grade,2);
1102c7eeac06SToby Isaac   *grade = forest->gradeFactor;
1103c7eeac06SToby Isaac   PetscFunctionReturn(0);
1104c7eeac06SToby Isaac }
1105c7eeac06SToby Isaac 
11069be51f97SToby Isaac /*@
11079be51f97SToby Isaac   DMForestSetCellWeightFactor - During the pre-setup phase, set the factor by which the level of refinement changes
11089be51f97SToby Isaac   the cell weight (see DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be
11099be51f97SToby Isaac   (cellWeight) * (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on
11109be51f97SToby Isaac   its level; a factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the
11119be51f97SToby Isaac   computation associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11129be51f97SToby Isaac 
11139be51f97SToby Isaac   Logically collective on dm
11149be51f97SToby Isaac 
11159be51f97SToby Isaac   Input Parameters:
11169be51f97SToby Isaac + dm - the forest
11179be51f97SToby Isaac - weightsFactors - default 1.
11189be51f97SToby Isaac 
11199be51f97SToby Isaac   Level: advanced
11209be51f97SToby Isaac 
11219be51f97SToby Isaac .seealso: DMForestGetCellWeightFactor(), DMForestSetCellWeights()
11229be51f97SToby Isaac @*/
1123ef51cf95SToby Isaac PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor)
1124c7eeac06SToby Isaac {
1125c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1126c7eeac06SToby Isaac 
1127c7eeac06SToby Isaac   PetscFunctionBegin;
1128c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1129ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup");
1130c7eeac06SToby Isaac   forest->weightsFactor = weightsFactor;
1131c7eeac06SToby Isaac   PetscFunctionReturn(0);
1132c7eeac06SToby Isaac }
1133c7eeac06SToby Isaac 
11349be51f97SToby Isaac /*@
11359be51f97SToby Isaac   DMForestGetCellWeightFactor - Get the factor by which the level of refinement changes the cell weight (see
11369be51f97SToby Isaac   DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be (cellWeight) *
11379be51f97SToby Isaac   (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on its level; a
11389be51f97SToby Isaac   factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the computation
11399be51f97SToby Isaac   associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11409be51f97SToby Isaac 
11419be51f97SToby Isaac   Not collective
11429be51f97SToby Isaac 
11439be51f97SToby Isaac   Input Parameter:
11449be51f97SToby Isaac . dm - the forest
11459be51f97SToby Isaac 
11469be51f97SToby Isaac   Output Parameter:
11479be51f97SToby Isaac . weightsFactors - default 1.
11489be51f97SToby Isaac 
11499be51f97SToby Isaac   Level: advanced
11509be51f97SToby Isaac 
11519be51f97SToby Isaac .seealso: DMForestSetCellWeightFactor(), DMForestSetCellWeights()
11529be51f97SToby Isaac @*/
1153ef51cf95SToby Isaac PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor)
1154c7eeac06SToby Isaac {
1155c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1156c7eeac06SToby Isaac 
1157c7eeac06SToby Isaac   PetscFunctionBegin;
1158c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1159c7eeac06SToby Isaac   PetscValidRealPointer(weightsFactor,2);
1160c7eeac06SToby Isaac   *weightsFactor = forest->weightsFactor;
1161c7eeac06SToby Isaac   PetscFunctionReturn(0);
1162c7eeac06SToby Isaac }
1163c7eeac06SToby Isaac 
11649be51f97SToby Isaac /*@
11659be51f97SToby Isaac   DMForestGetCellChart - After the setup phase, get the local half-open interval of the chart of cells on this process
11669be51f97SToby Isaac 
11679be51f97SToby Isaac   Not collective
11689be51f97SToby Isaac 
11699be51f97SToby Isaac   Input Parameter:
11709be51f97SToby Isaac . dm - the forest
11719be51f97SToby Isaac 
11729be51f97SToby Isaac   Output Parameters:
11739be51f97SToby Isaac + cStart - the first cell on this process
11749be51f97SToby Isaac - cEnd - one after the final cell on this process
11759be51f97SToby Isaac 
11761a244344SSatish Balay   Level: intermediate
11779be51f97SToby Isaac 
11789be51f97SToby Isaac .seealso: DMForestGetCellSF()
11799be51f97SToby Isaac @*/
1180c7eeac06SToby Isaac PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd)
1181c7eeac06SToby Isaac {
1182c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1183c7eeac06SToby Isaac   PetscErrorCode ierr;
1184c7eeac06SToby Isaac 
1185c7eeac06SToby Isaac   PetscFunctionBegin;
1186c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1187c7eeac06SToby Isaac   PetscValidIntPointer(cStart,2);
1188c7eeac06SToby Isaac   PetscValidIntPointer(cEnd,2);
1189c7eeac06SToby Isaac   if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) {
1190c7eeac06SToby Isaac     ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr);
1191c7eeac06SToby Isaac   }
1192c7eeac06SToby Isaac   *cStart =  forest->cStart;
1193c7eeac06SToby Isaac   *cEnd   =  forest->cEnd;
1194c7eeac06SToby Isaac   PetscFunctionReturn(0);
1195c7eeac06SToby Isaac }
1196c7eeac06SToby Isaac 
11979be51f97SToby Isaac /*@
11989be51f97SToby Isaac   DMForestGetCellSF - After the setup phase, get the PetscSF for overlapping cells between processes
11999be51f97SToby Isaac 
12009be51f97SToby Isaac   Not collective
12019be51f97SToby Isaac 
12029be51f97SToby Isaac   Input Parameter:
12039be51f97SToby Isaac . dm - the forest
12049be51f97SToby Isaac 
12059be51f97SToby Isaac   Output Parameter:
12069be51f97SToby Isaac . cellSF - the PetscSF
12079be51f97SToby Isaac 
12081a244344SSatish Balay   Level: intermediate
12099be51f97SToby Isaac 
12109be51f97SToby Isaac .seealso: DMForestGetCellChart()
12119be51f97SToby Isaac @*/
1212c7eeac06SToby Isaac PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF)
1213c7eeac06SToby Isaac {
1214c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1215c7eeac06SToby Isaac   PetscErrorCode ierr;
1216c7eeac06SToby Isaac 
1217c7eeac06SToby Isaac   PetscFunctionBegin;
1218c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1219c7eeac06SToby Isaac   PetscValidPointer(cellSF,2);
1220c7eeac06SToby Isaac   if ((!forest->cellSF) && forest->createcellsf) {
1221c7eeac06SToby Isaac     ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr);
1222c7eeac06SToby Isaac   }
1223c7eeac06SToby Isaac   *cellSF = forest->cellSF;
1224c7eeac06SToby Isaac   PetscFunctionReturn(0);
1225c7eeac06SToby Isaac }
1226c7eeac06SToby Isaac 
12279be51f97SToby Isaac /*@C
12289be51f97SToby Isaac   DMForestSetAdaptivityLabel - During the pre-setup phase, set the label of the pre-adaptation forest (see
12299be51f97SToby Isaac   DMForestGetAdaptivityForest()) that holds the adaptation flags (refinement, coarsening, or some combination).  The
1230cd3c525cSToby Isaac   interpretation of the label values is up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP,
1231cd3c525cSToby Isaac   DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have been reserved as choices that should be accepted by all subtypes.
12329be51f97SToby Isaac 
12339be51f97SToby Isaac   Logically collective on dm
12349be51f97SToby Isaac 
12359be51f97SToby Isaac   Input Parameters:
12369be51f97SToby Isaac - dm - the forest
1237a1b0c543SToby Isaac + adaptLabel - the label in the pre-adaptation forest
12389be51f97SToby Isaac 
12399be51f97SToby Isaac   Level: intermediate
12409be51f97SToby Isaac 
12419be51f97SToby Isaac .seealso DMForestGetAdaptivityLabel()
12429be51f97SToby Isaac @*/
1243a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityLabel(DM dm, DMLabel adaptLabel)
1244c7eeac06SToby Isaac {
1245c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1246c7eeac06SToby Isaac   PetscErrorCode ierr;
1247c7eeac06SToby Isaac 
1248c7eeac06SToby Isaac   PetscFunctionBegin;
1249c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1250a1b0c543SToby Isaac   adaptLabel->refct++;
1251a1b0c543SToby Isaac   if (forest->adaptLabel) {ierr = DMLabelDestroy(&forest->adaptLabel);CHKERRQ(ierr);}
1252a1b0c543SToby Isaac   forest->adaptLabel = adaptLabel;
1253c7eeac06SToby Isaac   PetscFunctionReturn(0);
1254c7eeac06SToby Isaac }
1255c7eeac06SToby Isaac 
12569be51f97SToby Isaac /*@C
12579be51f97SToby Isaac   DMForestGetAdaptivityLabel - Get the label of the pre-adaptation forest (see DMForestGetAdaptivityForest()) that
12589be51f97SToby Isaac   holds the adaptation flags (refinement, coarsening, or some combination).  The interpretation of the label values is
1259cd3c525cSToby Isaac   up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have
1260cd3c525cSToby Isaac   been reserved as choices that should be accepted by all subtypes.
12619be51f97SToby Isaac 
12629be51f97SToby Isaac   Not collective
12639be51f97SToby Isaac 
12649be51f97SToby Isaac   Input Parameter:
12659be51f97SToby Isaac . dm - the forest
12669be51f97SToby Isaac 
12679be51f97SToby Isaac   Output Parameter:
12689be51f97SToby Isaac . adaptLabel - the name of the label in the pre-adaptation forest
12699be51f97SToby Isaac 
12709be51f97SToby Isaac   Level: intermediate
12719be51f97SToby Isaac 
12729be51f97SToby Isaac .seealso DMForestSetAdaptivityLabel()
12739be51f97SToby Isaac @*/
1274a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityLabel(DM dm, DMLabel *adaptLabel)
1275c7eeac06SToby Isaac {
1276c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1277c7eeac06SToby Isaac 
1278c7eeac06SToby Isaac   PetscFunctionBegin;
1279c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1280ba936b91SToby Isaac   *adaptLabel = forest->adaptLabel;
1281c7eeac06SToby Isaac   PetscFunctionReturn(0);
1282c7eeac06SToby Isaac }
1283c7eeac06SToby Isaac 
12849be51f97SToby Isaac /*@
12859be51f97SToby Isaac   DMForestSetCellWeights - Set the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
12869be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
12879be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
12889be51f97SToby Isaac   of 1.
12899be51f97SToby Isaac 
12909be51f97SToby Isaac   Logically collective on dm
12919be51f97SToby Isaac 
12929be51f97SToby Isaac   Input Parameters:
12939be51f97SToby Isaac + dm - the forest
12949be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
12959be51f97SToby Isaac - copyMode - how weights should reference weights
12969be51f97SToby Isaac 
12979be51f97SToby Isaac   Level: advanced
12989be51f97SToby Isaac 
12999be51f97SToby Isaac .seealso: DMForestGetCellWeights(), DMForestSetWeightCapacity()
13009be51f97SToby Isaac @*/
1301c7eeac06SToby Isaac PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode)
1302c7eeac06SToby Isaac {
1303c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1304c7eeac06SToby Isaac   PetscInt       cStart, cEnd;
1305c7eeac06SToby Isaac   PetscErrorCode ierr;
1306c7eeac06SToby Isaac 
1307c7eeac06SToby Isaac   PetscFunctionBegin;
1308c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1309c7eeac06SToby Isaac   ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr);
1310c7eeac06SToby Isaac   if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd);
1311c7eeac06SToby Isaac   if (copyMode == PETSC_COPY_VALUES) {
1312c7eeac06SToby Isaac     if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) {
1313c7eeac06SToby Isaac       ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr);
1314c7eeac06SToby Isaac     }
1315c7eeac06SToby Isaac     ierr                        = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr);
1316c7eeac06SToby Isaac     forest->cellWeightsCopyMode = PETSC_OWN_POINTER;
1317c7eeac06SToby Isaac     PetscFunctionReturn(0);
1318c7eeac06SToby Isaac   }
1319c7eeac06SToby Isaac   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) {
1320c7eeac06SToby Isaac     ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr);
1321c7eeac06SToby Isaac   }
1322c7eeac06SToby Isaac   forest->cellWeights         = weights;
1323c7eeac06SToby Isaac   forest->cellWeightsCopyMode = copyMode;
1324c7eeac06SToby Isaac   PetscFunctionReturn(0);
1325c7eeac06SToby Isaac }
1326c7eeac06SToby Isaac 
13279be51f97SToby Isaac /*@
13289be51f97SToby Isaac   DMForestGetCellWeights - Get the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
13299be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
13309be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
13319be51f97SToby Isaac   of 1.
13329be51f97SToby Isaac 
13339be51f97SToby Isaac   Not collective
13349be51f97SToby Isaac 
13359be51f97SToby Isaac   Input Parameter:
13369be51f97SToby Isaac . dm - the forest
13379be51f97SToby Isaac 
13389be51f97SToby Isaac   Output Parameter:
13399be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
13409be51f97SToby Isaac 
13419be51f97SToby Isaac   Level: advanced
13429be51f97SToby Isaac 
13439be51f97SToby Isaac .seealso: DMForestSetCellWeights(), DMForestSetWeightCapacity()
13449be51f97SToby Isaac @*/
1345c7eeac06SToby Isaac PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights)
1346c7eeac06SToby Isaac {
1347c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1348c7eeac06SToby Isaac 
1349c7eeac06SToby Isaac   PetscFunctionBegin;
1350c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1351c7eeac06SToby Isaac   PetscValidPointer(weights,2);
1352c7eeac06SToby Isaac   *weights = forest->cellWeights;
1353c7eeac06SToby Isaac   PetscFunctionReturn(0);
1354c7eeac06SToby Isaac }
1355c7eeac06SToby Isaac 
13569be51f97SToby Isaac /*@
13579be51f97SToby Isaac   DMForestSetWeightCapacity - During the pre-setup phase, set the capacity of the current process when repartitioning
13589be51f97SToby Isaac   a pre-adaptation forest (see DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each
13599be51f97SToby Isaac   process's cells to the process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that
13609be51f97SToby Isaac   the current process should not have any cells after repartitioning.
13619be51f97SToby Isaac 
13629be51f97SToby Isaac   Logically Collective on dm
13639be51f97SToby Isaac 
13649be51f97SToby Isaac   Input parameters:
13659be51f97SToby Isaac + dm - the forest
13669be51f97SToby Isaac - capacity - this process's capacity
13679be51f97SToby Isaac 
13689be51f97SToby Isaac   Level: advanced
13699be51f97SToby Isaac 
13709be51f97SToby Isaac .seealso DMForestGetWeightCapacity(), DMForestSetCellWeights(), DMForestSetCellWeightFactor()
13719be51f97SToby Isaac @*/
1372c7eeac06SToby Isaac PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity)
1373c7eeac06SToby Isaac {
1374c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1375c7eeac06SToby Isaac 
1376c7eeac06SToby Isaac   PetscFunctionBegin;
1377c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1378ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup");
1379c7eeac06SToby Isaac   if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity);
1380c7eeac06SToby Isaac   forest->weightCapacity = capacity;
1381c7eeac06SToby Isaac   PetscFunctionReturn(0);
1382c7eeac06SToby Isaac }
1383c7eeac06SToby Isaac 
13849be51f97SToby Isaac /*@
13859be51f97SToby Isaac   DMForestGetWeightCapacity - Set the capacity of the current process when repartitioning a pre-adaptation forest (see
13869be51f97SToby Isaac   DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each process's cells to the
13879be51f97SToby Isaac   process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that the current process
13889be51f97SToby Isaac   should not have any cells after repartitioning.
13899be51f97SToby Isaac 
13909be51f97SToby Isaac   Not collective
13919be51f97SToby Isaac 
13929be51f97SToby Isaac   Input parameter:
13939be51f97SToby Isaac . dm - the forest
13949be51f97SToby Isaac 
13959be51f97SToby Isaac   Output parameter:
13969be51f97SToby Isaac . capacity - this process's capacity
13979be51f97SToby Isaac 
13989be51f97SToby Isaac   Level: advanced
13999be51f97SToby Isaac 
14009be51f97SToby Isaac .seealso DMForestSetWeightCapacity(), DMForestSetCellWeights(), DMForestSetCellWeightFactor()
14019be51f97SToby Isaac @*/
1402c7eeac06SToby Isaac PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity)
1403c7eeac06SToby Isaac {
1404c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1405c7eeac06SToby Isaac 
1406c7eeac06SToby Isaac   PetscFunctionBegin;
1407c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1408c7eeac06SToby Isaac   PetscValidRealPointer(capacity,2);
1409c7eeac06SToby Isaac   *capacity = forest->weightCapacity;
1410c7eeac06SToby Isaac   PetscFunctionReturn(0);
1411c7eeac06SToby Isaac }
1412c7eeac06SToby Isaac 
14130709b2feSToby Isaac PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptionItems *PetscOptionsObject,DM dm)
1414db4d5e8cSToby Isaac {
1415db4d5e8cSToby Isaac   DM_Forest                  *forest = (DM_Forest*) dm->data;
141656ba9f64SToby Isaac   PetscBool                  flg, flg1, flg2, flg3, flg4;
1417dd8e54a2SToby Isaac   DMForestTopology           oldTopo;
1418c7eeac06SToby Isaac   char                       stringBuffer[256];
1419dd8e54a2SToby Isaac   PetscViewer                viewer;
1420dd8e54a2SToby Isaac   PetscViewerFormat          format;
142156ba9f64SToby Isaac   PetscInt                   adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade;
1422c7eeac06SToby Isaac   PetscReal                  weightsFactor;
1423c7eeac06SToby Isaac   DMForestAdaptivityStrategy adaptStrategy;
1424db4d5e8cSToby Isaac   PetscErrorCode             ierr;
1425db4d5e8cSToby Isaac 
1426db4d5e8cSToby Isaac   PetscFunctionBegin;
1427db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
142858762b62SToby Isaac   forest->setfromoptionscalled = PETSC_TRUE;
1429dd8e54a2SToby Isaac   ierr                         = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr);
1430a3eda1eaSToby Isaac   ierr                         = PetscOptionsHead(PetscOptionsObject,"DMForest Options");CHKERRQ(ierr);
143156ba9f64SToby Isaac   ierr                         = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg1);CHKERRQ(ierr);
143256ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg2);CHKERRQ(ierr);
143356ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg3);CHKERRQ(ierr);
143456ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg4);CHKERRQ(ierr);
1435f885a11aSToby 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}");
143656ba9f64SToby Isaac   if (flg1) {
143756ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr);
143856ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
143920e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
144056ba9f64SToby Isaac   }
144156ba9f64SToby Isaac   if (flg2) {
1442dd8e54a2SToby Isaac     DM base;
1443dd8e54a2SToby Isaac 
1444dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr);
1445dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1446dd8e54a2SToby Isaac     ierr = DMLoad(base,viewer);CHKERRQ(ierr);
1447dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1448dd8e54a2SToby Isaac     ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
1449dd8e54a2SToby Isaac     ierr = DMDestroy(&base);CHKERRQ(ierr);
145056ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
145120e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
1452dd8e54a2SToby Isaac   }
145356ba9f64SToby Isaac   if (flg3) {
1454dd8e54a2SToby Isaac     DM coarse;
1455dd8e54a2SToby Isaac 
1456dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr);
1457dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1458dd8e54a2SToby Isaac     ierr = DMLoad(coarse,viewer);CHKERRQ(ierr);
1459dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
146020e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,coarse);CHKERRQ(ierr);
1461dd8e54a2SToby Isaac     ierr = DMDestroy(&coarse);CHKERRQ(ierr);
146256ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
146356ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
1464dd8e54a2SToby Isaac   }
146556ba9f64SToby Isaac   if (flg4) {
1466dd8e54a2SToby Isaac     DM fine;
1467dd8e54a2SToby Isaac 
1468dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr);
1469dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1470dd8e54a2SToby Isaac     ierr = DMLoad(fine,viewer);CHKERRQ(ierr);
1471dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
147220e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,fine);CHKERRQ(ierr);
1473dd8e54a2SToby Isaac     ierr = DMDestroy(&fine);CHKERRQ(ierr);
147456ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
147556ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
1476dd8e54a2SToby Isaac   }
1477dd8e54a2SToby Isaac   ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr);
1478dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr);
1479dd8e54a2SToby Isaac   if (flg) {
1480dd8e54a2SToby Isaac     ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr);
1481f885a11aSToby Isaac   } else {
1482dd8e54a2SToby Isaac     ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr);
1483dd8e54a2SToby Isaac     ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr);
1484dd8e54a2SToby Isaac     if (flg) {
1485dd8e54a2SToby Isaac       ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr);
1486dd8e54a2SToby Isaac     }
1487dd8e54a2SToby Isaac   }
1488dd8e54a2SToby Isaac   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
1489dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr);
1490dd8e54a2SToby Isaac   if (flg) {
1491dd8e54a2SToby Isaac     ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr);
1492dd8e54a2SToby Isaac   }
1493a6121fbdSMatthew G. Knepley #if 0
1494a6121fbdSMatthew 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);
1495a6121fbdSMatthew G. Knepley   if (flg) {
1496a6121fbdSMatthew G. Knepley     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
1497a6121fbdSMatthew G. Knepley     ierr = DMForestSetInitialRefinement(dm,minRefinement);CHKERRQ(ierr);
1498a6121fbdSMatthew G. Knepley   }
1499a6121fbdSMatthew 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);
1500a6121fbdSMatthew G. Knepley   if (flg) {
1501a6121fbdSMatthew G. Knepley     ierr = DMForestSetMinimumRefinement(dm,0);CHKERRQ(ierr);
1502a6121fbdSMatthew G. Knepley     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
1503a6121fbdSMatthew G. Knepley   }
1504a6121fbdSMatthew G. Knepley #endif
1505dd8e54a2SToby Isaac   ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr);
1506dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr);
1507dd8e54a2SToby Isaac   if (flg) {
1508dd8e54a2SToby Isaac     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
1509db4d5e8cSToby Isaac   }
151056ba9f64SToby Isaac   ierr = DMForestGetInitialRefinement(dm,&initRefinement);CHKERRQ(ierr);
151156ba9f64SToby Isaac   ierr = PetscOptionsInt("-dm_forest_initial_refinement","set the initial level of refinement in the forest","DMForestSetInitialRefinement",initRefinement,&initRefinement,&flg);CHKERRQ(ierr);
151256ba9f64SToby Isaac   if (flg) {
151356ba9f64SToby Isaac     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
151456ba9f64SToby Isaac   }
1515c7eeac06SToby Isaac   ierr = DMForestGetMaximumRefinement(dm,&maxRefinement);CHKERRQ(ierr);
1516c7eeac06SToby Isaac   ierr = PetscOptionsInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg);CHKERRQ(ierr);
1517c7eeac06SToby Isaac   if (flg) {
1518c7eeac06SToby Isaac     ierr = DMForestSetMaximumRefinement(dm,maxRefinement);CHKERRQ(ierr);
1519c7eeac06SToby Isaac   }
1520c7eeac06SToby Isaac   ierr = DMForestGetAdaptivityStrategy(dm,&adaptStrategy);CHKERRQ(ierr);
1521c7eeac06SToby Isaac   ierr = PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,256,&flg);CHKERRQ(ierr);
1522c7eeac06SToby Isaac   if (flg) {
1523c7eeac06SToby Isaac     ierr = DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer);CHKERRQ(ierr);
1524c7eeac06SToby Isaac   }
1525c7eeac06SToby Isaac   ierr = DMForestGetGradeFactor(dm,&grade);CHKERRQ(ierr);
1526c7eeac06SToby Isaac   ierr = PetscOptionsInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg);CHKERRQ(ierr);
1527c7eeac06SToby Isaac   if (flg) {
1528c7eeac06SToby Isaac     ierr = DMForestSetGradeFactor(dm,grade);CHKERRQ(ierr);
1529c7eeac06SToby Isaac   }
1530c7eeac06SToby Isaac   ierr = DMForestGetCellWeightFactor(dm,&weightsFactor);CHKERRQ(ierr);
1531c7eeac06SToby Isaac   ierr = PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg);CHKERRQ(ierr);
1532c7eeac06SToby Isaac   if (flg) {
1533c7eeac06SToby Isaac     ierr = DMForestSetCellWeightFactor(dm,weightsFactor);CHKERRQ(ierr);
1534c7eeac06SToby Isaac   }
1535db4d5e8cSToby Isaac   ierr = PetscOptionsTail();CHKERRQ(ierr);
1536db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1537db4d5e8cSToby Isaac }
1538db4d5e8cSToby Isaac 
1539d8984e3bSMatthew G. Knepley PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
1540d8984e3bSMatthew G. Knepley {
1541d8984e3bSMatthew G. Knepley   PetscErrorCode ierr;
1542d8984e3bSMatthew G. Knepley 
1543d8984e3bSMatthew G. Knepley   PetscFunctionBegin;
1544d8984e3bSMatthew G. Knepley   if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);}
1545d8984e3bSMatthew G. Knepley   ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
1546d8984e3bSMatthew G. Knepley   PetscFunctionReturn(0);
1547d8984e3bSMatthew G. Knepley }
1548d8984e3bSMatthew G. Knepley 
15495421bac9SToby Isaac PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined)
15505421bac9SToby Isaac {
15515421bac9SToby Isaac   DMLabel        refine;
15525421bac9SToby Isaac   DM             fineDM;
15535421bac9SToby Isaac   PetscErrorCode ierr;
15545421bac9SToby Isaac 
15555421bac9SToby Isaac   PetscFunctionBegin;
15565421bac9SToby Isaac   ierr = DMGetFineDM(dm,&fineDM);CHKERRQ(ierr);
15575421bac9SToby Isaac   if (fineDM) {
15585421bac9SToby Isaac     ierr       = PetscObjectReference((PetscObject)fineDM);CHKERRQ(ierr);
15595421bac9SToby Isaac     *dmRefined = fineDM;
15605421bac9SToby Isaac     PetscFunctionReturn(0);
15615421bac9SToby Isaac   }
15625421bac9SToby Isaac   ierr = DMForestTemplate(dm,comm,dmRefined);CHKERRQ(ierr);
15635421bac9SToby Isaac   ierr = DMGetLabel(dm,"refine",&refine);CHKERRQ(ierr);
15645421bac9SToby Isaac   if (!refine) {
1565a1b0c543SToby Isaac     ierr = DMLabelCreate("refine",&refine);CHKERRQ(ierr);
1566a1b0c543SToby Isaac     ierr = DMLabelSetDefaultValue(refine,DM_ADAPT_REFINE);CHKERRQ(ierr);
15675421bac9SToby Isaac   }
1568a1b0c543SToby Isaac   else {
1569a1b0c543SToby Isaac     refine->refct++;
1570a1b0c543SToby Isaac   }
1571a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*dmRefined,refine);CHKERRQ(ierr);
1572a1b0c543SToby Isaac   ierr = DMLabelDestroy(&refine);CHKERRQ(ierr);
15735421bac9SToby Isaac   PetscFunctionReturn(0);
15745421bac9SToby Isaac }
15755421bac9SToby Isaac 
15765421bac9SToby Isaac PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened)
15775421bac9SToby Isaac {
15785421bac9SToby Isaac   DMLabel        coarsen;
15795421bac9SToby Isaac   DM             coarseDM;
15805421bac9SToby Isaac   PetscErrorCode ierr;
15815421bac9SToby Isaac 
15825421bac9SToby Isaac   PetscFunctionBegin;
15834098eed7SToby Isaac   {
15844098eed7SToby Isaac     PetscMPIInt mpiComparison;
15854098eed7SToby Isaac     MPI_Comm    dmcomm = PetscObjectComm((PetscObject)dm);
15864098eed7SToby Isaac 
15874098eed7SToby Isaac     ierr = MPI_Comm_compare(comm, dmcomm, &mpiComparison);CHKERRQ(ierr);
1588f885a11aSToby Isaac     if (mpiComparison != MPI_IDENT && mpiComparison != MPI_CONGRUENT) SETERRQ(dmcomm,PETSC_ERR_SUP,"No support for different communicators yet");
15894098eed7SToby Isaac   }
15905421bac9SToby Isaac   ierr = DMGetCoarseDM(dm,&coarseDM);CHKERRQ(ierr);
15915421bac9SToby Isaac   if (coarseDM) {
15925421bac9SToby Isaac     ierr         = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr);
15935421bac9SToby Isaac     *dmCoarsened = coarseDM;
15945421bac9SToby Isaac     PetscFunctionReturn(0);
15955421bac9SToby Isaac   }
15965421bac9SToby Isaac   ierr = DMForestTemplate(dm,comm,dmCoarsened);CHKERRQ(ierr);
1597a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityPurpose(coarseDM,DM_ADAPT_COARSEN);CHKERRQ(ierr);
15985421bac9SToby Isaac   ierr = DMGetLabel(dm,"coarsen",&coarsen);CHKERRQ(ierr);
15995421bac9SToby Isaac   if (!coarsen) {
1600a1b0c543SToby Isaac     ierr = DMLabelCreate("coarsen",&coarsen);CHKERRQ(ierr);
1601a1b0c543SToby Isaac     ierr = DMLabelSetDefaultValue(coarsen,DM_ADAPT_COARSEN);CHKERRQ(ierr);
1602a1b0c543SToby Isaac   } else {
1603a1b0c543SToby Isaac     coarsen->refct++;
16045421bac9SToby Isaac   }
1605a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*dmCoarsened,coarsen);CHKERRQ(ierr);
1606a1b0c543SToby Isaac   ierr = DMLabelDestroy(&coarsen);CHKERRQ(ierr);
16075421bac9SToby Isaac   PetscFunctionReturn(0);
16085421bac9SToby Isaac }
16095421bac9SToby Isaac 
1610a1b0c543SToby Isaac static PetscErrorCode DMAdaptLabel_Forest(DM dm, DMLabel label, DM *adaptedDM)
161109350103SToby Isaac {
161209350103SToby Isaac   PetscBool      success;
161309350103SToby Isaac   PetscErrorCode ierr;
161409350103SToby Isaac 
161509350103SToby Isaac   PetscFunctionBegin;
161609350103SToby Isaac   ierr = DMForestTemplate(dm,PetscObjectComm((PetscObject)dm),adaptedDM);CHKERRQ(ierr);
1617a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*adaptedDM,label);CHKERRQ(ierr);
161809350103SToby Isaac   ierr = DMSetUp(*adaptedDM);CHKERRQ(ierr);
161909350103SToby Isaac   ierr = DMForestGetAdaptivitySuccess(*adaptedDM,&success);CHKERRQ(ierr);
162009350103SToby Isaac   if (!success) {
162109350103SToby Isaac     ierr = DMDestroy(adaptedDM);CHKERRQ(ierr);
162209350103SToby Isaac     *adaptedDM = NULL;
162309350103SToby Isaac   }
162409350103SToby Isaac   PetscFunctionReturn(0);
162509350103SToby Isaac }
162609350103SToby Isaac 
1627d222f98bSToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm)
1628d222f98bSToby Isaac {
1629d222f98bSToby Isaac   PetscErrorCode ierr;
1630d222f98bSToby Isaac 
1631d222f98bSToby Isaac   PetscFunctionBegin;
1632d222f98bSToby Isaac   ierr = PetscMemzero(dm->ops,sizeof(*(dm->ops)));CHKERRQ(ierr);
1633d222f98bSToby Isaac 
1634d222f98bSToby Isaac   dm->ops->clone          = DMClone_Forest;
1635d222f98bSToby Isaac   dm->ops->setfromoptions = DMSetFromOptions_Forest;
1636d222f98bSToby Isaac   dm->ops->destroy        = DMDestroy_Forest;
1637d8984e3bSMatthew G. Knepley   dm->ops->createsubdm    = DMCreateSubDM_Forest;
16385421bac9SToby Isaac   dm->ops->refine         = DMRefine_Forest;
16395421bac9SToby Isaac   dm->ops->coarsen        = DMCoarsen_Forest;
1640a1b0c543SToby Isaac   ierr                    = PetscObjectComposeFunction((PetscObject)dm,"DMAdaptLabel_C",DMAdaptLabel_Forest);CHKERRQ(ierr);
1641d222f98bSToby Isaac   PetscFunctionReturn(0);
1642d222f98bSToby Isaac }
1643d222f98bSToby Isaac 
16449be51f97SToby Isaac /*MC
16459be51f97SToby Isaac 
1646bae1f979SBarry Smith      DMFOREST = "forest" - A DM object that encapsulates a hierarchically refined mesh.  Forests usually have a base DM
1647bae1f979SBarry Smith   (see DMForestGetBaseDM()), from which it is refined.  The refinement and partitioning of forests is considered
1648bae1f979SBarry Smith   immutable after DMSetUp() is called.  To adapt a mesh, one should call DMForestTemplate() to create a new mesh that
1649bae1f979SBarry Smith   will default to being identical to it, specify how that mesh should differ, and then calling DMSetUp() on the new
1650bae1f979SBarry Smith   mesh.
1651bae1f979SBarry Smith 
1652bae1f979SBarry Smith   To specify that a mesh should be refined or coarsened from the previous mesh, a label should be defined on the
1653bae1f979SBarry Smith   previous mesh whose values indicate which cells should be refined (DM_ADAPT_REFINE) or coarsened (DM_ADAPT_COARSEN)
1654bae1f979SBarry Smith   and how (subtypes are free to allow additional values for things like anisotropic refinement).  The label should be
1655bae1f979SBarry Smith   given to the *new* mesh with DMForestSetAdaptivityLabel().
16569be51f97SToby Isaac 
16579be51f97SToby Isaac   Level: advanced
16589be51f97SToby Isaac 
16599be51f97SToby Isaac .seealso: DMType, DMCreate(), DMSetType(), DMForestGetBaseDM(), DMForestSetBaseDM(), DMForestTemplate(), DMForestSetAdaptivityLabel()
16609be51f97SToby Isaac M*/
16619be51f97SToby Isaac 
1662db4d5e8cSToby Isaac PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm)
1663db4d5e8cSToby Isaac {
1664db4d5e8cSToby Isaac   DM_Forest      *forest;
1665db4d5e8cSToby Isaac   PetscErrorCode ierr;
1666db4d5e8cSToby Isaac 
1667db4d5e8cSToby Isaac   PetscFunctionBegin;
1668db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1669db4d5e8cSToby Isaac   ierr                         = PetscNewLog(dm,&forest);CHKERRQ(ierr);
1670db4d5e8cSToby Isaac   dm->dim                      = 0;
1671db4d5e8cSToby Isaac   dm->data                     = forest;
1672db4d5e8cSToby Isaac   forest->refct                = 1;
1673db4d5e8cSToby Isaac   forest->data                 = NULL;
167458762b62SToby Isaac   forest->setfromoptionscalled = PETSC_FALSE;
1675db4d5e8cSToby Isaac   forest->topology             = NULL;
1676cd3c525cSToby Isaac   forest->adapt                = NULL;
1677db4d5e8cSToby Isaac   forest->base                 = NULL;
16786a87ffbfSToby Isaac   forest->adaptPurpose         = DM_ADAPT_DETERMINE;
1679db4d5e8cSToby Isaac   forest->adjDim               = PETSC_DEFAULT;
1680db4d5e8cSToby Isaac   forest->overlap              = PETSC_DEFAULT;
1681db4d5e8cSToby Isaac   forest->minRefinement        = PETSC_DEFAULT;
1682db4d5e8cSToby Isaac   forest->maxRefinement        = PETSC_DEFAULT;
168356ba9f64SToby Isaac   forest->initRefinement       = PETSC_DEFAULT;
1684c7eeac06SToby Isaac   forest->cStart               = PETSC_DETERMINE;
1685c7eeac06SToby Isaac   forest->cEnd                 = PETSC_DETERMINE;
1686cd3c525cSToby Isaac   forest->cellSF               = NULL;
1687ebdf65a2SToby Isaac   forest->adaptLabel           = NULL;
1688db4d5e8cSToby Isaac   forest->gradeFactor          = 2;
1689db4d5e8cSToby Isaac   forest->cellWeights          = NULL;
1690db4d5e8cSToby Isaac   forest->cellWeightsCopyMode  = PETSC_USE_POINTER;
1691db4d5e8cSToby Isaac   forest->weightsFactor        = 1.;
1692db4d5e8cSToby Isaac   forest->weightCapacity       = 1.;
1693a73e2921SToby Isaac   ierr                         = DMForestSetAdaptivityStrategy(dm,DMFORESTADAPTALL);CHKERRQ(ierr);
1694d222f98bSToby Isaac   ierr                         = DMInitialize_Forest(dm);CHKERRQ(ierr);
1695db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1696db4d5e8cSToby Isaac }
1697db4d5e8cSToby Isaac 
1698