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