xref: /petsc/src/dm/impls/forest/forest.c (revision 367003a68d4e38a62ba2a0620cd4e6f42aa373fd)
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);
17090b157c4SStefano Zampini   {
17190b157c4SStefano Zampini     PetscBool            isper;
172795844e7SToby Isaac     const PetscReal      *maxCell, *L;
173795844e7SToby Isaac     const DMBoundaryType *bd;
174795844e7SToby Isaac 
17590b157c4SStefano Zampini     ierr = DMGetPeriodicity(dm,&isper,&maxCell,&L,&bd);CHKERRQ(ierr);
17690b157c4SStefano 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);
216db4d5e8cSToby Isaac   PetscFunctionReturn(0);
217db4d5e8cSToby Isaac }
218db4d5e8cSToby Isaac 
2199be51f97SToby Isaac /*@C
2209be51f97SToby Isaac   DMForestSetTopology - Set the topology of a DMForest during the pre-setup phase.  The topology is a string (e.g.
22168d54884SBarry Smith   "cube", "shell") and can be interpreted by subtypes of DMFOREST) to construct the base DM of a forest during
2229be51f97SToby Isaac   DMSetUp().
2239be51f97SToby Isaac 
2249be51f97SToby Isaac   Logically collective on dm
2259be51f97SToby Isaac 
2269be51f97SToby Isaac   Input parameters:
2279be51f97SToby Isaac + dm - the forest
2289be51f97SToby Isaac - topology - the topology of the forest
2299be51f97SToby Isaac 
2309be51f97SToby Isaac   Level: intermediate
2319be51f97SToby Isaac 
2329be51f97SToby Isaac .seealso(): DMForestGetTopology(), DMForestSetBaseDM()
2339be51f97SToby Isaac @*/
234dd8e54a2SToby Isaac PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology)
235db4d5e8cSToby Isaac {
236db4d5e8cSToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
237db4d5e8cSToby Isaac   PetscErrorCode ierr;
238db4d5e8cSToby Isaac 
239db4d5e8cSToby Isaac   PetscFunctionBegin;
240db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
241ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup");
242dd8e54a2SToby Isaac   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
243dd8e54a2SToby Isaac   ierr = PetscStrallocpy((const char*)topology,(char**) &forest->topology);CHKERRQ(ierr);
244db4d5e8cSToby Isaac   PetscFunctionReturn(0);
245db4d5e8cSToby Isaac }
246db4d5e8cSToby Isaac 
2479be51f97SToby Isaac /*@C
2489be51f97SToby Isaac   DMForestGetTopology - Get a string describing the topology of a DMForest.
2499be51f97SToby Isaac 
2509be51f97SToby Isaac   Not collective
2519be51f97SToby Isaac 
2529be51f97SToby Isaac   Input parameter:
2539be51f97SToby Isaac . dm - the forest
2549be51f97SToby Isaac 
2559be51f97SToby Isaac   Output parameter:
2569be51f97SToby Isaac . topology - the topology of the forest (e.g., 'cube', 'shell')
2579be51f97SToby Isaac 
2589be51f97SToby Isaac   Level: intermediate
2599be51f97SToby Isaac 
2609be51f97SToby Isaac .seealso: DMForestSetTopology()
2619be51f97SToby Isaac @*/
262dd8e54a2SToby Isaac PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology)
263dd8e54a2SToby Isaac {
264dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
265dd8e54a2SToby Isaac 
266dd8e54a2SToby Isaac   PetscFunctionBegin;
267dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
268dd8e54a2SToby Isaac   PetscValidPointer(topology,2);
269dd8e54a2SToby Isaac   *topology = forest->topology;
270dd8e54a2SToby Isaac   PetscFunctionReturn(0);
271dd8e54a2SToby Isaac }
272dd8e54a2SToby Isaac 
2739be51f97SToby Isaac /*@
2749be51f97SToby Isaac   DMForestSetBaseDM - During the pre-setup phase, set the DM that defines the base mesh of a DMForest forest.  The
2759be51f97SToby Isaac   forest will be hierarchically refined from the base, and all refinements/coarsenings of the forest will share its
276765b024eSBarry Smith   base.  In general, two forest must share a base to be comparable, to do things like construct interpolators.
2779be51f97SToby Isaac 
2789be51f97SToby Isaac   Logically collective on dm
2799be51f97SToby Isaac 
2809be51f97SToby Isaac   Input Parameters:
2819be51f97SToby Isaac + dm - the forest
2829be51f97SToby Isaac - base - the base DM of the forest
2839be51f97SToby Isaac 
28495452b02SPatrick Sanan   Notes:
28595452b02SPatrick Sanan     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 
326*367003a6SStefano Zampini   Notes:
327*367003a6SStefano Zampini     After DMSetUp(), the base DM will be redundantly distributed across MPI processes
328*367003a6SStefano Zampini 
3299be51f97SToby Isaac   Level: intermediate
3309be51f97SToby Isaac 
3319be51f97SToby Isaac .seealso(); DMForestSetBaseDM()
3329be51f97SToby Isaac @*/
333dd8e54a2SToby Isaac PetscErrorCode DMForestGetBaseDM(DM dm, DM *base)
334dd8e54a2SToby Isaac {
335dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
336dd8e54a2SToby Isaac 
337dd8e54a2SToby Isaac   PetscFunctionBegin;
338dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
339dd8e54a2SToby Isaac   PetscValidPointer(base, 2);
340dd8e54a2SToby Isaac   *base = forest->base;
341dd8e54a2SToby Isaac   PetscFunctionReturn(0);
342dd8e54a2SToby Isaac }
343dd8e54a2SToby Isaac 
34499478f86SToby Isaac PetscErrorCode DMForestSetBaseCoordinateMapping(DM dm, PetscErrorCode (*func)(DM,PetscInt,PetscInt,const PetscReal [],PetscReal [],void*),void *ctx)
345cf38a08cSToby Isaac {
346cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
347cf38a08cSToby Isaac 
348cf38a08cSToby Isaac   PetscFunctionBegin;
349cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
350cf38a08cSToby Isaac   forest->mapcoordinates    = func;
351cf38a08cSToby Isaac   forest->mapcoordinatesctx = ctx;
352cf38a08cSToby Isaac   PetscFunctionReturn(0);
353cf38a08cSToby Isaac }
354cf38a08cSToby Isaac 
35599478f86SToby Isaac PetscErrorCode DMForestGetBaseCoordinateMapping(DM dm, PetscErrorCode (**func) (DM,PetscInt,PetscInt,const PetscReal [],PetscReal [],void*),void *ctx)
356cf38a08cSToby Isaac {
357cf38a08cSToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
358cf38a08cSToby Isaac 
359cf38a08cSToby Isaac   PetscFunctionBegin;
360cf38a08cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
361cf38a08cSToby Isaac   if (func) *func = forest->mapcoordinates;
362cf38a08cSToby Isaac   if (ctx) *((void**) ctx) = forest->mapcoordinatesctx;
363cf38a08cSToby Isaac   PetscFunctionReturn(0);
364cf38a08cSToby Isaac }
365cf38a08cSToby Isaac 
3669be51f97SToby Isaac /*@
3679be51f97SToby Isaac   DMForestSetAdaptivityForest - During the pre-setup phase, set the forest from which the current forest will be
3689be51f97SToby Isaac   adapted (e.g., the current forest will be refined/coarsened/repartitioned from it) im DMSetUp().  Usually not needed
3699be51f97SToby Isaac   by users directly: DMForestTemplate() constructs a new forest to be adapted from an old forest and calls this
3709be51f97SToby Isaac   routine.
3719be51f97SToby Isaac 
372dffe73a3SToby Isaac   Note that this can be called after setup with adapt = NULL, which will clear all internal data related to the
373dffe73a3SToby Isaac   adaptivity forest from dm.  This way, repeatedly adapting does not leave stale DM objects in memory.
374dffe73a3SToby Isaac 
3759be51f97SToby Isaac   Logically collective on dm
3769be51f97SToby Isaac 
3779be51f97SToby Isaac   Input Parameter:
3789be51f97SToby Isaac + dm - the new forest, which will be constructed from adapt
3799be51f97SToby Isaac - adapt - the old forest
3809be51f97SToby Isaac 
3819be51f97SToby Isaac   Level: intermediate
3829be51f97SToby Isaac 
3839be51f97SToby Isaac .seealso: DMForestGetAdaptivityForest(), DMForestSetAdaptivityPurpose()
3849be51f97SToby Isaac @*/
385ba936b91SToby Isaac PetscErrorCode DMForestSetAdaptivityForest(DM dm,DM adapt)
386dd8e54a2SToby Isaac {
387dffe73a3SToby Isaac   DM_Forest      *forest, *adaptForest, *oldAdaptForest;
388dffe73a3SToby Isaac   DM             oldAdapt;
389456cc5b7SMatthew G. Knepley   PetscBool      isForest;
390dd8e54a2SToby Isaac   PetscErrorCode ierr;
391dd8e54a2SToby Isaac 
392dd8e54a2SToby Isaac   PetscFunctionBegin;
393dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
394ba936b91SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
395456cc5b7SMatthew G. Knepley   ierr = DMIsForest(dm, &isForest);CHKERRQ(ierr);
396456cc5b7SMatthew G. Knepley   if (!isForest) PetscFunctionReturn(0);
397ba936b91SToby Isaac   forest   = (DM_Forest*) dm->data;
398dffe73a3SToby Isaac   ierr     = DMForestGetAdaptivityForest(dm,&oldAdapt);CHKERRQ(ierr);
399dffe73a3SToby Isaac   if (adapt != NULL && dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
400193eb951SToby Isaac   adaptForest    = (DM_Forest*) (adapt ? adapt->data : NULL);
401193eb951SToby Isaac   oldAdaptForest = (DM_Forest*) (oldAdapt ? oldAdapt->data : NULL);
402dffe73a3SToby Isaac   if (adaptForest != oldAdaptForest) {
403dffe73a3SToby Isaac     ierr = PetscSFDestroy(&forest->preCoarseToFine);CHKERRQ(ierr);
404dffe73a3SToby Isaac     ierr = PetscSFDestroy(&forest->coarseToPreFine);CHKERRQ(ierr);
405dffe73a3SToby Isaac     if (forest->clearadaptivityforest) {ierr = (forest->clearadaptivityforest)(dm);CHKERRQ(ierr);}
406dffe73a3SToby Isaac   }
40726d9498aSToby Isaac   switch (forest->adaptPurpose) {
408cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
409ba936b91SToby Isaac     ierr          = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
410ba936b91SToby Isaac     ierr          = DMDestroy(&(forest->adapt));CHKERRQ(ierr);
411ba936b91SToby Isaac     forest->adapt = adapt;
41226d9498aSToby Isaac     break;
413a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
41426d9498aSToby Isaac     ierr = DMSetCoarseDM(dm,adapt);CHKERRQ(ierr);
41526d9498aSToby Isaac     break;
416a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
41726d9498aSToby Isaac     ierr = DMSetFineDM(dm,adapt);CHKERRQ(ierr);
41826d9498aSToby Isaac     break;
41926d9498aSToby Isaac   default:
42026d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
42126d9498aSToby Isaac   }
422dd8e54a2SToby Isaac   PetscFunctionReturn(0);
423dd8e54a2SToby Isaac }
424dd8e54a2SToby Isaac 
4259be51f97SToby Isaac /*@
4269be51f97SToby Isaac   DMForestGetAdaptivityForest - Get the forest from which the current forest is adapted.
4279be51f97SToby Isaac 
4289be51f97SToby Isaac   Not collective
4299be51f97SToby Isaac 
4309be51f97SToby Isaac   Input Parameter:
4319be51f97SToby Isaac . dm - the forest
4329be51f97SToby Isaac 
4339be51f97SToby Isaac   Output Parameter:
4349be51f97SToby Isaac . adapt - the forest from which dm is/was adapted
4359be51f97SToby Isaac 
4369be51f97SToby Isaac   Level: intermediate
4379be51f97SToby Isaac 
4389be51f97SToby Isaac .seealso: DMForestSetAdaptivityForest(), DMForestSetAdaptivityPurpose()
4399be51f97SToby Isaac @*/
440ba936b91SToby Isaac PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt)
441dd8e54a2SToby Isaac {
442ba936b91SToby Isaac   DM_Forest      *forest;
44326d9498aSToby Isaac   PetscErrorCode ierr;
444dd8e54a2SToby Isaac 
445dd8e54a2SToby Isaac   PetscFunctionBegin;
446dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
447ba936b91SToby Isaac   forest = (DM_Forest*) dm->data;
44826d9498aSToby Isaac   switch (forest->adaptPurpose) {
449cd3c525cSToby Isaac   case DM_ADAPT_DETERMINE:
450ba936b91SToby Isaac     *adapt = forest->adapt;
45126d9498aSToby Isaac     break;
452a1b0c543SToby Isaac   case DM_ADAPT_REFINE:
45326d9498aSToby Isaac     ierr = DMGetCoarseDM(dm,adapt);CHKERRQ(ierr);
45426d9498aSToby Isaac     break;
455a1b0c543SToby Isaac   case DM_ADAPT_COARSEN:
45626d9498aSToby Isaac     ierr = DMGetFineDM(dm,adapt);CHKERRQ(ierr);
45726d9498aSToby Isaac     break;
45826d9498aSToby Isaac   default:
45926d9498aSToby Isaac     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
46026d9498aSToby Isaac   }
46126d9498aSToby Isaac   PetscFunctionReturn(0);
46226d9498aSToby Isaac }
46326d9498aSToby Isaac 
4649be51f97SToby Isaac /*@
4659be51f97SToby Isaac   DMForestSetAdaptivityPurpose - During the pre-setup phase, set whether the current DM is being adapted from its
466a1b0c543SToby Isaac   source (set with DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening
467cd3c525cSToby Isaac   (DM_ADAPT_COARSEN), or undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting:
4689be51f97SToby Isaac   during DMDestroy(), cyclic references can be found between DMs only if the cyclic reference is due to a fine/coarse
4699be51f97SToby Isaac   relationship (see DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does
4709be51f97SToby Isaac   not maintain a reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can
4719be51f97SToby Isaac   cause a memory leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
4729be51f97SToby Isaac 
4739be51f97SToby Isaac   Logically collective on dm
4749be51f97SToby Isaac 
4759be51f97SToby Isaac   Input Parameters:
4769be51f97SToby Isaac + dm - the forest
477cd3c525cSToby Isaac - purpose - the adaptivity purpose (DM_ADAPT_DETERMINE/DM_ADAPT_REFINE/DM_ADAPT_COARSEN)
4789be51f97SToby Isaac 
4799be51f97SToby Isaac   Level: advanced
4809be51f97SToby Isaac 
4819be51f97SToby Isaac .seealso: DMForestTemplate(), DMForestSetAdaptivityForest(), DMForestGetAdaptivityForest()
4829be51f97SToby Isaac @*/
483a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMAdaptFlag purpose)
48426d9498aSToby Isaac {
48526d9498aSToby Isaac   DM_Forest      *forest;
48626d9498aSToby Isaac   PetscErrorCode ierr;
48726d9498aSToby Isaac 
48826d9498aSToby Isaac   PetscFunctionBegin;
48926d9498aSToby Isaac   forest = (DM_Forest*) dm->data;
4909be51f97SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
49126d9498aSToby Isaac   if (purpose != forest->adaptPurpose) {
49226d9498aSToby Isaac     DM adapt;
49326d9498aSToby Isaac 
49426d9498aSToby Isaac     ierr = DMForestGetAdaptivityForest(dm,&adapt);CHKERRQ(ierr);
49526d9498aSToby Isaac     ierr = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
49626d9498aSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
497f885a11aSToby Isaac 
49826d9498aSToby Isaac     forest->adaptPurpose = purpose;
499f885a11aSToby Isaac 
50026d9498aSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,adapt);CHKERRQ(ierr);
50126d9498aSToby Isaac     ierr = DMDestroy(&adapt);CHKERRQ(ierr);
50226d9498aSToby Isaac   }
503dd8e54a2SToby Isaac   PetscFunctionReturn(0);
504dd8e54a2SToby Isaac }
505dd8e54a2SToby Isaac 
50656c0450aSToby Isaac /*@
50756c0450aSToby Isaac   DMForestGetAdaptivityPurpose - Get whether the current DM is being adapted from its source (set with
508a1b0c543SToby Isaac   DMForestSetAdaptivityForest()) for the purpose of refinement (DM_ADAPT_REFINE), coarsening (DM_ADAPT_COARSEN), or
509cd3c525cSToby Isaac   undefined (DM_ADAPT_DETERMINE).  This only matters for the purposes of reference counting: during DMDestroy(), cyclic
51056c0450aSToby Isaac   references can be found between DMs only if the cyclic reference is due to a fine/coarse relationship (see
51156c0450aSToby Isaac   DMSetFineDM()/DMSetCoarseDM()).  If the purpose is not refinement or coarsening, and the user does not maintain a
51256c0450aSToby Isaac   reference to the post-adaptation forest (i.e., the one created by DMForestTemplate()), then this can cause a memory
51356c0450aSToby Isaac   leak.  This method is used by subtypes of DMForest when automatically constructing mesh hierarchies.
51456c0450aSToby Isaac 
51556c0450aSToby Isaac   Not collective
51656c0450aSToby Isaac 
51756c0450aSToby Isaac   Input Parameter:
51856c0450aSToby Isaac . dm - the forest
51956c0450aSToby Isaac 
52056c0450aSToby Isaac   Output Parameter:
521cd3c525cSToby Isaac . purpose - the adaptivity purpose (DM_ADAPT_DETERMINE/DM_ADAPT_REFINE/DM_ADAPT_COARSEN)
52256c0450aSToby Isaac 
52356c0450aSToby Isaac   Level: advanced
52456c0450aSToby Isaac 
52556c0450aSToby Isaac .seealso: DMForestTemplate(), DMForestSetAdaptivityForest(), DMForestGetAdaptivityForest()
52656c0450aSToby Isaac @*/
527a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityPurpose(DM dm, DMAdaptFlag *purpose)
52856c0450aSToby Isaac {
52956c0450aSToby Isaac   DM_Forest *forest;
53056c0450aSToby Isaac 
53156c0450aSToby Isaac   PetscFunctionBegin;
53256c0450aSToby Isaac   forest   = (DM_Forest*) dm->data;
53356c0450aSToby Isaac   *purpose = forest->adaptPurpose;
53456c0450aSToby Isaac   PetscFunctionReturn(0);
53556c0450aSToby Isaac }
53656c0450aSToby Isaac 
5379be51f97SToby Isaac /*@
5389be51f97SToby Isaac   DMForestSetAdjacencyDimension - During the pre-setup phase, set the dimension of interface points that determine
5399be51f97SToby Isaac   cell adjacency (for the purposes of partitioning and overlap).
5409be51f97SToby Isaac 
5419be51f97SToby Isaac   Logically collective on dm
5429be51f97SToby Isaac 
5439be51f97SToby Isaac   Input Parameters:
5449be51f97SToby Isaac + dm - the forest
5459be51f97SToby Isaac - adjDim - default 0 (i.e., vertices determine adjacency)
5469be51f97SToby Isaac 
5479be51f97SToby Isaac   Level: intermediate
5489be51f97SToby Isaac 
5499be51f97SToby Isaac .seealso: DMForestGetAdjacencyDimension(), DMForestSetAdjacencyCodimension(), DMForestSetPartitionOverlap()
5509be51f97SToby Isaac @*/
551dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim)
552dd8e54a2SToby Isaac {
553dd8e54a2SToby Isaac   PetscInt       dim;
554dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
555dd8e54a2SToby Isaac   PetscErrorCode ierr;
556dd8e54a2SToby Isaac 
557dd8e54a2SToby Isaac   PetscFunctionBegin;
558dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
559ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup");
560dd8e54a2SToby Isaac   if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim);
561dd8e54a2SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
562dd8e54a2SToby Isaac   if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim);
563dd8e54a2SToby Isaac   forest->adjDim = adjDim;
564dd8e54a2SToby Isaac   PetscFunctionReturn(0);
565dd8e54a2SToby Isaac }
566dd8e54a2SToby Isaac 
5679be51f97SToby Isaac /*@
5689be51f97SToby Isaac   DMForestSetAdjacencyCodimension - Like DMForestSetAdjacencyDimension(), but specified as a co-dimension (so that,
5699be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
5709be51f97SToby Isaac 
5719be51f97SToby Isaac   Logically collective on dm
5729be51f97SToby Isaac 
5739be51f97SToby Isaac   Input Parameters:
5749be51f97SToby Isaac + dm - the forest
5759be51f97SToby Isaac - adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
5769be51f97SToby Isaac 
5779be51f97SToby Isaac   Level: intermediate
5789be51f97SToby Isaac 
5799be51f97SToby Isaac .seealso: DMForestGetAdjacencyCodimension(), DMForestSetAdjacencyDimension()
5809be51f97SToby Isaac @*/
581dd8e54a2SToby Isaac PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim)
582dd8e54a2SToby Isaac {
583dd8e54a2SToby Isaac   PetscInt       dim;
584dd8e54a2SToby Isaac   PetscErrorCode ierr;
585dd8e54a2SToby Isaac 
586dd8e54a2SToby Isaac   PetscFunctionBegin;
587dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
588dd8e54a2SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
589dd8e54a2SToby Isaac   ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr);
590dd8e54a2SToby Isaac   PetscFunctionReturn(0);
591dd8e54a2SToby Isaac }
592dd8e54a2SToby Isaac 
5939be51f97SToby Isaac /*@
5949be51f97SToby Isaac   DMForestGetAdjacencyDimension - Get the dimension of interface points that determine cell adjacency (for the
5959be51f97SToby Isaac   purposes of partitioning and overlap).
5969be51f97SToby Isaac 
5979be51f97SToby Isaac   Not collective
5989be51f97SToby Isaac 
5999be51f97SToby Isaac   Input Parameter:
6009be51f97SToby Isaac . dm - the forest
6019be51f97SToby Isaac 
6029be51f97SToby Isaac   Output Parameter:
6039be51f97SToby Isaac . adjDim - default 0 (i.e., vertices determine adjacency)
6049be51f97SToby Isaac 
6059be51f97SToby Isaac   Level: intermediate
6069be51f97SToby Isaac 
6079be51f97SToby Isaac .seealso: DMForestSetAdjacencyDimension(), DMForestGetAdjacencyCodimension(), DMForestSetPartitionOverlap()
6089be51f97SToby Isaac @*/
609dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim)
610dd8e54a2SToby Isaac {
611dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
612dd8e54a2SToby Isaac 
613dd8e54a2SToby Isaac   PetscFunctionBegin;
614dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
615dd8e54a2SToby Isaac   PetscValidIntPointer(adjDim,2);
616dd8e54a2SToby Isaac   *adjDim = forest->adjDim;
617dd8e54a2SToby Isaac   PetscFunctionReturn(0);
618dd8e54a2SToby Isaac }
619dd8e54a2SToby Isaac 
6209be51f97SToby Isaac /*@
6219be51f97SToby Isaac   DMForestGetAdjacencyCodimension - Like DMForestGetAdjacencyDimension(), but specified as a co-dimension (so that,
6229be51f97SToby Isaac   e.g., adjacency based on facets can be specified by codimension 1 in all cases)
6239be51f97SToby Isaac 
6249be51f97SToby Isaac   Not collective
6259be51f97SToby Isaac 
6269be51f97SToby Isaac   Input Parameter:
6279be51f97SToby Isaac . dm - the forest
6289be51f97SToby Isaac 
6299be51f97SToby Isaac   Output Parameter:
6309be51f97SToby Isaac . adjCodim - default isthe dimension of the forest (see DMGetDimension()), since this is the codimension of vertices
6319be51f97SToby Isaac 
6329be51f97SToby Isaac   Level: intermediate
6339be51f97SToby Isaac 
6349be51f97SToby Isaac .seealso: DMForestSetAdjacencyCodimension(), DMForestGetAdjacencyDimension()
6359be51f97SToby Isaac @*/
636dd8e54a2SToby Isaac PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim)
637dd8e54a2SToby Isaac {
638dd8e54a2SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
639dd8e54a2SToby Isaac   PetscInt       dim;
640dd8e54a2SToby Isaac   PetscErrorCode ierr;
641dd8e54a2SToby Isaac 
642dd8e54a2SToby Isaac   PetscFunctionBegin;
643dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
644dd8e54a2SToby Isaac   PetscValidIntPointer(adjCodim,2);
645dd8e54a2SToby Isaac   ierr      = DMGetDimension(dm,&dim);CHKERRQ(ierr);
646dd8e54a2SToby Isaac   *adjCodim = dim - forest->adjDim;
647dd8e54a2SToby Isaac   PetscFunctionReturn(0);
648dd8e54a2SToby Isaac }
649dd8e54a2SToby Isaac 
6509be51f97SToby Isaac /*@
6519be51f97SToby Isaac   DMForestSetPartitionOverlap - During the pre-setup phase, set the amount of cell-overlap present in parallel
6529be51f97SToby Isaac   partitions of a forest, with values > 0 indicating subdomains that are expanded by that many iterations of adding
6539be51f97SToby Isaac   adjacent cells
6549be51f97SToby Isaac 
6559be51f97SToby Isaac   Logically collective on dm
6569be51f97SToby Isaac 
6579be51f97SToby Isaac   Input Parameters:
6589be51f97SToby Isaac + dm - the forest
6599be51f97SToby Isaac - overlap - default 0
6609be51f97SToby Isaac 
6619be51f97SToby Isaac   Level: intermediate
6629be51f97SToby Isaac 
6639be51f97SToby Isaac .seealso: DMForestGetPartitionOverlap(), DMForestSetAdjacencyDimension(), DMForestSetAdjacencyCodimension()
6649be51f97SToby Isaac @*/
665dd8e54a2SToby Isaac PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap)
666dd8e54a2SToby Isaac {
667dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
668dd8e54a2SToby Isaac 
669dd8e54a2SToby Isaac   PetscFunctionBegin;
670dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
671ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup");
672dd8e54a2SToby Isaac   if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap);
673dd8e54a2SToby Isaac   forest->overlap = overlap;
674dd8e54a2SToby Isaac   PetscFunctionReturn(0);
675dd8e54a2SToby Isaac }
676dd8e54a2SToby Isaac 
6779be51f97SToby Isaac /*@
6789be51f97SToby Isaac   DMForestGetPartitionOverlap - Get the amount of cell-overlap present in parallel partitions of a forest, with values
6799be51f97SToby Isaac   > 0 indicating subdomains that are expanded by that many iterations of adding adjacent cells
6809be51f97SToby Isaac 
6819be51f97SToby Isaac   Not collective
6829be51f97SToby Isaac 
6839be51f97SToby Isaac   Input Parameter:
6849be51f97SToby Isaac . dm - the forest
6859be51f97SToby Isaac 
6869be51f97SToby Isaac   Output Parameter:
6879be51f97SToby Isaac . overlap - default 0
6889be51f97SToby Isaac 
6899be51f97SToby Isaac   Level: intermediate
6909be51f97SToby Isaac 
6919be51f97SToby Isaac .seealso: DMForestGetPartitionOverlap(), DMForestSetAdjacencyDimension(), DMForestSetAdjacencyCodimension()
6929be51f97SToby Isaac @*/
693dd8e54a2SToby Isaac PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap)
694dd8e54a2SToby Isaac {
695dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
696dd8e54a2SToby Isaac 
697dd8e54a2SToby Isaac   PetscFunctionBegin;
698dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
699dd8e54a2SToby Isaac   PetscValidIntPointer(overlap,2);
700dd8e54a2SToby Isaac   *overlap = forest->overlap;
701dd8e54a2SToby Isaac   PetscFunctionReturn(0);
702dd8e54a2SToby Isaac }
703dd8e54a2SToby Isaac 
7049be51f97SToby Isaac /*@
7059be51f97SToby Isaac   DMForestSetMinimumRefinement - During the pre-setup phase, set the minimum level of refinement (relative to the base
7069be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest
7079be51f97SToby Isaac   (see DMForestGetAdaptivityForest()) this limits the amount of coarsening.
7089be51f97SToby Isaac 
7099be51f97SToby Isaac   Logically collective on dm
7109be51f97SToby Isaac 
7119be51f97SToby Isaac   Input Parameters:
7129be51f97SToby Isaac + dm - the forest
7139be51f97SToby Isaac - minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7149be51f97SToby Isaac 
7159be51f97SToby Isaac   Level: intermediate
7169be51f97SToby Isaac 
7179be51f97SToby Isaac .seealso: DMForestGetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestSetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityForest()
7189be51f97SToby Isaac @*/
719dd8e54a2SToby Isaac PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement)
720dd8e54a2SToby Isaac {
721dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
722dd8e54a2SToby Isaac 
723dd8e54a2SToby Isaac   PetscFunctionBegin;
724dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
725ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup");
726dd8e54a2SToby Isaac   forest->minRefinement = minRefinement;
727dd8e54a2SToby Isaac   PetscFunctionReturn(0);
728dd8e54a2SToby Isaac }
729dd8e54a2SToby Isaac 
7309be51f97SToby Isaac /*@
7319be51f97SToby Isaac   DMForestGetMinimumRefinement - Get the minimum level of refinement (relative to the base DM, see
7329be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by coarsening a previous forest (see
7339be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of coarsening.
7349be51f97SToby Isaac 
7359be51f97SToby Isaac   Not collective
7369be51f97SToby Isaac 
7379be51f97SToby Isaac   Input Parameter:
7389be51f97SToby Isaac . dm - the forest
7399be51f97SToby Isaac 
7409be51f97SToby Isaac   Output Parameter:
7419be51f97SToby Isaac . minRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7429be51f97SToby Isaac 
7439be51f97SToby Isaac   Level: intermediate
7449be51f97SToby Isaac 
7459be51f97SToby Isaac .seealso: DMForestSetMinimumRefinement(), DMForestGetMaximumRefinement(), DMForestGetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityForest()
7469be51f97SToby Isaac @*/
747dd8e54a2SToby Isaac PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement)
748dd8e54a2SToby Isaac {
749dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
750dd8e54a2SToby Isaac 
751dd8e54a2SToby Isaac   PetscFunctionBegin;
752dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
753dd8e54a2SToby Isaac   PetscValidIntPointer(minRefinement,2);
754dd8e54a2SToby Isaac   *minRefinement = forest->minRefinement;
755dd8e54a2SToby Isaac   PetscFunctionReturn(0);
756dd8e54a2SToby Isaac }
757dd8e54a2SToby Isaac 
7589be51f97SToby Isaac /*@
7599be51f97SToby Isaac   DMForestSetInitialRefinement - During the pre-setup phase, set the initial level of refinement (relative to the base
7609be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.
7619be51f97SToby Isaac 
7629be51f97SToby Isaac   Logically collective on dm
7639be51f97SToby Isaac 
7649be51f97SToby Isaac   Input Parameters:
7659be51f97SToby Isaac + dm - the forest
7669be51f97SToby Isaac - initefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7679be51f97SToby Isaac 
7689be51f97SToby Isaac   Level: intermediate
7699be51f97SToby Isaac 
7709be51f97SToby Isaac .seealso: DMForestSetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestGetBaseDM()
7719be51f97SToby Isaac @*/
77256ba9f64SToby Isaac PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement)
77356ba9f64SToby Isaac {
77456ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
77556ba9f64SToby Isaac 
77656ba9f64SToby Isaac   PetscFunctionBegin;
77756ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
77856ba9f64SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the initial refinement after setup");
77956ba9f64SToby Isaac   forest->initRefinement = initRefinement;
78056ba9f64SToby Isaac   PetscFunctionReturn(0);
78156ba9f64SToby Isaac }
78256ba9f64SToby Isaac 
7839be51f97SToby Isaac /*@
7849be51f97SToby Isaac   DMForestGetInitialRefinement - Get the initial level of refinement (relative to the base DM, see
7859be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.
7869be51f97SToby Isaac 
7879be51f97SToby Isaac   Not collective
7889be51f97SToby Isaac 
7899be51f97SToby Isaac   Input Parameter:
7909be51f97SToby Isaac . dm - the forest
7919be51f97SToby Isaac 
7929be51f97SToby Isaac   Output Paramater:
7939be51f97SToby Isaac . initefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
7949be51f97SToby Isaac 
7959be51f97SToby Isaac   Level: intermediate
7969be51f97SToby Isaac 
7979be51f97SToby Isaac .seealso: DMForestSetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestGetBaseDM()
7989be51f97SToby Isaac @*/
79956ba9f64SToby Isaac PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement)
80056ba9f64SToby Isaac {
80156ba9f64SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
80256ba9f64SToby Isaac 
80356ba9f64SToby Isaac   PetscFunctionBegin;
80456ba9f64SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
80556ba9f64SToby Isaac   PetscValidIntPointer(initRefinement,2);
80656ba9f64SToby Isaac   *initRefinement = forest->initRefinement;
80756ba9f64SToby Isaac   PetscFunctionReturn(0);
80856ba9f64SToby Isaac }
80956ba9f64SToby Isaac 
8109be51f97SToby Isaac /*@
8119be51f97SToby Isaac   DMForestSetMaximumRefinement - During the pre-setup phase, set the maximum level of refinement (relative to the base
8129be51f97SToby Isaac   DM, see DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest
8139be51f97SToby Isaac   (see DMForestGetAdaptivityForest()), this limits the amount of refinement.
8149be51f97SToby Isaac 
8159be51f97SToby Isaac   Logically collective on dm
8169be51f97SToby Isaac 
8179be51f97SToby Isaac   Input Parameters:
8189be51f97SToby Isaac + dm - the forest
8199be51f97SToby Isaac - maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
8209be51f97SToby Isaac 
8219be51f97SToby Isaac   Level: intermediate
8229be51f97SToby Isaac 
8239be51f97SToby Isaac .seealso: DMForestGetMinimumRefinement(), DMForestSetMaximumRefinement(), DMForestSetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityDM()
8249be51f97SToby Isaac @*/
825c7eeac06SToby Isaac PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement)
826dd8e54a2SToby Isaac {
827dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
828dd8e54a2SToby Isaac 
829dd8e54a2SToby Isaac   PetscFunctionBegin;
830dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
831ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup");
832c7eeac06SToby Isaac   forest->maxRefinement = maxRefinement;
833dd8e54a2SToby Isaac   PetscFunctionReturn(0);
834dd8e54a2SToby Isaac }
835dd8e54a2SToby Isaac 
8369be51f97SToby Isaac /*@
8379be51f97SToby Isaac   DMForestGetMaximumRefinement - Get the maximum level of refinement (relative to the base DM, see
8389be51f97SToby Isaac   DMForestGetBaseDM()) allowed in the forest.  If the forest is being created by refining a previous forest (see
8399be51f97SToby Isaac   DMForestGetAdaptivityForest()), this limits the amount of refinement.
8409be51f97SToby Isaac 
8419be51f97SToby Isaac   Not collective
8429be51f97SToby Isaac 
8439be51f97SToby Isaac   Input Parameter:
8449be51f97SToby Isaac . dm - the forest
8459be51f97SToby Isaac 
8469be51f97SToby Isaac   Output Parameter:
8479be51f97SToby Isaac . maxRefinement - default PETSC_DEFAULT (interpreted by the subtype of DMForest)
8489be51f97SToby Isaac 
8499be51f97SToby Isaac   Level: intermediate
8509be51f97SToby Isaac 
8519be51f97SToby Isaac .seealso: DMForestSetMaximumRefinement(), DMForestGetMinimumRefinement(), DMForestGetInitialRefinement(), DMForestGetBaseDM(), DMForestGetAdaptivityForest()
8529be51f97SToby Isaac @*/
853c7eeac06SToby Isaac PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement)
854dd8e54a2SToby Isaac {
855dd8e54a2SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
856dd8e54a2SToby Isaac 
857dd8e54a2SToby Isaac   PetscFunctionBegin;
858dd8e54a2SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
859c7eeac06SToby Isaac   PetscValidIntPointer(maxRefinement,2);
860c7eeac06SToby Isaac   *maxRefinement = forest->maxRefinement;
861dd8e54a2SToby Isaac   PetscFunctionReturn(0);
862dd8e54a2SToby Isaac }
863c7eeac06SToby Isaac 
8649be51f97SToby Isaac /*@C
8659be51f97SToby Isaac   DMForestSetAdaptivityStrategy - During the pre-setup phase, set the strategy for combining adaptivity labels from multiple processes.
8669be51f97SToby Isaac   Subtypes of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all processes must agree
8679be51f97SToby Isaac   for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only one process needs to
8689be51f97SToby Isaac   specify refinement/coarsening.
8699be51f97SToby Isaac 
8709be51f97SToby Isaac   Logically collective on dm
8719be51f97SToby Isaac 
8729be51f97SToby Isaac   Input Parameters:
8739be51f97SToby Isaac + dm - the forest
8749be51f97SToby Isaac - adaptStrategy - default DMFORESTADAPTALL
8759be51f97SToby Isaac 
8769be51f97SToby Isaac   Level: advanced
8779be51f97SToby Isaac 
8789be51f97SToby Isaac .seealso: DMForestGetAdaptivityStrategy()
8799be51f97SToby Isaac @*/
880c7eeac06SToby Isaac PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy)
881c7eeac06SToby Isaac {
882c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
883c7eeac06SToby Isaac   PetscErrorCode ierr;
884c7eeac06SToby Isaac 
885c7eeac06SToby Isaac   PetscFunctionBegin;
886c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
887c7eeac06SToby Isaac   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
888a73e2921SToby Isaac   ierr = PetscStrallocpy((const char*) adaptStrategy,(char**)&forest->adaptStrategy);CHKERRQ(ierr);
889c7eeac06SToby Isaac   PetscFunctionReturn(0);
890c7eeac06SToby Isaac }
891c7eeac06SToby Isaac 
8929be51f97SToby Isaac /*@C
8939be51f97SToby Isaac   DMForestSetAdaptivityStrategy - Get the strategy for combining adaptivity labels from multiple processes.  Subtypes
8949be51f97SToby Isaac   of DMForest may define their own strategies.  Two default strategies are DMFORESTADAPTALL, which indicates that all
8959be51f97SToby Isaac   processes must agree for a refinement/coarsening flag to be valid, and DMFORESTADAPTANY, which indicates that only
8969be51f97SToby Isaac   one process needs to specify refinement/coarsening.
8979be51f97SToby Isaac 
8989be51f97SToby Isaac   Not collective
8999be51f97SToby Isaac 
9009be51f97SToby Isaac   Input Parameter:
9019be51f97SToby Isaac . dm - the forest
9029be51f97SToby Isaac 
9039be51f97SToby Isaac   Output Parameter:
9049be51f97SToby Isaac . adaptStrategy - the adaptivity strategy (default DMFORESTADAPTALL)
9059be51f97SToby Isaac 
9069be51f97SToby Isaac   Level: advanced
9079be51f97SToby Isaac 
9089be51f97SToby Isaac .seealso: DMForestSetAdaptivityStrategy()
9099be51f97SToby Isaac @*/
910c7eeac06SToby Isaac PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy)
911c7eeac06SToby Isaac {
912c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
913c7eeac06SToby Isaac 
914c7eeac06SToby Isaac   PetscFunctionBegin;
915c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
916c7eeac06SToby Isaac   PetscValidPointer(adaptStrategy,2);
917c7eeac06SToby Isaac   *adaptStrategy = forest->adaptStrategy;
918c7eeac06SToby Isaac   PetscFunctionReturn(0);
919c7eeac06SToby Isaac }
920c7eeac06SToby Isaac 
9212a133e43SToby Isaac /*@
9222a133e43SToby Isaac   DMForestGetAdaptivitySuccess - Return whether the requested adaptation (refinement, coarsening, repartitioning,
9232a133e43SToby Isaac   etc.) was successful.  PETSC_FALSE indicates that the post-adaptation forest is the same as the pre-adpatation
9242a133e43SToby Isaac   forest.  A requested adaptation may have been unsuccessful if, for example, the requested refinement would have
9252a133e43SToby Isaac   exceeded the maximum refinement level.
9262a133e43SToby Isaac 
9272a133e43SToby Isaac   Collective on dm
9282a133e43SToby Isaac 
9292a133e43SToby Isaac   Input Parameter:
9302a133e43SToby Isaac 
9312a133e43SToby Isaac . dm - the post-adaptation forest
9322a133e43SToby Isaac 
9332a133e43SToby Isaac   Output Parameter:
9342a133e43SToby Isaac 
9352a133e43SToby Isaac . success - PETSC_TRUE if the post-adaptation forest is different from the pre-adaptation forest.
9362a133e43SToby Isaac 
9372a133e43SToby Isaac   Level: intermediate
9382a133e43SToby Isaac 
9392a133e43SToby Isaac .see
9402a133e43SToby Isaac @*/
9412a133e43SToby Isaac PetscErrorCode DMForestGetAdaptivitySuccess(DM dm, PetscBool *success)
9422a133e43SToby Isaac {
9432a133e43SToby Isaac   DM_Forest      *forest;
9442a133e43SToby Isaac   PetscErrorCode ierr;
9452a133e43SToby Isaac 
9462a133e43SToby Isaac   PetscFunctionBegin;
9472a133e43SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
9482a133e43SToby Isaac   if (!dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() has not been called yet.");
9492a133e43SToby Isaac   forest = (DM_Forest *) dm->data;
9502a133e43SToby Isaac   ierr = (forest->getadaptivitysuccess)(dm,success);CHKERRQ(ierr);
9512a133e43SToby Isaac   PetscFunctionReturn(0);
9522a133e43SToby Isaac }
9532a133e43SToby Isaac 
954bf9b5d84SToby Isaac /*@
955bf9b5d84SToby Isaac   DMForestSetComputeAdaptivitySF - During the pre-setup phase, set whether transfer PetscSFs should be computed
956bf9b5d84SToby 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().
957bf9b5d84SToby Isaac 
958bf9b5d84SToby Isaac   Logically collective on dm
959bf9b5d84SToby Isaac 
960bf9b5d84SToby Isaac   Input Parameters:
961bf9b5d84SToby Isaac + dm - the post-adaptation forest
962bf9b5d84SToby Isaac - computeSF - default PETSC_TRUE
963bf9b5d84SToby Isaac 
964bf9b5d84SToby Isaac   Level: advanced
965bf9b5d84SToby Isaac 
966bf9b5d84SToby Isaac .seealso: DMForestGetComputeAdaptivitySF(), DMForestGetAdaptivitySF()
967bf9b5d84SToby Isaac @*/
968bf9b5d84SToby Isaac PetscErrorCode DMForestSetComputeAdaptivitySF(DM dm, PetscBool computeSF)
969bf9b5d84SToby Isaac {
970bf9b5d84SToby Isaac   DM_Forest *forest;
971bf9b5d84SToby Isaac 
972bf9b5d84SToby Isaac   PetscFunctionBegin;
973bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
974bf9b5d84SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot compute adaptivity PetscSFs after setup is called");
975bf9b5d84SToby Isaac   forest                 = (DM_Forest*) dm->data;
976bf9b5d84SToby Isaac   forest->computeAdaptSF = computeSF;
977bf9b5d84SToby Isaac   PetscFunctionReturn(0);
978bf9b5d84SToby Isaac }
979bf9b5d84SToby Isaac 
9800eb7e1eaSToby Isaac PetscErrorCode DMForestTransferVec(DM dmIn, Vec vecIn, DM dmOut, Vec vecOut, PetscBool useBCs, PetscReal time)
98180b27e07SToby Isaac {
98280b27e07SToby Isaac   DM_Forest      *forest;
98380b27e07SToby Isaac   PetscErrorCode ierr;
98480b27e07SToby Isaac 
98580b27e07SToby Isaac   PetscFunctionBegin;
98680b27e07SToby Isaac   PetscValidHeaderSpecific(dmIn   ,DM_CLASSID  ,1);
98780b27e07SToby Isaac   PetscValidHeaderSpecific(vecIn  ,VEC_CLASSID ,2);
98880b27e07SToby Isaac   PetscValidHeaderSpecific(dmOut  ,DM_CLASSID  ,3);
98980b27e07SToby Isaac   PetscValidHeaderSpecific(vecOut ,VEC_CLASSID ,4);
99080b27e07SToby Isaac   forest = (DM_Forest *) dmIn->data;
99180b27e07SToby Isaac   if (!forest->transfervec) SETERRQ(PetscObjectComm((PetscObject)dmIn),PETSC_ERR_SUP,"DMForestTransferVec() not implemented");
9920eb7e1eaSToby Isaac   ierr = (forest->transfervec)(dmIn,vecIn,dmOut,vecOut,useBCs,time);CHKERRQ(ierr);
99380b27e07SToby Isaac   PetscFunctionReturn(0);
99480b27e07SToby Isaac }
99580b27e07SToby Isaac 
996bf9b5d84SToby Isaac /*@
997bf9b5d84SToby Isaac   DMForestGetComputeAdaptivitySF - Get whether transfer PetscSFs should be computed relating the cells of the
998bf9b5d84SToby Isaac   pre-adaptation forest to the post-adaptiation forest.  After DMSetUp() is called, these transfer PetscSFs can be
999bf9b5d84SToby Isaac   accessed with DMForestGetAdaptivitySF().
1000bf9b5d84SToby Isaac 
1001bf9b5d84SToby Isaac   Not collective
1002bf9b5d84SToby Isaac 
1003bf9b5d84SToby Isaac   Input Parameter:
1004bf9b5d84SToby Isaac . dm - the post-adaptation forest
1005bf9b5d84SToby Isaac 
1006bf9b5d84SToby Isaac   Output Parameter:
1007bf9b5d84SToby Isaac . computeSF - default PETSC_TRUE
1008bf9b5d84SToby Isaac 
1009bf9b5d84SToby Isaac   Level: advanced
1010bf9b5d84SToby Isaac 
1011bf9b5d84SToby Isaac .seealso: DMForestSetComputeAdaptivitySF(), DMForestGetAdaptivitySF()
1012bf9b5d84SToby Isaac @*/
1013bf9b5d84SToby Isaac PetscErrorCode DMForestGetComputeAdaptivitySF(DM dm, PetscBool *computeSF)
1014bf9b5d84SToby Isaac {
1015bf9b5d84SToby Isaac   DM_Forest *forest;
1016bf9b5d84SToby Isaac 
1017bf9b5d84SToby Isaac   PetscFunctionBegin;
1018bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1019bf9b5d84SToby Isaac   forest     = (DM_Forest*) dm->data;
1020bf9b5d84SToby Isaac   *computeSF = forest->computeAdaptSF;
1021bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1022bf9b5d84SToby Isaac }
1023bf9b5d84SToby Isaac 
1024bf9b5d84SToby Isaac /*@
1025bf9b5d84SToby Isaac   DMForestGetAdaptivitySF - Get PetscSFs that relate the pre-adaptation forest to the post-adaptation forest.
1026bf9b5d84SToby Isaac   Adaptation can be any combination of refinement, coarsening, repartition, and change of overlap, so there may be
1027bf9b5d84SToby Isaac   some cells of the pre-adaptation that are parents of post-adaptation cells, and vice versa.  Therefore there are two
1028bf9b5d84SToby Isaac   PetscSFs: one that relates pre-adaptation coarse cells to post-adaptation fine cells, and one that relates
1029bf9b5d84SToby Isaac   pre-adaptation fine cells to post-adaptation coarse cells.
1030bf9b5d84SToby Isaac 
1031bf9b5d84SToby Isaac   Not collective
1032bf9b5d84SToby Isaac 
1033bf9b5d84SToby Isaac   Input Parameter:
1034bf9b5d84SToby Isaac   dm - the post-adaptation forest
1035bf9b5d84SToby Isaac 
1036bf9b5d84SToby Isaac   Output Parameter:
10370f17b9e3SToby Isaac   preCoarseToFine - pre-adaptation coarse cells to post-adaptation fine cells: BCast goes from pre- to post-
10380f17b9e3SToby Isaac   coarseToPreFine - post-adaptation coarse cells to pre-adaptation fine cells: BCast goes from post- to pre-
1039bf9b5d84SToby Isaac 
1040bf9b5d84SToby Isaac   Level: advanced
1041bf9b5d84SToby Isaac 
1042bf9b5d84SToby Isaac .seealso: DMForestGetComputeAdaptivitySF(), DMForestSetComputeAdaptivitySF()
1043bf9b5d84SToby Isaac @*/
10440f17b9e3SToby Isaac PetscErrorCode DMForestGetAdaptivitySF(DM dm, PetscSF *preCoarseToFine, PetscSF *coarseToPreFine)
1045bf9b5d84SToby Isaac {
1046bf9b5d84SToby Isaac   DM_Forest      *forest;
1047bf9b5d84SToby Isaac   PetscErrorCode ierr;
1048bf9b5d84SToby Isaac 
1049bf9b5d84SToby Isaac   PetscFunctionBegin;
1050bf9b5d84SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1051bf9b5d84SToby Isaac   ierr   = DMSetUp(dm);CHKERRQ(ierr);
1052bf9b5d84SToby Isaac   forest = (DM_Forest*) dm->data;
1053f885a11aSToby Isaac   if (preCoarseToFine) *preCoarseToFine = forest->preCoarseToFine;
1054f885a11aSToby Isaac   if (coarseToPreFine) *coarseToPreFine = forest->coarseToPreFine;
1055bf9b5d84SToby Isaac   PetscFunctionReturn(0);
1056bf9b5d84SToby Isaac }
1057bf9b5d84SToby Isaac 
10589be51f97SToby Isaac /*@
10599be51f97SToby Isaac   DMForestSetGradeFactor - During the pre-setup phase, set the desired amount of grading in the mesh, e.g. give 2 to
10609be51f97SToby Isaac   indicate that the diameter of neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may
10619be51f97SToby Isaac   only support one particular choice of grading factor.
10629be51f97SToby Isaac 
10639be51f97SToby Isaac   Logically collective on dm
10649be51f97SToby Isaac 
10659be51f97SToby Isaac   Input Parameters:
10669be51f97SToby Isaac + dm - the forest
10679be51f97SToby Isaac - grade - the grading factor
10689be51f97SToby Isaac 
10699be51f97SToby Isaac   Level: advanced
10709be51f97SToby Isaac 
10719be51f97SToby Isaac .seealso: DMForestGetGradeFactor()
10729be51f97SToby Isaac @*/
1073c7eeac06SToby Isaac PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade)
1074c7eeac06SToby Isaac {
1075c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1076c7eeac06SToby Isaac 
1077c7eeac06SToby Isaac   PetscFunctionBegin;
1078c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1079ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup");
1080c7eeac06SToby Isaac   forest->gradeFactor = grade;
1081c7eeac06SToby Isaac   PetscFunctionReturn(0);
1082c7eeac06SToby Isaac }
1083c7eeac06SToby Isaac 
10849be51f97SToby Isaac /*@
10859be51f97SToby Isaac   DMForestGetGradeFactor - Get the desired amount of grading in the mesh, e.g. give 2 to indicate that the diameter of
10869be51f97SToby Isaac   neighboring cells should differ by at most a factor of 2.  Subtypes of DMForest may only support one particular
10879be51f97SToby Isaac   choice of grading factor.
10889be51f97SToby Isaac 
10899be51f97SToby Isaac   Not collective
10909be51f97SToby Isaac 
10919be51f97SToby Isaac   Input Parameter:
10929be51f97SToby Isaac . dm - the forest
10939be51f97SToby Isaac 
10949be51f97SToby Isaac   Output Parameter:
10959be51f97SToby Isaac . grade - the grading factor
10969be51f97SToby Isaac 
10979be51f97SToby Isaac   Level: advanced
10989be51f97SToby Isaac 
10999be51f97SToby Isaac .seealso: DMForestSetGradeFactor()
11009be51f97SToby Isaac @*/
1101c7eeac06SToby Isaac PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade)
1102c7eeac06SToby Isaac {
1103c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1104c7eeac06SToby Isaac 
1105c7eeac06SToby Isaac   PetscFunctionBegin;
1106c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1107c7eeac06SToby Isaac   PetscValidIntPointer(grade,2);
1108c7eeac06SToby Isaac   *grade = forest->gradeFactor;
1109c7eeac06SToby Isaac   PetscFunctionReturn(0);
1110c7eeac06SToby Isaac }
1111c7eeac06SToby Isaac 
11129be51f97SToby Isaac /*@
11139be51f97SToby Isaac   DMForestSetCellWeightFactor - During the pre-setup phase, set the factor by which the level of refinement changes
11149be51f97SToby Isaac   the cell weight (see DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be
11159be51f97SToby Isaac   (cellWeight) * (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on
11169be51f97SToby Isaac   its level; a factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the
11179be51f97SToby Isaac   computation associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11189be51f97SToby Isaac 
11199be51f97SToby Isaac   Logically collective on dm
11209be51f97SToby Isaac 
11219be51f97SToby Isaac   Input Parameters:
11229be51f97SToby Isaac + dm - the forest
11239be51f97SToby Isaac - weightsFactors - default 1.
11249be51f97SToby Isaac 
11259be51f97SToby Isaac   Level: advanced
11269be51f97SToby Isaac 
11279be51f97SToby Isaac .seealso: DMForestGetCellWeightFactor(), DMForestSetCellWeights()
11289be51f97SToby Isaac @*/
1129ef51cf95SToby Isaac PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor)
1130c7eeac06SToby Isaac {
1131c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1132c7eeac06SToby Isaac 
1133c7eeac06SToby Isaac   PetscFunctionBegin;
1134c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1135ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup");
1136c7eeac06SToby Isaac   forest->weightsFactor = weightsFactor;
1137c7eeac06SToby Isaac   PetscFunctionReturn(0);
1138c7eeac06SToby Isaac }
1139c7eeac06SToby Isaac 
11409be51f97SToby Isaac /*@
11419be51f97SToby Isaac   DMForestGetCellWeightFactor - Get the factor by which the level of refinement changes the cell weight (see
11429be51f97SToby Isaac   DMForestSetCellWeights()) when calculating partitions.  The final weight of a cell will be (cellWeight) *
11439be51f97SToby Isaac   (weightFactor^refinementLevel).  A factor of 1 indicates that the weight of a cell does not depend on its level; a
11449be51f97SToby Isaac   factor of 2, for example, might be appropriate for sub-cycling time-stepping methods, when the computation
11459be51f97SToby Isaac   associated with a cell is multiplied by a factor of 2 for each additional level of refinement.
11469be51f97SToby Isaac 
11479be51f97SToby Isaac   Not collective
11489be51f97SToby Isaac 
11499be51f97SToby Isaac   Input Parameter:
11509be51f97SToby Isaac . dm - the forest
11519be51f97SToby Isaac 
11529be51f97SToby Isaac   Output Parameter:
11539be51f97SToby Isaac . weightsFactors - default 1.
11549be51f97SToby Isaac 
11559be51f97SToby Isaac   Level: advanced
11569be51f97SToby Isaac 
11579be51f97SToby Isaac .seealso: DMForestSetCellWeightFactor(), DMForestSetCellWeights()
11589be51f97SToby Isaac @*/
1159ef51cf95SToby Isaac PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor)
1160c7eeac06SToby Isaac {
1161c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1162c7eeac06SToby Isaac 
1163c7eeac06SToby Isaac   PetscFunctionBegin;
1164c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1165c7eeac06SToby Isaac   PetscValidRealPointer(weightsFactor,2);
1166c7eeac06SToby Isaac   *weightsFactor = forest->weightsFactor;
1167c7eeac06SToby Isaac   PetscFunctionReturn(0);
1168c7eeac06SToby Isaac }
1169c7eeac06SToby Isaac 
11709be51f97SToby Isaac /*@
11719be51f97SToby Isaac   DMForestGetCellChart - After the setup phase, get the local half-open interval of the chart of cells on this process
11729be51f97SToby Isaac 
11739be51f97SToby Isaac   Not collective
11749be51f97SToby Isaac 
11759be51f97SToby Isaac   Input Parameter:
11769be51f97SToby Isaac . dm - the forest
11779be51f97SToby Isaac 
11789be51f97SToby Isaac   Output Parameters:
11799be51f97SToby Isaac + cStart - the first cell on this process
11809be51f97SToby Isaac - cEnd - one after the final cell on this process
11819be51f97SToby Isaac 
11821a244344SSatish Balay   Level: intermediate
11839be51f97SToby Isaac 
11849be51f97SToby Isaac .seealso: DMForestGetCellSF()
11859be51f97SToby Isaac @*/
1186c7eeac06SToby Isaac PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd)
1187c7eeac06SToby Isaac {
1188c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1189c7eeac06SToby Isaac   PetscErrorCode ierr;
1190c7eeac06SToby Isaac 
1191c7eeac06SToby Isaac   PetscFunctionBegin;
1192c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1193c7eeac06SToby Isaac   PetscValidIntPointer(cStart,2);
1194c7eeac06SToby Isaac   PetscValidIntPointer(cEnd,2);
1195c7eeac06SToby Isaac   if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) {
1196c7eeac06SToby Isaac     ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr);
1197c7eeac06SToby Isaac   }
1198c7eeac06SToby Isaac   *cStart =  forest->cStart;
1199c7eeac06SToby Isaac   *cEnd   =  forest->cEnd;
1200c7eeac06SToby Isaac   PetscFunctionReturn(0);
1201c7eeac06SToby Isaac }
1202c7eeac06SToby Isaac 
12039be51f97SToby Isaac /*@
12049be51f97SToby Isaac   DMForestGetCellSF - After the setup phase, get the PetscSF for overlapping cells between processes
12059be51f97SToby Isaac 
12069be51f97SToby Isaac   Not collective
12079be51f97SToby Isaac 
12089be51f97SToby Isaac   Input Parameter:
12099be51f97SToby Isaac . dm - the forest
12109be51f97SToby Isaac 
12119be51f97SToby Isaac   Output Parameter:
12129be51f97SToby Isaac . cellSF - the PetscSF
12139be51f97SToby Isaac 
12141a244344SSatish Balay   Level: intermediate
12159be51f97SToby Isaac 
12169be51f97SToby Isaac .seealso: DMForestGetCellChart()
12179be51f97SToby Isaac @*/
1218c7eeac06SToby Isaac PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF)
1219c7eeac06SToby Isaac {
1220c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1221c7eeac06SToby Isaac   PetscErrorCode ierr;
1222c7eeac06SToby Isaac 
1223c7eeac06SToby Isaac   PetscFunctionBegin;
1224c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1225c7eeac06SToby Isaac   PetscValidPointer(cellSF,2);
1226c7eeac06SToby Isaac   if ((!forest->cellSF) && forest->createcellsf) {
1227c7eeac06SToby Isaac     ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr);
1228c7eeac06SToby Isaac   }
1229c7eeac06SToby Isaac   *cellSF = forest->cellSF;
1230c7eeac06SToby Isaac   PetscFunctionReturn(0);
1231c7eeac06SToby Isaac }
1232c7eeac06SToby Isaac 
12339be51f97SToby Isaac /*@C
12349be51f97SToby Isaac   DMForestSetAdaptivityLabel - During the pre-setup phase, set the label of the pre-adaptation forest (see
12359be51f97SToby Isaac   DMForestGetAdaptivityForest()) that holds the adaptation flags (refinement, coarsening, or some combination).  The
1236cd3c525cSToby Isaac   interpretation of the label values is up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP,
1237cd3c525cSToby Isaac   DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have been reserved as choices that should be accepted by all subtypes.
12389be51f97SToby Isaac 
12399be51f97SToby Isaac   Logically collective on dm
12409be51f97SToby Isaac 
12419be51f97SToby Isaac   Input Parameters:
12429be51f97SToby Isaac - dm - the forest
1243a1b0c543SToby Isaac + adaptLabel - the label in the pre-adaptation forest
12449be51f97SToby Isaac 
12459be51f97SToby Isaac   Level: intermediate
12469be51f97SToby Isaac 
12479be51f97SToby Isaac .seealso DMForestGetAdaptivityLabel()
12489be51f97SToby Isaac @*/
1249a1b0c543SToby Isaac PetscErrorCode DMForestSetAdaptivityLabel(DM dm, DMLabel adaptLabel)
1250c7eeac06SToby Isaac {
1251c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1252c7eeac06SToby Isaac   PetscErrorCode ierr;
1253c7eeac06SToby Isaac 
1254c7eeac06SToby Isaac   PetscFunctionBegin;
1255c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1256a1b0c543SToby Isaac   adaptLabel->refct++;
1257a1b0c543SToby Isaac   if (forest->adaptLabel) {ierr = DMLabelDestroy(&forest->adaptLabel);CHKERRQ(ierr);}
1258a1b0c543SToby Isaac   forest->adaptLabel = adaptLabel;
1259c7eeac06SToby Isaac   PetscFunctionReturn(0);
1260c7eeac06SToby Isaac }
1261c7eeac06SToby Isaac 
12629be51f97SToby Isaac /*@C
12639be51f97SToby Isaac   DMForestGetAdaptivityLabel - Get the label of the pre-adaptation forest (see DMForestGetAdaptivityForest()) that
12649be51f97SToby Isaac   holds the adaptation flags (refinement, coarsening, or some combination).  The interpretation of the label values is
1265cd3c525cSToby Isaac   up to the subtype of DMForest, but DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN have
1266cd3c525cSToby Isaac   been reserved as choices that should be accepted by all subtypes.
12679be51f97SToby Isaac 
12689be51f97SToby Isaac   Not collective
12699be51f97SToby Isaac 
12709be51f97SToby Isaac   Input Parameter:
12719be51f97SToby Isaac . dm - the forest
12729be51f97SToby Isaac 
12739be51f97SToby Isaac   Output Parameter:
12749be51f97SToby Isaac . adaptLabel - the name of the label in the pre-adaptation forest
12759be51f97SToby Isaac 
12769be51f97SToby Isaac   Level: intermediate
12779be51f97SToby Isaac 
12789be51f97SToby Isaac .seealso DMForestSetAdaptivityLabel()
12799be51f97SToby Isaac @*/
1280a1b0c543SToby Isaac PetscErrorCode DMForestGetAdaptivityLabel(DM dm, DMLabel *adaptLabel)
1281c7eeac06SToby Isaac {
1282c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1283c7eeac06SToby Isaac 
1284c7eeac06SToby Isaac   PetscFunctionBegin;
1285c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1286ba936b91SToby Isaac   *adaptLabel = forest->adaptLabel;
1287c7eeac06SToby Isaac   PetscFunctionReturn(0);
1288c7eeac06SToby Isaac }
1289c7eeac06SToby Isaac 
12909be51f97SToby Isaac /*@
12919be51f97SToby Isaac   DMForestSetCellWeights - Set the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
12929be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
12939be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
12949be51f97SToby Isaac   of 1.
12959be51f97SToby Isaac 
12969be51f97SToby Isaac   Logically collective on dm
12979be51f97SToby Isaac 
12989be51f97SToby Isaac   Input Parameters:
12999be51f97SToby Isaac + dm - the forest
13009be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
13019be51f97SToby Isaac - copyMode - how weights should reference weights
13029be51f97SToby Isaac 
13039be51f97SToby Isaac   Level: advanced
13049be51f97SToby Isaac 
13059be51f97SToby Isaac .seealso: DMForestGetCellWeights(), DMForestSetWeightCapacity()
13069be51f97SToby Isaac @*/
1307c7eeac06SToby Isaac PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode)
1308c7eeac06SToby Isaac {
1309c7eeac06SToby Isaac   DM_Forest      *forest = (DM_Forest*) dm->data;
1310c7eeac06SToby Isaac   PetscInt       cStart, cEnd;
1311c7eeac06SToby Isaac   PetscErrorCode ierr;
1312c7eeac06SToby Isaac 
1313c7eeac06SToby Isaac   PetscFunctionBegin;
1314c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1315c7eeac06SToby Isaac   ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr);
1316c7eeac06SToby Isaac   if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd);
1317c7eeac06SToby Isaac   if (copyMode == PETSC_COPY_VALUES) {
1318c7eeac06SToby Isaac     if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) {
1319c7eeac06SToby Isaac       ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr);
1320c7eeac06SToby Isaac     }
1321c7eeac06SToby Isaac     ierr                        = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr);
1322c7eeac06SToby Isaac     forest->cellWeightsCopyMode = PETSC_OWN_POINTER;
1323c7eeac06SToby Isaac     PetscFunctionReturn(0);
1324c7eeac06SToby Isaac   }
1325c7eeac06SToby Isaac   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) {
1326c7eeac06SToby Isaac     ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr);
1327c7eeac06SToby Isaac   }
1328c7eeac06SToby Isaac   forest->cellWeights         = weights;
1329c7eeac06SToby Isaac   forest->cellWeightsCopyMode = copyMode;
1330c7eeac06SToby Isaac   PetscFunctionReturn(0);
1331c7eeac06SToby Isaac }
1332c7eeac06SToby Isaac 
13339be51f97SToby Isaac /*@
13349be51f97SToby Isaac   DMForestGetCellWeights - Get the weights assigned to each of the cells (see DMForestGetCellChart()) of the current
13359be51f97SToby Isaac   process: weights are used to determine parallel partitioning.  Partitions will be created so that each process's
13369be51f97SToby Isaac   ratio of weight to capacity (see DMForestSetWeightCapacity()) is roughly equal. If NULL, each cell receives a weight
13379be51f97SToby Isaac   of 1.
13389be51f97SToby Isaac 
13399be51f97SToby Isaac   Not collective
13409be51f97SToby Isaac 
13419be51f97SToby Isaac   Input Parameter:
13429be51f97SToby Isaac . dm - the forest
13439be51f97SToby Isaac 
13449be51f97SToby Isaac   Output Parameter:
13459be51f97SToby Isaac . weights - the array of weights for all cells, or NULL to indicate each cell has weight 1.
13469be51f97SToby Isaac 
13479be51f97SToby Isaac   Level: advanced
13489be51f97SToby Isaac 
13499be51f97SToby Isaac .seealso: DMForestSetCellWeights(), DMForestSetWeightCapacity()
13509be51f97SToby Isaac @*/
1351c7eeac06SToby Isaac PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights)
1352c7eeac06SToby Isaac {
1353c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1354c7eeac06SToby Isaac 
1355c7eeac06SToby Isaac   PetscFunctionBegin;
1356c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1357c7eeac06SToby Isaac   PetscValidPointer(weights,2);
1358c7eeac06SToby Isaac   *weights = forest->cellWeights;
1359c7eeac06SToby Isaac   PetscFunctionReturn(0);
1360c7eeac06SToby Isaac }
1361c7eeac06SToby Isaac 
13629be51f97SToby Isaac /*@
13639be51f97SToby Isaac   DMForestSetWeightCapacity - During the pre-setup phase, set the capacity of the current process when repartitioning
13649be51f97SToby Isaac   a pre-adaptation forest (see DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each
13659be51f97SToby Isaac   process's cells to the process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that
13669be51f97SToby Isaac   the current process should not have any cells after repartitioning.
13679be51f97SToby Isaac 
13689be51f97SToby Isaac   Logically Collective on dm
13699be51f97SToby Isaac 
13709be51f97SToby Isaac   Input parameters:
13719be51f97SToby Isaac + dm - the forest
13729be51f97SToby Isaac - capacity - this process's capacity
13739be51f97SToby Isaac 
13749be51f97SToby Isaac   Level: advanced
13759be51f97SToby Isaac 
13769be51f97SToby Isaac .seealso DMForestGetWeightCapacity(), DMForestSetCellWeights(), DMForestSetCellWeightFactor()
13779be51f97SToby Isaac @*/
1378c7eeac06SToby Isaac PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity)
1379c7eeac06SToby Isaac {
1380c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1381c7eeac06SToby Isaac 
1382c7eeac06SToby Isaac   PetscFunctionBegin;
1383c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1384ef51cf95SToby Isaac   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup");
1385c7eeac06SToby Isaac   if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity);
1386c7eeac06SToby Isaac   forest->weightCapacity = capacity;
1387c7eeac06SToby Isaac   PetscFunctionReturn(0);
1388c7eeac06SToby Isaac }
1389c7eeac06SToby Isaac 
13909be51f97SToby Isaac /*@
13919be51f97SToby Isaac   DMForestGetWeightCapacity - Set the capacity of the current process when repartitioning a pre-adaptation forest (see
13929be51f97SToby Isaac   DMForestGetAdaptivityForest()).  After partitioning, the ratio of the weight of each process's cells to the
13939be51f97SToby Isaac   process's capacity will be roughly equal for all processes.  A capacity of 0 indicates that the current process
13949be51f97SToby Isaac   should not have any cells after repartitioning.
13959be51f97SToby Isaac 
13969be51f97SToby Isaac   Not collective
13979be51f97SToby Isaac 
13989be51f97SToby Isaac   Input parameter:
13999be51f97SToby Isaac . dm - the forest
14009be51f97SToby Isaac 
14019be51f97SToby Isaac   Output parameter:
14029be51f97SToby Isaac . capacity - this process's capacity
14039be51f97SToby Isaac 
14049be51f97SToby Isaac   Level: advanced
14059be51f97SToby Isaac 
14069be51f97SToby Isaac .seealso DMForestSetWeightCapacity(), DMForestSetCellWeights(), DMForestSetCellWeightFactor()
14079be51f97SToby Isaac @*/
1408c7eeac06SToby Isaac PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity)
1409c7eeac06SToby Isaac {
1410c7eeac06SToby Isaac   DM_Forest *forest = (DM_Forest*) dm->data;
1411c7eeac06SToby Isaac 
1412c7eeac06SToby Isaac   PetscFunctionBegin;
1413c7eeac06SToby Isaac   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1414c7eeac06SToby Isaac   PetscValidRealPointer(capacity,2);
1415c7eeac06SToby Isaac   *capacity = forest->weightCapacity;
1416c7eeac06SToby Isaac   PetscFunctionReturn(0);
1417c7eeac06SToby Isaac }
1418c7eeac06SToby Isaac 
14190709b2feSToby Isaac PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptionItems *PetscOptionsObject,DM dm)
1420db4d5e8cSToby Isaac {
1421db4d5e8cSToby Isaac   DM_Forest                  *forest = (DM_Forest*) dm->data;
142256ba9f64SToby Isaac   PetscBool                  flg, flg1, flg2, flg3, flg4;
1423dd8e54a2SToby Isaac   DMForestTopology           oldTopo;
1424c7eeac06SToby Isaac   char                       stringBuffer[256];
1425dd8e54a2SToby Isaac   PetscViewer                viewer;
1426dd8e54a2SToby Isaac   PetscViewerFormat          format;
142756ba9f64SToby Isaac   PetscInt                   adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade;
1428c7eeac06SToby Isaac   PetscReal                  weightsFactor;
1429c7eeac06SToby Isaac   DMForestAdaptivityStrategy adaptStrategy;
1430db4d5e8cSToby Isaac   PetscErrorCode             ierr;
1431db4d5e8cSToby Isaac 
1432db4d5e8cSToby Isaac   PetscFunctionBegin;
1433db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
143458762b62SToby Isaac   forest->setfromoptionscalled = PETSC_TRUE;
1435dd8e54a2SToby Isaac   ierr                         = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr);
1436a3eda1eaSToby Isaac   ierr                         = PetscOptionsHead(PetscOptionsObject,"DMForest Options");CHKERRQ(ierr);
143756ba9f64SToby Isaac   ierr                         = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg1);CHKERRQ(ierr);
143856ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg2);CHKERRQ(ierr);
143956ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg3);CHKERRQ(ierr);
144056ba9f64SToby Isaac   ierr                         = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg4);CHKERRQ(ierr);
1441f885a11aSToby 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}");
144256ba9f64SToby Isaac   if (flg1) {
144356ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr);
144456ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
144520e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
144656ba9f64SToby Isaac   }
144756ba9f64SToby Isaac   if (flg2) {
1448dd8e54a2SToby Isaac     DM base;
1449dd8e54a2SToby Isaac 
1450dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr);
1451dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1452dd8e54a2SToby Isaac     ierr = DMLoad(base,viewer);CHKERRQ(ierr);
1453dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1454dd8e54a2SToby Isaac     ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
1455dd8e54a2SToby Isaac     ierr = DMDestroy(&base);CHKERRQ(ierr);
145656ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
145720e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
1458dd8e54a2SToby Isaac   }
145956ba9f64SToby Isaac   if (flg3) {
1460dd8e54a2SToby Isaac     DM coarse;
1461dd8e54a2SToby Isaac 
1462dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr);
1463dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1464dd8e54a2SToby Isaac     ierr = DMLoad(coarse,viewer);CHKERRQ(ierr);
1465dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
146620e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,coarse);CHKERRQ(ierr);
1467dd8e54a2SToby Isaac     ierr = DMDestroy(&coarse);CHKERRQ(ierr);
146856ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
146956ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
1470dd8e54a2SToby Isaac   }
147156ba9f64SToby Isaac   if (flg4) {
1472dd8e54a2SToby Isaac     DM fine;
1473dd8e54a2SToby Isaac 
1474dd8e54a2SToby Isaac     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr);
1475dd8e54a2SToby Isaac     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
1476dd8e54a2SToby Isaac     ierr = DMLoad(fine,viewer);CHKERRQ(ierr);
1477dd8e54a2SToby Isaac     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
147820e8089bSToby Isaac     ierr = DMForestSetAdaptivityForest(dm,fine);CHKERRQ(ierr);
1479dd8e54a2SToby Isaac     ierr = DMDestroy(&fine);CHKERRQ(ierr);
148056ba9f64SToby Isaac     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
148156ba9f64SToby Isaac     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
1482dd8e54a2SToby Isaac   }
1483dd8e54a2SToby Isaac   ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr);
1484dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr);
1485dd8e54a2SToby Isaac   if (flg) {
1486dd8e54a2SToby Isaac     ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr);
1487f885a11aSToby Isaac   } else {
1488dd8e54a2SToby Isaac     ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr);
1489dd8e54a2SToby Isaac     ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr);
1490dd8e54a2SToby Isaac     if (flg) {
1491dd8e54a2SToby Isaac       ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr);
1492dd8e54a2SToby Isaac     }
1493dd8e54a2SToby Isaac   }
1494dd8e54a2SToby Isaac   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
1495dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr);
1496dd8e54a2SToby Isaac   if (flg) {
1497dd8e54a2SToby Isaac     ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr);
1498dd8e54a2SToby Isaac   }
1499a6121fbdSMatthew G. Knepley #if 0
1500a6121fbdSMatthew 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);
1501a6121fbdSMatthew G. Knepley   if (flg) {
1502a6121fbdSMatthew G. Knepley     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
1503a6121fbdSMatthew G. Knepley     ierr = DMForestSetInitialRefinement(dm,minRefinement);CHKERRQ(ierr);
1504a6121fbdSMatthew G. Knepley   }
1505a6121fbdSMatthew 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);
1506a6121fbdSMatthew G. Knepley   if (flg) {
1507a6121fbdSMatthew G. Knepley     ierr = DMForestSetMinimumRefinement(dm,0);CHKERRQ(ierr);
1508a6121fbdSMatthew G. Knepley     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
1509a6121fbdSMatthew G. Knepley   }
1510a6121fbdSMatthew G. Knepley #endif
1511dd8e54a2SToby Isaac   ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr);
1512dd8e54a2SToby Isaac   ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr);
1513dd8e54a2SToby Isaac   if (flg) {
1514dd8e54a2SToby Isaac     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
1515db4d5e8cSToby Isaac   }
151656ba9f64SToby Isaac   ierr = DMForestGetInitialRefinement(dm,&initRefinement);CHKERRQ(ierr);
151756ba9f64SToby Isaac   ierr = PetscOptionsInt("-dm_forest_initial_refinement","set the initial level of refinement in the forest","DMForestSetInitialRefinement",initRefinement,&initRefinement,&flg);CHKERRQ(ierr);
151856ba9f64SToby Isaac   if (flg) {
151956ba9f64SToby Isaac     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
152056ba9f64SToby Isaac   }
1521c7eeac06SToby Isaac   ierr = DMForestGetMaximumRefinement(dm,&maxRefinement);CHKERRQ(ierr);
1522c7eeac06SToby Isaac   ierr = PetscOptionsInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg);CHKERRQ(ierr);
1523c7eeac06SToby Isaac   if (flg) {
1524c7eeac06SToby Isaac     ierr = DMForestSetMaximumRefinement(dm,maxRefinement);CHKERRQ(ierr);
1525c7eeac06SToby Isaac   }
1526c7eeac06SToby Isaac   ierr = DMForestGetAdaptivityStrategy(dm,&adaptStrategy);CHKERRQ(ierr);
1527c7eeac06SToby Isaac   ierr = PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,256,&flg);CHKERRQ(ierr);
1528c7eeac06SToby Isaac   if (flg) {
1529c7eeac06SToby Isaac     ierr = DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer);CHKERRQ(ierr);
1530c7eeac06SToby Isaac   }
1531c7eeac06SToby Isaac   ierr = DMForestGetGradeFactor(dm,&grade);CHKERRQ(ierr);
1532c7eeac06SToby Isaac   ierr = PetscOptionsInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg);CHKERRQ(ierr);
1533c7eeac06SToby Isaac   if (flg) {
1534c7eeac06SToby Isaac     ierr = DMForestSetGradeFactor(dm,grade);CHKERRQ(ierr);
1535c7eeac06SToby Isaac   }
1536c7eeac06SToby Isaac   ierr = DMForestGetCellWeightFactor(dm,&weightsFactor);CHKERRQ(ierr);
1537c7eeac06SToby Isaac   ierr = PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg);CHKERRQ(ierr);
1538c7eeac06SToby Isaac   if (flg) {
1539c7eeac06SToby Isaac     ierr = DMForestSetCellWeightFactor(dm,weightsFactor);CHKERRQ(ierr);
1540c7eeac06SToby Isaac   }
1541db4d5e8cSToby Isaac   ierr = PetscOptionsTail();CHKERRQ(ierr);
1542db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1543db4d5e8cSToby Isaac }
1544db4d5e8cSToby Isaac 
1545276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
1546d8984e3bSMatthew G. Knepley {
1547d8984e3bSMatthew G. Knepley   PetscErrorCode ierr;
1548d8984e3bSMatthew G. Knepley 
1549d8984e3bSMatthew G. Knepley   PetscFunctionBegin;
1550d8984e3bSMatthew G. Knepley   if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);}
1551d8984e3bSMatthew G. Knepley   ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
1552d8984e3bSMatthew G. Knepley   PetscFunctionReturn(0);
1553d8984e3bSMatthew G. Knepley }
1554d8984e3bSMatthew G. Knepley 
15555421bac9SToby Isaac PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined)
15565421bac9SToby Isaac {
15575421bac9SToby Isaac   DMLabel        refine;
15585421bac9SToby Isaac   DM             fineDM;
15595421bac9SToby Isaac   PetscErrorCode ierr;
15605421bac9SToby Isaac 
15615421bac9SToby Isaac   PetscFunctionBegin;
15625421bac9SToby Isaac   ierr = DMGetFineDM(dm,&fineDM);CHKERRQ(ierr);
15635421bac9SToby Isaac   if (fineDM) {
15645421bac9SToby Isaac     ierr       = PetscObjectReference((PetscObject)fineDM);CHKERRQ(ierr);
15655421bac9SToby Isaac     *dmRefined = fineDM;
15665421bac9SToby Isaac     PetscFunctionReturn(0);
15675421bac9SToby Isaac   }
15685421bac9SToby Isaac   ierr = DMForestTemplate(dm,comm,dmRefined);CHKERRQ(ierr);
15695421bac9SToby Isaac   ierr = DMGetLabel(dm,"refine",&refine);CHKERRQ(ierr);
15705421bac9SToby Isaac   if (!refine) {
1571a1b0c543SToby Isaac     ierr = DMLabelCreate("refine",&refine);CHKERRQ(ierr);
1572a1b0c543SToby Isaac     ierr = DMLabelSetDefaultValue(refine,DM_ADAPT_REFINE);CHKERRQ(ierr);
15735421bac9SToby Isaac   }
1574a1b0c543SToby Isaac   else {
1575a1b0c543SToby Isaac     refine->refct++;
1576a1b0c543SToby Isaac   }
1577a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*dmRefined,refine);CHKERRQ(ierr);
1578a1b0c543SToby Isaac   ierr = DMLabelDestroy(&refine);CHKERRQ(ierr);
15795421bac9SToby Isaac   PetscFunctionReturn(0);
15805421bac9SToby Isaac }
15815421bac9SToby Isaac 
15825421bac9SToby Isaac PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened)
15835421bac9SToby Isaac {
15845421bac9SToby Isaac   DMLabel        coarsen;
15855421bac9SToby Isaac   DM             coarseDM;
15865421bac9SToby Isaac   PetscErrorCode ierr;
15875421bac9SToby Isaac 
15885421bac9SToby Isaac   PetscFunctionBegin;
15894098eed7SToby Isaac   {
15904098eed7SToby Isaac     PetscMPIInt mpiComparison;
15914098eed7SToby Isaac     MPI_Comm    dmcomm = PetscObjectComm((PetscObject)dm);
15924098eed7SToby Isaac 
15934098eed7SToby Isaac     ierr = MPI_Comm_compare(comm, dmcomm, &mpiComparison);CHKERRQ(ierr);
1594f885a11aSToby Isaac     if (mpiComparison != MPI_IDENT && mpiComparison != MPI_CONGRUENT) SETERRQ(dmcomm,PETSC_ERR_SUP,"No support for different communicators yet");
15954098eed7SToby Isaac   }
15965421bac9SToby Isaac   ierr = DMGetCoarseDM(dm,&coarseDM);CHKERRQ(ierr);
15975421bac9SToby Isaac   if (coarseDM) {
15985421bac9SToby Isaac     ierr         = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr);
15995421bac9SToby Isaac     *dmCoarsened = coarseDM;
16005421bac9SToby Isaac     PetscFunctionReturn(0);
16015421bac9SToby Isaac   }
16025421bac9SToby Isaac   ierr = DMForestTemplate(dm,comm,dmCoarsened);CHKERRQ(ierr);
1603a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityPurpose(coarseDM,DM_ADAPT_COARSEN);CHKERRQ(ierr);
16045421bac9SToby Isaac   ierr = DMGetLabel(dm,"coarsen",&coarsen);CHKERRQ(ierr);
16055421bac9SToby Isaac   if (!coarsen) {
1606a1b0c543SToby Isaac     ierr = DMLabelCreate("coarsen",&coarsen);CHKERRQ(ierr);
1607a1b0c543SToby Isaac     ierr = DMLabelSetDefaultValue(coarsen,DM_ADAPT_COARSEN);CHKERRQ(ierr);
1608a1b0c543SToby Isaac   } else {
1609a1b0c543SToby Isaac     coarsen->refct++;
16105421bac9SToby Isaac   }
1611a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*dmCoarsened,coarsen);CHKERRQ(ierr);
1612a1b0c543SToby Isaac   ierr = DMLabelDestroy(&coarsen);CHKERRQ(ierr);
16135421bac9SToby Isaac   PetscFunctionReturn(0);
16145421bac9SToby Isaac }
16155421bac9SToby Isaac 
1616a1b0c543SToby Isaac static PetscErrorCode DMAdaptLabel_Forest(DM dm, DMLabel label, DM *adaptedDM)
161709350103SToby Isaac {
161809350103SToby Isaac   PetscBool      success;
161909350103SToby Isaac   PetscErrorCode ierr;
162009350103SToby Isaac 
162109350103SToby Isaac   PetscFunctionBegin;
162209350103SToby Isaac   ierr = DMForestTemplate(dm,PetscObjectComm((PetscObject)dm),adaptedDM);CHKERRQ(ierr);
1623a1b0c543SToby Isaac   ierr = DMForestSetAdaptivityLabel(*adaptedDM,label);CHKERRQ(ierr);
162409350103SToby Isaac   ierr = DMSetUp(*adaptedDM);CHKERRQ(ierr);
162509350103SToby Isaac   ierr = DMForestGetAdaptivitySuccess(*adaptedDM,&success);CHKERRQ(ierr);
162609350103SToby Isaac   if (!success) {
162709350103SToby Isaac     ierr = DMDestroy(adaptedDM);CHKERRQ(ierr);
162809350103SToby Isaac     *adaptedDM = NULL;
162909350103SToby Isaac   }
163009350103SToby Isaac   PetscFunctionReturn(0);
163109350103SToby Isaac }
163209350103SToby Isaac 
1633d222f98bSToby Isaac static PetscErrorCode DMInitialize_Forest(DM dm)
1634d222f98bSToby Isaac {
1635d222f98bSToby Isaac   PetscErrorCode ierr;
1636d222f98bSToby Isaac 
1637d222f98bSToby Isaac   PetscFunctionBegin;
1638d222f98bSToby Isaac   ierr = PetscMemzero(dm->ops,sizeof(*(dm->ops)));CHKERRQ(ierr);
1639d222f98bSToby Isaac 
1640d222f98bSToby Isaac   dm->ops->clone          = DMClone_Forest;
1641d222f98bSToby Isaac   dm->ops->setfromoptions = DMSetFromOptions_Forest;
1642d222f98bSToby Isaac   dm->ops->destroy        = DMDestroy_Forest;
1643d8984e3bSMatthew G. Knepley   dm->ops->createsubdm    = DMCreateSubDM_Forest;
16445421bac9SToby Isaac   dm->ops->refine         = DMRefine_Forest;
16455421bac9SToby Isaac   dm->ops->coarsen        = DMCoarsen_Forest;
16460d1cd5e0SMatthew G. Knepley   dm->ops->adaptlabel     = DMAdaptLabel_Forest;
1647d222f98bSToby Isaac   PetscFunctionReturn(0);
1648d222f98bSToby Isaac }
1649d222f98bSToby Isaac 
16509be51f97SToby Isaac /*MC
16519be51f97SToby Isaac 
1652bae1f979SBarry Smith      DMFOREST = "forest" - A DM object that encapsulates a hierarchically refined mesh.  Forests usually have a base DM
1653bae1f979SBarry Smith   (see DMForestGetBaseDM()), from which it is refined.  The refinement and partitioning of forests is considered
1654bae1f979SBarry Smith   immutable after DMSetUp() is called.  To adapt a mesh, one should call DMForestTemplate() to create a new mesh that
1655bae1f979SBarry Smith   will default to being identical to it, specify how that mesh should differ, and then calling DMSetUp() on the new
1656bae1f979SBarry Smith   mesh.
1657bae1f979SBarry Smith 
1658bae1f979SBarry Smith   To specify that a mesh should be refined or coarsened from the previous mesh, a label should be defined on the
1659bae1f979SBarry Smith   previous mesh whose values indicate which cells should be refined (DM_ADAPT_REFINE) or coarsened (DM_ADAPT_COARSEN)
1660bae1f979SBarry Smith   and how (subtypes are free to allow additional values for things like anisotropic refinement).  The label should be
1661bae1f979SBarry Smith   given to the *new* mesh with DMForestSetAdaptivityLabel().
16629be51f97SToby Isaac 
16639be51f97SToby Isaac   Level: advanced
16649be51f97SToby Isaac 
16659be51f97SToby Isaac .seealso: DMType, DMCreate(), DMSetType(), DMForestGetBaseDM(), DMForestSetBaseDM(), DMForestTemplate(), DMForestSetAdaptivityLabel()
16669be51f97SToby Isaac M*/
16679be51f97SToby Isaac 
1668db4d5e8cSToby Isaac PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm)
1669db4d5e8cSToby Isaac {
1670db4d5e8cSToby Isaac   DM_Forest      *forest;
1671db4d5e8cSToby Isaac   PetscErrorCode ierr;
1672db4d5e8cSToby Isaac 
1673db4d5e8cSToby Isaac   PetscFunctionBegin;
1674db4d5e8cSToby Isaac   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
1675db4d5e8cSToby Isaac   ierr                         = PetscNewLog(dm,&forest);CHKERRQ(ierr);
1676db4d5e8cSToby Isaac   dm->dim                      = 0;
1677db4d5e8cSToby Isaac   dm->data                     = forest;
1678db4d5e8cSToby Isaac   forest->refct                = 1;
1679db4d5e8cSToby Isaac   forest->data                 = NULL;
168058762b62SToby Isaac   forest->setfromoptionscalled = PETSC_FALSE;
1681db4d5e8cSToby Isaac   forest->topology             = NULL;
1682cd3c525cSToby Isaac   forest->adapt                = NULL;
1683db4d5e8cSToby Isaac   forest->base                 = NULL;
16846a87ffbfSToby Isaac   forest->adaptPurpose         = DM_ADAPT_DETERMINE;
1685db4d5e8cSToby Isaac   forest->adjDim               = PETSC_DEFAULT;
1686db4d5e8cSToby Isaac   forest->overlap              = PETSC_DEFAULT;
1687db4d5e8cSToby Isaac   forest->minRefinement        = PETSC_DEFAULT;
1688db4d5e8cSToby Isaac   forest->maxRefinement        = PETSC_DEFAULT;
168956ba9f64SToby Isaac   forest->initRefinement       = PETSC_DEFAULT;
1690c7eeac06SToby Isaac   forest->cStart               = PETSC_DETERMINE;
1691c7eeac06SToby Isaac   forest->cEnd                 = PETSC_DETERMINE;
1692cd3c525cSToby Isaac   forest->cellSF               = NULL;
1693ebdf65a2SToby Isaac   forest->adaptLabel           = NULL;
1694db4d5e8cSToby Isaac   forest->gradeFactor          = 2;
1695db4d5e8cSToby Isaac   forest->cellWeights          = NULL;
1696db4d5e8cSToby Isaac   forest->cellWeightsCopyMode  = PETSC_USE_POINTER;
1697db4d5e8cSToby Isaac   forest->weightsFactor        = 1.;
1698db4d5e8cSToby Isaac   forest->weightCapacity       = 1.;
1699a73e2921SToby Isaac   ierr                         = DMForestSetAdaptivityStrategy(dm,DMFORESTADAPTALL);CHKERRQ(ierr);
1700d222f98bSToby Isaac   ierr                         = DMInitialize_Forest(dm);CHKERRQ(ierr);
1701db4d5e8cSToby Isaac   PetscFunctionReturn(0);
1702db4d5e8cSToby Isaac }
1703