xref: /petsc/src/dm/impls/da/dacorn.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
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 {
11dd4c3f67SMatthew G. Knepley   const char *prefix;
12dd4c3f67SMatthew G. Knepley 
133f2d3b52SPeter Brune   PetscFunctionBegin;
149566063dSJacob Faibussowitsch   PetscCall(DMDACreateCompatibleDMDA(dm, dm->dim, cdm));
15dd4c3f67SMatthew G. Knepley   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)dm, &prefix));
16dd4c3f67SMatthew G. Knepley   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*cdm, prefix));
17dd4c3f67SMatthew G. Knepley   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)*cdm, "cdm_"));
18*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
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));
39*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40f19dbd58SToby Isaac }
41f19dbd58SToby Isaac 
4247c6ae99SBarry Smith /*@C
43aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
44dce8aebaSBarry 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
50dce8aebaSBarry Smith .  nf - field number for the `DMDA` (0, 1, ... dof-1), where dof indicates the
51dce8aebaSBarry Smith         number of degrees of freedom per node within the `DMDA`
5247c6ae99SBarry Smith -  names - the name of the field (component)
5347c6ae99SBarry Smith 
5447c6ae99SBarry Smith   Level: intermediate
5547c6ae99SBarry Smith 
56dce8aebaSBarry Smith   Note:
57dce8aebaSBarry Smith     It must be called after having called `DMSetUp()`.
58dce8aebaSBarry Smith 
59dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `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]));
71*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7247c6ae99SBarry Smith }
7347c6ae99SBarry Smith 
74c629b14aSBarry Smith /*@C
75dce8aebaSBarry 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:
80dce8aebaSBarry Smith .  dm - the `DMDA` object
81c629b14aSBarry Smith 
82c629b14aSBarry Smith    Output Parameter:
83dce8aebaSBarry 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 
87dce8aebaSBarry Smith    Fortran Note:
88dce8aebaSBarry Smith    Not supported from Fortran, use `DMDAGetFieldName()`
89f5f57ec0SBarry Smith 
90dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDASetFieldNames()`
91c629b14aSBarry Smith @*/
92d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetFieldNames(DM da, const char *const **names)
93d71ae5a4SJacob Faibussowitsch {
94c629b14aSBarry Smith   DM_DA *dd = (DM_DA *)da->data;
95c629b14aSBarry Smith 
96c629b14aSBarry Smith   PetscFunctionBegin;
97c629b14aSBarry Smith   *names = (const char *const *)dd->fieldname;
98*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
99c629b14aSBarry Smith }
100c629b14aSBarry Smith 
101c629b14aSBarry Smith /*@C
102c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
103c629b14aSBarry Smith 
104b1dd8793SDave May    Logically collective; names must contain a common value
105c629b14aSBarry Smith 
106c629b14aSBarry Smith    Input Parameters:
107dce8aebaSBarry Smith +  dm - the `DMDA` object
108dce8aebaSBarry 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`
1093eac1ceeSStefano Zampini 
110c629b14aSBarry Smith    Level: intermediate
111c629b14aSBarry Smith 
112dce8aebaSBarry Smith    Note:
113dce8aebaSBarry Smith     It must be called after having called `DMSetUp()`.
114f5f57ec0SBarry Smith 
115dce8aebaSBarry Smith    Fortran Note:
116dce8aebaSBarry Smith    Not supported from Fortran, use `DMDASetFieldName()`
117dce8aebaSBarry Smith 
118dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMSetUp()`
119c629b14aSBarry Smith @*/
120d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetFieldNames(DM da, const char *const *names)
121d71ae5a4SJacob Faibussowitsch {
122c629b14aSBarry Smith   DM_DA   *dd = (DM_DA *)da->data;
1233eac1ceeSStefano Zampini   char   **fieldname;
1243eac1ceeSStefano Zampini   PetscInt nf = 0;
125c629b14aSBarry Smith 
126c629b14aSBarry Smith   PetscFunctionBegin;
1277a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
1283eac1ceeSStefano Zampini   while (names[nf++]) { };
12963a3b9bcSJacob Faibussowitsch   PetscCheck(nf == dd->w + 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of fields %" PetscInt_FMT, nf - 1);
1309566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names, &fieldname));
1319566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&dd->fieldname));
1323eac1ceeSStefano Zampini   dd->fieldname = fieldname;
133*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
134c629b14aSBarry Smith }
135c629b14aSBarry Smith 
13647c6ae99SBarry Smith /*@C
137aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
138dce8aebaSBarry Smith    vectors associated with a `DMDA`.
13947c6ae99SBarry Smith 
140b1dd8793SDave May    Not collective; name will contain a common value
14147c6ae99SBarry Smith 
142d8d19677SJose E. Roman    Input Parameters:
14347c6ae99SBarry Smith +  da - the distributed array
144dce8aebaSBarry Smith -  nf - field number for the `DMDA` (0, 1, ... dof-1), where dof indicates the
145dce8aebaSBarry Smith         number of degrees of freedom per node within the `DMDA`
14647c6ae99SBarry Smith 
14747c6ae99SBarry Smith    Output Parameter:
14847c6ae99SBarry Smith .  names - the name of the field (component)
14947c6ae99SBarry Smith 
15047c6ae99SBarry Smith   Level: intermediate
15147c6ae99SBarry Smith 
152dce8aebaSBarry Smith   Note:
153dce8aebaSBarry Smith     It must be called after having called `DMSetUp()`.
154dce8aebaSBarry Smith 
155dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDASetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMSetUp()`
15647c6ae99SBarry Smith @*/
157d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetFieldName(DM da, PetscInt nf, const char **name)
158d71ae5a4SJacob Faibussowitsch {
15947c6ae99SBarry Smith   DM_DA *dd = (DM_DA *)da->data;
16047c6ae99SBarry Smith 
16147c6ae99SBarry Smith   PetscFunctionBegin;
162a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
16347c6ae99SBarry Smith   PetscValidPointer(name, 3);
1641dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dd->w, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid field number: %" PetscInt_FMT, nf);
1657a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
16647c6ae99SBarry Smith   *name = dd->fieldname[nf];
167*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16847c6ae99SBarry Smith }
16947c6ae99SBarry Smith 
170109c9344SBarry Smith /*@C
171dce8aebaSBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a `DMDA`, for example "x" or "y"
172109c9344SBarry Smith 
173b1dd8793SDave May    Logically collective; name must contain a common value
174109c9344SBarry Smith 
175109c9344SBarry Smith    Input Parameters:
176dce8aebaSBarry Smith +  dm - the `DMDA`
177109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
178109c9344SBarry Smith -  name - the name of the coordinate
179109c9344SBarry Smith 
180109c9344SBarry Smith   Level: intermediate
181109c9344SBarry Smith 
182dce8aebaSBarry Smith   Note:
183dce8aebaSBarry Smith     It must be called after having called `DMSetUp()`.
184dce8aebaSBarry Smith 
185dce8aebaSBarry Smith   Fortran Note:
186f5f57ec0SBarry Smith   Not supported from Fortran
187f5f57ec0SBarry Smith 
188dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
189109c9344SBarry Smith @*/
190d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetCoordinateName(DM dm, PetscInt nf, const char name[])
191d71ae5a4SJacob Faibussowitsch {
192c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA *)dm->data;
193109c9344SBarry Smith 
194109c9344SBarry Smith   PetscFunctionBegin;
195a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
1961dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dm->dim, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid coordinate number: %" PetscInt_FMT, nf);
1977a8be351SBarry Smith   PetscCheck(dd->coordinatename, PetscObjectComm((PetscObject)dm), PETSC_ERR_ORDER, "You should call DMSetUp() first");
1989566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->coordinatename[nf]));
1999566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &dd->coordinatename[nf]));
200*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
201109c9344SBarry Smith }
202109c9344SBarry Smith 
203109c9344SBarry Smith /*@C
204dce8aebaSBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a `DMDA`.
205109c9344SBarry Smith 
206b1dd8793SDave May    Not collective; name will contain a common value
207109c9344SBarry Smith 
208d8d19677SJose E. Roman    Input Parameters:
209dce8aebaSBarry Smith +  dm - the `DMDA`
210109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
211109c9344SBarry Smith 
212109c9344SBarry Smith    Output Parameter:
213109c9344SBarry Smith .  names - the name of the coordinate direction
214109c9344SBarry Smith 
215109c9344SBarry Smith   Level: intermediate
216109c9344SBarry Smith 
217dce8aebaSBarry Smith   Note:
218dce8aebaSBarry Smith     It must be called after having called `DMSetUp()`.
219dce8aebaSBarry Smith 
220dce8aebaSBarry Smith   Fortran Note:
221f5f57ec0SBarry Smith   Not supported from Fortran
222f5f57ec0SBarry Smith 
223dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
224109c9344SBarry Smith @*/
225d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCoordinateName(DM dm, PetscInt nf, const char **name)
226d71ae5a4SJacob Faibussowitsch {
227c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA *)dm->data;
228109c9344SBarry Smith 
229109c9344SBarry Smith   PetscFunctionBegin;
230a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
231109c9344SBarry Smith   PetscValidPointer(name, 3);
2321dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dm->dim, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid coordinate number: %" PetscInt_FMT, nf);
2337a8be351SBarry Smith   PetscCheck(dd->coordinatename, PetscObjectComm((PetscObject)dm), PETSC_ERR_ORDER, "You should call DMSetUp() first");
234109c9344SBarry Smith   *name = dd->coordinatename[nf];
235*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
236109c9344SBarry Smith }
237109c9344SBarry Smith 
238a5d1443cSVincent Le Chenadec /*@C
239aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
24059f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
24147c6ae99SBarry Smith 
242b1dd8793SDave May    Not collective
24347c6ae99SBarry Smith 
24447c6ae99SBarry Smith    Input Parameter:
24547c6ae99SBarry Smith .  da - the distributed array
24647c6ae99SBarry Smith 
24747c6ae99SBarry Smith    Output Parameters:
2486b867d5aSJose E. Roman +  x - the corner index for the first dimension
2496b867d5aSJose E. Roman .  y - the corner index for the second dimension (only used in 2D and 3D problems)
2506b867d5aSJose E. Roman .  z - the corner index for the third dimension (only used in 3D problems)
2516b867d5aSJose E. Roman .  m - the width in the first dimension
2526b867d5aSJose E. Roman .  n - the width in the second dimension (only used in 2D and 3D problems)
2536b867d5aSJose E. Roman -  p - the width in the third dimension (only used in 3D problems)
25447c6ae99SBarry Smith 
255dce8aebaSBarry Smith   Level: beginner
256dce8aebaSBarry Smith 
25747c6ae99SBarry Smith    Note:
25847c6ae99SBarry Smith    The corner information is independent of the number of degrees of
259dce8aebaSBarry Smith    freedom per node set with the `DMDACreateXX()` routine. Thus the x, y, z, and
26047c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
26147c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2620298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
26347c6ae99SBarry Smith 
264dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMDAGetOwnershipRanges()`, `DMStagGetCorners()`
26547c6ae99SBarry Smith @*/
266d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCorners(DM da, PetscInt *x, PetscInt *y, PetscInt *z, PetscInt *m, PetscInt *n, PetscInt *p)
267d71ae5a4SJacob Faibussowitsch {
26847c6ae99SBarry Smith   PetscInt w;
26947c6ae99SBarry Smith   DM_DA   *dd = (DM_DA *)da->data;
27047c6ae99SBarry Smith 
27147c6ae99SBarry Smith   PetscFunctionBegin;
272a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
27347c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
27447c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
27547c6ae99SBarry Smith   w = dd->w;
27659bc5b24SSatish Balay   if (x) *x = dd->xs / w + dd->xo;
27747c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
27859bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
27959bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
28059bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs) / w;
28159bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
28259bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
283*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28447c6ae99SBarry Smith }
28547c6ae99SBarry Smith 
286d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalBoundingIndices_DMDA(DM dm, PetscReal lmin[], PetscReal lmax[])
287d71ae5a4SJacob Faibussowitsch {
2887324c66bSJed Brown   DMDALocalInfo info;
28947c6ae99SBarry Smith 
29047c6ae99SBarry Smith   PetscFunctionBegin;
2919566063dSJacob Faibussowitsch   PetscCall(DMDAGetLocalInfo(dm, &info));
292b2e4378dSMatthew G. Knepley   lmin[0] = info.xs;
293b2e4378dSMatthew G. Knepley   lmin[1] = info.ys;
294b2e4378dSMatthew G. Knepley   lmin[2] = info.zs;
295b2e4378dSMatthew G. Knepley   lmax[0] = info.xs + info.xm - 1;
296b2e4378dSMatthew G. Knepley   lmax[1] = info.ys + info.ym - 1;
297b2e4378dSMatthew G. Knepley   lmax[2] = info.zs + info.zm - 1;
298*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29947c6ae99SBarry Smith }
300bc2bf880SBarry Smith 
301bc2bf880SBarry Smith /*@
30283d91586SPatrick Sanan    DMDAGetReducedDMDA - Deprecated; use DMDACreateCompatibleDMDA()
30383d91586SPatrick Sanan 
30483d91586SPatrick Sanan    Level: deprecated
30583d91586SPatrick Sanan @*/
306d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetReducedDMDA(DM da, PetscInt nfields, DM *nda)
307d71ae5a4SJacob Faibussowitsch {
30883d91586SPatrick Sanan   PetscFunctionBegin;
3099566063dSJacob Faibussowitsch   PetscCall(DMDACreateCompatibleDMDA(da, nfields, nda));
310*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31183d91586SPatrick Sanan }
31283d91586SPatrick Sanan 
31383d91586SPatrick Sanan /*@
314dce8aebaSBarry Smith    DMDACreateCompatibleDMDA - Creates a `DMDA` with the same layout but with fewer or more fields
315bc2bf880SBarry Smith 
316b1dd8793SDave May    Collective
317bc2bf880SBarry Smith 
318907376e6SBarry Smith    Input Parameters:
319bc2bf880SBarry Smith +  da - the distributed array
320dce8aebaSBarry Smith -  nfields - number of fields in new `DMDA`
321bc2bf880SBarry Smith 
322bc2bf880SBarry Smith    Output Parameter:
323dce8aebaSBarry Smith .  nda - the new `DMDA`
324bc2bf880SBarry Smith 
325bc2bf880SBarry Smith   Level: intermediate
326bc2bf880SBarry Smith 
327dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDAGetGhostCorners()`, `DMSetCoordinates()`, `DMDASetUniformCoordinates()`, `DMGetCoordinates()`, `DMDAGetGhostedCoordinates()`, `DMStagCreateCompatibleDMStag()`
328bc2bf880SBarry Smith @*/
329d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDACreateCompatibleDMDA(DM da, PetscInt nfields, DM *nda)
330d71ae5a4SJacob Faibussowitsch {
331bc2bf880SBarry Smith   DM_DA          *dd = (DM_DA *)da->data;
33295c13181SPeter Brune   PetscInt        s, m, n, p, M, N, P, dim, Mo, No, Po;
333320964c4SBlaise Bourdin   const PetscInt *lx, *ly, *lz;
334bff4a2f0SMatthew G. Knepley   DMBoundaryType  bx, by, bz;
335320964c4SBlaise Bourdin   DMDAStencilType stencil_type;
3366858538eSMatthew G. Knepley   Vec             coords;
33795c13181SPeter Brune   PetscInt        ox, oy, oz;
33895c13181SPeter Brune   PetscInt        cl, rl;
339320964c4SBlaise Bourdin 
340320964c4SBlaise Bourdin   PetscFunctionBegin;
341c73cfb54SMatthew G. Knepley   dim = da->dim;
34295c13181SPeter Brune   M   = dd->M;
34395c13181SPeter Brune   N   = dd->N;
34495c13181SPeter Brune   P   = dd->P;
34595c13181SPeter Brune   m   = dd->m;
34695c13181SPeter Brune   n   = dd->n;
34795c13181SPeter Brune   p   = dd->p;
34895c13181SPeter Brune   s   = dd->s;
34995c13181SPeter Brune   bx  = dd->bx;
35095c13181SPeter Brune   by  = dd->by;
35195c13181SPeter Brune   bz  = dd->bz;
3528865f1eaSKarl Rupp 
35395c13181SPeter Brune   stencil_type = dd->stencil_type;
3548865f1eaSKarl Rupp 
3559566063dSJacob Faibussowitsch   PetscCall(DMDAGetOwnershipRanges(da, &lx, &ly, &lz));
356320964c4SBlaise Bourdin   if (dim == 1) {
3579566063dSJacob Faibussowitsch     PetscCall(DMDACreate1d(PetscObjectComm((PetscObject)da), bx, M, nfields, s, dd->lx, nda));
358320964c4SBlaise Bourdin   } else if (dim == 2) {
3599566063dSJacob Faibussowitsch     PetscCall(DMDACreate2d(PetscObjectComm((PetscObject)da), bx, by, stencil_type, M, N, m, n, nfields, s, lx, ly, nda));
360320964c4SBlaise Bourdin   } else if (dim == 3) {
3619566063dSJacob Faibussowitsch     PetscCall(DMDACreate3d(PetscObjectComm((PetscObject)da), bx, by, bz, stencil_type, M, N, P, m, n, p, nfields, s, lx, ly, lz, nda));
362bc2bf880SBarry Smith   }
3639566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*nda));
3646858538eSMatthew G. Knepley   PetscCall(DMGetCoordinates(da, &coords));
3656858538eSMatthew G. Knepley   PetscCall(DMSetCoordinates(*nda, coords));
36695c13181SPeter Brune 
36795c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
3689566063dSJacob Faibussowitsch   PetscCall(DMDAGetOffset(da, &ox, &oy, &oz, &Mo, &No, &Po));
3699566063dSJacob Faibussowitsch   PetscCall(DMDASetOffset(*nda, ox, oy, oz, Mo, No, Po));
37095c13181SPeter Brune 
37195c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
3729566063dSJacob Faibussowitsch   PetscCall(DMGetCoarsenLevel(da, &cl));
3739566063dSJacob Faibussowitsch   PetscCall(DMGetRefineLevel(da, &rl));
3748865f1eaSKarl Rupp 
37595c13181SPeter Brune   (*nda)->levelup   = rl;
37695c13181SPeter Brune   (*nda)->leveldown = cl;
377*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
378bc2bf880SBarry Smith }
379bc2bf880SBarry Smith 
380c593f006SBarry Smith /*@C
381dce8aebaSBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the `DMDA`
382c593f006SBarry Smith 
383b1dd8793SDave May    Not collective
384c593f006SBarry Smith 
385c593f006SBarry Smith    Input Parameter:
386dce8aebaSBarry Smith .  dm - the `DMDA`
387c593f006SBarry Smith 
388c593f006SBarry Smith    Output Parameter:
389c593f006SBarry Smith .  xc - the coordinates
390c593f006SBarry Smith 
391c593f006SBarry Smith   Level: intermediate
392c593f006SBarry Smith 
393dce8aebaSBarry Smith   Fortran Note:
394f5f57ec0SBarry Smith   Not supported from Fortran
395f5f57ec0SBarry Smith 
396dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDARestoreCoordinateArray()`
397c593f006SBarry Smith @*/
398d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCoordinateArray(DM dm, void *xc)
399d71ae5a4SJacob Faibussowitsch {
400c593f006SBarry Smith   DM  cdm;
401c593f006SBarry Smith   Vec x;
402c593f006SBarry Smith 
403c593f006SBarry Smith   PetscFunctionBegin;
404c593f006SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4059566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinates(dm, &x));
4069566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
4079566063dSJacob Faibussowitsch   PetscCall(DMDAVecGetArray(cdm, x, xc));
408*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
409c593f006SBarry Smith }
410c593f006SBarry Smith 
411c593f006SBarry Smith /*@C
412dce8aebaSBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the `DMDA`
413c593f006SBarry Smith 
414b1dd8793SDave May    Not collective
415c593f006SBarry Smith 
416d8d19677SJose E. Roman    Input Parameters:
417dce8aebaSBarry Smith +  dm - the `DMDA`
418c593f006SBarry Smith -  xc - the coordinates
419c593f006SBarry Smith 
420c593f006SBarry Smith   Level: intermediate
421c593f006SBarry Smith 
422dce8aebaSBarry Smith   Fortran Note:
423f5f57ec0SBarry Smith   Not supported from Fortran
424f5f57ec0SBarry Smith 
425dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDAGetCoordinateArray()`
426c593f006SBarry Smith @*/
427d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDARestoreCoordinateArray(DM dm, void *xc)
428d71ae5a4SJacob Faibussowitsch {
429c593f006SBarry Smith   DM  cdm;
430c593f006SBarry Smith   Vec x;
431c593f006SBarry Smith 
432c593f006SBarry Smith   PetscFunctionBegin;
433c593f006SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4349566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinates(dm, &x));
4359566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
4369566063dSJacob Faibussowitsch   PetscCall(DMDAVecRestoreArray(cdm, x, xc));
437*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
438c593f006SBarry Smith }
439