xref: /petsc/src/dm/impls/forest/forest.c (revision dd8e54a282f003ea2417b4268b52ab701d4c1fa1)
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__ "DMForestSetMinimumRefinement"
285 PetscErrorCode DMForestSetMinimumRefinement (DM dm, PetscInt minRefinement)
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 minimum refinement after setup");
292   forest->minRefinement = minRefinement;
293   PetscFunctionReturn(0);
294 }
295 
296 #undef __FUNCT__
297 #define __FUNCT__ "DMForestGetMinimumRefinement"
298 PetscErrorCode DMForestGetMinimumRefinement (DM dm, PetscInt *minRefinement)
299 {
300   DM_Forest      *forest = (DM_Forest *) dm->data;
301 
302   PetscFunctionBegin;
303   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
304   PetscValidIntPointer(minRefinement,2);
305   *minRefinement = forest->minRefinement;
306   PetscFunctionReturn(0);
307 }
308 #undef __FUNCT__
309 #define __FUNCT__ "DMSetFromOptions_Forest"
310 PetscErrorCode DMSetFromFromOptions_Forest(DM dm)
311 {
312   DM_Forest        *forest = (DM_Forest *) dm->data;
313   PetscBool        flg;
314   DMForestTopology oldTopo;
315   char             topology[256];
316   PetscViewer       viewer;
317   PetscViewerFormat format;
318   PetscInt         adjDim, adjCodim, overlap, minRefinement;
319   PetscErrorCode   ierr;
320 
321   PetscFunctionBegin;
322   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
323   forest->setFromOptions = PETSC_TRUE;
324   ierr = PetscOptionsHead("DMForest Options");CHKERRQ(ierr);
325   ierr = DMForestGetTopology(dm, &oldTopo);CHKERRQ(ierr);
326   ierr = PetscOptionsString("-dm_forest_topology","the topology of the forest's base mesh","DMForestSetTopology",oldTopo,topology,256,&flg);CHKERRQ(ierr);
327   if (flg) {
328     ierr = DMForestSetTopology(dm,(DMForestTopology)topology);CHKERRQ(ierr);
329   }
330   ierr = PetscOptionsViewer("-dm_forest_base_dm","load the base DM from a viewer specification","DMForestSetBaseDM",&viewer,&format,&flg);CHKERRQ(ierr);
331   if (flg) {
332     DM         base;
333 
334     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&base);CHKERRQ(ierr);
335     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
336     ierr = DMLoad(base,viewer);CHKERRQ(ierr);
337     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
338     ierr = DMForestSetBaseDM(dm,base);CHKERRQ(ierr);
339     ierr = DMDestroy(&base);CHKERRQ(ierr);
340   }
341   ierr = PetscOptionsViewer("-dm_forest_coarse_forest","load the coarse forest from a viewer specification","DMForestSetCoarseForest",&viewer,&format,&flg);CHKERRQ(ierr);
342   if (flg) {
343     DM         coarse;
344 
345     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&coarse);CHKERRQ(ierr);
346     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
347     ierr = DMLoad(coarse,viewer);CHKERRQ(ierr);
348     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
349     ierr = DMForestSetCoarseForest(dm,coarse);CHKERRQ(ierr);
350     ierr = DMDestroy(&coarse);CHKERRQ(ierr);
351   }
352   ierr = PetscOptionsViewer("-dm_forest_fine_forest","load the fine forest from a viewer specification","DMForestSetFineForest",&viewer,&format,&flg);CHKERRQ(ierr);
353   if (flg) {
354     DM         fine;
355 
356     ierr = DMCreate(PetscObjectComm((PetscObject)dm),&fine);CHKERRQ(ierr);
357     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
358     ierr = DMLoad(fine,viewer);CHKERRQ(ierr);
359     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
360     ierr = DMForestSetFineForest(dm,fine);CHKERRQ(ierr);
361     ierr = DMDestroy(&fine);CHKERRQ(ierr);
362   }
363   ierr = DMForestGetAdjacencyDimension(dm,&adjDim);CHKERRQ(ierr);
364   ierr = PetscOptionsInt("-dm_forest_adjacency_dimension","set the dimension of points that define adjacency in the forest","DMForestSetAdjacencyDimension",adjDim,&adjDim,&flg);CHKERRQ(ierr);
365   if (flg) {
366     ierr = DMForestSetAdjacencyDimension(dm,adjDim);CHKERRQ(ierr);
367   }
368   else {
369     ierr = DMForestGetAdjacencyCodimension(dm,&adjCodim);CHKERRQ(ierr);
370     ierr = PetscOptionsInt("-dm_forest_adjacency_codimension","set the codimension of points that define adjacency in the forest","DMForestSetAdjacencyCodimension",adjCodim,&adjCodim,&flg);CHKERRQ(ierr);
371     if (flg) {
372       ierr = DMForestSetAdjacencyCodimension(dm,adjCodim);CHKERRQ(ierr);
373     }
374   }
375   ierr = DMForestGetPartitionOverlap(dm,&overlap);CHKERRQ(ierr);
376   ierr = PetscOptionsInt("-dm_forest_partition_overlap","set the degree of partition overlap","DMForestSetPartitionOverlap",overlap,&overlap,&flg);CHKERRQ(ierr);
377   if (flg) {
378     ierr = DMForestSetPartitionOverlap(dm,overlap);CHKERRQ(ierr);
379   }
380   ierr = DMForestGetMinimumRefinement(dm,&minRefinement);CHKERRQ(ierr);
381   ierr = PetscOptionsInt("-dm_forest_minimum_refinement","set the minimum level of refinement in the forest","DMForestSetMinimumRefinement",minRefinement,&minRefinement,&flg);CHKERRQ(ierr);
382   if (flg) {
383     ierr = DMForestSetMinimumRefinement(dm,minRefinement);CHKERRQ(ierr);
384   }
385   ierr = PetscOptionsTail();CHKERRQ(ierr);
386   PetscFunctionReturn(0);
387 }
388 
389 #undef __FUNCT__
390 #define __FUNCT__ "DMCreate_Forest"
391 PETSC_EXTERN PetscErrorCode DMCreate_Forest(DM dm)
392 {
393   DM_Forest      *forest;
394   PetscErrorCode ierr;
395 
396   PetscFunctionBegin;
397   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
398   ierr                        = PetscNewLog(dm,&forest);CHKERRQ(ierr);
399   dm->dim                     = 0;
400   dm->data                    = forest;
401   forest->refct               = 1;
402   forest->data                = NULL;
403   forest->setup               = 0;
404   forest->setFromOptions      = PETSC_FALSE;
405   forest->topology            = NULL;
406   forest->base                = NULL;
407   forest->coarse              = NULL;
408   forest->fine                = NULL;
409   forest->adjDim              = PETSC_DEFAULT;
410   forest->overlap             = PETSC_DEFAULT;
411   forest->minRefinement       = PETSC_DEFAULT;
412   forest->maxRefinement       = PETSC_DEFAULT;
413   forest->cStart              = 0;
414   forest->cEnd                = 0;
415   forest->cellSF              = 0;
416   forest->adaptMarkers        = NULL;
417   forest->adaptCopyMode       = PETSC_USE_POINTER;
418   forest->adaptStrategy       = DMFORESTADAPTALL;
419   forest->gradeFactor         = 2;
420   forest->cellWeights         = NULL;
421   forest->cellWeightsCopyMode = PETSC_USE_POINTER;
422   forest->weightsFactor       = 1.;
423   forest->weightCapacity      = 1.;
424   PetscFunctionReturn(0);
425 }
426 
427