xref: /petsc/src/dm/impls/forest/forest.c (revision fbbfd4723ecc59da2191385614f809b84d9232dc)
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 #undef __FUNCT__
6 #define __FUNCT__ "DMClone_Forest"
7 PETSC_EXTERN PetscErrorCode DMClone_Forest(DM dm, DM *newdm)
8 {
9   DM_Forest        *forest = (DM_Forest *) dm->data;
10   const char       *type;
11   PetscErrorCode ierr;
12 
13   PetscFunctionBegin;
14   forest->refct++;
15   (*newdm)->data = forest;
16   ierr = PetscObjectGetType((PetscObject) dm, &type);CHKERRQ(ierr);
17   ierr = PetscObjectChangeTypeName((PetscObject) *newdm, type);CHKERRQ(ierr);
18   PetscFunctionReturn(0);
19 }
20 
21 #undef __FUNCT__
22 #define __FUNCT__ "DMDestroy_Forest"
23 static PetscErrorCode DMDestroy_Forest(DM dm)
24 {
25   DM_Forest     *forest = (DM_Forest*) dm->data;
26   PetscErrorCode ierr;
27 
28   PetscFunctionBegin;
29   if (--forest->refct > 0) PetscFunctionReturn(0);
30   if (forest->destroy) {ierr = forest->destroy(dm);CHKERRQ(ierr);}
31   ierr = PetscSFDestroy(&forest->cellSF);CHKERRQ(ierr);
32   if (forest->adaptCopyMode == PETSC_OWN_POINTER) {
33     ierr = PetscFree(forest->adaptMarkers);CHKERRQ(ierr);
34   }
35   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) {
36     ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr);
37   }
38   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
39   ierr = PetscFree(forest);CHKERRQ(ierr);
40   PetscFunctionReturn(0);
41 }
42 
43 #undef __FUNCT__
44 #define __FUNCT__ "DMForestSetTopology"
45 PetscErrorCode DMForestSetTopology(DM dm, DMForestTopology topology)
46 {
47   DM_Forest      *forest = (DM_Forest *) dm->data;
48   PetscErrorCode ierr;
49 
50   PetscFunctionBegin;
51   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
52   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the topology after setup");
53   ierr = PetscFree(forest->topology);CHKERRQ(ierr);
54   ierr = PetscStrallocpy((const char *)topology,(char **) &forest->topology);CHKERRQ(ierr);
55   PetscFunctionReturn(0);
56 }
57 
58 #undef __FUNCT__
59 #define __FUNCT__ "DMForestGetTopology"
60 PetscErrorCode DMForestGetTopology(DM dm, DMForestTopology *topology)
61 {
62   DM_Forest      *forest = (DM_Forest *) dm->data;
63 
64   PetscFunctionBegin;
65   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
66   PetscValidPointer(topology,2);
67   *topology = forest->topology;
68   PetscFunctionReturn(0);
69 }
70 
71 #undef __FUNCT__
72 #define __FUNCT__ "DMForestSetBaseDM"
73 PetscErrorCode DMForestSetBaseDM(DM dm, DM base)
74 {
75   DM_Forest      *forest = (DM_Forest *) dm->data;
76   PetscInt       dim, dimEmbed;
77   PetscErrorCode ierr;
78 
79   PetscFunctionBegin;
80   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
81   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
82   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the base after setup");
83   ierr = PetscObjectReference((PetscObject)base);CHKERRQ(ierr);
84   ierr = DMDestroy(&forest->base);CHKERRQ(ierr);
85   forest->base = base;
86   ierr = DMGetDimension(base,&dim);CHKERRQ(ierr);
87   ierr = DMSetDimension(dm,dim);CHKERRQ(ierr);
88   ierr = DMGetCoordinateDim(base,&dimEmbed);CHKERRQ(ierr);
89   ierr = DMSetCoordinateDim(dm,dimEmbed);CHKERRQ(ierr);
90   PetscFunctionReturn(0);
91 }
92 
93 #undef __FUNCT__
94 #define __FUNCT__ "DMForestGetBaseDM"
95 PetscErrorCode DMForestGetBaseDM(DM dm, DM *base)
96 {
97   DM_Forest      *forest = (DM_Forest *) dm->data;
98 
99   PetscFunctionBegin;
100   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
101   PetscValidPointer(base, 2);
102   *base = forest->base;
103   PetscFunctionReturn(0);
104 }
105 
106 #undef __FUNCT__
107 #define __FUNCT__ "DMForestSetCoarseForest"
108 PetscErrorCode DMForestSetCoarseForest(DM dm,DM coarse)
109 {
110   DM_Forest        *forest       = (DM_Forest *) dm->data;
111   DM               base;
112   DMForestTopology topology;
113   PetscErrorCode   ierr;
114 
115   PetscFunctionBegin;
116   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
117   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
118   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the coarse forest after setup");
119   if (!coarse->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot set a coarse forest that is not set up");
120   ierr = PetscObjectReference((PetscObject)coarse);CHKERRQ(ierr);
121   ierr = DMDestroy(&forest->coarse);CHKERRQ(ierr);
122   ierr = DMForestGetBaseDM(coarse,&base);CHKERRQ(ierr);
123   ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
124   ierr = DMForestGetTopology(coarse,&topology);CHKERRQ(ierr);
125   ierr = DMForestSetTopology(dm,topology);CHKERRQ(ierr);
126   forest->coarse = coarse;
127   PetscFunctionReturn(0);
128 }
129 
130 #undef __FUNCT__
131 #define __FUNCT__ "DMForestGetCoarseForest"
132 PetscErrorCode DMForestGetCoarseForest(DM dm, DM *coarse)
133 {
134   DM_Forest      *forest = (DM_Forest *) dm->data;
135 
136   PetscFunctionBegin;
137   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
138   PetscValidPointer(coarse, 2);
139   *coarse = forest->coarse;
140   PetscFunctionReturn(0);
141 }
142 
143 #undef __FUNCT__
144 #define __FUNCT__ "DMForestSetFineForest"
145 PetscErrorCode DMForestSetFineForest(DM dm,DM fine)
146 {
147   DM_Forest        *forest = (DM_Forest *) dm->data;
148   DM               base;
149   DMForestTopology topology;
150   PetscErrorCode   ierr;
151 
152   PetscFunctionBegin;
153   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
154   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
155   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the fine forest after setup");
156   if (!fine->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot set a fine forest that is not set up");
157   ierr = PetscObjectReference((PetscObject)fine);CHKERRQ(ierr);
158   ierr = DMDestroy(&forest->fine);CHKERRQ(ierr);
159   ierr = DMForestGetBaseDM(fine,&base);CHKERRQ(ierr);
160   ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
161   ierr = DMForestGetTopology(fine,&topology);CHKERRQ(ierr);
162   ierr = DMForestSetTopology(dm,topology);CHKERRQ(ierr);
163   forest->fine = fine;
164   PetscFunctionReturn(0);
165 }
166 
167 #undef __FUNCT__
168 #define __FUNCT__ "DMForestGetFineForest"
169 PetscErrorCode DMForestGetFineForest(DM dm, DM *fine)
170 {
171   DM_Forest      *forest = (DM_Forest *) dm->data;
172 
173   PetscFunctionBegin;
174   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
175   PetscValidPointer(fine, 2);
176   *fine = forest->fine;
177   PetscFunctionReturn(0);
178 }
179 
180 #undef __FUNCT__
181 #define __FUNCT__ "DMForestSetAdjacencyDimension"
182 PetscErrorCode DMForestSetAdjacencyDimension(DM dm, PetscInt adjDim)
183 {
184   PetscInt        dim;
185   DM_Forest      *forest = (DM_Forest *) dm->data;
186   PetscErrorCode  ierr;
187 
188   PetscFunctionBegin;
189   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
190   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the adjacency dimension after setup");
191   if (adjDim < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be < 0: %d", adjDim);
192   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
193   if (adjDim > dim) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"adjacency dim cannot be > %d: %d", dim, adjDim);
194   forest->adjDim = adjDim;
195   PetscFunctionReturn(0);
196 }
197 
198 #undef __FUNCT__
199 #define __FUNCT__ "DMForestSetAdjacencyCodimension"
200 PetscErrorCode DMForestSetAdjacencyCodimension(DM dm, PetscInt adjCodim)
201 {
202   PetscInt        dim;
203   PetscErrorCode  ierr;
204 
205   PetscFunctionBegin;
206   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
207   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
208   ierr = DMForestSetAdjacencyDimension(dm,dim-adjCodim);CHKERRQ(ierr);
209   PetscFunctionReturn(0);
210 }
211 
212 #undef __FUNCT__
213 #define __FUNCT__ "DMForestGetAdjacencyDimension"
214 PetscErrorCode DMForestGetAdjacencyDimension(DM dm, PetscInt *adjDim)
215 {
216   DM_Forest      *forest = (DM_Forest *) dm->data;
217 
218   PetscFunctionBegin;
219   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
220   PetscValidIntPointer(adjDim,2);
221   *adjDim = forest->adjDim;
222   PetscFunctionReturn(0);
223 }
224 
225 #undef __FUNCT__
226 #define __FUNCT__ "DMForestGetAdjacencyCodimension"
227 PetscErrorCode DMForestGetAdjacencyCodimension(DM dm, PetscInt *adjCodim)
228 {
229   DM_Forest      *forest = (DM_Forest *) dm->data;
230   PetscInt       dim;
231   PetscErrorCode ierr;
232 
233   PetscFunctionBegin;
234   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
235   PetscValidIntPointer(adjCodim,2);
236   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
237   *adjCodim = dim - forest->adjDim;
238   PetscFunctionReturn(0);
239 }
240 
241 #undef __FUNCT__
242 #define __FUNCT__ "DMForestSetPartitionOverlap"
243 PetscErrorCode DMForestSetPartitionOverlap(DM dm, PetscInt overlap)
244 {
245   DM_Forest      *forest = (DM_Forest *) dm->data;
246 
247   PetscFunctionBegin;
248   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
249   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the overlap after setup");
250   if (overlap < 0) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"overlap cannot be < 0: %d", overlap);
251   forest->overlap = overlap;
252   PetscFunctionReturn(0);
253 }
254 
255 #undef __FUNCT__
256 #define __FUNCT__ "DMForestGetPartitionOverlap"
257 PetscErrorCode DMForestGetPartitionOverlap(DM dm, PetscInt *overlap)
258 {
259   DM_Forest      *forest = (DM_Forest *) dm->data;
260 
261   PetscFunctionBegin;
262   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
263   PetscValidIntPointer(overlap,2);
264   *overlap = forest->overlap;
265   PetscFunctionReturn(0);
266 }
267 
268 #undef __FUNCT__
269 #define __FUNCT__ "DMForestSetMinimumRefinement"
270 PetscErrorCode DMForestSetMinimumRefinement(DM dm, PetscInt minRefinement)
271 {
272   DM_Forest      *forest = (DM_Forest *) dm->data;
273 
274   PetscFunctionBegin;
275   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
276   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the minimum refinement after setup");
277   forest->minRefinement = minRefinement;
278   PetscFunctionReturn(0);
279 }
280 
281 #undef __FUNCT__
282 #define __FUNCT__ "DMForestGetMinimumRefinement"
283 PetscErrorCode DMForestGetMinimumRefinement(DM dm, PetscInt *minRefinement)
284 {
285   DM_Forest      *forest = (DM_Forest *) dm->data;
286 
287   PetscFunctionBegin;
288   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
289   PetscValidIntPointer(minRefinement,2);
290   *minRefinement = forest->minRefinement;
291   PetscFunctionReturn(0);
292 }
293 
294 #undef __FUNCT__
295 #define __FUNCT__ "DMForestSetMaximumRefinement"
296 PetscErrorCode DMForestSetMaximumRefinement(DM dm, PetscInt maxRefinement)
297 {
298   DM_Forest      *forest = (DM_Forest *) dm->data;
299 
300   PetscFunctionBegin;
301   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
302   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the maximum refinement after setup");
303   forest->maxRefinement = maxRefinement;
304   PetscFunctionReturn(0);
305 }
306 
307 #undef __FUNCT__
308 #define __FUNCT__ "DMForestGetMaximumRefinement"
309 PetscErrorCode DMForestGetMaximumRefinement(DM dm, PetscInt *maxRefinement)
310 {
311   DM_Forest      *forest = (DM_Forest *) dm->data;
312 
313   PetscFunctionBegin;
314   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
315   PetscValidIntPointer(maxRefinement,2);
316   *maxRefinement = forest->maxRefinement;
317   PetscFunctionReturn(0);
318 }
319 
320 #undef __FUNCT__
321 #define __FUNCT__ "DMForestSetAdaptivityStrategy"
322 PetscErrorCode DMForestSetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy adaptStrategy)
323 {
324   DM_Forest      *forest = (DM_Forest *) dm->data;
325   PetscErrorCode ierr;
326 
327   PetscFunctionBegin;
328   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
329   ierr = PetscFree(forest->adaptStrategy);CHKERRQ(ierr);
330   ierr = PetscStrallocpy((const char *)adaptStrategy,(char **)adaptStrategy);CHKERRQ(ierr);
331   PetscFunctionReturn(0);
332 }
333 
334 #undef __FUNCT__
335 #define __FUNCT__ "DMForestGetAdaptivityStrategy"
336 PetscErrorCode DMForestGetAdaptivityStrategy(DM dm, DMForestAdaptivityStrategy *adaptStrategy)
337 {
338   DM_Forest      *forest = (DM_Forest *) dm->data;
339 
340   PetscFunctionBegin;
341   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
342   PetscValidPointer(adaptStrategy,2);
343   *adaptStrategy = forest->adaptStrategy;
344   PetscFunctionReturn(0);
345 }
346 
347 #undef __FUNCT__
348 #define __FUNCT__ "DMForestSetGradeFactor"
349 PetscErrorCode DMForestSetGradeFactor(DM dm, PetscInt grade)
350 {
351   DM_Forest      *forest = (DM_Forest *) dm->data;
352 
353   PetscFunctionBegin;
354   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
355   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the grade factor after setup");
356   forest->gradeFactor = grade;
357   PetscFunctionReturn(0);
358 }
359 
360 #undef __FUNCT__
361 #define __FUNCT__ "DMForestGetGradeFactor"
362 PetscErrorCode DMForestGetGradeFactor(DM dm, PetscInt *grade)
363 {
364   DM_Forest      *forest = (DM_Forest *) dm->data;
365 
366   PetscFunctionBegin;
367   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
368   PetscValidIntPointer(grade,2);
369   *grade = forest->gradeFactor;
370   PetscFunctionReturn(0);
371 }
372 
373 #undef __FUNCT__
374 #define __FUNCT__ "DMForestSetCellWeightFactor"
375 PetscErrorCode DMForestSetCellWeightFactor(DM dm, PetscReal weightsFactor)
376 {
377   DM_Forest      *forest = (DM_Forest *) dm->data;
378 
379   PetscFunctionBegin;
380   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
381   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weights factor after setup");
382   forest->weightsFactor = weightsFactor;
383   PetscFunctionReturn(0);
384 }
385 
386 #undef __FUNCT__
387 #define __FUNCT__ "DMForestGetCellWeightFactor"
388 PetscErrorCode DMForestGetCellWeightFactor(DM dm, PetscReal *weightsFactor)
389 {
390   DM_Forest      *forest = (DM_Forest *) dm->data;
391 
392   PetscFunctionBegin;
393   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
394   PetscValidRealPointer(weightsFactor,2);
395   *weightsFactor = forest->weightsFactor;
396   PetscFunctionReturn(0);
397 }
398 
399 #undef __FUNCT__
400 #define __FUNCT__ "DMForestGetCellChart"
401 PetscErrorCode DMForestGetCellChart(DM dm, PetscInt *cStart, PetscInt *cEnd)
402 {
403   DM_Forest      *forest = (DM_Forest *) dm->data;
404   PetscErrorCode ierr;
405 
406   PetscFunctionBegin;
407   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
408   PetscValidIntPointer(cStart,2);
409   PetscValidIntPointer(cEnd,2);
410   if (((forest->cStart == PETSC_DETERMINE) || (forest->cEnd == PETSC_DETERMINE)) && forest->createcellchart) {
411     ierr = forest->createcellchart(dm,&forest->cStart,&forest->cEnd);CHKERRQ(ierr);
412   }
413   *cStart =  forest->cStart;
414   *cEnd   =  forest->cEnd;
415   PetscFunctionReturn(0);
416 }
417 
418 #undef __FUNCT__
419 #define __FUNCT__ "DMForestGetCellSF"
420 PetscErrorCode DMForestGetCellSF(DM dm, PetscSF *cellSF)
421 {
422   DM_Forest      *forest = (DM_Forest *) dm->data;
423   PetscErrorCode ierr;
424 
425   PetscFunctionBegin;
426   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
427   PetscValidPointer(cellSF,2);
428   if ((!forest->cellSF) && forest->createcellsf) {
429     ierr = forest->createcellsf(dm,&forest->cellSF);CHKERRQ(ierr);
430   }
431   *cellSF = forest->cellSF;
432   PetscFunctionReturn(0);
433 }
434 
435 #undef __FUNCT__
436 #define __FUNCT__ "DMForestSetAdaptivityMarkers"
437 PetscErrorCode DMForestSetAdaptivityMarkers(DM dm, PetscInt markers[], PetscCopyMode copyMode)
438 {
439   DM_Forest      *forest = (DM_Forest *) dm->data;
440   PetscInt       cStart, cEnd;
441   PetscErrorCode ierr;
442 
443   PetscFunctionBegin;
444   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
445   ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr);
446   if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd);
447   if (copyMode == PETSC_COPY_VALUES) {
448     if (forest->adaptCopyMode != PETSC_OWN_POINTER || forest->adaptMarkers == markers) {
449       ierr = PetscMalloc1(cEnd-cStart,&forest->adaptMarkers);CHKERRQ(ierr);
450     }
451     ierr = PetscMemcpy(forest->adaptMarkers,markers,(cEnd-cStart)*sizeof(*markers));CHKERRQ(ierr);
452     forest->adaptCopyMode = PETSC_OWN_POINTER;
453     PetscFunctionReturn(0);
454   }
455   if (forest->adaptCopyMode == PETSC_OWN_POINTER) {
456     ierr = PetscFree(forest->adaptMarkers);CHKERRQ(ierr);
457   }
458   forest->adaptMarkers  = markers;
459   forest->adaptCopyMode = copyMode;
460   PetscFunctionReturn(0);
461 }
462 
463 #undef __FUNCT__
464 #define __FUNCT__ "DMForestGetAdaptivityMarkers"
465 PetscErrorCode DMForestGetAdaptivityMarkers(DM dm, PetscInt **markers)
466 {
467   DM_Forest      *forest = (DM_Forest *) dm->data;
468 
469   PetscFunctionBegin;
470   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
471   PetscValidPointer(markers,2);
472   *markers = forest->adaptMarkers;
473   PetscFunctionReturn(0);
474 }
475 
476 #undef __FUNCT__
477 #define __FUNCT__ "DMForestSetCellWeights"
478 PetscErrorCode DMForestSetCellWeights(DM dm, PetscReal weights[], PetscCopyMode copyMode)
479 {
480   DM_Forest      *forest = (DM_Forest *) dm->data;
481   PetscInt       cStart, cEnd;
482   PetscErrorCode ierr;
483 
484   PetscFunctionBegin;
485   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
486   ierr = DMForestGetCellChart(dm,&cStart,&cEnd);CHKERRQ(ierr);
487   if (cEnd < cStart) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"cell chart [%d,%d) is not valid",cStart,cEnd);
488   if (copyMode == PETSC_COPY_VALUES) {
489     if (forest->cellWeightsCopyMode != PETSC_OWN_POINTER || forest->cellWeights == weights) {
490       ierr = PetscMalloc1(cEnd-cStart,&forest->cellWeights);CHKERRQ(ierr);
491     }
492     ierr = PetscMemcpy(forest->cellWeights,weights,(cEnd-cStart)*sizeof(*weights));CHKERRQ(ierr);
493     forest->cellWeightsCopyMode = PETSC_OWN_POINTER;
494     PetscFunctionReturn(0);
495   }
496   if (forest->cellWeightsCopyMode == PETSC_OWN_POINTER) {
497     ierr = PetscFree(forest->cellWeights);CHKERRQ(ierr);
498   }
499   forest->cellWeights  = weights;
500   forest->cellWeightsCopyMode = copyMode;
501   PetscFunctionReturn(0);
502 }
503 
504 #undef __FUNCT__
505 #define __FUNCT__ "DMForestGetCellWeights"
506 PetscErrorCode DMForestGetCellWeights(DM dm, PetscReal **weights)
507 {
508   DM_Forest      *forest = (DM_Forest *) dm->data;
509 
510   PetscFunctionBegin;
511   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
512   PetscValidPointer(weights,2);
513   *weights = forest->cellWeights;
514   PetscFunctionReturn(0);
515 }
516 
517 #undef __FUNCT__
518 #define __FUNCT__ "DMForestSetWeightCapacity"
519 PetscErrorCode DMForestSetWeightCapacity(DM dm, PetscReal capacity)
520 {
521   DM_Forest      *forest = (DM_Forest *) dm->data;
522 
523   PetscFunctionBegin;
524   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
525   if (dm->setupcalled) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Cannot change the weight capacity after setup");
526   if (capacity < 0.) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_OUTOFRANGE,"Cannot have negative weight capacity; %f",capacity);
527   forest->weightCapacity = capacity;
528   PetscFunctionReturn(0);
529 }
530 
531 #undef __FUNCT__
532 #define __FUNCT__ "DMForestGetWeightCapacity"
533 PetscErrorCode DMForestGetWeightCapacity(DM dm, PetscReal *capacity)
534 {
535   DM_Forest      *forest = (DM_Forest *) dm->data;
536 
537   PetscFunctionBegin;
538   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
539   PetscValidRealPointer(capacity,2);
540   *capacity = forest->weightCapacity;
541   PetscFunctionReturn(0);
542 }
543 
544 #undef __FUNCT__
545 #define __FUNCT__ "DMSetFromOptions_Forest"
546 PETSC_EXTERN PetscErrorCode DMSetFromOptions_Forest(PetscOptions *PetscOptionsObject,DM dm)
547 {
548   DM_Forest                  *forest = (DM_Forest *) dm->data;
549   PetscBool                  flg;
550   DMForestTopology           oldTopo;
551   char                       stringBuffer[256];
552   PetscViewer                viewer;
553   PetscViewerFormat          format;
554   PetscInt                   adjDim, adjCodim, overlap, minRefinement, maxRefinement, grade;
555   PetscReal                  weightsFactor;
556   DMForestAdaptivityStrategy adaptStrategy;
557   PetscErrorCode             ierr;
558 
559   PetscFunctionBegin;
560   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
561   forest->setFromOptions = PETSC_TRUE;
562   ierr = PetscOptionsHead(PetscOptionsObject,"DMForest Options");CHKERRQ(ierr);
563   ierr = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr);
564   ierr = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,stringBuffer,256,&flg);CHKERRQ(ierr);
565   if (flg) {
566     ierr = DMForestSetTopology(dm,(DMForestTopology)stringBuffer);CHKERRQ(ierr);
567   }
568   ierr = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg);CHKERRQ(ierr);
569   if (flg) {
570     DM         base;
571 
572     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr);
573     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
574     ierr = DMLoad(base,viewer);CHKERRQ(ierr);
575     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
576     ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
577     ierr = DMDestroy(&base);CHKERRQ(ierr);
578   }
579   ierr = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg);CHKERRQ(ierr);
580   if (flg) {
581     DM         coarse;
582 
583     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr);
584     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
585     ierr = DMLoad(coarse,viewer);CHKERRQ(ierr);
586     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
587     ierr = DMForestSetCoarseForest(dm,coarse);CHKERRQ(ierr);
588     ierr = DMDestroy(&coarse);CHKERRQ(ierr);
589   }
590   ierr = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg);CHKERRQ(ierr);
591   if (flg) {
592     DM         fine;
593 
594     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr);
595     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
596     ierr = DMLoad(fine,viewer);CHKERRQ(ierr);
597     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
598     ierr = DMForestSetFineForest(dm,fine);CHKERRQ(ierr);
599     ierr = DMDestroy(&fine);CHKERRQ(ierr);
600   }
601   ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr);
602   ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr);
603   if (flg) {
604     ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr);
605   }
606   else {
607     ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr);
608     ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr);
609     if (flg) {
610       ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr);
611     }
612   }
613   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
614   ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr);
615   if (flg) {
616     ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr);
617   }
618   ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr);
619   ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr);
620   if (flg) {
621     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
622   }
623   ierr = DMForestGetMaximumRefinement(dm,&maxRefinement);CHKERRQ(ierr);
624   ierr = PetscOptionsInt("-dm_forest_maximum_refinement","set the maximum level of refinement in the forest","DMForestSetMaximumRefinement",maxRefinement,&maxRefinement,&flg);CHKERRQ(ierr);
625   if (flg) {
626     ierr = DMForestSetMaximumRefinement(dm,maxRefinement);CHKERRQ(ierr);
627   }
628   ierr = DMForestGetAdaptivityStrategy(dm,&adaptStrategy);CHKERRQ(ierr);
629   ierr = PetscOptionsString("-dm_forest_adaptivity_strategy","the forest's adaptivity-flag resolution strategy","DMForestSetAdaptivityStrategy",adaptStrategy,stringBuffer,256,&flg);CHKERRQ(ierr);
630   if (flg) {
631     ierr = DMForestSetAdaptivityStrategy(dm,(DMForestAdaptivityStrategy)stringBuffer);CHKERRQ(ierr);
632   }
633   ierr = DMForestGetGradeFactor(dm,&grade);CHKERRQ(ierr);
634   ierr = PetscOptionsInt("-dm_forest_grade_factor","grade factor between neighboring cells","DMForestSetGradeFactor",grade,&grade,&flg);CHKERRQ(ierr);
635   if (flg) {
636     ierr = DMForestSetGradeFactor(dm,grade);CHKERRQ(ierr);
637   }
638   ierr = DMForestGetCellWeightFactor(dm,&weightsFactor);CHKERRQ(ierr);
639   ierr = PetscOptionsReal("-dm_forest_cell_weight_factor","multiplying weight factor for cell refinement","DMForestSetCellWeightFactor",weightsFactor,&weightsFactor,&flg);CHKERRQ(ierr);
640   if (flg) {
641     ierr = DMForestSetCellWeightFactor(dm,weightsFactor);CHKERRQ(ierr);
642   }
643   ierr = PetscOptionsTail();CHKERRQ(ierr);
644   PetscFunctionReturn(0);
645 }
646 
647 #undef __FUNCT__
648 #define __FUNCT__ "DMInitialize_Forest"
649 static PetscErrorCode DMInitialize_Forest(DM dm)
650 {
651   PetscErrorCode ierr;
652 
653   PetscFunctionBegin;
654   ierr = PetscMemzero(dm->ops,sizeof(*(dm->ops)));CHKERRQ(ierr);
655 
656   dm->ops->clone          = DMClone_Forest;
657   dm->ops->setfromoptions = DMSetFromOptions_Forest;
658   dm->ops->destroy        = DMDestroy_Forest;
659   PetscFunctionReturn(0);
660 }
661 
662 #undef __FUNCT__
663 #define __FUNCT__ "DMCreate_Forest"
664 PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm)
665 {
666   DM_Forest      *forest;
667   PetscErrorCode ierr;
668 
669   PetscFunctionBegin;
670   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
671   ierr                        = PetscNewLog(dm,&forest);CHKERRQ(ierr);
672   dm->dim                     = 0;
673   dm->data                    = forest;
674   forest->refct               = 1;
675   forest->data                = NULL;
676   forest->setFromOptions      = PETSC_FALSE;
677   forest->topology            = NULL;
678   forest->base                = NULL;
679   forest->coarse              = NULL;
680   forest->fine                = NULL;
681   forest->adjDim              = PETSC_DEFAULT;
682   forest->overlap             = PETSC_DEFAULT;
683   forest->minRefinement       = PETSC_DEFAULT;
684   forest->maxRefinement       = PETSC_DEFAULT;
685   forest->cStart              = PETSC_DETERMINE;
686   forest->cEnd                = PETSC_DETERMINE;
687   forest->cellSF              = 0;
688   forest->adaptMarkers        = NULL;
689   forest->adaptCopyMode       = PETSC_USE_POINTER;
690   forest->adaptStrategy       = DMFORESTADAPTALL;
691   forest->gradeFactor         = 2;
692   forest->cellWeights         = NULL;
693   forest->cellWeightsCopyMode = PETSC_USE_POINTER;
694   forest->weightsFactor       = 1.;
695   forest->weightCapacity      = 1.;
696   ierr = DMInitialize_Forest(dm);CHKERRQ(ierr);
697   PetscFunctionReturn(0);
698 }
699 
700