147c6ae99SBarry Smith 247c6ae99SBarry Smith /* 347c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 447c6ae99SBarry Smith */ 547c6ae99SBarry Smith 64035e84dSBarry Smith #include <petsc-private/dmdaimpl.h> /*I "petscdmda.h" I*/ 747c6ae99SBarry Smith 847c6ae99SBarry Smith #undef __FUNCT__ 96636e97aSMatthew G Knepley #define __FUNCT__ "DMCreateCoordinateDM_DA" 106636e97aSMatthew G Knepley PetscErrorCode DMCreateCoordinateDM_DA(DM dm, DM *cdm) 1147c6ae99SBarry Smith { 1247c6ae99SBarry Smith PetscErrorCode ierr; 133f2d3b52SPeter Brune PetscFunctionBegin; 14*c73cfb54SMatthew G. Knepley ierr = DMDAGetReducedDMDA(dm,dm->dim,cdm);CHKERRQ(ierr); 1547c6ae99SBarry Smith PetscFunctionReturn(0); 1647c6ae99SBarry Smith } 1747c6ae99SBarry Smith 1847c6ae99SBarry Smith #undef __FUNCT__ 19aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName" 2047c6ae99SBarry Smith /*@C 21aa219208SBarry Smith DMDASetFieldName - Sets the names of individual field components in multicomponent 22aa219208SBarry Smith vectors associated with a DMDA. 2347c6ae99SBarry Smith 2447c6ae99SBarry Smith Not Collective 2547c6ae99SBarry Smith 2647c6ae99SBarry Smith Input Parameters: 2747c6ae99SBarry Smith + da - the distributed array 28aa219208SBarry Smith . nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 29aa219208SBarry Smith number of degrees of freedom per node within the DMDA 3047c6ae99SBarry Smith - names - the name of the field (component) 3147c6ae99SBarry Smith 3247c6ae99SBarry Smith Level: intermediate 3347c6ae99SBarry Smith 3447c6ae99SBarry Smith .keywords: distributed array, get, component name 3547c6ae99SBarry Smith 36109c9344SBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName() 3747c6ae99SBarry Smith @*/ 387087cfbeSBarry Smith PetscErrorCode DMDASetFieldName(DM da,PetscInt nf,const char name[]) 3947c6ae99SBarry Smith { 4047c6ae99SBarry Smith PetscErrorCode ierr; 4147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 4247c6ae99SBarry Smith 4347c6ae99SBarry Smith PetscFunctionBegin; 4447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 4547c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 46c31cb41cSBarry Smith ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr); 4747c6ae99SBarry Smith ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr); 4847c6ae99SBarry Smith PetscFunctionReturn(0); 4947c6ae99SBarry Smith } 5047c6ae99SBarry Smith 5147c6ae99SBarry Smith #undef __FUNCT__ 52aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName" 5347c6ae99SBarry Smith /*@C 54aa219208SBarry Smith DMDAGetFieldName - Gets the names of individual field components in multicomponent 55aa219208SBarry Smith vectors associated with a DMDA. 5647c6ae99SBarry Smith 5747c6ae99SBarry Smith Not Collective 5847c6ae99SBarry Smith 5947c6ae99SBarry Smith Input Parameter: 6047c6ae99SBarry Smith + da - the distributed array 61aa219208SBarry Smith - nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 62aa219208SBarry Smith number of degrees of freedom per node within the DMDA 6347c6ae99SBarry Smith 6447c6ae99SBarry Smith Output Parameter: 6547c6ae99SBarry Smith . names - the name of the field (component) 6647c6ae99SBarry Smith 6747c6ae99SBarry Smith Level: intermediate 6847c6ae99SBarry Smith 6947c6ae99SBarry Smith .keywords: distributed array, get, component name 7047c6ae99SBarry Smith 71109c9344SBarry Smith .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName() 7247c6ae99SBarry Smith @*/ 737087cfbeSBarry Smith PetscErrorCode DMDAGetFieldName(DM da,PetscInt nf,const char **name) 7447c6ae99SBarry Smith { 7547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 7647c6ae99SBarry Smith 7747c6ae99SBarry Smith PetscFunctionBegin; 7847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 7947c6ae99SBarry Smith PetscValidPointer(name,3); 8047c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 8147c6ae99SBarry Smith *name = dd->fieldname[nf]; 8247c6ae99SBarry Smith PetscFunctionReturn(0); 8347c6ae99SBarry Smith } 8447c6ae99SBarry Smith 8547c6ae99SBarry Smith #undef __FUNCT__ 86109c9344SBarry Smith #define __FUNCT__ "DMDASetCoordinateName" 87109c9344SBarry Smith /*@C 88109c9344SBarry Smith DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y" 89109c9344SBarry Smith 90109c9344SBarry Smith Not Collective 91109c9344SBarry Smith 92109c9344SBarry Smith Input Parameters: 93*c73cfb54SMatthew G. Knepley + dm - the DM 94109c9344SBarry Smith . nf - coordinate number for the DMDA (0, 1, ... dim-1), 95109c9344SBarry Smith - name - the name of the coordinate 96109c9344SBarry Smith 97109c9344SBarry Smith Level: intermediate 98109c9344SBarry Smith 99109c9344SBarry Smith .keywords: distributed array, get, component name 100109c9344SBarry Smith 101109c9344SBarry Smith .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName() 102109c9344SBarry Smith @*/ 103*c73cfb54SMatthew G. Knepley PetscErrorCode DMDASetCoordinateName(DM dm,PetscInt nf,const char name[]) 104109c9344SBarry Smith { 105109c9344SBarry Smith PetscErrorCode ierr; 106*c73cfb54SMatthew G. Knepley DM_DA *dd = (DM_DA*)dm->data; 107109c9344SBarry Smith 108109c9344SBarry Smith PetscFunctionBegin; 109*c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 110*c73cfb54SMatthew G. Knepley if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf); 111109c9344SBarry Smith ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr); 112109c9344SBarry Smith ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr); 113109c9344SBarry Smith PetscFunctionReturn(0); 114109c9344SBarry Smith } 115109c9344SBarry Smith 116109c9344SBarry Smith #undef __FUNCT__ 117109c9344SBarry Smith #define __FUNCT__ "DMDAGetCoordinateName" 118109c9344SBarry Smith /*@C 119109c9344SBarry Smith DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA. 120109c9344SBarry Smith 121109c9344SBarry Smith Not Collective 122109c9344SBarry Smith 123109c9344SBarry Smith Input Parameter: 124*c73cfb54SMatthew G. Knepley + dm - the DM 125109c9344SBarry Smith - nf - number for the DMDA (0, 1, ... dim-1) 126109c9344SBarry Smith 127109c9344SBarry Smith Output Parameter: 128109c9344SBarry Smith . names - the name of the coordinate direction 129109c9344SBarry Smith 130109c9344SBarry Smith Level: intermediate 131109c9344SBarry Smith 132109c9344SBarry Smith .keywords: distributed array, get, component name 133109c9344SBarry Smith 134109c9344SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName() 135109c9344SBarry Smith @*/ 136*c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetCoordinateName(DM dm,PetscInt nf,const char **name) 137109c9344SBarry Smith { 138*c73cfb54SMatthew G. Knepley DM_DA *dd = (DM_DA*)dm->data; 139109c9344SBarry Smith 140109c9344SBarry Smith PetscFunctionBegin; 141*c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 142109c9344SBarry Smith PetscValidPointer(name,3); 143*c73cfb54SMatthew G. Knepley if (nf < 0 || nf >= dm->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf); 144109c9344SBarry Smith *name = dd->coordinatename[nf]; 145109c9344SBarry Smith PetscFunctionReturn(0); 146109c9344SBarry Smith } 147109c9344SBarry Smith 148109c9344SBarry Smith #undef __FUNCT__ 149aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners" 15047c6ae99SBarry Smith /*@ 151aa219208SBarry Smith DMDAGetCorners - Returns the global (x,y,z) indices of the lower left 15247c6ae99SBarry Smith corner of the local region, excluding ghost points. 15347c6ae99SBarry Smith 15447c6ae99SBarry Smith Not Collective 15547c6ae99SBarry Smith 15647c6ae99SBarry Smith Input Parameter: 15747c6ae99SBarry Smith . da - the distributed array 15847c6ae99SBarry Smith 15947c6ae99SBarry Smith Output Parameters: 16047c6ae99SBarry Smith + x,y,z - the corner indices (where y and z are optional; these are used 16147c6ae99SBarry Smith for 2D and 3D problems) 16247c6ae99SBarry Smith - m,n,p - widths in the corresponding directions (where n and p are optional; 16347c6ae99SBarry Smith these are used for 2D and 3D problems) 16447c6ae99SBarry Smith 16547c6ae99SBarry Smith Note: 16647c6ae99SBarry Smith The corner information is independent of the number of degrees of 167aa219208SBarry Smith freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and 16847c6ae99SBarry Smith m, n, p can be thought of as coordinates on a logical grid, where each 16947c6ae99SBarry Smith grid point has (potentially) several degrees of freedom. 1700298fd71SBarry Smith Any of y, z, n, and p can be passed in as NULL if not needed. 17147c6ae99SBarry Smith 17247c6ae99SBarry Smith Level: beginner 17347c6ae99SBarry Smith 17447c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices 17547c6ae99SBarry Smith 176aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges() 17747c6ae99SBarry Smith @*/ 1787087cfbeSBarry Smith PetscErrorCode DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p) 17947c6ae99SBarry Smith { 18047c6ae99SBarry Smith PetscInt w; 18147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 18247c6ae99SBarry Smith 18347c6ae99SBarry Smith PetscFunctionBegin; 18447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 18547c6ae99SBarry Smith /* since the xs, xe ... have all been multiplied by the number of degrees 18647c6ae99SBarry Smith of freedom per cell, w = dd->w, we divide that out before returning.*/ 18747c6ae99SBarry Smith w = dd->w; 188d886c4f4SPeter Brune if (x) *x = dd->xs/w + dd->xo; if (m) *m = (dd->xe - dd->xs)/w; 18947c6ae99SBarry Smith /* the y and z have NOT been multiplied by w */ 190d886c4f4SPeter Brune if (y) *y = dd->ys + dd->yo; if (n) *n = (dd->ye - dd->ys); 191d886c4f4SPeter Brune if (z) *z = dd->zs + dd->zo; if (p) *p = (dd->ze - dd->zs); 19247c6ae99SBarry Smith PetscFunctionReturn(0); 19347c6ae99SBarry Smith } 19447c6ae99SBarry Smith 19547c6ae99SBarry Smith #undef __FUNCT__ 196aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox" 19747c6ae99SBarry Smith /*@ 198aa219208SBarry Smith DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA. 19947c6ae99SBarry Smith 20047c6ae99SBarry Smith Not Collective 20147c6ae99SBarry Smith 20247c6ae99SBarry Smith Input Parameter: 203*c73cfb54SMatthew G. Knepley . dm - the DM 20447c6ae99SBarry Smith 20547c6ae99SBarry Smith Output Parameters: 20647c6ae99SBarry Smith + lmin - local minimum coordinates (length dim, optional) 20747c6ae99SBarry Smith - lmax - local maximim coordinates (length dim, optional) 20847c6ae99SBarry Smith 20947c6ae99SBarry Smith Level: beginner 21047c6ae99SBarry Smith 21147c6ae99SBarry Smith .keywords: distributed array, get, coordinates 21247c6ae99SBarry Smith 2132150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox() 21447c6ae99SBarry Smith @*/ 215*c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetLocalBoundingBox(DM dm,PetscReal lmin[],PetscReal lmax[]) 21647c6ae99SBarry Smith { 21747c6ae99SBarry Smith PetscErrorCode ierr; 2180298fd71SBarry Smith Vec coords = NULL; 21947c6ae99SBarry Smith PetscInt dim,i,j; 22047c6ae99SBarry Smith const PetscScalar *local_coords; 221ea345e14SBarry Smith PetscReal min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL}; 22247c6ae99SBarry Smith PetscInt N,Ni; 22347c6ae99SBarry Smith 22447c6ae99SBarry Smith PetscFunctionBegin; 225*c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 226*c73cfb54SMatthew G. Knepley dim = dm->dim; 227*c73cfb54SMatthew G. Knepley ierr = DMGetCoordinates(dm,&coords);CHKERRQ(ierr); 2287324c66bSJed Brown if (coords) { 22947c6ae99SBarry Smith ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr); 23047c6ae99SBarry Smith ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr); 23147c6ae99SBarry Smith Ni = N/dim; 23247c6ae99SBarry Smith for (i=0; i<Ni; i++) { 2337324c66bSJed Brown for (j=0; j<3; j++) { 2347324c66bSJed Brown min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0; 2352197688cSJed Brown max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0; 23647c6ae99SBarry Smith } 23747c6ae99SBarry Smith } 23847c6ae99SBarry Smith ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr); 2397324c66bSJed Brown } else { /* Just use grid indices */ 2407324c66bSJed Brown DMDALocalInfo info; 241*c73cfb54SMatthew G. Knepley ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr); 2427324c66bSJed Brown min[0] = info.xs; 2437324c66bSJed Brown min[1] = info.ys; 2447324c66bSJed Brown min[2] = info.zs; 2457324c66bSJed Brown max[0] = info.xs + info.xm-1; 2467324c66bSJed Brown max[1] = info.ys + info.ym-1; 2477324c66bSJed Brown max[2] = info.zs + info.zm-1; 2487324c66bSJed Brown } 24947c6ae99SBarry Smith if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);} 25047c6ae99SBarry Smith if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);} 25147c6ae99SBarry Smith PetscFunctionReturn(0); 25247c6ae99SBarry Smith } 25347c6ae99SBarry Smith 25447c6ae99SBarry Smith #undef __FUNCT__ 255aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox" 25647c6ae99SBarry Smith /*@ 257aa219208SBarry Smith DMDAGetBoundingBox - Returns the global bounding box for the DMDA. 25847c6ae99SBarry Smith 259aa219208SBarry Smith Collective on DMDA 26047c6ae99SBarry Smith 26147c6ae99SBarry Smith Input Parameter: 262*c73cfb54SMatthew G. Knepley . dm - the DM 26347c6ae99SBarry Smith 26447c6ae99SBarry Smith Output Parameters: 26547c6ae99SBarry Smith + gmin - global minimum coordinates (length dim, optional) 26647c6ae99SBarry Smith - gmax - global maximim coordinates (length dim, optional) 26747c6ae99SBarry Smith 26847c6ae99SBarry Smith Level: beginner 26947c6ae99SBarry Smith 27047c6ae99SBarry Smith .keywords: distributed array, get, coordinates 27147c6ae99SBarry Smith 2722150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox() 27347c6ae99SBarry Smith @*/ 274*c73cfb54SMatthew G. Knepley PetscErrorCode DMDAGetBoundingBox(DM dm,PetscReal gmin[],PetscReal gmax[]) 27547c6ae99SBarry Smith { 27647c6ae99SBarry Smith PetscErrorCode ierr; 27747c6ae99SBarry Smith PetscMPIInt count; 27847c6ae99SBarry Smith PetscReal lmin[3],lmax[3]; 27947c6ae99SBarry Smith 28047c6ae99SBarry Smith PetscFunctionBegin; 281*c73cfb54SMatthew G. Knepley PetscValidHeaderSpecific(dm,DM_CLASSID,1); 282*c73cfb54SMatthew G. Knepley ierr = PetscMPIIntCast(dm->dim,&count);CHKERRQ(ierr); 283*c73cfb54SMatthew G. Knepley ierr = DMDAGetLocalBoundingBox(dm,lmin,lmax);CHKERRQ(ierr); 284*c73cfb54SMatthew G. Knepley if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);} 285*c73cfb54SMatthew G. Knepley if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);} 28647c6ae99SBarry Smith PetscFunctionReturn(0); 28747c6ae99SBarry Smith } 288bc2bf880SBarry Smith 289bc2bf880SBarry Smith #undef __FUNCT__ 290db05f41bSBarry Smith #define __FUNCT__ "DMDAGetReducedDMDA" 291bc2bf880SBarry Smith /*@ 292db05f41bSBarry Smith DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields 293bc2bf880SBarry Smith 294bc2bf880SBarry Smith Collective on DMDA 295bc2bf880SBarry Smith 296bc2bf880SBarry Smith Input Parameter: 297bc2bf880SBarry Smith + da - the distributed array 298bc2bf880SBarry Smith . nfields - number of fields in new DMDA 299bc2bf880SBarry Smith 300bc2bf880SBarry Smith Output Parameter: 301bc2bf880SBarry Smith . nda - the new DMDA 302bc2bf880SBarry Smith 303bc2bf880SBarry Smith Level: intermediate 304bc2bf880SBarry Smith 305bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 306bc2bf880SBarry Smith 3072150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates() 308bc2bf880SBarry Smith @*/ 309db05f41bSBarry Smith PetscErrorCode DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda) 310bc2bf880SBarry Smith { 311bc2bf880SBarry Smith PetscErrorCode ierr; 312bc2bf880SBarry Smith DM_DA *dd = (DM_DA*)da->data; 31395c13181SPeter Brune PetscInt s,m,n,p,M,N,P,dim,Mo,No,Po; 314320964c4SBlaise Bourdin const PetscInt *lx,*ly,*lz; 315bff4a2f0SMatthew G. Knepley DMBoundaryType bx,by,bz; 316320964c4SBlaise Bourdin DMDAStencilType stencil_type; 31795c13181SPeter Brune PetscInt ox,oy,oz; 31895c13181SPeter Brune PetscInt cl,rl; 319320964c4SBlaise Bourdin 320320964c4SBlaise Bourdin PetscFunctionBegin; 321*c73cfb54SMatthew G. Knepley dim = da->dim; 32295c13181SPeter Brune M = dd->M; 32395c13181SPeter Brune N = dd->N; 32495c13181SPeter Brune P = dd->P; 32595c13181SPeter Brune m = dd->m; 32695c13181SPeter Brune n = dd->n; 32795c13181SPeter Brune p = dd->p; 32895c13181SPeter Brune s = dd->s; 32995c13181SPeter Brune bx = dd->bx; 33095c13181SPeter Brune by = dd->by; 33195c13181SPeter Brune bz = dd->bz; 3328865f1eaSKarl Rupp 33395c13181SPeter Brune stencil_type = dd->stencil_type; 3348865f1eaSKarl Rupp 335320964c4SBlaise Bourdin ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr); 336320964c4SBlaise Bourdin if (dim == 1) { 337ce94432eSBarry Smith ierr = DMDACreate1d(PetscObjectComm((PetscObject)da),bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr); 338320964c4SBlaise Bourdin } else if (dim == 2) { 339ce94432eSBarry Smith ierr = DMDACreate2d(PetscObjectComm((PetscObject)da),bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr); 340320964c4SBlaise Bourdin } else if (dim == 3) { 341ce94432eSBarry 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); 342bc2bf880SBarry Smith } 3436636e97aSMatthew G Knepley if (da->coordinates) { 3446636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr); 3458865f1eaSKarl Rupp 3466636e97aSMatthew G Knepley (*nda)->coordinates = da->coordinates; 347bc2bf880SBarry Smith } 34895c13181SPeter Brune 34995c13181SPeter Brune /* allow for getting a reduced DA corresponding to a domain decomposition */ 35095c13181SPeter Brune ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr); 35195c13181SPeter Brune ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr); 35295c13181SPeter Brune 35395c13181SPeter Brune /* allow for getting a reduced DA corresponding to a coarsened DA */ 35495c13181SPeter Brune ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr); 35595c13181SPeter Brune ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr); 3568865f1eaSKarl Rupp 35795c13181SPeter Brune (*nda)->levelup = rl; 35895c13181SPeter Brune (*nda)->leveldown = cl; 359bc2bf880SBarry Smith PetscFunctionReturn(0); 360bc2bf880SBarry Smith } 361bc2bf880SBarry Smith 362