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