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