xref: /petsc/src/dm/impls/da/dacorn.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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 
9*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
10*d71ae5a4SJacob Faibussowitsch {
113f2d3b52SPeter Brune   PetscFunctionBegin;
129566063dSJacob Faibussowitsch   PetscCall(DMDACreateCompatibleDMDA(dm, dm->dim, cdm));
1347c6ae99SBarry Smith   PetscFunctionReturn(0);
1447c6ae99SBarry Smith }
1547c6ae99SBarry Smith 
16*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMCreateCoordinateField_DA(DM dm, DMField *field)
17*d71ae5a4SJacob Faibussowitsch {
18f19dbd58SToby Isaac   PetscReal   gmin[3], gmax[3];
194d1a973fSToby Isaac   PetscScalar corners[24];
20f19dbd58SToby Isaac   PetscInt    dim;
21f19dbd58SToby Isaac   PetscInt    i, j;
22f19dbd58SToby Isaac   DM          cdm;
23f19dbd58SToby Isaac 
24f19dbd58SToby Isaac   PetscFunctionBegin;
259566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
26f19dbd58SToby Isaac   /* TODO: this is wrong if coordinates are not rectilinear */
279566063dSJacob Faibussowitsch   PetscCall(DMGetBoundingBox(dm, gmin, gmax));
28f19dbd58SToby Isaac   for (i = 0; i < (1 << dim); i++) {
29ad540459SPierre Jolivet     for (j = 0; j < dim; j++) corners[i * dim + j] = (i & (1 << j)) ? gmax[j] : gmin[j];
30f19dbd58SToby Isaac   }
319566063dSJacob Faibussowitsch   PetscCall(DMClone(dm, &cdm));
329566063dSJacob Faibussowitsch   PetscCall(DMFieldCreateDA(cdm, dim, corners, field));
339566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&cdm));
34f19dbd58SToby Isaac   PetscFunctionReturn(0);
35f19dbd58SToby Isaac }
36f19dbd58SToby Isaac 
3747c6ae99SBarry Smith /*@C
38aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
39aa219208SBarry Smith    vectors associated with a DMDA.
4047c6ae99SBarry Smith 
41b1dd8793SDave May    Logically collective; name must contain a common value
4247c6ae99SBarry Smith 
4347c6ae99SBarry Smith    Input Parameters:
4447c6ae99SBarry Smith +  da - the distributed array
45aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
46aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
4747c6ae99SBarry Smith -  names - the name of the field (component)
4847c6ae99SBarry Smith 
4995452b02SPatrick Sanan   Notes:
5095452b02SPatrick Sanan     It must be called after having called DMSetUp().
513eac1ceeSStefano Zampini 
5247c6ae99SBarry Smith   Level: intermediate
5347c6ae99SBarry Smith 
54db781477SPatrick Sanan .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldNames()`, `DMSetUp()`
5547c6ae99SBarry Smith @*/
56*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetFieldName(DM da, PetscInt nf, const char name[])
57*d71ae5a4SJacob Faibussowitsch {
5847c6ae99SBarry Smith   DM_DA *dd = (DM_DA *)da->data;
5947c6ae99SBarry Smith 
6047c6ae99SBarry Smith   PetscFunctionBegin;
61a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
621dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dd->w, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid field number: %" PetscInt_FMT, nf);
637a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
649566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->fieldname[nf]));
659566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &dd->fieldname[nf]));
6647c6ae99SBarry Smith   PetscFunctionReturn(0);
6747c6ae99SBarry Smith }
6847c6ae99SBarry Smith 
69c629b14aSBarry Smith /*@C
70c629b14aSBarry Smith    DMDAGetFieldNames - Gets the name of each component in the vector associated with the DMDA
71c629b14aSBarry Smith 
72b1dd8793SDave May    Not collective; names will contain a common value
73c629b14aSBarry Smith 
74c629b14aSBarry Smith    Input Parameter:
75c629b14aSBarry Smith .  dm - the DMDA object
76c629b14aSBarry Smith 
77c629b14aSBarry Smith    Output Parameter:
78c629b14aSBarry 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
79c629b14aSBarry Smith 
80c629b14aSBarry Smith    Level: intermediate
81c629b14aSBarry Smith 
82f5f57ec0SBarry Smith    Not supported from Fortran, use DMDAGetFieldName()
83f5f57ec0SBarry Smith 
84db781477SPatrick Sanan .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDASetFieldNames()`
85c629b14aSBarry Smith @*/
86*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetFieldNames(DM da, const char *const **names)
87*d71ae5a4SJacob Faibussowitsch {
88c629b14aSBarry Smith   DM_DA *dd = (DM_DA *)da->data;
89c629b14aSBarry Smith 
90c629b14aSBarry Smith   PetscFunctionBegin;
91c629b14aSBarry Smith   *names = (const char *const *)dd->fieldname;
92c629b14aSBarry Smith   PetscFunctionReturn(0);
93c629b14aSBarry Smith }
94c629b14aSBarry Smith 
95c629b14aSBarry Smith /*@C
96c629b14aSBarry Smith    DMDASetFieldNames - Sets the name of each component in the vector associated with the DMDA
97c629b14aSBarry Smith 
98b1dd8793SDave May    Logically collective; names must contain a common value
99c629b14aSBarry Smith 
100c629b14aSBarry Smith    Input Parameters:
101c629b14aSBarry Smith +  dm - the DMDA object
102c629b14aSBarry 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
103c629b14aSBarry Smith 
10495452b02SPatrick Sanan    Notes:
10595452b02SPatrick Sanan     It must be called after having called DMSetUp().
1063eac1ceeSStefano Zampini 
107c629b14aSBarry Smith    Level: intermediate
108c629b14aSBarry Smith 
109f5f57ec0SBarry Smith    Not supported from Fortran, use DMDASetFieldName()
110f5f57ec0SBarry Smith 
111db781477SPatrick Sanan .seealso: `DMDAGetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMSetUp()`
112c629b14aSBarry Smith @*/
113*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetFieldNames(DM da, const char *const *names)
114*d71ae5a4SJacob Faibussowitsch {
115c629b14aSBarry Smith   DM_DA   *dd = (DM_DA *)da->data;
1163eac1ceeSStefano Zampini   char   **fieldname;
1173eac1ceeSStefano Zampini   PetscInt nf = 0;
118c629b14aSBarry Smith 
119c629b14aSBarry Smith   PetscFunctionBegin;
1207a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
1213eac1ceeSStefano Zampini   while (names[nf++]) { };
12263a3b9bcSJacob Faibussowitsch   PetscCheck(nf == dd->w + 1, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of fields %" PetscInt_FMT, nf - 1);
1239566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(names, &fieldname));
1249566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayDestroy(&dd->fieldname));
1253eac1ceeSStefano Zampini   dd->fieldname = fieldname;
126c629b14aSBarry Smith   PetscFunctionReturn(0);
127c629b14aSBarry Smith }
128c629b14aSBarry Smith 
12947c6ae99SBarry Smith /*@C
130aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
131aa219208SBarry Smith    vectors associated with a DMDA.
13247c6ae99SBarry Smith 
133b1dd8793SDave May    Not collective; name will contain a common value
13447c6ae99SBarry Smith 
135d8d19677SJose E. Roman    Input Parameters:
13647c6ae99SBarry Smith +  da - the distributed array
137aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
138aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
13947c6ae99SBarry Smith 
14047c6ae99SBarry Smith    Output Parameter:
14147c6ae99SBarry Smith .  names - the name of the field (component)
14247c6ae99SBarry Smith 
14395452b02SPatrick Sanan   Notes:
14495452b02SPatrick Sanan     It must be called after having called DMSetUp().
1453eac1ceeSStefano Zampini 
14647c6ae99SBarry Smith   Level: intermediate
14747c6ae99SBarry Smith 
148db781477SPatrick Sanan .seealso: `DMDASetFieldName()`, `DMDASetCoordinateName()`, `DMDAGetCoordinateName()`, `DMSetUp()`
14947c6ae99SBarry Smith @*/
150*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetFieldName(DM da, PetscInt nf, const char **name)
151*d71ae5a4SJacob Faibussowitsch {
15247c6ae99SBarry Smith   DM_DA *dd = (DM_DA *)da->data;
15347c6ae99SBarry Smith 
15447c6ae99SBarry Smith   PetscFunctionBegin;
155a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
15647c6ae99SBarry Smith   PetscValidPointer(name, 3);
1571dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dd->w, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid field number: %" PetscInt_FMT, nf);
1587a8be351SBarry Smith   PetscCheck(dd->fieldname, PetscObjectComm((PetscObject)da), PETSC_ERR_ORDER, "You should call DMSetUp() first");
15947c6ae99SBarry Smith   *name = dd->fieldname[nf];
16047c6ae99SBarry Smith   PetscFunctionReturn(0);
16147c6ae99SBarry Smith }
16247c6ae99SBarry Smith 
163109c9344SBarry Smith /*@C
164109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
165109c9344SBarry Smith 
166b1dd8793SDave May    Logically collective; name must contain a common value
167109c9344SBarry Smith 
168109c9344SBarry Smith    Input Parameters:
169c73cfb54SMatthew G. Knepley +  dm - the DM
170109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
171109c9344SBarry Smith -  name - the name of the coordinate
172109c9344SBarry Smith 
17395452b02SPatrick Sanan   Notes:
17495452b02SPatrick Sanan     It must be called after having called DMSetUp().
1753eac1ceeSStefano Zampini 
176109c9344SBarry Smith   Level: intermediate
177109c9344SBarry Smith 
178f5f57ec0SBarry Smith   Not supported from Fortran
179f5f57ec0SBarry Smith 
180db781477SPatrick Sanan .seealso: `DMDAGetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
181109c9344SBarry Smith @*/
182*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetCoordinateName(DM dm, PetscInt nf, const char name[])
183*d71ae5a4SJacob Faibussowitsch {
184c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA *)dm->data;
185109c9344SBarry Smith 
186109c9344SBarry Smith   PetscFunctionBegin;
187a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
1881dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dm->dim, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid coordinate number: %" PetscInt_FMT, nf);
1897a8be351SBarry Smith   PetscCheck(dd->coordinatename, PetscObjectComm((PetscObject)dm), PETSC_ERR_ORDER, "You should call DMSetUp() first");
1909566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->coordinatename[nf]));
1919566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name, &dd->coordinatename[nf]));
192109c9344SBarry Smith   PetscFunctionReturn(0);
193109c9344SBarry Smith }
194109c9344SBarry Smith 
195109c9344SBarry Smith /*@C
196109c9344SBarry Smith    DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA.
197109c9344SBarry Smith 
198b1dd8793SDave May    Not collective; name will contain a common value
199109c9344SBarry Smith 
200d8d19677SJose E. Roman    Input Parameters:
201c73cfb54SMatthew G. Knepley +  dm - the DM
202109c9344SBarry Smith -  nf -  number for the DMDA (0, 1, ... dim-1)
203109c9344SBarry Smith 
204109c9344SBarry Smith    Output Parameter:
205109c9344SBarry Smith .  names - the name of the coordinate direction
206109c9344SBarry Smith 
20795452b02SPatrick Sanan   Notes:
20895452b02SPatrick Sanan     It must be called after having called DMSetUp().
2093eac1ceeSStefano Zampini 
210109c9344SBarry Smith   Level: intermediate
211109c9344SBarry Smith 
212f5f57ec0SBarry Smith   Not supported from Fortran
213f5f57ec0SBarry Smith 
214db781477SPatrick Sanan .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMSetUp()`
215109c9344SBarry Smith @*/
216*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCoordinateName(DM dm, PetscInt nf, const char **name)
217*d71ae5a4SJacob Faibussowitsch {
218c73cfb54SMatthew G. Knepley   DM_DA *dd = (DM_DA *)dm->data;
219109c9344SBarry Smith 
220109c9344SBarry Smith   PetscFunctionBegin;
221a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm, DM_CLASSID, 1, DMDA);
222109c9344SBarry Smith   PetscValidPointer(name, 3);
2231dca8a05SBarry Smith   PetscCheck(nf >= 0 && nf < dm->dim, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid coordinate number: %" PetscInt_FMT, nf);
2247a8be351SBarry Smith   PetscCheck(dd->coordinatename, PetscObjectComm((PetscObject)dm), PETSC_ERR_ORDER, "You should call DMSetUp() first");
225109c9344SBarry Smith   *name = dd->coordinatename[nf];
226109c9344SBarry Smith   PetscFunctionReturn(0);
227109c9344SBarry Smith }
228109c9344SBarry Smith 
229a5d1443cSVincent Le Chenadec /*@C
230aa219208SBarry Smith    DMDAGetCorners - Returns the global (x,y,z) indices of the lower left
23159f3ab6dSMatthew G. Knepley    corner and size of the local region, excluding ghost points.
23247c6ae99SBarry Smith 
233b1dd8793SDave May    Not collective
23447c6ae99SBarry Smith 
23547c6ae99SBarry Smith    Input Parameter:
23647c6ae99SBarry Smith .  da - the distributed array
23747c6ae99SBarry Smith 
23847c6ae99SBarry Smith    Output Parameters:
2396b867d5aSJose E. Roman +  x - the corner index for the first dimension
2406b867d5aSJose E. Roman .  y - the corner index for the second dimension (only used in 2D and 3D problems)
2416b867d5aSJose E. Roman .  z - the corner index for the third dimension (only used in 3D problems)
2426b867d5aSJose E. Roman .  m - the width in the first dimension
2436b867d5aSJose E. Roman .  n - the width in the second dimension (only used in 2D and 3D problems)
2446b867d5aSJose E. Roman -  p - the width in the third dimension (only used in 3D problems)
24547c6ae99SBarry Smith 
24647c6ae99SBarry Smith    Note:
24747c6ae99SBarry Smith    The corner information is independent of the number of degrees of
248aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
24947c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
25047c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2510298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
25247c6ae99SBarry Smith 
25347c6ae99SBarry Smith   Level: beginner
25447c6ae99SBarry Smith 
255db781477SPatrick Sanan .seealso: `DMDAGetGhostCorners()`, `DMDAGetOwnershipRanges()`, `DMStagGetCorners()`
25647c6ae99SBarry Smith @*/
257*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCorners(DM da, PetscInt *x, PetscInt *y, PetscInt *z, PetscInt *m, PetscInt *n, PetscInt *p)
258*d71ae5a4SJacob Faibussowitsch {
25947c6ae99SBarry Smith   PetscInt w;
26047c6ae99SBarry Smith   DM_DA   *dd = (DM_DA *)da->data;
26147c6ae99SBarry Smith 
26247c6ae99SBarry Smith   PetscFunctionBegin;
263a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
26447c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
26547c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
26647c6ae99SBarry Smith   w = dd->w;
26759bc5b24SSatish Balay   if (x) *x = dd->xs / w + dd->xo;
26847c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
26959bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
27059bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
27159bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs) / w;
27259bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
27359bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
27447c6ae99SBarry Smith   PetscFunctionReturn(0);
27547c6ae99SBarry Smith }
27647c6ae99SBarry Smith 
277*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMGetLocalBoundingIndices_DMDA(DM dm, PetscReal lmin[], PetscReal lmax[])
278*d71ae5a4SJacob Faibussowitsch {
2797324c66bSJed Brown   DMDALocalInfo info;
28047c6ae99SBarry Smith 
28147c6ae99SBarry Smith   PetscFunctionBegin;
2829566063dSJacob Faibussowitsch   PetscCall(DMDAGetLocalInfo(dm, &info));
283b2e4378dSMatthew G. Knepley   lmin[0] = info.xs;
284b2e4378dSMatthew G. Knepley   lmin[1] = info.ys;
285b2e4378dSMatthew G. Knepley   lmin[2] = info.zs;
286b2e4378dSMatthew G. Knepley   lmax[0] = info.xs + info.xm - 1;
287b2e4378dSMatthew G. Knepley   lmax[1] = info.ys + info.ym - 1;
288b2e4378dSMatthew G. Knepley   lmax[2] = info.zs + info.zm - 1;
28947c6ae99SBarry Smith   PetscFunctionReturn(0);
29047c6ae99SBarry Smith }
291bc2bf880SBarry Smith 
292bc2bf880SBarry Smith /*@
29383d91586SPatrick Sanan    DMDAGetReducedDMDA - Deprecated; use DMDACreateCompatibleDMDA()
29483d91586SPatrick Sanan 
29583d91586SPatrick Sanan    Level: deprecated
29683d91586SPatrick Sanan @*/
297*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetReducedDMDA(DM da, PetscInt nfields, DM *nda)
298*d71ae5a4SJacob Faibussowitsch {
29983d91586SPatrick Sanan   PetscFunctionBegin;
3009566063dSJacob Faibussowitsch   PetscCall(DMDACreateCompatibleDMDA(da, nfields, nda));
30183d91586SPatrick Sanan   PetscFunctionReturn(0);
30283d91586SPatrick Sanan }
30383d91586SPatrick Sanan 
30483d91586SPatrick Sanan /*@
305211d3afbSPatrick Sanan    DMDACreateCompatibleDMDA - Creates a DMDA with the same layout but with fewer or more fields
306bc2bf880SBarry Smith 
307b1dd8793SDave May    Collective
308bc2bf880SBarry Smith 
309907376e6SBarry Smith    Input Parameters:
310bc2bf880SBarry Smith +  da - the distributed array
311907376e6SBarry Smith -  nfields - number of fields in new DMDA
312bc2bf880SBarry Smith 
313bc2bf880SBarry Smith    Output Parameter:
314bc2bf880SBarry Smith .  nda - the new DMDA
315bc2bf880SBarry Smith 
316bc2bf880SBarry Smith   Level: intermediate
317bc2bf880SBarry Smith 
318db781477SPatrick Sanan .seealso: `DMDAGetGhostCorners()`, `DMSetCoordinates()`, `DMDASetUniformCoordinates()`, `DMGetCoordinates()`, `DMDAGetGhostedCoordinates()`, `DMStagCreateCompatibleDMStag()`
319bc2bf880SBarry Smith @*/
320*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDACreateCompatibleDMDA(DM da, PetscInt nfields, DM *nda)
321*d71ae5a4SJacob Faibussowitsch {
322bc2bf880SBarry Smith   DM_DA          *dd = (DM_DA *)da->data;
32395c13181SPeter Brune   PetscInt        s, m, n, p, M, N, P, dim, Mo, No, Po;
324320964c4SBlaise Bourdin   const PetscInt *lx, *ly, *lz;
325bff4a2f0SMatthew G. Knepley   DMBoundaryType  bx, by, bz;
326320964c4SBlaise Bourdin   DMDAStencilType stencil_type;
3276858538eSMatthew G. Knepley   Vec             coords;
32895c13181SPeter Brune   PetscInt        ox, oy, oz;
32995c13181SPeter Brune   PetscInt        cl, rl;
330320964c4SBlaise Bourdin 
331320964c4SBlaise Bourdin   PetscFunctionBegin;
332c73cfb54SMatthew G. Knepley   dim = da->dim;
33395c13181SPeter Brune   M   = dd->M;
33495c13181SPeter Brune   N   = dd->N;
33595c13181SPeter Brune   P   = dd->P;
33695c13181SPeter Brune   m   = dd->m;
33795c13181SPeter Brune   n   = dd->n;
33895c13181SPeter Brune   p   = dd->p;
33995c13181SPeter Brune   s   = dd->s;
34095c13181SPeter Brune   bx  = dd->bx;
34195c13181SPeter Brune   by  = dd->by;
34295c13181SPeter Brune   bz  = dd->bz;
3438865f1eaSKarl Rupp 
34495c13181SPeter Brune   stencil_type = dd->stencil_type;
3458865f1eaSKarl Rupp 
3469566063dSJacob Faibussowitsch   PetscCall(DMDAGetOwnershipRanges(da, &lx, &ly, &lz));
347320964c4SBlaise Bourdin   if (dim == 1) {
3489566063dSJacob Faibussowitsch     PetscCall(DMDACreate1d(PetscObjectComm((PetscObject)da), bx, M, nfields, s, dd->lx, nda));
349320964c4SBlaise Bourdin   } else if (dim == 2) {
3509566063dSJacob Faibussowitsch     PetscCall(DMDACreate2d(PetscObjectComm((PetscObject)da), bx, by, stencil_type, M, N, m, n, nfields, s, lx, ly, nda));
351320964c4SBlaise Bourdin   } else if (dim == 3) {
3529566063dSJacob Faibussowitsch     PetscCall(DMDACreate3d(PetscObjectComm((PetscObject)da), bx, by, bz, stencil_type, M, N, P, m, n, p, nfields, s, lx, ly, lz, nda));
353bc2bf880SBarry Smith   }
3549566063dSJacob Faibussowitsch   PetscCall(DMSetUp(*nda));
3556858538eSMatthew G. Knepley   PetscCall(DMGetCoordinates(da, &coords));
3566858538eSMatthew G. Knepley   PetscCall(DMSetCoordinates(*nda, coords));
35795c13181SPeter Brune 
35895c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
3599566063dSJacob Faibussowitsch   PetscCall(DMDAGetOffset(da, &ox, &oy, &oz, &Mo, &No, &Po));
3609566063dSJacob Faibussowitsch   PetscCall(DMDASetOffset(*nda, ox, oy, oz, Mo, No, Po));
36195c13181SPeter Brune 
36295c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
3639566063dSJacob Faibussowitsch   PetscCall(DMGetCoarsenLevel(da, &cl));
3649566063dSJacob Faibussowitsch   PetscCall(DMGetRefineLevel(da, &rl));
3658865f1eaSKarl Rupp 
36695c13181SPeter Brune   (*nda)->levelup   = rl;
36795c13181SPeter Brune   (*nda)->leveldown = cl;
368bc2bf880SBarry Smith   PetscFunctionReturn(0);
369bc2bf880SBarry Smith }
370bc2bf880SBarry Smith 
371c593f006SBarry Smith /*@C
372c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
373c593f006SBarry Smith 
374b1dd8793SDave May    Not collective
375c593f006SBarry Smith 
376c593f006SBarry Smith    Input Parameter:
377c593f006SBarry Smith .  dm - the DM
378c593f006SBarry Smith 
379c593f006SBarry Smith    Output Parameter:
380c593f006SBarry Smith .  xc - the coordinates
381c593f006SBarry Smith 
382c593f006SBarry Smith   Level: intermediate
383c593f006SBarry Smith 
384f5f57ec0SBarry Smith   Not supported from Fortran
385f5f57ec0SBarry Smith 
386db781477SPatrick Sanan .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDARestoreCoordinateArray()`
387c593f006SBarry Smith @*/
388*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetCoordinateArray(DM dm, void *xc)
389*d71ae5a4SJacob Faibussowitsch {
390c593f006SBarry Smith   DM  cdm;
391c593f006SBarry Smith   Vec x;
392c593f006SBarry Smith 
393c593f006SBarry Smith   PetscFunctionBegin;
394c593f006SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3959566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinates(dm, &x));
3969566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
3979566063dSJacob Faibussowitsch   PetscCall(DMDAVecGetArray(cdm, x, xc));
398c593f006SBarry Smith   PetscFunctionReturn(0);
399c593f006SBarry Smith }
400c593f006SBarry Smith 
401c593f006SBarry Smith /*@C
402c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
403c593f006SBarry Smith 
404b1dd8793SDave May    Not collective
405c593f006SBarry Smith 
406d8d19677SJose E. Roman    Input Parameters:
407c593f006SBarry Smith +  dm - the DM
408c593f006SBarry Smith -  xc - the coordinates
409c593f006SBarry Smith 
410c593f006SBarry Smith   Level: intermediate
411c593f006SBarry Smith 
412f5f57ec0SBarry Smith   Not supported from Fortran
413f5f57ec0SBarry Smith 
414db781477SPatrick Sanan .seealso: `DMDASetCoordinateName()`, `DMDASetFieldName()`, `DMDAGetFieldName()`, `DMDAGetCoordinateArray()`
415c593f006SBarry Smith @*/
416*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDARestoreCoordinateArray(DM dm, void *xc)
417*d71ae5a4SJacob Faibussowitsch {
418c593f006SBarry Smith   DM  cdm;
419c593f006SBarry Smith   Vec x;
420c593f006SBarry Smith 
421c593f006SBarry Smith   PetscFunctionBegin;
422c593f006SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
4239566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinates(dm, &x));
4249566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDM(dm, &cdm));
4259566063dSJacob Faibussowitsch   PetscCall(DMDAVecRestoreArray(cdm, x, xc));
426c593f006SBarry Smith   PetscFunctionReturn(0);
427c593f006SBarry Smith }
428