xref: /petsc/src/dm/impls/da/dacorn.c (revision dd4c3f67496275a10180fa3e9c7ac555daec1908)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
7f19dbd58SToby Isaac #include <petscdmfield.h>
847c6ae99SBarry Smith 
9d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
10d71ae5a4SJacob Faibussowitsch {
11*dd4c3f67SMatthew G. Knepley   const char *prefix;
12*dd4c3f67SMatthew G. Knepley 
133f2d3b52SPeter Brune   PetscFunctionBegin;
149566063dSJacob Faibussowitsch   PetscCall(DMDACreateCompatibleDMDA(dm, dm->dim, cdm));
15*dd4c3f67SMatthew G. Knepley   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
16*dd4c3f67SMatthew G. Knepley   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*cdm, prefix));
17*dd4c3f67SMatthew G. Knepley   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*cdm, "cdm_"));
1847c6ae99SBarry Smith   PetscFunctionReturn(0);
1947c6ae99SBarry Smith }
2047c6ae99SBarry Smith 
21d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateCoordinateField_DA(DM dm, DMField *field)
22d71ae5a4SJacob Faibussowitsch {
23f19dbd58SToby Isaac   PetscReal   gmin[3], gmax[3];
244d1a973fSToby Isaac   PetscScalar corners[24];
25f19dbd58SToby Isaac   PetscInt    dim;
26f19dbd58SToby Isaac   PetscInt    i, j;
27f19dbd58SToby Isaac   DM          cdm;
28f19dbd58SToby Isaac 
29f19dbd58SToby Isaac   PetscFunctionBegin;
309566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
31f19dbd58SToby Isaac   /* TODO: this is wrong if coordinates are not rectilinear */
329566063dSJacob Faibussowitsch   PetscCall(DMGetBoundingBox(dm, gmin, gmax));
33f19dbd58SToby Isaac   for (i = 0; i < (1 << dim); i++) {
34ad540459SPierre Jolivet     for (j = 0; j < dim; j++) corners[i * dim + j] = (i & (1 << j)) ? gmax[j] : gmin[j];
35f19dbd58SToby Isaac   }
369566063dSJacob Faibussowitsch   PetscCall(DMClone(dm, &cdm));
379566063dSJacob Faibussowitsch   PetscCall(DMFieldCreateDA(cdm, dim, corners, field));
389566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&cdm));
39f19dbd58SToby Isaac   PetscFunctionReturn(0);
40f19dbd58SToby Isaac }
41f19dbd58SToby Isaac 
4247c6ae99SBarry Smith /*@C
43aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
44aa219208SBarry Smith    vectors associated with a DMDA.
4547c6ae99SBarry Smith 
46b1dd8793SDave May    Logically collective; name must contain a common value
4747c6ae99SBarry Smith 
4847c6ae99SBarry Smith    Input Parameters:
4947c6ae99SBarry Smith +  da - the distributed array
50aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
51aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
5247c6ae99SBarry Smith -  names - the name of the field (component)
5347c6ae99SBarry Smith 
5495452b02SPatrick Sanan   Notes:
5595452b02SPatrick Sanan     It must be called after having called DMSetUp().
563eac1ceeSStefano Zampini 
5747c6ae99SBarry Smith   Level: intermediate
5847c6ae99SBarry Smith 
59db781477SPatrick Sanan .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldNames()`, `DMSetUp()`
6047c6ae99SBarry Smith @*/
61d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetFieldName(DM da, PetscInt nf, const char name[])
62d71ae5a4SJacob Faibussowitsch {
6347c6ae99SBarry Smith   DM_DA *dd = (DM_DA *)da->data;
6447c6ae99SBarry Smith 
6547c6ae99SBarry Smith   PetscFunctionBegin;
66a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
671dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dd->w, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid field number: %" PetscInt_FMT, nf);
687a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
699566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->fieldname[nf]));
709566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &dd->fieldname[nf]));
7147c6ae99SBarry Smith   PetscFunctionReturn(0);
7247c6ae99SBarry Smith }
7347c6ae99SBarry Smith 
74c629b14aSBarry Smith /*@C
75c629b14aSBarry Smith    DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
76c629b14aSBarry Smith 
77b1dd8793SDave May    Not collective; names will contain a common value
78c629b14aSBarry Smith 
79c629b14aSBarry Smith    Input Parameter:
80c629b14aSBarry Smith .  dm - the DMDA object
81c629b14aSBarry Smith 
82c629b14aSBarry Smith    Output Parameter:
83c629b14aSBarry Smith .  names - the names of the components, final string is NULL, will have the same number of entries as the dof used in creating the DMDA
84c629b14aSBarry Smith 
85c629b14aSBarry Smith    Level: intermediate
86c629b14aSBarry Smith 
87f5f57ec0SBarry Smith    Not supported from Fortran, use DMDAGetFieldName()
88f5f57ec0SBarry Smith 
89db781477SPatrick Sanan .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDASetFieldNames()`
90c629b14aSBarry Smith @*/
91d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetFieldNames(DM da, const char *const **names)
92d71ae5a4SJacob Faibussowitsch {
93c629b14aSBarry Smith   DM_DA *dd = (DM_DA *)da->data;
94c629b14aSBarry Smith 
95c629b14aSBarry Smith   PetscFunctionBegin;
96c629b14aSBarry Smith   *names = (const char *const *)dd->fieldname;
97c629b14aSBarry Smith   PetscFunctionReturn(0);
98c629b14aSBarry Smith }
99c629b14aSBarry Smith 
100c629b14aSBarry Smith /*@C
101c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
102c629b14aSBarry Smith 
103b1dd8793SDave May    Logically collective; names must contain a common value
104c629b14aSBarry Smith 
105c629b14aSBarry Smith    Input Parameters:
106c629b14aSBarry Smith +  dm - the DMDA object
107c629b14aSBarry Smith -  names - the names of the components, final string must be NULL, must have the same number of entries as the dof used in creating the DMDA
108c629b14aSBarry Smith 
10995452b02SPatrick Sanan    Notes:
11095452b02SPatrick Sanan     It must be called after having called DMSetUp().
1113eac1ceeSStefano Zampini 
112c629b14aSBarry Smith    Level: intermediate
113c629b14aSBarry Smith 
114f5f57ec0SBarry Smith    Not supported from Fortran, use DMDASetFieldName()
115f5f57ec0SBarry Smith 
116db781477SPatrick Sanan .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMSetUp()`
117c629b14aSBarry Smith @*/
118d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetFieldNames(DM da, const char *const *names)
119d71ae5a4SJacob Faibussowitsch {
120c629b14aSBarry Smith   DM_DA   *dd = (DM_DA *)da->data;
1213eac1ceeSStefano Zampini   char   **fieldname;
1223eac1ceeSStefano Zampini   PetscInt nf = 0;
123c629b14aSBarry Smith 
124c629b14aSBarry Smith   PetscFunctionBegin;
1257a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
1263eac1ceeSStefano Zampini   while (names[nf++]) { };
12763a3b9bcSJacob Faibussowitsch   PetscCheck(nf == dd->w + 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of fields %" PetscInt_FMT, nf - 1);
1289566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names, &fieldname));
1299566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&dd->fieldname));
1303eac1ceeSStefano Zampini   dd->fieldname = fieldname;
131c629b14aSBarry Smith   PetscFunctionReturn(0);
132c629b14aSBarry Smith }
133c629b14aSBarry Smith 
13447c6ae99SBarry Smith /*@C
135aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
136aa219208SBarry Smith    vectors associated with a DMDA.
13747c6ae99SBarry Smith 
138b1dd8793SDave May    Not collective; name will contain a common value
13947c6ae99SBarry Smith 
140d8d19677SJose E. Roman    Input Parameters:
14147c6ae99SBarry Smith +  da - the distributed array
142aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
143aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
14447c6ae99SBarry Smith 
14547c6ae99SBarry Smith    Output Parameter:
14647c6ae99SBarry Smith .  names - the name of the field (component)
14747c6ae99SBarry Smith 
14895452b02SPatrick Sanan   Notes:
14995452b02SPatrick Sanan     It must be called after having called DMSetUp().
1503eac1ceeSStefano Zampini 
15147c6ae99SBarry Smith   Level: intermediate
15247c6ae99SBarry Smith 
153db781477SPatrick Sanan .seealso: `DMDASetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMSetUp()`
15447c6ae99SBarry Smith @*/
155d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetFieldName(DM da, PetscInt nf, const char **name)
156d71ae5a4SJacob Faibussowitsch {
15747c6ae99SBarry Smith   DM_DA *dd = (DM_DA *)da->data;
15847c6ae99SBarry Smith 
15947c6ae99SBarry Smith   PetscFunctionBegin;
160a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
16147c6ae99SBarry Smith   PetscValidPointer(name, 3);
1621dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dd->w, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid field number: %" PetscInt_FMT, nf);
1637a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
16447c6ae99SBarry Smith   *name = dd->fieldname[nf];
16547c6ae99SBarry Smith   PetscFunctionReturn(0);
16647c6ae99SBarry Smith }
16747c6ae99SBarry Smith 
168109c9344SBarry Smith /*@C
169109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
170109c9344SBarry Smith 
171b1dd8793SDave May    Logically collective; name must contain a common value
172109c9344SBarry Smith 
173109c9344SBarry Smith    Input Parameters:
174c73cfb54SMatthew G. Knepley +  dm - the DM
175109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
176109c9344SBarry Smith -  name - the name of the coordinate
177109c9344SBarry Smith 
17895452b02SPatrick Sanan   Notes:
17995452b02SPatrick Sanan     It must be called after having called DMSetUp().
1803eac1ceeSStefano Zampini 
181109c9344SBarry Smith   Level: intermediate
182109c9344SBarry Smith 
183f5f57ec0SBarry Smith   Not supported from Fortran
184f5f57ec0SBarry Smith 
185db781477SPatrick Sanan .seealso: `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
186109c9344SBarry Smith @*/
187d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetCoordinateName(DM dm, PetscInt nf, const char name[])
188d71ae5a4SJacob Faibussowitsch {
189c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA *)dm->data;
190109c9344SBarry Smith 
191109c9344SBarry Smith   PetscFunctionBegin;
192a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
1931dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dm->dim, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid coordinate number: %" PetscInt_FMT, nf);
1947a8be351SBarry Smith   PetscCheck(dd->coordinatename, PetscObjectComm((PetscObject)dm), PETSC_ERR_ORDER, "You should call DMSetUp() first");
1959566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->coordinatename[nf]));
1969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &dd->coordinatename[nf]));
197109c9344SBarry Smith   PetscFunctionReturn(0);
198109c9344SBarry Smith }
199109c9344SBarry Smith 
200109c9344SBarry Smith /*@C
201109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
202109c9344SBarry Smith 
203b1dd8793SDave May    Not collective; name will contain a common value
204109c9344SBarry Smith 
205d8d19677SJose E. Roman    Input Parameters:
206c73cfb54SMatthew G. Knepley +  dm - the DM
207109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
208109c9344SBarry Smith 
209109c9344SBarry Smith    Output Parameter:
210109c9344SBarry Smith .  names - the name of the coordinate direction
211109c9344SBarry Smith 
21295452b02SPatrick Sanan   Notes:
21395452b02SPatrick Sanan     It must be called after having called DMSetUp().
2143eac1ceeSStefano Zampini 
215109c9344SBarry Smith   Level: intermediate
216109c9344SBarry Smith 
217f5f57ec0SBarry Smith   Not supported from Fortran
218f5f57ec0SBarry Smith 
219db781477SPatrick Sanan .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
220109c9344SBarry Smith @*/
221d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCoordinateName(DM dm, PetscInt nf, const char **name)
222d71ae5a4SJacob Faibussowitsch {
223c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA *)dm->data;
224109c9344SBarry Smith 
225109c9344SBarry Smith   PetscFunctionBegin;
226a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
227109c9344SBarry Smith   PetscValidPointer(name, 3);
2281dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dm->dim, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid coordinate number: %" PetscInt_FMT, nf);
2297a8be351SBarry Smith   PetscCheck(dd->coordinatename, PetscObjectComm((PetscObject)dm), PETSC_ERR_ORDER, "You should call DMSetUp() first");
230109c9344SBarry Smith   *name = dd->coordinatename[nf];
231109c9344SBarry Smith   PetscFunctionReturn(0);
232109c9344SBarry Smith }
233109c9344SBarry Smith 
234a5d1443cSVincent Le Chenadec /*@C
235aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
23659f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
23747c6ae99SBarry Smith 
238b1dd8793SDave May    Not collective
23947c6ae99SBarry Smith 
24047c6ae99SBarry Smith    Input Parameter:
24147c6ae99SBarry Smith .  da - the distributed array
24247c6ae99SBarry Smith 
24347c6ae99SBarry Smith    Output Parameters:
2446b867d5aSJose E. Roman +  x - the corner index for the first dimension
2456b867d5aSJose E. Roman .  y - the corner index for the second dimension (only used in 2D and 3D problems)
2466b867d5aSJose E. Roman .  z - the corner index for the third dimension (only used in 3D problems)
2476b867d5aSJose E. Roman .  m - the width in the first dimension
2486b867d5aSJose E. Roman .  n - the width in the second dimension (only used in 2D and 3D problems)
2496b867d5aSJose E. Roman -  p - the width in the third dimension (only used in 3D problems)
25047c6ae99SBarry Smith 
25147c6ae99SBarry Smith    Note:
25247c6ae99SBarry Smith    The corner information is independent of the number of degrees of
253aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
25447c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
25547c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2560298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
25747c6ae99SBarry Smith 
25847c6ae99SBarry Smith   Level: beginner
25947c6ae99SBarry Smith 
260db781477SPatrick Sanan .seealso: `DMDAGetGhostCorners()`, `DMDAGetOwnershipRanges()`, `DMStagGetCorners()`
26147c6ae99SBarry Smith @*/
262d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCorners(DM da, PetscInt *x, PetscInt *y, PetscInt *z, PetscInt *m, PetscInt *n, PetscInt *p)
263d71ae5a4SJacob Faibussowitsch {
26447c6ae99SBarry Smith   PetscInt w;
26547c6ae99SBarry Smith   DM_DA   *dd = (DM_DA *)da->data;
26647c6ae99SBarry Smith 
26747c6ae99SBarry Smith   PetscFunctionBegin;
268a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
26947c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
27047c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
27147c6ae99SBarry Smith   w = dd->w;
27259bc5b24SSatish Balay   if (x) *x = dd->xs / w + dd->xo;
27347c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
27459bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
27559bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
27659bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs) / w;
27759bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
27859bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
27947c6ae99SBarry Smith   PetscFunctionReturn(0);
28047c6ae99SBarry Smith }
28147c6ae99SBarry Smith 
282d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalBoundingIndices_DMDA(DM dm, PetscReal lmin[], PetscReal lmax[])
283d71ae5a4SJacob Faibussowitsch {
2847324c66bSJed Brown   DMDALocalInfo info;
28547c6ae99SBarry Smith 
28647c6ae99SBarry Smith   PetscFunctionBegin;
2879566063dSJacob Faibussowitsch   PetscCall(DMDAGetLocalInfo(dm, &info));
288b2e4378dSMatthew G. Knepley   lmin[0] = info.xs;
289b2e4378dSMatthew G. Knepley   lmin[1] = info.ys;
290b2e4378dSMatthew G. Knepley   lmin[2] = info.zs;
291b2e4378dSMatthew G. Knepley   lmax[0] = info.xs + info.xm - 1;
292b2e4378dSMatthew G. Knepley   lmax[1] = info.ys + info.ym - 1;
293b2e4378dSMatthew G. Knepley   lmax[2] = info.zs + info.zm - 1;
29447c6ae99SBarry Smith   PetscFunctionReturn(0);
29547c6ae99SBarry Smith }
296bc2bf880SBarry Smith 
297bc2bf880SBarry Smith /*@
29883d91586SPatrick Sanan    DMDAGetReducedDMDA - Deprecated; use DMDACreateCompatibleDMDA()
29983d91586SPatrick Sanan 
30083d91586SPatrick Sanan    Level: deprecated
30183d91586SPatrick Sanan @*/
302d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetReducedDMDA(DM da, PetscInt nfields, DM *nda)
303d71ae5a4SJacob Faibussowitsch {
30483d91586SPatrick Sanan   PetscFunctionBegin;
3059566063dSJacob Faibussowitsch   PetscCall(DMDACreateCompatibleDMDA(da, nfields, nda));
30683d91586SPatrick Sanan   PetscFunctionReturn(0);
30783d91586SPatrick Sanan }
30883d91586SPatrick Sanan 
30983d91586SPatrick Sanan /*@
310211d3afbSPatrick Sanan    DMDACreateCompatibleDMDA - Creates a DMDA with the same layout but with fewer or more fields
311bc2bf880SBarry Smith 
312b1dd8793SDave May    Collective
313bc2bf880SBarry Smith 
314907376e6SBarry Smith    Input Parameters:
315bc2bf880SBarry Smith +  da - the distributed array
316907376e6SBarry Smith -  nfields - number of fields in new DMDA
317bc2bf880SBarry Smith 
318bc2bf880SBarry Smith    Output Parameter:
319bc2bf880SBarry Smith .  nda - the new DMDA
320bc2bf880SBarry Smith 
321bc2bf880SBarry Smith   Level: intermediate
322bc2bf880SBarry Smith 
323db781477SPatrick Sanan .seealso: `DMDAGetGhostCorners()`, `DMSetCoordinates()`, `DMDASetUniformCoordinates()`, `DMGetCoordinates()`, `DMDAGetGhostedCoordinates()`, `DMStagCreateCompatibleDMStag()`
324bc2bf880SBarry Smith @*/
325d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDACreateCompatibleDMDA(DM da, PetscInt nfields, DM *nda)
326d71ae5a4SJacob Faibussowitsch {
327bc2bf880SBarry Smith   DM_DA          *dd = (DM_DA *)da->data;
32895c13181SPeter Brune   PetscInt        s, m, n, p, M, N, P, dim, Mo, No, Po;
329320964c4SBlaise Bourdin   const PetscInt *lx, *ly, *lz;
330bff4a2f0SMatthew G. Knepley   DMBoundaryType  bx, by, bz;
331320964c4SBlaise Bourdin   DMDAStencilType stencil_type;
3326858538eSMatthew G. Knepley   Vec             coords;
33395c13181SPeter Brune   PetscInt        ox, oy, oz;
33495c13181SPeter Brune   PetscInt        cl, rl;
335320964c4SBlaise Bourdin 
336320964c4SBlaise Bourdin   PetscFunctionBegin;
337c73cfb54SMatthew G. Knepley   dim = da->dim;
33895c13181SPeter Brune   M   = dd->M;
33995c13181SPeter Brune   N   = dd->N;
34095c13181SPeter Brune   P   = dd->P;
34195c13181SPeter Brune   m   = dd->m;
34295c13181SPeter Brune   n   = dd->n;
34395c13181SPeter Brune   p   = dd->p;
34495c13181SPeter Brune   s   = dd->s;
34595c13181SPeter Brune   bx  = dd->bx;
34695c13181SPeter Brune   by  = dd->by;
34795c13181SPeter Brune   bz  = dd->bz;
3488865f1eaSKarl Rupp 
34995c13181SPeter Brune   stencil_type = dd->stencil_type;
3508865f1eaSKarl Rupp 
3519566063dSJacob Faibussowitsch   PetscCall(DMDAGetOwnershipRanges(da, &lx, &ly, &lz));
352320964c4SBlaise Bourdin   if (dim == 1) {
3539566063dSJacob Faibussowitsch     PetscCall(DMDACreate1d(PetscObjectComm((PetscObject)da), bx, M, nfields, s, dd->lx, nda));
354320964c4SBlaise Bourdin   } else if (dim == 2) {
3559566063dSJacob Faibussowitsch     PetscCall(DMDACreate2d(PetscObjectComm((PetscObject)da), bx, by, stencil_type, M, N, m, n, nfields, s, lx, ly, nda));
356320964c4SBlaise Bourdin   } else if (dim == 3) {
3579566063dSJacob Faibussowitsch     PetscCall(DMDACreate3d(PetscObjectComm((PetscObject)da), bx, by, bz, stencil_type, M, N, P, m, n, p, nfields, s, lx, ly, lz, nda));
358bc2bf880SBarry Smith   }
3599566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*nda));
3606858538eSMatthew G. Knepley   PetscCall(DMGetCoordinates(da, &coords));
3616858538eSMatthew G. Knepley   PetscCall(DMSetCoordinates(*nda, coords));
36295c13181SPeter Brune 
36395c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
3649566063dSJacob Faibussowitsch   PetscCall(DMDAGetOffset(da, &ox, &oy, &oz, &Mo, &No, &Po));
3659566063dSJacob Faibussowitsch   PetscCall(DMDASetOffset(*nda, ox, oy, oz, Mo, No, Po));
36695c13181SPeter Brune 
36795c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
3689566063dSJacob Faibussowitsch   PetscCall(DMGetCoarsenLevel(da, &cl));
3699566063dSJacob Faibussowitsch   PetscCall(DMGetRefineLevel(da, &rl));
3708865f1eaSKarl Rupp 
37195c13181SPeter Brune   (*nda)->levelup   = rl;
37295c13181SPeter Brune   (*nda)->leveldown = cl;
373bc2bf880SBarry Smith   PetscFunctionReturn(0);
374bc2bf880SBarry Smith }
375bc2bf880SBarry Smith 
376c593f006SBarry Smith /*@C
377c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
378c593f006SBarry Smith 
379b1dd8793SDave May    Not collective
380c593f006SBarry Smith 
381c593f006SBarry Smith    Input Parameter:
382c593f006SBarry Smith .  dm - the DM
383c593f006SBarry Smith 
384c593f006SBarry Smith    Output Parameter:
385c593f006SBarry Smith .  xc - the coordinates
386c593f006SBarry Smith 
387c593f006SBarry Smith   Level: intermediate
388c593f006SBarry Smith 
389f5f57ec0SBarry Smith   Not supported from Fortran
390f5f57ec0SBarry Smith 
391db781477SPatrick Sanan .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDARestoreCoordinateArray()`
392c593f006SBarry Smith @*/
393d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCoordinateArray(DM dm, void *xc)
394d71ae5a4SJacob Faibussowitsch {
395c593f006SBarry Smith   DM  cdm;
396c593f006SBarry Smith   Vec x;
397c593f006SBarry Smith 
398c593f006SBarry Smith   PetscFunctionBegin;
399c593f006SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4009566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinates(dm, &x));
4019566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
4029566063dSJacob Faibussowitsch   PetscCall(DMDAVecGetArray(cdm, x, xc));
403c593f006SBarry Smith   PetscFunctionReturn(0);
404c593f006SBarry Smith }
405c593f006SBarry Smith 
406c593f006SBarry Smith /*@C
407c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
408c593f006SBarry Smith 
409b1dd8793SDave May    Not collective
410c593f006SBarry Smith 
411d8d19677SJose E. Roman    Input Parameters:
412c593f006SBarry Smith +  dm - the DM
413c593f006SBarry Smith -  xc - the coordinates
414c593f006SBarry Smith 
415c593f006SBarry Smith   Level: intermediate
416c593f006SBarry Smith 
417f5f57ec0SBarry Smith   Not supported from Fortran
418f5f57ec0SBarry Smith 
419db781477SPatrick Sanan .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDAGetCoordinateArray()`
420c593f006SBarry Smith @*/
421d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDARestoreCoordinateArray(DM dm, void *xc)
422d71ae5a4SJacob Faibussowitsch {
423c593f006SBarry Smith   DM  cdm;
424c593f006SBarry Smith   Vec x;
425c593f006SBarry Smith 
426c593f006SBarry Smith   PetscFunctionBegin;
427c593f006SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4289566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinates(dm, &x));
4299566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
4309566063dSJacob Faibussowitsch   PetscCall(DMDAVecRestoreArray(cdm, x, xc));
431c593f006SBarry Smith   PetscFunctionReturn(0);
432c593f006SBarry Smith }
433