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