xref: /petsc/src/dm/impls/forest/forest.c (revision 26d9498a6f9f10e42780cedfbe76690d1ae7fbfa)
1 #include <petsc/private/dmforestimpl.h> /*I petscdmforest.h I*/
2 #include <petsc/private/dmimpl.h>       /*I petscdm.h */
3 #include <petscsf.h>
4 
5 PetscBool DMForestPackageInitialized = PETSC_FALSE;
6 
7 typedef struct _DMForestTypeLink *DMForestTypeLink;
8 
9 struct _DMForestTypeLink
10 {
11   char *name;
12   DMForestTypeLink next;
13 };
14 
15 DMForestTypeLink DMForestTypeList;
16 
17 #undef __FUNCT__
18 #define __FUNCT__ "DMForestPackageFinalize"
19 static PetscErrorCode DMForestPackageFinalize(void)
20 {
21   DMForestTypeLink oldLink, link = DMForestTypeList;
22   PetscErrorCode ierr;
23 
24   PetscFunctionBegin;
25   while (link) {
26     oldLink = link;
27     ierr = PetscFree(oldLink->name);
28     link = oldLink->next;
29     ierr = PetscFree(oldLink);CHKERRQ(ierr);
30   }
31   PetscFunctionReturn(0);
32 }
33 
34 #undef __FUNCT__
35 #define __FUNCT__ "DMForestPackageInitialize"
36 static PetscErrorCode DMForestPackageInitialize(void)
37 {
38   PetscErrorCode ierr;
39 
40   PetscFunctionBegin;
41   if (DMForestPackageInitialized) PetscFunctionReturn(0);
42   DMForestPackageInitialized = PETSC_TRUE;
43   ierr = DMForestRegisterType(DMFOREST);CHKERRQ(ierr);
44   ierr = PetscRegisterFinalize(DMForestPackageFinalize);CHKERRQ(ierr);
45   PetscFunctionReturn(0);
46 }
47 
48 #undef __FUNCT__
49 #define __FUNCT__ "DMForestRegisterType"
50 PetscErrorCode DMForestRegisterType(DMType name)
51 {
52   DMForestTypeLink link;
53   PetscErrorCode ierr;
54 
55   PetscFunctionBegin;
56   ierr = DMForestPackageInitialize();CHKERRQ(ierr);
57   ierr = PetscNew(&link);CHKERRQ(ierr);
58   ierr = PetscStrallocpy(name,&link->name);CHKERRQ(ierr);
59   link->next = DMForestTypeList;
60   DMForestTypeList = link;
61   PetscFunctionReturn(0);
62 }
63 
64 #undef __FUNCT__
65 #define __FUNCT__ "DMIsForest"
66 PetscErrorCode DMIsForest(DM dm, PetscBool *isForest)
67 {
68   DMForestTypeLink link = DMForestTypeList;
69   PetscErrorCode ierr;
70 
71   PetscFunctionBegin;
72   while (link) {
73     PetscBool sameType;
74     ierr = PetscObjectTypeCompare((PetscObject)dm,link->name,&sameType);CHKERRQ(ierr);
75     if (sameType) {
76       *isForest = PETSC_TRUE;
77       PetscFunctionReturn(0);
78     }
79     link = link->next;
80   }
81   *isForest = PETSC_FALSE;
82   PetscFunctionReturn(0);
83 }
84 
85 #undef __FUNCT__
86 #define __FUNCT__ "DMForestTemplate"
87 PETSC_EXTERN PetscErrorCode DMForestTemplate(DM dm, MPI_Comm comm, DM *tdm)
88 {
89   DM_Forest        *forest = (DM_Forest *) dm->data;
90   DMType           type;
91   DM               base;
92   DMForestTopology topology;
93   PetscInt         dim, overlap, ref, factor;
94   DMForestAdaptivityStrategy strat;
95   PetscDS          ds;
96   void             *ctx;
97   PetscErrorCode   ierr;
98 
99   PetscFunctionBegin;
100   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
101   ierr = DMCreate(PetscObjectComm((PetscObject)dm),tdm);CHKERRQ(ierr);
102   ierr = DMGetType(dm,&type);CHKERRQ(ierr);
103   ierr = DMSetType(*tdm,type);CHKERRQ(ierr);
104   ierr = DMForestGetBaseDM(dm,&base);CHKERRQ(ierr);
105   ierr = DMForestSetBaseDM(*tdm,base);CHKERRQ(ierr);
106   ierr = DMForestGetTopology(dm,&topology);CHKERRQ(ierr);
107   ierr = DMForestSetTopology(*tdm,topology);CHKERRQ(ierr);
108   ierr = DMForestGetAdjacencyDimension(dm,&dim);CHKERRQ(ierr);
109   ierr = DMForestSetAdjacencyDimension(*tdm,dim);CHKERRQ(ierr);
110   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
111   ierr = DMForestSetPartitionOverlap(*tdm,overlap);CHKERRQ(ierr);
112   ierr = DMForestGetMinimumRefinement(dm,&ref);CHKERRQ(ierr);
113   ierr = DMForestSetMinimumRefinement(*tdm,ref);CHKERRQ(ierr);
114   ierr = DMForestGetMaximumRefinement(dm,&ref);CHKERRQ(ierr);
115   ierr = DMForestSetMaximumRefinement(*tdm,ref);CHKERRQ(ierr);
116   ierr = DMForestGetAdaptivityStrategy(dm,&strat);CHKERRQ(ierr);
117   ierr = DMForestSetAdaptivityStrategy(*tdm,strat);CHKERRQ(ierr);
118   ierr = DMForestGetGradeFactor(dm,&factor);CHKERRQ(ierr);
119   ierr = DMForestSetGradeFactor(*tdm,factor);CHKERRQ(ierr);
120   if (forest->ftemplate) {
121     ierr = (forest->ftemplate) (dm, *tdm);CHKERRQ(ierr);
122   }
123   ierr = DMForestSetAdaptivityForest(*tdm,dm);CHKERRQ(ierr);
124   ierr = DMGetDS(dm,&ds);CHKERRQ(ierr);
125   ierr = DMSetDS(*tdm,ds);CHKERRQ(ierr);
126   ierr = DMGetApplicationContext(dm,&ctx);CHKERRQ(ierr);
127   ierr = DMSetApplicationContext(*tdm,&ctx);CHKERRQ(ierr);
128   if (dm->maxCell) {
129     const PetscReal *maxCell, *L;
130     const DMBoundaryType *bd;
131 
132     ierr = DMGetPeriodicity(dm,&maxCell,&L,&bd);CHKERRQ(ierr);
133     ierr = DMSetPeriodicity(*tdm,maxCell,L,bd);CHKERRQ(ierr);
134   }
135   PetscFunctionReturn(0);
136 }
137 
138 static PetscErrorCode DMInitialize_Forest(DM dm);
139 
140 #undef __FUNCT__
141 #define __FUNCT__ "DMClone_Forest"
142 PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm)
143 {
144   DM_Forest        *forest = (DM_Forest *) dm->data;
145   const char       *type;
146   PetscErrorCode ierr;
147 
148   PetscFunctionBegin;
149   forest->refct++;
150   (*newdm)->data = forest;
151   ierr = PetscObjectGetType((PetscObject) dm, &type);CHKERRQ(ierr);
152   ierr = PetscObjectChangeTypeName((PetscObject) *newdm, type);CHKERRQ(ierr);
153   ierr = DMInitialize_Forest(*newdm);CHKERRQ(ierr);
154   PetscFunctionReturn(0);
155 }
156 
157 #undef __FUNCT__
158 #define __FUNCT__ "DMDestroy_Forest"
159 static PetscErrorCode DMDestroy_Forest(DM dm)
160 {
161   DM_Forest     *forest = (DM_Forest*) dm->data;
162   PetscErrorCode ierr;
163 
164   PetscFunctionBegin;
165   if (--forest->refct > 0) PetscFunctionReturn(0);
166   if (forest->destroy) {ierr = forest->destroy(dm);CHKERRQ(ierr);}
167   ierr = PetscSFDestroy(&forest->cellSF);CHKERRQ(ierr);
168   ierr = PetscFree(forest->adaptLabel);CHKERRQ(ierr);
169   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
170   ierr = DMDestroy(&forest->base);CHKERRQ(ierr);
171   ierr = DMDestroy(&forest->adapt);CHKERRQ(ierr);
172   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
173   ierr = PetscFree(forest);CHKERRQ(ierr);
174   PetscFunctionReturn(0);
175 }
176 
177 #undef __FUNCT__
178 #define __FUNCT__ "DMForestSetTopology"
179 PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology)
180 {
181   DM_Forest      *forest = (DM_Forest *) dm->data;
182   PetscErrorCode ierr;
183 
184   PetscFunctionBegin;
185   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
186   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup");
187   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
188   ierr = PetscStrallocpy((const char *)topology,(char **) &forest->topology);CHKERRQ(ierr);
189   PetscFunctionReturn(0);
190 }
191 
192 #undef __FUNCT__
193 #define __FUNCT__ "DMForestGetTopology"
194 PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology)
195 {
196   DM_Forest      *forest = (DM_Forest *) dm->data;
197 
198   PetscFunctionBegin;
199   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
200   PetscValidPointer(topology,2);
201   *topology = forest->topology;
202   PetscFunctionReturn(0);
203 }
204 
205 #undef __FUNCT__
206 #define __FUNCT__ "DMForestSetBaseDM"
207 PetscErrorCode DMForestSetBaseDM(DM dm, DM base)
208 {
209   DM_Forest      *forest = (DM_Forest *) dm->data;
210   PetscInt       dim, dimEmbed;
211   PetscErrorCode ierr;
212 
213   PetscFunctionBegin;
214   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
215   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup");
216   ierr = PetscObjectReference((PetscObject)base);CHKERRQ(ierr);
217   ierr = DMDestroy(&forest->base);CHKERRQ(ierr);
218   forest->base = base;
219   if (base) {
220     PetscValidHeaderSpecific(base, DM_CLASSID, 2);
221     ierr = DMGetDimension(base,&dim);CHKERRQ(ierr);
222     ierr = DMSetDimension(dm,dim);CHKERRQ(ierr);
223     ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr);
224     ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr);
225   }
226   PetscFunctionReturn(0);
227 }
228 
229 #undef __FUNCT__
230 #define __FUNCT__ "DMForestGetBaseDM"
231 PetscErrorCode DMForestGetBaseDM(DM dm, DM *base)
232 {
233   DM_Forest      *forest = (DM_Forest *) dm->data;
234 
235   PetscFunctionBegin;
236   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
237   PetscValidPointer(base, 2);
238   *base = forest->base;
239   PetscFunctionReturn(0);
240 }
241 
242 #undef __FUNCT__
243 #define __FUNCT__ "DMForestSetAdaptivityForest"
244 PetscErrorCode DMForestSetAdaptivityForest(DM dm,DM adapt)
245 {
246   DM_Forest        *forest;
247   PetscErrorCode   ierr;
248 
249   PetscFunctionBegin;
250   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
251   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
252   forest = (DM_Forest *) dm->data;
253   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adaptation forest after setup");
254   switch (forest->adaptPurpose) {
255   case DM_FOREST_KEEP:
256     ierr = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
257     ierr = DMDestroy(&(forest->adapt));CHKERRQ(ierr);
258     forest->adapt = adapt;
259     break;
260   case DM_FOREST_REFINE:
261     ierr = DMSetCoarseDM(dm,adapt);CHKERRQ(ierr);
262     break;
263   case DM_FOREST_COARSEN:
264     ierr = DMSetFineDM(dm,adapt);CHKERRQ(ierr);
265     break;
266   default:
267     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
268   }
269   PetscFunctionReturn(0);
270 }
271 
272 #undef __FUNCT__
273 #define __FUNCT__ "DMForestGetAdaptivityForest"
274 PetscErrorCode DMForestGetAdaptivityForest(DM dm, DM *adapt)
275 {
276   DM_Forest        *forest;
277   PetscErrorCode   ierr;
278 
279   PetscFunctionBegin;
280   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
281   forest = (DM_Forest *) dm->data;
282   switch (forest->adaptPurpose) {
283   case DM_FOREST_KEEP:
284     *adapt = forest->adapt;
285     break;
286   case DM_FOREST_REFINE:
287     ierr = DMGetCoarseDM(dm,adapt);CHKERRQ(ierr);
288     break;
289   case DM_FOREST_COARSEN:
290     ierr = DMGetFineDM(dm,adapt);CHKERRQ(ierr);
291     break;
292   default:
293     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"invalid adaptivity purpose");
294   }
295   PetscFunctionReturn(0);
296 }
297 
298 #undef __FUNCT__
299 #define __FUNCT__ "DMForestSetAdaptivityPurpose"
300 PetscErrorCode DMForestSetAdaptivityPurpose(DM dm, DMForestAdaptivityPurpose purpose)
301 {
302   DM_Forest      *forest;
303   PetscErrorCode ierr;
304 
305   PetscFunctionBegin;
306   forest = (DM_Forest *) dm->data;
307   if (purpose != forest->adaptPurpose) {
308     DM adapt;
309 
310     ierr = DMForestGetAdaptivityForest(dm,&adapt);CHKERRQ(ierr);
311     ierr = PetscObjectReference((PetscObject)adapt);CHKERRQ(ierr);
312     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
313     forest->adaptPurpose = purpose;
314     ierr = DMForestSetAdaptivityForest(dm,adapt);CHKERRQ(ierr);
315     ierr = DMDestroy(&adapt);CHKERRQ(ierr);
316   }
317   PetscFunctionReturn(0);
318 }
319 
320 #undef __FUNCT__
321 #define __FUNCT__ "DMForestSetAdjacencyDimension"
322 PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim)
323 {
324   PetscInt        dim;
325   DM_Forest      *forest = (DM_Forest *) dm->data;
326   PetscErrorCode  ierr;
327 
328   PetscFunctionBegin;
329   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
330   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup");
331   if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim);
332   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
333   if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim);
334   forest->adjDim = adjDim;
335   PetscFunctionReturn(0);
336 }
337 
338 #undef __FUNCT__
339 #define __FUNCT__ "DMForestSetAdjacencyCodimension"
340 PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim)
341 {
342   PetscInt        dim;
343   PetscErrorCode  ierr;
344 
345   PetscFunctionBegin;
346   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
347   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
348   ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr);
349   PetscFunctionReturn(0);
350 }
351 
352 #undef __FUNCT__
353 #define __FUNCT__ "DMForestGetAdjacencyDimension"
354 PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim)
355 {
356   DM_Forest      *forest = (DM_Forest *) dm->data;
357 
358   PetscFunctionBegin;
359   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
360   PetscValidIntPointer(adjDim,2);
361   *adjDim = forest->adjDim;
362   PetscFunctionReturn(0);
363 }
364 
365 #undef __FUNCT__
366 #define __FUNCT__ "DMForestGetAdjacencyCodimension"
367 PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim)
368 {
369   DM_Forest      *forest = (DM_Forest *) dm->data;
370   PetscInt       dim;
371   PetscErrorCode ierr;
372 
373   PetscFunctionBegin;
374   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
375   PetscValidIntPointer(adjCodim,2);
376   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
377   *adjCodim = dim - forest->adjDim;
378   PetscFunctionReturn(0);
379 }
380 
381 #undef __FUNCT__
382 #define __FUNCT__ "DMForestSetPartitionOverlap"
383 PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap)
384 {
385   DM_Forest      *forest = (DM_Forest *) dm->data;
386 
387   PetscFunctionBegin;
388   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
389   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup");
390   if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap);
391   forest->overlap = overlap;
392   PetscFunctionReturn(0);
393 }
394 
395 #undef __FUNCT__
396 #define __FUNCT__ "DMForestGetPartitionOverlap"
397 PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap)
398 {
399   DM_Forest      *forest = (DM_Forest *) dm->data;
400 
401   PetscFunctionBegin;
402   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
403   PetscValidIntPointer(overlap,2);
404   *overlap = forest->overlap;
405   PetscFunctionReturn(0);
406 }
407 
408 #undef __FUNCT__
409 #define __FUNCT__ "DMForestSetMinimumRefinement"
410 PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement)
411 {
412   DM_Forest      *forest = (DM_Forest *) dm->data;
413 
414   PetscFunctionBegin;
415   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
416   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup");
417   forest->minRefinement = minRefinement;
418   PetscFunctionReturn(0);
419 }
420 
421 #undef __FUNCT__
422 #define __FUNCT__ "DMForestGetMinimumRefinement"
423 PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement)
424 {
425   DM_Forest      *forest = (DM_Forest *) dm->data;
426 
427   PetscFunctionBegin;
428   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
429   PetscValidIntPointer(minRefinement,2);
430   *minRefinement = forest->minRefinement;
431   PetscFunctionReturn(0);
432 }
433 
434 #undef __FUNCT__
435 #define __FUNCT__ "DMForestSetInitialRefinement"
436 PetscErrorCode DMForestSetInitialRefinement(DM dm, PetscInt initRefinement)
437 {
438   DM_Forest      *forest = (DM_Forest *) dm->data;
439 
440   PetscFunctionBegin;
441   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
442   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the initial refinement after setup");
443   forest->initRefinement = initRefinement;
444   PetscFunctionReturn(0);
445 }
446 
447 #undef __FUNCT__
448 #define __FUNCT__ "DMForestGetInitialRefinement"
449 PetscErrorCode DMForestGetInitialRefinement(DM dm, PetscInt *initRefinement)
450 {
451   DM_Forest      *forest = (DM_Forest *) dm->data;
452 
453   PetscFunctionBegin;
454   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
455   PetscValidIntPointer(initRefinement,2);
456   *initRefinement = forest->initRefinement;
457   PetscFunctionReturn(0);
458 }
459 
460 #undef __FUNCT__
461 #define __FUNCT__ "DMForestSetMaximumRefinement"
462 PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement)
463 {
464   DM_Forest      *forest = (DM_Forest *) dm->data;
465 
466   PetscFunctionBegin;
467   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
468   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup");
469   forest->maxRefinement = maxRefinement;
470   PetscFunctionReturn(0);
471 }
472 
473 #undef __FUNCT__
474 #define __FUNCT__ "DMForestGetMaximumRefinement"
475 PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement)
476 {
477   DM_Forest      *forest = (DM_Forest *) dm->data;
478 
479   PetscFunctionBegin;
480   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
481   PetscValidIntPointer(maxRefinement,2);
482   *maxRefinement = forest->maxRefinement;
483   PetscFunctionReturn(0);
484 }
485 
486 #undef __FUNCT__
487 #define __FUNCT__ "DMForestSetAdaptivityStrategy"
488 PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy)
489 {
490   DM_Forest      *forest = (DM_Forest *) dm->data;
491   PetscErrorCode ierr;
492 
493   PetscFunctionBegin;
494   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
495   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
496   ierr = PetscStrallocpy((const char *) adaptStrategy,(char **)&forest->adaptStrategy);CHKERRQ(ierr);
497   PetscFunctionReturn(0);
498 }
499 
500 #undef __FUNCT__
501 #define __FUNCT__ "DMForestGetAdaptivityStrategy"
502 PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy)
503 {
504   DM_Forest      *forest = (DM_Forest *) dm->data;
505 
506   PetscFunctionBegin;
507   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
508   PetscValidPointer(adaptStrategy,2);
509   *adaptStrategy = forest->adaptStrategy;
510   PetscFunctionReturn(0);
511 }
512 
513 #undef __FUNCT__
514 #define __FUNCT__ "DMForestSetGradeFactor"
515 PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade)
516 {
517   DM_Forest      *forest = (DM_Forest *) dm->data;
518 
519   PetscFunctionBegin;
520   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
521   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup");
522   forest->gradeFactor = grade;
523   PetscFunctionReturn(0);
524 }
525 
526 #undef __FUNCT__
527 #define __FUNCT__ "DMForestGetGradeFactor"
528 PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade)
529 {
530   DM_Forest      *forest = (DM_Forest *) dm->data;
531 
532   PetscFunctionBegin;
533   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
534   PetscValidIntPointer(grade,2);
535   *grade = forest->gradeFactor;
536   PetscFunctionReturn(0);
537 }
538 
539 #undef __FUNCT__
540 #define __FUNCT__ "DMForestSetCellWeightFactor"
541 PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor)
542 {
543   DM_Forest      *forest = (DM_Forest *) dm->data;
544 
545   PetscFunctionBegin;
546   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
547   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup");
548   forest->weightsFactor = weightsFactor;
549   PetscFunctionReturn(0);
550 }
551 
552 #undef __FUNCT__
553 #define __FUNCT__ "DMForestGetCellWeightFactor"
554 PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor)
555 {
556   DM_Forest      *forest = (DM_Forest *) dm->data;
557 
558   PetscFunctionBegin;
559   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
560   PetscValidRealPointer(weightsFactor,2);
561   *weightsFactor = forest->weightsFactor;
562   PetscFunctionReturn(0);
563 }
564 
565 #undef __FUNCT__
566 #define __FUNCT__ "DMForestGetCellChart"
567 PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd)
568 {
569   DM_Forest      *forest = (DM_Forest *) dm->data;
570   PetscErrorCode ierr;
571 
572   PetscFunctionBegin;
573   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
574   PetscValidIntPointer(cStart,2);
575   PetscValidIntPointer(cEnd,2);
576   if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) {
577     ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr);
578   }
579   *cStart =  forest->cStart;
580   *cEnd   =  forest->cEnd;
581   PetscFunctionReturn(0);
582 }
583 
584 #undef __FUNCT__
585 #define __FUNCT__ "DMForestGetCellSF"
586 PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF)
587 {
588   DM_Forest      *forest = (DM_Forest *) dm->data;
589   PetscErrorCode ierr;
590 
591   PetscFunctionBegin;
592   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
593   PetscValidPointer(cellSF,2);
594   if ((!forest->cellSF) && forest->createcellsf) {
595     ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr);
596   }
597   *cellSF = forest->cellSF;
598   PetscFunctionReturn(0);
599 }
600 
601 #undef __FUNCT__
602 #define __FUNCT__ "DMForestSetAdaptivityLabel"
603 PetscErrorCode DMForestSetAdaptivityLabel(DM dm, const char * adaptLabel)
604 {
605   DM_Forest      *forest = (DM_Forest *) dm->data;
606   PetscErrorCode ierr;
607 
608   PetscFunctionBegin;
609   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
610   ierr = PetscFree(forest->adaptLabel);CHKERRQ(ierr);
611   ierr = PetscStrallocpy(adaptLabel,&forest->adaptLabel);CHKERRQ(ierr);
612   PetscFunctionReturn(0);
613 }
614 
615 #undef __FUNCT__
616 #define __FUNCT__ "DMForestGetAdaptivityLabel"
617 PetscErrorCode DMForestGetAdaptivityLabel(DM dm, const char ** adaptLabel)
618 {
619   DM_Forest      *forest = (DM_Forest *) dm->data;
620 
621   PetscFunctionBegin;
622   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
623   *adaptLabel = forest->adaptLabel;
624   PetscFunctionReturn(0);
625 }
626 
627 #undef __FUNCT__
628 #define __FUNCT__ "DMForestSetCellWeights"
629 PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode)
630 {
631   DM_Forest      *forest = (DM_Forest *) dm->data;
632   PetscInt       cStart, cEnd;
633   PetscErrorCode ierr;
634 
635   PetscFunctionBegin;
636   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
637   ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr);
638   if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd);
639   if (copyMode == PETSC_COPY_VALUES) {
640     if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) {
641       ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr);
642     }
643     ierr = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr);
644     forest->cellWeightsCopyMode = PETSC_OWN_POINTER;
645     PetscFunctionReturn(0);
646   }
647   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) {
648     ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr);
649   }
650   forest->cellWeights  = weights;
651   forest->cellWeightsCopyMode = copyMode;
652   PetscFunctionReturn(0);
653 }
654 
655 #undef __FUNCT__
656 #define __FUNCT__ "DMForestGetCellWeights"
657 PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights)
658 {
659   DM_Forest      *forest = (DM_Forest *) dm->data;
660 
661   PetscFunctionBegin;
662   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
663   PetscValidPointer(weights,2);
664   *weights = forest->cellWeights;
665   PetscFunctionReturn(0);
666 }
667 
668 #undef __FUNCT__
669 #define __FUNCT__ "DMForestSetWeightCapacity"
670 PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity)
671 {
672   DM_Forest      *forest = (DM_Forest *) dm->data;
673 
674   PetscFunctionBegin;
675   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
676   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup");
677   if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity);
678   forest->weightCapacity = capacity;
679   PetscFunctionReturn(0);
680 }
681 
682 #undef __FUNCT__
683 #define __FUNCT__ "DMForestGetWeightCapacity"
684 PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity)
685 {
686   DM_Forest      *forest = (DM_Forest *) dm->data;
687 
688   PetscFunctionBegin;
689   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
690   PetscValidRealPointer(capacity,2);
691   *capacity = forest->weightCapacity;
692   PetscFunctionReturn(0);
693 }
694 
695 #undef __FUNCT__
696 #define __FUNCT__ "DMSetFromOptions_Forest"
697 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptionItems *PetscOptionsObject,DM dm)
698 {
699   DM_Forest                  *forest = (DM_Forest *) dm->data;
700   PetscBool                  flg, flg1, flg2, flg3, flg4;
701   DMForestTopology           oldTopo;
702   char                       stringBuffer[256];
703   PetscViewer                viewer;
704   PetscViewerFormat          format;
705   PetscInt                   adjDim, adjCodim, overlap, minRefinement, initRefinement, maxRefinement, grade;
706   PetscReal                  weightsFactor;
707   DMForestAdaptivityStrategy adaptStrategy;
708   PetscErrorCode             ierr;
709 
710   PetscFunctionBegin;
711   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
712   forest->setfromoptionscalled = PETSC_TRUE;
713   ierr = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr);
714   ierr = PetscOptionsHead(PetscOptionsObject,"DMForest Options");CHKERRQ(ierr);
715   ierr = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg1);CHKERRQ(ierr);
716   ierr = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg2);CHKERRQ(ierr);
717   ierr = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg3);CHKERRQ(ierr);
718   ierr = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg4);CHKERRQ(ierr);
719   if ((PetscInt) flg1 + (PetscInt) flg2 + (PetscInt) flg3 + (PetscInt) flg4 > 1) {
720     SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Specify only one of -dm_forest_{topology,base_dm,coarse_forest,fine_forest}");
721   }
722   if (flg1) {
723     ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr);
724     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
725     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
726   }
727   if (flg2) {
728     DM         base;
729 
730     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr);
731     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
732     ierr = DMLoad(base,viewer);CHKERRQ(ierr);
733     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
734     ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
735     ierr = DMDestroy(&base);CHKERRQ(ierr);
736     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
737     ierr = DMForestSetAdaptivityForest(dm,NULL);CHKERRQ(ierr);
738   }
739   if (flg3) {
740     DM         coarse;
741 
742     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr);
743     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
744     ierr = DMLoad(coarse,viewer);CHKERRQ(ierr);
745     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
746     ierr = DMForestSetAdaptivityForest(dm,coarse);CHKERRQ(ierr);
747     ierr = DMDestroy(&coarse);CHKERRQ(ierr);
748     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
749     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
750   }
751   if (flg4) {
752     DM         fine;
753 
754     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr);
755     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
756     ierr = DMLoad(fine,viewer);CHKERRQ(ierr);
757     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
758     ierr = DMForestSetAdaptivityForest(dm,fine);CHKERRQ(ierr);
759     ierr = DMDestroy(&fine);CHKERRQ(ierr);
760     ierr = DMForestSetTopology(dm,NULL);CHKERRQ(ierr);
761     ierr = DMForestSetBaseDM(dm,NULL);CHKERRQ(ierr);
762   }
763   ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr);
764   ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr);
765   if (flg) {
766     ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr);
767   }
768   else {
769     ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr);
770     ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr);
771     if (flg) {
772       ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr);
773     }
774   }
775   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
776   ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr);
777   if (flg) {
778     ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr);
779   }
780 #if 0
781   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);
782   if (flg) {
783     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
784     ierr = DMForestSetInitialRefinement(dm,minRefinement);CHKERRQ(ierr);
785   }
786   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);
787   if (flg) {
788     ierr = DMForestSetMinimumRefinement(dm,0);CHKERRQ(ierr);
789     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
790   }
791 #endif
792   ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr);
793   ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr);
794   if (flg) {
795     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
796   }
797   ierr = DMForestGetInitialRefinement(dm,&initRefinement);CHKERRQ(ierr);
798   ierr = PetscOptionsInt("-dm_forest_initial_refinement","set the initial level of refinement in the forest","DMForestSetInitialRefinement",initRefinement,&initRefinement,&flg);CHKERRQ(ierr);
799   if (flg) {
800     ierr = DMForestSetInitialRefinement(dm,initRefinement);CHKERRQ(ierr);
801   }
802   ierr = DMForestGetMaximumRefinement(dm,&maxRefinement);CHKERRQ(ierr);
803   ierr = PetscOptionsInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg);CHKERRQ(ierr);
804   if (flg) {
805     ierr = DMForestSetMaximumRefinement(dm,maxRefinement);CHKERRQ(ierr);
806   }
807   ierr = DMForestGetAdaptivityStrategy(dm,&adaptStrategy);CHKERRQ(ierr);
808   ierr = PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,256,&flg);CHKERRQ(ierr);
809   if (flg) {
810     ierr = DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer);CHKERRQ(ierr);
811   }
812   ierr = DMForestGetGradeFactor(dm,&grade);CHKERRQ(ierr);
813   ierr = PetscOptionsInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg);CHKERRQ(ierr);
814   if (flg) {
815     ierr = DMForestSetGradeFactor(dm,grade);CHKERRQ(ierr);
816   }
817   ierr = DMForestGetCellWeightFactor(dm,&weightsFactor);CHKERRQ(ierr);
818   ierr = PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg);CHKERRQ(ierr);
819   if (flg) {
820     ierr = DMForestSetCellWeightFactor(dm,weightsFactor);CHKERRQ(ierr);
821   }
822   ierr = PetscOptionsTail();CHKERRQ(ierr);
823   PetscFunctionReturn(0);
824 }
825 
826 #undef __FUNCT__
827 #define __FUNCT__ "DMCreateSubDM_Forest"
828 PetscErrorCode DMCreateSubDM_Forest(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm)
829 {
830   PetscErrorCode ierr;
831 
832   PetscFunctionBegin;
833   if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);}
834   ierr = DMCreateSubDM_Section_Private(dm, numFields, fields, is, subdm);CHKERRQ(ierr);
835   PetscFunctionReturn(0);
836 }
837 
838 #undef __FUNCT__
839 #define __FUNCT__ "DMRefine_Forest"
840 PetscErrorCode DMRefine_Forest(DM dm, MPI_Comm comm, DM *dmRefined)
841 {
842   DMLabel        refine;
843   DM             fineDM;
844   PetscErrorCode ierr;
845 
846   PetscFunctionBegin;
847   ierr = DMGetFineDM(dm,&fineDM);CHKERRQ(ierr);
848   if (fineDM) {
849     ierr = PetscObjectReference((PetscObject)fineDM);CHKERRQ(ierr);
850     *dmRefined = fineDM;
851     PetscFunctionReturn(0);
852   }
853   ierr = DMForestTemplate(dm,comm,dmRefined);CHKERRQ(ierr);
854   ierr = DMGetLabel(dm,"refine",&refine);CHKERRQ(ierr);
855   if (!refine) {
856     ierr = DMCreateLabel(dm,"refine");CHKERRQ(ierr);
857     ierr = DMGetLabel(dm,"refine",&refine);CHKERRQ(ierr);
858     ierr = DMLabelSetDefaultValue(refine,DM_FOREST_REFINE);CHKERRQ(ierr);
859   }
860   ierr = DMForestSetAdaptivityLabel(*dmRefined,"refine");CHKERRQ(ierr);
861   PetscFunctionReturn(0);
862 }
863 
864 #undef __FUNCT__
865 #define __FUNCT__ "DMCoarsen_Forest"
866 PetscErrorCode DMCoarsen_Forest(DM dm, MPI_Comm comm, DM *dmCoarsened)
867 {
868   DMLabel        coarsen;
869   DM             coarseDM;
870   PetscErrorCode ierr;
871 
872   PetscFunctionBegin;
873   ierr = DMGetCoarseDM(dm,&coarseDM);CHKERRQ(ierr);
874   if (coarseDM) {
875     ierr = PetscObjectReference((PetscObject)coarseDM);CHKERRQ(ierr);
876     *dmCoarsened = coarseDM;
877     PetscFunctionReturn(0);
878   }
879   ierr = DMForestTemplate(dm,comm,dmCoarsened);CHKERRQ(ierr);
880   ierr = DMGetLabel(dm,"coarsen",&coarsen);CHKERRQ(ierr);
881   if (!coarsen) {
882     ierr = DMCreateLabel(dm,"coarsen");CHKERRQ(ierr);
883     ierr = DMGetLabel(dm,"coarsen",&coarsen);CHKERRQ(ierr);
884     ierr = DMLabelSetDefaultValue(coarsen,DM_FOREST_COARSEN);CHKERRQ(ierr);
885   }
886   ierr = DMForestSetAdaptivityLabel(*dmCoarsened,"coarsen");CHKERRQ(ierr);
887   PetscFunctionReturn(0);
888 }
889 
890 #undef __FUNCT__
891 #define __FUNCT__ "DMInitialize_Forest"
892 static PetscErrorCode DMInitialize_Forest(DM dm)
893 {
894   PetscErrorCode ierr;
895 
896   PetscFunctionBegin;
897   ierr = PetscMemzero(dm->ops,sizeof(*(dm->ops)));CHKERRQ(ierr);
898 
899   dm->ops->clone          = DMClone_Forest;
900   dm->ops->setfromoptions = DMSetFromOptions_Forest;
901   dm->ops->destroy        = DMDestroy_Forest;
902   dm->ops->createsubdm    = DMCreateSubDM_Forest;
903   dm->ops->refine         = DMRefine_Forest;
904   dm->ops->coarsen        = DMCoarsen_Forest;
905   PetscFunctionReturn(0);
906 }
907 
908 #undef __FUNCT__
909 #define __FUNCT__ "DMCreate_Forest"
910 PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm)
911 {
912   DM_Forest      *forest;
913   PetscErrorCode ierr;
914 
915   PetscFunctionBegin;
916   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
917   ierr                        = PetscNewLog(dm,&forest);CHKERRQ(ierr);
918   dm->dim                     = 0;
919   dm->data                    = forest;
920   forest->refct               = 1;
921   forest->data                = NULL;
922   forest->setfromoptionscalled      = PETSC_FALSE;
923   forest->topology            = NULL;
924   forest->base                = NULL;
925   forest->adjDim              = PETSC_DEFAULT;
926   forest->overlap             = PETSC_DEFAULT;
927   forest->minRefinement       = PETSC_DEFAULT;
928   forest->maxRefinement       = PETSC_DEFAULT;
929   forest->initRefinement      = PETSC_DEFAULT;
930   forest->cStart              = PETSC_DETERMINE;
931   forest->cEnd                = PETSC_DETERMINE;
932   forest->cellSF              = 0;
933   forest->adaptLabel          = NULL;
934   forest->gradeFactor         = 2;
935   forest->cellWeights         = NULL;
936   forest->cellWeightsCopyMode = PETSC_USE_POINTER;
937   forest->weightsFactor       = 1.;
938   forest->weightCapacity      = 1.;
939   ierr = DMForestSetAdaptivityStrategy(dm,DMFORESTADAPTALL);CHKERRQ(ierr);
940   ierr = DMInitialize_Forest(dm);CHKERRQ(ierr);
941   PetscFunctionReturn(0);
942 }
943 
944