xref: /petsc/src/dm/impls/da/dacorn.c (revision b2e4378d4b9d6aa5fb88b5b4eec64d3c2d3252df)
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 
96636e97aSMatthew G Knepley PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm)
1047c6ae99SBarry Smith {
1147c6ae99SBarry Smith   PetscErrorCode ierr;
123f2d3b52SPeter Brune   PetscFunctionBegin;
13211d3afbSPatrick Sanan   ierr = DMDACreateCompatibleDMDA(dm,dm->dim,cdm);CHKERRQ(ierr);
1447c6ae99SBarry Smith   PetscFunctionReturn(0);
1547c6ae99SBarry Smith }
1647c6ae99SBarry Smith 
17f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_DA(DM dm, DMField *field)
18f19dbd58SToby Isaac {
19f19dbd58SToby Isaac   PetscReal      gmin[3], gmax[3];
204d1a973fSToby Isaac   PetscScalar    corners[24];
21f19dbd58SToby Isaac   PetscInt       dim;
22f19dbd58SToby Isaac   PetscInt       i, j;
23f19dbd58SToby Isaac   DM             cdm;
24f19dbd58SToby Isaac   PetscErrorCode ierr;
25f19dbd58SToby Isaac 
26f19dbd58SToby Isaac   PetscFunctionBegin;
27f19dbd58SToby Isaac   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
28f19dbd58SToby Isaac   /* TODO: this is wrong if coordinates are not rectilinear */
29*b2e4378dSMatthew G. Knepley   ierr = DMGetBoundingBox(dm,gmin,gmax);CHKERRQ(ierr);
30f19dbd58SToby Isaac   for (i = 0; i < (1 << dim); i++) {
31f19dbd58SToby Isaac     for (j = 0; j < dim; j++) {
32f19dbd58SToby Isaac       corners[i*dim + j] = (i & (1 << j)) ? gmax[j] : gmin[j];
33f19dbd58SToby Isaac     }
34f19dbd58SToby Isaac   }
35f19dbd58SToby Isaac   ierr = DMClone(dm,&cdm);CHKERRQ(ierr);
36f19dbd58SToby Isaac   ierr = DMFieldCreateDA(cdm,dim,corners,field);CHKERRQ(ierr);
37f19dbd58SToby Isaac   ierr = DMDestroy(&cdm);CHKERRQ(ierr);
38f19dbd58SToby Isaac   PetscFunctionReturn(0);
39f19dbd58SToby Isaac }
40f19dbd58SToby Isaac 
4147c6ae99SBarry Smith /*@C
42aa219208SBarry Smith    DMDASetFieldName - Sets the names of individual field components in multicomponent
43aa219208SBarry Smith    vectors associated with a DMDA.
4447c6ae99SBarry Smith 
45b1dd8793SDave May    Logically collective; name must contain a common value
4647c6ae99SBarry Smith 
4747c6ae99SBarry Smith    Input Parameters:
4847c6ae99SBarry Smith +  da - the distributed array
49aa219208SBarry Smith .  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
50aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
5147c6ae99SBarry Smith -  names - the name of the field (component)
5247c6ae99SBarry Smith 
5395452b02SPatrick Sanan   Notes:
5495452b02SPatrick Sanan     It must be called after having called DMSetUp().
553eac1ceeSStefano Zampini 
5647c6ae99SBarry Smith   Level: intermediate
5747c6ae99SBarry Smith 
583eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldNames(), DMSetUp()
5947c6ae99SBarry Smith @*/
607087cfbeSBarry Smith PetscErrorCode  DMDASetFieldName(DM da,PetscInt nf,const char name[])
6147c6ae99SBarry Smith {
6247c6ae99SBarry Smith   PetscErrorCode ierr;
6347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
6447c6ae99SBarry Smith 
6547c6ae99SBarry Smith   PetscFunctionBegin;
66a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
6747c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
683eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
69c31cb41cSBarry Smith   ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr);
7047c6ae99SBarry Smith   ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr);
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 
89c629b14aSBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMDASetFieldNames()
90c629b14aSBarry Smith @*/
91c629b14aSBarry Smith PetscErrorCode  DMDAGetFieldNames(DM da,const char * const **names)
92c629b14aSBarry Smith {
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 
1163eac1ceeSStefano Zampini .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMDASetFieldName(), DMSetUp()
117c629b14aSBarry Smith @*/
118c629b14aSBarry Smith PetscErrorCode  DMDASetFieldNames(DM da,const char * const *names)
119c629b14aSBarry Smith {
120c629b14aSBarry Smith   PetscErrorCode ierr;
121c629b14aSBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
1223eac1ceeSStefano Zampini   char           **fieldname;
1233eac1ceeSStefano Zampini   PetscInt       nf = 0;
124c629b14aSBarry Smith 
125c629b14aSBarry Smith   PetscFunctionBegin;
1263eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
1273eac1ceeSStefano Zampini   while (names[nf++]) {};
1283eac1ceeSStefano Zampini   if (nf != dd->w+1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid number of fields %D",nf-1);
1293eac1ceeSStefano Zampini   ierr = PetscStrArrayallocpy(names,&fieldname);CHKERRQ(ierr);
130c629b14aSBarry Smith   ierr = PetscStrArrayDestroy(&dd->fieldname);CHKERRQ(ierr);
1313eac1ceeSStefano Zampini   dd->fieldname = fieldname;
132c629b14aSBarry Smith   PetscFunctionReturn(0);
133c629b14aSBarry Smith }
134c629b14aSBarry Smith 
13547c6ae99SBarry Smith /*@C
136aa219208SBarry Smith    DMDAGetFieldName - Gets the names of individual field components in multicomponent
137aa219208SBarry Smith    vectors associated with a DMDA.
13847c6ae99SBarry Smith 
139b1dd8793SDave May    Not collective; name will contain a common value
14047c6ae99SBarry Smith 
14147c6ae99SBarry Smith    Input Parameter:
14247c6ae99SBarry Smith +  da - the distributed array
143aa219208SBarry Smith -  nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the
144aa219208SBarry Smith         number of degrees of freedom per node within the DMDA
14547c6ae99SBarry Smith 
14647c6ae99SBarry Smith    Output Parameter:
14747c6ae99SBarry Smith .  names - the name of the field (component)
14847c6ae99SBarry Smith 
14995452b02SPatrick Sanan   Notes:
15095452b02SPatrick Sanan     It must be called after having called DMSetUp().
1513eac1ceeSStefano Zampini 
15247c6ae99SBarry Smith   Level: intermediate
15347c6ae99SBarry Smith 
1543eac1ceeSStefano Zampini .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName(), DMSetUp()
15547c6ae99SBarry Smith @*/
1567087cfbeSBarry Smith PetscErrorCode  DMDAGetFieldName(DM da,PetscInt nf,const char **name)
15747c6ae99SBarry Smith {
15847c6ae99SBarry Smith   DM_DA *dd = (DM_DA*)da->data;
15947c6ae99SBarry Smith 
16047c6ae99SBarry Smith   PetscFunctionBegin;
161a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
16247c6ae99SBarry Smith   PetscValidPointer(name,3);
16347c6ae99SBarry Smith   if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf);
1643eac1ceeSStefano Zampini   if (!dd->fieldname) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ORDER,"You should call DMSetUp() first");
16547c6ae99SBarry Smith   *name = dd->fieldname[nf];
16647c6ae99SBarry Smith   PetscFunctionReturn(0);
16747c6ae99SBarry Smith }
16847c6ae99SBarry Smith 
169109c9344SBarry Smith /*@C
170109c9344SBarry Smith    DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y"
171109c9344SBarry Smith 
172b1dd8793SDave May    Logically collective; name must contain a common value
173109c9344SBarry Smith 
174109c9344SBarry Smith    Input Parameters:
175c73cfb54SMatthew G. Knepley +  dm - the DM
176109c9344SBarry Smith .  nf - coordinate number for the DMDA (0, 1, ... dim-1),
177109c9344SBarry Smith -  name - the name of the coordinate
178109c9344SBarry Smith 
17995452b02SPatrick Sanan   Notes:
18095452b02SPatrick Sanan     It must be called after having called DMSetUp().
1813eac1ceeSStefano Zampini 
18216108f1bSDave May 
183109c9344SBarry Smith   Level: intermediate
184109c9344SBarry Smith 
185f5f57ec0SBarry Smith   Not supported from Fortran
186f5f57ec0SBarry Smith 
1873eac1ceeSStefano Zampini .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
188109c9344SBarry Smith @*/
189c73cfb54SMatthew G. Knepley PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[])
190109c9344SBarry Smith {
191109c9344SBarry Smith   PetscErrorCode ierr;
192c73cfb54SMatthew G. Knepley   DM_DA          *dd = (DM_DA*)dm->data;
193109c9344SBarry Smith 
194109c9344SBarry Smith   PetscFunctionBegin;
195a9a02de4SBarry Smith   PetscValidHeaderSpecificType(dm,DM_CLASSID,1,DMDA);
196c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
1973eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
198109c9344SBarry Smith   ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr);
199109c9344SBarry Smith   ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr);
200109c9344SBarry Smith   PetscFunctionReturn(0);
201109c9344SBarry Smith }
202109c9344SBarry Smith 
203109c9344SBarry Smith /*@C
204109c9344SBarry 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 
208109c9344SBarry Smith    Input Parameter:
209c73cfb54SMatthew G. Knepley +  dm - the DM
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 
21595452b02SPatrick Sanan   Notes:
21695452b02SPatrick Sanan     It must be called after having called DMSetUp().
2173eac1ceeSStefano Zampini 
21816108f1bSDave May 
219109c9344SBarry Smith   Level: intermediate
220109c9344SBarry Smith 
221f5f57ec0SBarry Smith   Not supported from Fortran
222f5f57ec0SBarry Smith 
2233eac1ceeSStefano Zampini .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMSetUp()
224109c9344SBarry Smith @*/
225c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name)
226109c9344SBarry Smith {
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);
232c73cfb54SMatthew G. Knepley   if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf);
2333eac1ceeSStefano Zampini   if (!dd->coordinatename) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ORDER,"You should call DMSetUp() first");
234109c9344SBarry Smith   *name = dd->coordinatename[nf];
235109c9344SBarry Smith   PetscFunctionReturn(0);
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:
24847c6ae99SBarry Smith +  x,y,z - the corner indices (where y and z are optional; these are used
24947c6ae99SBarry Smith            for 2D and 3D problems)
25047c6ae99SBarry Smith -  m,n,p - widths in the corresponding directions (where n and p are optional;
25147c6ae99SBarry Smith            these are used for 2D and 3D problems)
25247c6ae99SBarry Smith 
25347c6ae99SBarry Smith    Note:
25447c6ae99SBarry Smith    The corner information is independent of the number of degrees of
255aa219208SBarry Smith    freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and
25647c6ae99SBarry Smith    m, n, p can be thought of as coordinates on a logical grid, where each
25747c6ae99SBarry Smith    grid point has (potentially) several degrees of freedom.
2580298fd71SBarry Smith    Any of y, z, n, and p can be passed in as NULL if not needed.
25947c6ae99SBarry Smith 
26047c6ae99SBarry Smith   Level: beginner
26147c6ae99SBarry Smith 
262aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges()
26347c6ae99SBarry Smith @*/
2647087cfbeSBarry Smith PetscErrorCode  DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p)
26547c6ae99SBarry Smith {
26647c6ae99SBarry Smith   PetscInt w;
26747c6ae99SBarry Smith   DM_DA    *dd = (DM_DA*)da->data;
26847c6ae99SBarry Smith 
26947c6ae99SBarry Smith   PetscFunctionBegin;
270a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
27147c6ae99SBarry Smith   /* since the xs, xe ... have all been multiplied by the number of degrees
27247c6ae99SBarry Smith      of freedom per cell, w = dd->w, we divide that out before returning.*/
27347c6ae99SBarry Smith   w = dd->w;
27459bc5b24SSatish Balay   if (x) *x = dd->xs/w + dd->xo;
27547c6ae99SBarry Smith   /* the y and z have NOT been multiplied by w */
27659bc5b24SSatish Balay   if (y) *y = dd->ys + dd->yo;
27759bc5b24SSatish Balay   if (z) *z = dd->zs + dd->zo;
27859bc5b24SSatish Balay   if (m) *m = (dd->xe - dd->xs)/w;
27959bc5b24SSatish Balay   if (n) *n = (dd->ye - dd->ys);
28059bc5b24SSatish Balay   if (p) *p = (dd->ze - dd->zs);
28147c6ae99SBarry Smith   PetscFunctionReturn(0);
28247c6ae99SBarry Smith }
28347c6ae99SBarry Smith 
284*b2e4378dSMatthew G. Knepley PetscErrorCode DMGetLocalBoundingIndices_DMDA(DM dm, PetscReal lmin[], PetscReal lmax[])
28547c6ae99SBarry Smith {
2867324c66bSJed Brown   DMDALocalInfo  info;
28747c6ae99SBarry Smith   PetscErrorCode ierr;
28847c6ae99SBarry Smith 
28947c6ae99SBarry Smith   PetscFunctionBegin;
290*b2e4378dSMatthew G. Knepley   ierr   = DMDAGetLocalInfo(dm, &info);CHKERRQ(ierr);
291*b2e4378dSMatthew G. Knepley   lmin[0] = info.xs;
292*b2e4378dSMatthew G. Knepley   lmin[1] = info.ys;
293*b2e4378dSMatthew G. Knepley   lmin[2] = info.zs;
294*b2e4378dSMatthew G. Knepley   lmax[0] = info.xs + info.xm-1;
295*b2e4378dSMatthew G. Knepley   lmax[1] = info.ys + info.ym-1;
296*b2e4378dSMatthew G. Knepley   lmax[2] = info.zs + info.zm-1;
29747c6ae99SBarry Smith   PetscFunctionReturn(0);
29847c6ae99SBarry Smith }
299bc2bf880SBarry Smith 
300bc2bf880SBarry Smith /*@
30183d91586SPatrick Sanan    DMDAGetReducedDMDA - Deprecated; use DMDACreateCompatibleDMDA()
30283d91586SPatrick Sanan 
30383d91586SPatrick Sanan    Level: deprecated
30483d91586SPatrick Sanan @*/
30583d91586SPatrick Sanan PetscErrorCode DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda)
30683d91586SPatrick Sanan {
30783d91586SPatrick Sanan   PetscErrorCode ierr;
30883d91586SPatrick Sanan 
30983d91586SPatrick Sanan   PetscFunctionBegin;
31083d91586SPatrick Sanan   ierr = DMDACreateCompatibleDMDA(da,nfields,nda);CHKERRQ(ierr);
31183d91586SPatrick Sanan   PetscFunctionReturn(0);
31283d91586SPatrick Sanan }
31383d91586SPatrick Sanan 
31483d91586SPatrick Sanan /*@
315211d3afbSPatrick Sanan    DMDACreateCompatibleDMDA - Creates a DMDA with the same layout but with fewer or more fields
316bc2bf880SBarry Smith 
317b1dd8793SDave May    Collective
318bc2bf880SBarry Smith 
319907376e6SBarry Smith    Input Parameters:
320bc2bf880SBarry Smith +  da - the distributed array
321907376e6SBarry Smith -  nfields - number of fields in new DMDA
322bc2bf880SBarry Smith 
323bc2bf880SBarry Smith    Output Parameter:
324bc2bf880SBarry Smith .  nda - the new DMDA
325bc2bf880SBarry Smith 
326bc2bf880SBarry Smith   Level: intermediate
327bc2bf880SBarry Smith 
3282150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates()
329bc2bf880SBarry Smith @*/
330211d3afbSPatrick Sanan PetscErrorCode  DMDACreateCompatibleDMDA(DM da,PetscInt nfields,DM *nda)
331bc2bf880SBarry Smith {
332bc2bf880SBarry Smith   PetscErrorCode   ierr;
333bc2bf880SBarry Smith   DM_DA            *dd = (DM_DA*)da->data;
33495c13181SPeter Brune   PetscInt         s,m,n,p,M,N,P,dim,Mo,No,Po;
335320964c4SBlaise Bourdin   const PetscInt   *lx,*ly,*lz;
336bff4a2f0SMatthew G. Knepley   DMBoundaryType   bx,by,bz;
337320964c4SBlaise Bourdin   DMDAStencilType  stencil_type;
33895c13181SPeter Brune   PetscInt         ox,oy,oz;
33995c13181SPeter Brune   PetscInt         cl,rl;
340320964c4SBlaise Bourdin 
341320964c4SBlaise Bourdin   PetscFunctionBegin;
342c73cfb54SMatthew G. Knepley   dim = da->dim;
34395c13181SPeter Brune   M   = dd->M;
34495c13181SPeter Brune   N   = dd->N;
34595c13181SPeter Brune   P   = dd->P;
34695c13181SPeter Brune   m   = dd->m;
34795c13181SPeter Brune   n   = dd->n;
34895c13181SPeter Brune   p   = dd->p;
34995c13181SPeter Brune   s   = dd->s;
35095c13181SPeter Brune   bx  = dd->bx;
35195c13181SPeter Brune   by  = dd->by;
35295c13181SPeter Brune   bz  = dd->bz;
3538865f1eaSKarl Rupp 
35495c13181SPeter Brune   stencil_type = dd->stencil_type;
3558865f1eaSKarl Rupp 
356320964c4SBlaise Bourdin   ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr);
357320964c4SBlaise Bourdin   if (dim == 1) {
358ce94432eSBarry Smith     ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr);
359320964c4SBlaise Bourdin   } else if (dim == 2) {
360ce94432eSBarry Smith     ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr);
361320964c4SBlaise Bourdin   } else if (dim == 3) {
362ce94432eSBarry Smith     ierr = DMDACreate3d(PetscObjectComm((PetscObject)da),bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);CHKERRQ(ierr);
363bc2bf880SBarry Smith   }
364897f7067SBarry Smith   ierr = DMSetUp(*nda);CHKERRQ(ierr);
3656636e97aSMatthew G Knepley   if (da->coordinates) {
3666636e97aSMatthew G Knepley     ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr);
3676636e97aSMatthew G Knepley     (*nda)->coordinates = da->coordinates;
368bc2bf880SBarry Smith   }
36995c13181SPeter Brune 
37095c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a domain decomposition */
37195c13181SPeter Brune   ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr);
37295c13181SPeter Brune   ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr);
37395c13181SPeter Brune 
37495c13181SPeter Brune   /* allow for getting a reduced DA corresponding to a coarsened DA */
37595c13181SPeter Brune   ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr);
37695c13181SPeter Brune   ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr);
3778865f1eaSKarl Rupp 
37895c13181SPeter Brune   (*nda)->levelup   = rl;
37995c13181SPeter Brune   (*nda)->leveldown = cl;
380bc2bf880SBarry Smith   PetscFunctionReturn(0);
381bc2bf880SBarry Smith }
382bc2bf880SBarry Smith 
383c593f006SBarry Smith /*@C
384c593f006SBarry Smith    DMDAGetCoordinateArray - Gets an array containing the coordinates of the DMDA
385c593f006SBarry Smith 
386b1dd8793SDave May    Not collective
387c593f006SBarry Smith 
388c593f006SBarry Smith    Input Parameter:
389c593f006SBarry Smith .  dm - the DM
390c593f006SBarry Smith 
391c593f006SBarry Smith    Output Parameter:
392c593f006SBarry Smith .  xc - the coordinates
393c593f006SBarry Smith 
394c593f006SBarry Smith   Level: intermediate
395c593f006SBarry Smith 
396f5f57ec0SBarry Smith   Not supported from Fortran
397f5f57ec0SBarry Smith 
398c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDARestoreCoordinateArray()
399c593f006SBarry Smith @*/
400c593f006SBarry Smith PetscErrorCode DMDAGetCoordinateArray(DM dm,void *xc)
401c593f006SBarry Smith {
402c593f006SBarry Smith   PetscErrorCode ierr;
403c593f006SBarry Smith   DM             cdm;
404c593f006SBarry Smith   Vec            x;
405c593f006SBarry Smith 
406c593f006SBarry Smith   PetscFunctionBegin;
407c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
408c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
409c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
410c593f006SBarry Smith   ierr = DMDAVecGetArray(cdm,x,xc);CHKERRQ(ierr);
411c593f006SBarry Smith   PetscFunctionReturn(0);
412c593f006SBarry Smith }
413c593f006SBarry Smith 
414c593f006SBarry Smith /*@C
415c593f006SBarry Smith    DMDARestoreCoordinateArray - Sets an array containing the coordinates of the DMDA
416c593f006SBarry Smith 
417b1dd8793SDave May    Not collective
418c593f006SBarry Smith 
419c593f006SBarry Smith    Input Parameter:
420c593f006SBarry Smith +  dm - the DM
421c593f006SBarry Smith -  xc - the coordinates
422c593f006SBarry Smith 
423c593f006SBarry Smith   Level: intermediate
424c593f006SBarry Smith 
425f5f57ec0SBarry Smith   Not supported from Fortran
426f5f57ec0SBarry Smith 
427c593f006SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName(), DMDAGetCoordinateArray()
428c593f006SBarry Smith @*/
429c593f006SBarry Smith PetscErrorCode DMDARestoreCoordinateArray(DM dm,void *xc)
430c593f006SBarry Smith {
431c593f006SBarry Smith   PetscErrorCode ierr;
432c593f006SBarry Smith   DM             cdm;
433c593f006SBarry Smith   Vec            x;
434c593f006SBarry Smith 
435c593f006SBarry Smith   PetscFunctionBegin;
436c593f006SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
437c593f006SBarry Smith   ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr);
438c593f006SBarry Smith   ierr = DMGetCoordinateDM(dm,&cdm);CHKERRQ(ierr);
439c593f006SBarry Smith   ierr = DMDAVecRestoreArray(cdm,x,xc);CHKERRQ(ierr);
440c593f006SBarry Smith   PetscFunctionReturn(0);
441c593f006SBarry Smith }
442