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