xref: /petsc/src/dm/impls/da/dacreate.c (revision ca0d62ff0b92f3b3ec10dd93d500c979243edb4e)
1 
2 #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
3 
4 static PetscErrorCode DMSetFromOptions_DA(DM da, PetscOptionItems *PetscOptionsObject)
5 {
6   DM_DA    *dd     = (DM_DA *)da->data;
7   PetscInt  refine = 0, dim = da->dim, maxnlevels = 100, refx[100], refy[100], refz[100], n, i;
8   PetscBool flg;
9 
10   PetscFunctionBegin;
11   PetscCheck(dd->M >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime");
12   PetscCheck(dd->N >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime");
13   PetscCheck(dd->P >= 0, PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_OUTOFRANGE, "Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime");
14 
15   PetscOptionsHeadBegin(PetscOptionsObject, "DMDA Options");
16   PetscCall(PetscOptionsBoundedInt("-da_grid_x", "Number of grid points in x direction", "DMDASetSizes", dd->M, &dd->M, NULL, 1));
17   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_grid_y", "Number of grid points in y direction", "DMDASetSizes", dd->N, &dd->N, NULL, 1));
18   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_grid_z", "Number of grid points in z direction", "DMDASetSizes", dd->P, &dd->P, NULL, 1));
19 
20   PetscCall(PetscOptionsBoundedInt("-da_overlap", "Decomposition overlap in all directions", "DMDASetOverlap", dd->xol, &dd->xol, &flg, 0));
21   if (flg) PetscCall(DMDASetOverlap(da, dd->xol, dd->xol, dd->xol));
22   PetscCall(PetscOptionsBoundedInt("-da_overlap_x", "Decomposition overlap in x direction", "DMDASetOverlap", dd->xol, &dd->xol, NULL, 0));
23   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_overlap_y", "Decomposition overlap in y direction", "DMDASetOverlap", dd->yol, &dd->yol, NULL, 0));
24   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_overlap_z", "Decomposition overlap in z direction", "DMDASetOverlap", dd->zol, &dd->zol, NULL, 0));
25 
26   PetscCall(PetscOptionsBoundedInt("-da_local_subdomains", "", "DMDASetNumLocalSubdomains", dd->Nsub, &dd->Nsub, &flg, PETSC_DECIDE));
27   if (flg) PetscCall(DMDASetNumLocalSubDomains(da, dd->Nsub));
28 
29   /* Handle DMDA parallel distribution */
30   PetscCall(PetscOptionsBoundedInt("-da_processors_x", "Number of processors in x direction", "DMDASetNumProcs", dd->m, &dd->m, NULL, PETSC_DECIDE));
31   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_processors_y", "Number of processors in y direction", "DMDASetNumProcs", dd->n, &dd->n, NULL, PETSC_DECIDE));
32   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_processors_z", "Number of processors in z direction", "DMDASetNumProcs", dd->p, &dd->p, NULL, PETSC_DECIDE));
33   /* Handle DMDA refinement */
34   PetscCall(PetscOptionsBoundedInt("-da_refine_x", "Refinement ratio in x direction", "DMDASetRefinementFactor", dd->refine_x, &dd->refine_x, NULL, 1));
35   if (dim > 1) PetscCall(PetscOptionsBoundedInt("-da_refine_y", "Refinement ratio in y direction", "DMDASetRefinementFactor", dd->refine_y, &dd->refine_y, NULL, 1));
36   if (dim > 2) PetscCall(PetscOptionsBoundedInt("-da_refine_z", "Refinement ratio in z direction", "DMDASetRefinementFactor", dd->refine_z, &dd->refine_z, NULL, 1));
37   dd->coarsen_x = dd->refine_x;
38   dd->coarsen_y = dd->refine_y;
39   dd->coarsen_z = dd->refine_z;
40 
41   /* Get refinement factors, defaults taken from the coarse DMDA */
42   PetscCall(DMDAGetRefinementFactor(da, &refx[0], &refy[0], &refz[0]));
43   for (i = 1; i < maxnlevels; i++) {
44     refx[i] = refx[0];
45     refy[i] = refy[0];
46     refz[i] = refz[0];
47   }
48   n = maxnlevels;
49   PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_x", "Refinement factor for each level", "None", refx, &n, &flg));
50   if (flg) {
51     dd->refine_x        = refx[0];
52     dd->refine_x_hier_n = n;
53     PetscCall(PetscMalloc1(n, &dd->refine_x_hier));
54     PetscCall(PetscArraycpy(dd->refine_x_hier, refx, n));
55   }
56   if (dim > 1) {
57     n = maxnlevels;
58     PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_y", "Refinement factor for each level", "None", refy, &n, &flg));
59     if (flg) {
60       dd->refine_y        = refy[0];
61       dd->refine_y_hier_n = n;
62       PetscCall(PetscMalloc1(n, &dd->refine_y_hier));
63       PetscCall(PetscArraycpy(dd->refine_y_hier, refy, n));
64     }
65   }
66   if (dim > 2) {
67     n = maxnlevels;
68     PetscCall(PetscOptionsIntArray("-da_refine_hierarchy_z", "Refinement factor for each level", "None", refz, &n, &flg));
69     if (flg) {
70       dd->refine_z        = refz[0];
71       dd->refine_z_hier_n = n;
72       PetscCall(PetscMalloc1(n, &dd->refine_z_hier));
73       PetscCall(PetscArraycpy(dd->refine_z_hier, refz, n));
74     }
75   }
76 
77   PetscCall(PetscOptionsBoundedInt("-da_refine", "Uniformly refine DA one or more times", "None", refine, &refine, NULL, 0));
78   PetscOptionsHeadEnd();
79 
80   while (refine--) {
81     if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
82       PetscCall(PetscIntMultError(dd->refine_x, dd->M, &dd->M));
83     } else {
84       PetscCall(PetscIntMultError(dd->refine_x, dd->M - 1, &dd->M));
85       dd->M += 1;
86     }
87     if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
88       PetscCall(PetscIntMultError(dd->refine_y, dd->N, &dd->N));
89     } else {
90       PetscCall(PetscIntMultError(dd->refine_y, dd->N - 1, &dd->N));
91       dd->N += 1;
92     }
93     if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) {
94       PetscCall(PetscIntMultError(dd->refine_z, dd->P, &dd->P));
95     } else {
96       PetscCall(PetscIntMultError(dd->refine_z, dd->P - 1, &dd->P));
97       dd->P += 1;
98     }
99     da->levelup++;
100     if (da->levelup - da->leveldown >= 0) {
101       dd->refine_x = refx[da->levelup - da->leveldown];
102       dd->refine_y = refy[da->levelup - da->leveldown];
103       dd->refine_z = refz[da->levelup - da->leveldown];
104     }
105     if (da->levelup - da->leveldown >= 1) {
106       dd->coarsen_x = refx[da->levelup - da->leveldown - 1];
107       dd->coarsen_y = refy[da->levelup - da->leveldown - 1];
108       dd->coarsen_z = refz[da->levelup - da->leveldown - 1];
109     }
110   }
111   PetscFunctionReturn(PETSC_SUCCESS);
112 }
113 
114 static PetscErrorCode DMLoad_DA(DM da, PetscViewer viewer)
115 {
116   PetscInt        dim, m, n, p, dof, swidth;
117   DMDAStencilType stencil;
118   DMBoundaryType  bx, by, bz;
119   PetscBool       coors;
120   DM              dac;
121   Vec             c;
122 
123   PetscFunctionBegin;
124   PetscCall(PetscViewerBinaryRead(viewer, &dim, 1, NULL, PETSC_INT));
125   PetscCall(PetscViewerBinaryRead(viewer, &m, 1, NULL, PETSC_INT));
126   PetscCall(PetscViewerBinaryRead(viewer, &n, 1, NULL, PETSC_INT));
127   PetscCall(PetscViewerBinaryRead(viewer, &p, 1, NULL, PETSC_INT));
128   PetscCall(PetscViewerBinaryRead(viewer, &dof, 1, NULL, PETSC_INT));
129   PetscCall(PetscViewerBinaryRead(viewer, &swidth, 1, NULL, PETSC_INT));
130   PetscCall(PetscViewerBinaryRead(viewer, &bx, 1, NULL, PETSC_ENUM));
131   PetscCall(PetscViewerBinaryRead(viewer, &by, 1, NULL, PETSC_ENUM));
132   PetscCall(PetscViewerBinaryRead(viewer, &bz, 1, NULL, PETSC_ENUM));
133   PetscCall(PetscViewerBinaryRead(viewer, &stencil, 1, NULL, PETSC_ENUM));
134 
135   PetscCall(DMSetDimension(da, dim));
136   PetscCall(DMDASetSizes(da, m, n, p));
137   PetscCall(DMDASetBoundaryType(da, bx, by, bz));
138   PetscCall(DMDASetDof(da, dof));
139   PetscCall(DMDASetStencilType(da, stencil));
140   PetscCall(DMDASetStencilWidth(da, swidth));
141   PetscCall(DMSetUp(da));
142   PetscCall(PetscViewerBinaryRead(viewer, &coors, 1, NULL, PETSC_ENUM));
143   if (coors) {
144     PetscCall(DMGetCoordinateDM(da, &dac));
145     PetscCall(DMCreateGlobalVector(dac, &c));
146     PetscCall(VecLoad(c, viewer));
147     PetscCall(DMSetCoordinates(da, c));
148     PetscCall(VecDestroy(&c));
149   }
150   PetscFunctionReturn(PETSC_SUCCESS);
151 }
152 
153 static PetscErrorCode DMCreateSubDM_DA(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm)
154 {
155   DM_DA *da = (DM_DA *)dm->data;
156 
157   PetscFunctionBegin;
158   if (subdm) {
159     PetscSF sf;
160     Vec     coords;
161     void   *ctx;
162     /* Cannot use DMClone since the dof stuff is mixed in. Ugh
163     PetscCall(DMClone(dm, subdm)); */
164     PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), subdm));
165     PetscCall(DMGetPointSF(dm, &sf));
166     PetscCall(DMSetPointSF(*subdm, sf));
167     PetscCall(DMGetApplicationContext(dm, &ctx));
168     PetscCall(DMSetApplicationContext(*subdm, ctx));
169     PetscCall(DMGetCoordinatesLocal(dm, &coords));
170     if (coords) {
171       PetscCall(DMSetCoordinatesLocal(*subdm, coords));
172     } else {
173       PetscCall(DMGetCoordinates(dm, &coords));
174       if (coords) PetscCall(DMSetCoordinates(*subdm, coords));
175     }
176 
177     PetscCall(DMSetType(*subdm, DMDA));
178     PetscCall(DMSetDimension(*subdm, dm->dim));
179     PetscCall(DMDASetSizes(*subdm, da->M, da->N, da->P));
180     PetscCall(DMDASetNumProcs(*subdm, da->m, da->n, da->p));
181     PetscCall(DMDASetBoundaryType(*subdm, da->bx, da->by, da->bz));
182     PetscCall(DMDASetDof(*subdm, numFields));
183     PetscCall(DMDASetStencilType(*subdm, da->stencil_type));
184     PetscCall(DMDASetStencilWidth(*subdm, da->s));
185     PetscCall(DMDASetOwnershipRanges(*subdm, da->lx, da->ly, da->lz));
186   }
187   if (is) {
188     PetscInt *indices, cnt = 0, dof = da->w, i, j;
189 
190     PetscCall(PetscMalloc1(da->Nlocal * numFields / dof, &indices));
191     for (i = da->base / dof; i < (da->base + da->Nlocal) / dof; ++i) {
192       for (j = 0; j < numFields; ++j) indices[cnt++] = dof * i + fields[j];
193     }
194     PetscCheck(cnt == da->Nlocal * numFields / dof, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Count %" PetscInt_FMT " does not equal expected value %" PetscInt_FMT, cnt, da->Nlocal * numFields / dof);
195     PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)dm), cnt, indices, PETSC_OWN_POINTER, is));
196   }
197   PetscFunctionReturn(PETSC_SUCCESS);
198 }
199 
200 static PetscErrorCode DMCreateFieldDecomposition_DA(DM dm, PetscInt *len, char ***namelist, IS **islist, DM **dmlist)
201 {
202   PetscInt i;
203   DM_DA   *dd  = (DM_DA *)dm->data;
204   PetscInt dof = dd->w;
205 
206   PetscFunctionBegin;
207   if (len) *len = dof;
208   if (islist) {
209     Vec      v;
210     PetscInt rstart, n;
211 
212     PetscCall(DMGetGlobalVector(dm, &v));
213     PetscCall(VecGetOwnershipRange(v, &rstart, NULL));
214     PetscCall(VecGetLocalSize(v, &n));
215     PetscCall(DMRestoreGlobalVector(dm, &v));
216     PetscCall(PetscMalloc1(dof, islist));
217     for (i = 0; i < dof; i++) PetscCall(ISCreateStride(PetscObjectComm((PetscObject)dm), n / dof, rstart + i, dof, &(*islist)[i]));
218   }
219   if (namelist) {
220     PetscCall(PetscMalloc1(dof, namelist));
221     if (dd->fieldname) {
222       for (i = 0; i < dof; i++) PetscCall(PetscStrallocpy(dd->fieldname[i], &(*namelist)[i]));
223     } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Currently DMDA must have fieldnames");
224   }
225   if (dmlist) {
226     DM da;
227 
228     PetscCall(DMDACreate(PetscObjectComm((PetscObject)dm), &da));
229     PetscCall(DMSetDimension(da, dm->dim));
230     PetscCall(DMDASetSizes(da, dd->M, dd->N, dd->P));
231     PetscCall(DMDASetNumProcs(da, dd->m, dd->n, dd->p));
232     PetscCall(DMDASetBoundaryType(da, dd->bx, dd->by, dd->bz));
233     PetscCall(DMDASetDof(da, 1));
234     PetscCall(DMDASetStencilType(da, dd->stencil_type));
235     PetscCall(DMDASetStencilWidth(da, dd->s));
236     PetscCall(DMSetUp(da));
237     PetscCall(PetscMalloc1(dof, dmlist));
238     for (i = 0; i < dof - 1; i++) PetscCall(PetscObjectReference((PetscObject)da));
239     for (i = 0; i < dof; i++) (*dmlist)[i] = da;
240   }
241   PetscFunctionReturn(PETSC_SUCCESS);
242 }
243 
244 static PetscErrorCode DMClone_DA(DM dm, DM *newdm)
245 {
246   DM_DA *da = (DM_DA *)dm->data;
247 
248   PetscFunctionBegin;
249   PetscCall(DMSetType(*newdm, DMDA));
250   PetscCall(DMSetDimension(*newdm, dm->dim));
251   PetscCall(DMDASetSizes(*newdm, da->M, da->N, da->P));
252   PetscCall(DMDASetNumProcs(*newdm, da->m, da->n, da->p));
253   PetscCall(DMDASetBoundaryType(*newdm, da->bx, da->by, da->bz));
254   PetscCall(DMDASetDof(*newdm, da->w));
255   PetscCall(DMDASetStencilType(*newdm, da->stencil_type));
256   PetscCall(DMDASetStencilWidth(*newdm, da->s));
257   PetscCall(DMDASetOwnershipRanges(*newdm, da->lx, da->ly, da->lz));
258   PetscCall(DMSetUp(*newdm));
259   PetscFunctionReturn(PETSC_SUCCESS);
260 }
261 
262 static PetscErrorCode DMHasCreateInjection_DA(DM dm, PetscBool *flg)
263 {
264   DM_DA *da = (DM_DA *)dm->data;
265 
266   PetscFunctionBegin;
267   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
268   PetscAssertPointer(flg, 2);
269   *flg = da->interptype == DMDA_Q1 ? PETSC_TRUE : PETSC_FALSE;
270   PetscFunctionReturn(PETSC_SUCCESS);
271 }
272 
273 static PetscErrorCode DMGetDimPoints_DA(DM dm, PetscInt dim, PetscInt *pStart, PetscInt *pEnd)
274 {
275   PetscFunctionBegin;
276   PetscCall(DMDAGetDepthStratum(dm, dim, pStart, pEnd));
277   PetscFunctionReturn(PETSC_SUCCESS);
278 }
279 
280 static PetscErrorCode DMGetNeighbors_DA(DM dm, PetscInt *nranks, const PetscMPIInt *ranks[])
281 {
282   PetscInt        dim;
283   DMDAStencilType st;
284 
285   PetscFunctionBegin;
286   PetscCall(DMDAGetNeighbors(dm, ranks));
287   PetscCall(DMDAGetInfo(dm, &dim, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &st));
288 
289   switch (dim) {
290   case 1:
291     *nranks = 3;
292     /* if (st == DMDA_STENCIL_STAR) *nranks = 3; */
293     break;
294   case 2:
295     *nranks = 9;
296     /* if (st == DMDA_STENCIL_STAR) *nranks = 5; */
297     break;
298   case 3:
299     *nranks = 27;
300     /* if (st == DMDA_STENCIL_STAR) *nranks = 7; */
301     break;
302   default:
303     break;
304   }
305   PetscFunctionReturn(PETSC_SUCCESS);
306 }
307 
308 /*MC
309    DMDA = "da" - A `DM` object that is used to manage data for a structured grid in 1, 2, or 3 dimensions.
310          In the global representation of the vector each process stores a non-overlapping rectangular (or slab in 3d) portion of the grid points.
311          In the local representation these rectangular regions (slabs) are extended in all directions by a stencil width.
312 
313          The vectors can be thought of as either cell centered or vertex centered on the mesh. But some variables cannot be cell centered and others
314          vertex centered; see the documentation for `DMSTAG`, a similar DM implementation which supports these staggered grids.
315 
316   Level: intermediate
317 
318 .seealso: `DMType`, `DMCOMPOSITE`, `DMSTAG`, `DMDACreate()`, `DMCreate()`, `DMSetType()`
319 M*/
320 
321 PETSC_EXTERN PetscErrorCode DMCreate_DA(DM da)
322 {
323   DM_DA *dd;
324 
325   PetscFunctionBegin;
326   PetscAssertPointer(da, 1);
327   PetscCall(PetscNew(&dd));
328   da->data = dd;
329 
330   da->dim        = -1;
331   dd->interptype = DMDA_Q1;
332   dd->refine_x   = 2;
333   dd->refine_y   = 2;
334   dd->refine_z   = 2;
335   dd->coarsen_x  = 2;
336   dd->coarsen_y  = 2;
337   dd->coarsen_z  = 2;
338   dd->fieldname  = NULL;
339   dd->nlocal     = -1;
340   dd->Nlocal     = -1;
341   dd->M          = -1;
342   dd->N          = -1;
343   dd->P          = -1;
344   dd->m          = -1;
345   dd->n          = -1;
346   dd->p          = -1;
347   dd->w          = -1;
348   dd->s          = -1;
349 
350   dd->xs = -1;
351   dd->xe = -1;
352   dd->ys = -1;
353   dd->ye = -1;
354   dd->zs = -1;
355   dd->ze = -1;
356   dd->Xs = -1;
357   dd->Xe = -1;
358   dd->Ys = -1;
359   dd->Ye = -1;
360   dd->Zs = -1;
361   dd->Ze = -1;
362 
363   dd->Nsub = 1;
364   dd->xol  = 0;
365   dd->yol  = 0;
366   dd->zol  = 0;
367   dd->xo   = 0;
368   dd->yo   = 0;
369   dd->zo   = 0;
370   dd->Mo   = -1;
371   dd->No   = -1;
372   dd->Po   = -1;
373 
374   dd->gtol = NULL;
375   dd->ltol = NULL;
376   dd->ao   = NULL;
377   PetscCall(PetscStrallocpy(AOBASIC, (char **)&dd->aotype));
378   dd->base         = -1;
379   dd->bx           = DM_BOUNDARY_NONE;
380   dd->by           = DM_BOUNDARY_NONE;
381   dd->bz           = DM_BOUNDARY_NONE;
382   dd->stencil_type = DMDA_STENCIL_BOX;
383   dd->interptype   = DMDA_Q1;
384   dd->lx           = NULL;
385   dd->ly           = NULL;
386   dd->lz           = NULL;
387 
388   dd->elementtype = DMDA_ELEMENT_Q1;
389 
390   da->ops->globaltolocalbegin        = DMGlobalToLocalBegin_DA;
391   da->ops->globaltolocalend          = DMGlobalToLocalEnd_DA;
392   da->ops->localtoglobalbegin        = DMLocalToGlobalBegin_DA;
393   da->ops->localtoglobalend          = DMLocalToGlobalEnd_DA;
394   da->ops->localtolocalbegin         = DMLocalToLocalBegin_DA;
395   da->ops->localtolocalend           = DMLocalToLocalEnd_DA;
396   da->ops->createglobalvector        = DMCreateGlobalVector_DA;
397   da->ops->createlocalvector         = DMCreateLocalVector_DA;
398   da->ops->createinterpolation       = DMCreateInterpolation_DA;
399   da->ops->getcoloring               = DMCreateColoring_DA;
400   da->ops->creatematrix              = DMCreateMatrix_DA;
401   da->ops->refine                    = DMRefine_DA;
402   da->ops->coarsen                   = DMCoarsen_DA;
403   da->ops->refinehierarchy           = DMRefineHierarchy_DA;
404   da->ops->coarsenhierarchy          = DMCoarsenHierarchy_DA;
405   da->ops->createinjection           = DMCreateInjection_DA;
406   da->ops->hascreateinjection        = DMHasCreateInjection_DA;
407   da->ops->destroy                   = DMDestroy_DA;
408   da->ops->view                      = NULL;
409   da->ops->setfromoptions            = DMSetFromOptions_DA;
410   da->ops->setup                     = DMSetUp_DA;
411   da->ops->clone                     = DMClone_DA;
412   da->ops->load                      = DMLoad_DA;
413   da->ops->createcoordinatedm        = DMCreateCoordinateDM_DA;
414   da->ops->createsubdm               = DMCreateSubDM_DA;
415   da->ops->createfielddecomposition  = DMCreateFieldDecomposition_DA;
416   da->ops->createdomaindecomposition = DMCreateDomainDecomposition_DA;
417   da->ops->createddscatters          = DMCreateDomainDecompositionScatters_DA;
418   da->ops->getdimpoints              = DMGetDimPoints_DA;
419   da->ops->getneighbors              = DMGetNeighbors_DA;
420   da->ops->locatepoints              = DMLocatePoints_DA_Regular;
421   da->ops->getcompatibility          = DMGetCompatibility_DA;
422   PetscCall(PetscObjectComposeFunction((PetscObject)da, "DMSetUpGLVisViewer_C", DMSetUpGLVisViewer_DMDA));
423   PetscFunctionReturn(PETSC_SUCCESS);
424 }
425 
426 /*@
427   DMDACreate - Creates a DMDA object.
428 
429   Collective
430 
431   Input Parameter:
432 . comm - The communicator for the DMDA object
433 
434   Output Parameter:
435 . da - The DMDA object
436 
437   Level: advanced
438 
439   Developer Notes:
440   Since there exists DMDACreate1/2/3d() should this routine even exist?
441 
442 .seealso: `DMDASetSizes()`, `DMClone()`, `DMDACreate1d()`, `DMDACreate2d()`, `DMDACreate3d()`
443 @*/
444 PetscErrorCode DMDACreate(MPI_Comm comm, DM *da)
445 {
446   PetscFunctionBegin;
447   PetscAssertPointer(da, 2);
448   PetscCall(DMCreate(comm, da));
449   PetscCall(DMSetType(*da, DMDA));
450   PetscFunctionReturn(PETSC_SUCCESS);
451 }
452