147c6ae99SBarry Smith 247c6ae99SBarry Smith /* 347c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 447c6ae99SBarry Smith */ 547c6ae99SBarry Smith 6b45d2f2cSJed Brown #include <petsc-private/daimpl.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 { 126636e97aSMatthew G Knepley DM_DA *da = (DM_DA *) dm->data; 1347c6ae99SBarry Smith PetscMPIInt size; 1447c6ae99SBarry Smith PetscErrorCode ierr; 1547c6ae99SBarry Smith 1647c6ae99SBarry Smith PetscFunctionBegin; 176636e97aSMatthew G Knepley ierr = MPI_Comm_size(((PetscObject) dm)->comm, &size);CHKERRQ(ierr); 186636e97aSMatthew G Knepley if (da->dim == 1) { 1947c6ae99SBarry Smith PetscInt s,m,*lc,l; 201321219cSEthan Coon DMDABoundaryType bx; 216636e97aSMatthew G Knepley 226636e97aSMatthew G Knepley ierr = DMDAGetInfo(dm,0,&m,0,0,0,0,0,0,&s,&bx,0,0,0);CHKERRQ(ierr); 236636e97aSMatthew G Knepley ierr = DMDAGetCorners(dm,0,0,0,&l,0,0);CHKERRQ(ierr); 2447c6ae99SBarry Smith ierr = PetscMalloc(size * sizeof(PetscInt), &lc);CHKERRQ(ierr); 256636e97aSMatthew G Knepley ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 266636e97aSMatthew G Knepley ierr = DMDACreate1d(((PetscObject)dm)->comm,bx,m,1,s,lc,cdm);CHKERRQ(ierr); 2747c6ae99SBarry Smith ierr = PetscFree(lc);CHKERRQ(ierr); 286636e97aSMatthew G Knepley } else if (da->dim == 2) { 2947c6ae99SBarry Smith PetscInt i,s,m,*lc,*ld,l,k,n,M,N; 301321219cSEthan Coon DMDABoundaryType bx,by; 316636e97aSMatthew G Knepley 326636e97aSMatthew G Knepley ierr = DMDAGetInfo(dm,0,&m,&n,0,&M,&N,0,0,&s,&bx,&by,0,0);CHKERRQ(ierr); 336636e97aSMatthew G Knepley ierr = DMDAGetCorners(dm,0,0,0,&l,&k,0);CHKERRQ(ierr); 3447c6ae99SBarry Smith ierr = PetscMalloc2(size,PetscInt,&lc,size,PetscInt,&ld);CHKERRQ(ierr); 3547c6ae99SBarry Smith /* only first M values in lc matter */ 366636e97aSMatthew G Knepley ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 3747c6ae99SBarry Smith /* every Mth value in ld matters */ 386636e97aSMatthew G Knepley ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 396636e97aSMatthew G Knepley for (i = 0; i < N; ++i) { 4047c6ae99SBarry Smith ld[i] = ld[M*i]; 4147c6ae99SBarry Smith } 42cc76e2cfSBarry Smith if (bx == DMDA_BOUNDARY_MIRROR || by == DMDA_BOUNDARY_MIRROR) { 43cc76e2cfSBarry Smith ierr = DMDACreate2d(((PetscObject)dm)->comm,bx,by,DMDA_STENCIL_STAR,m,n,M,N,2,s,lc,ld,cdm);CHKERRQ(ierr); 44cc76e2cfSBarry Smith } else { 456636e97aSMatthew G Knepley ierr = DMDACreate2d(((PetscObject)dm)->comm,bx,by,DMDA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,cdm);CHKERRQ(ierr); 46cc76e2cfSBarry Smith } 4747c6ae99SBarry Smith ierr = PetscFree2(lc,ld);CHKERRQ(ierr); 486636e97aSMatthew G Knepley } else if (da->dim == 3) { 4947c6ae99SBarry Smith PetscInt i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p; 501321219cSEthan Coon DMDABoundaryType bx,by,bz; 516636e97aSMatthew G Knepley 526636e97aSMatthew G Knepley ierr = DMDAGetInfo(dm,0,&m,&n,&p,&M,&N,&P,0,&s,&bx,&by,&bz,0);CHKERRQ(ierr); 536636e97aSMatthew G Knepley ierr = DMDAGetCorners(dm,0,0,0,&l,&k,&q);CHKERRQ(ierr); 5447c6ae99SBarry Smith ierr = PetscMalloc3(size,PetscInt,&lc,size,PetscInt,&ld,size,PetscInt,&le);CHKERRQ(ierr); 5547c6ae99SBarry Smith /* only first M values in lc matter */ 566636e97aSMatthew G Knepley ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 5747c6ae99SBarry Smith /* every Mth value in ld matters */ 586636e97aSMatthew G Knepley ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 596636e97aSMatthew G Knepley for (i = 0; i < N; ++i) { 6047c6ae99SBarry Smith ld[i] = ld[M*i]; 6147c6ae99SBarry Smith } 626636e97aSMatthew G Knepley ierr = MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); 636636e97aSMatthew G Knepley for (i = 0; i < P; ++i) { 6447c6ae99SBarry Smith le[i] = le[M*N*i]; 6547c6ae99SBarry Smith } 666636e97aSMatthew G Knepley ierr = DMDACreate3d(((PetscObject)dm)->comm,bx,by,bz,DMDA_STENCIL_BOX,m,n,p,M,N,P,3,s,lc,ld,le,cdm);CHKERRQ(ierr); 6747c6ae99SBarry Smith ierr = PetscFree3(lc,ld,le);CHKERRQ(ierr); 6847c6ae99SBarry Smith } 6947c6ae99SBarry Smith PetscFunctionReturn(0); 7047c6ae99SBarry Smith } 7147c6ae99SBarry Smith 7247c6ae99SBarry Smith #undef __FUNCT__ 73aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName" 7447c6ae99SBarry Smith /*@C 75aa219208SBarry Smith DMDASetFieldName - Sets the names of individual field components in multicomponent 76aa219208SBarry Smith vectors associated with a DMDA. 7747c6ae99SBarry Smith 7847c6ae99SBarry Smith Not Collective 7947c6ae99SBarry Smith 8047c6ae99SBarry Smith Input Parameters: 8147c6ae99SBarry Smith + da - the distributed array 82aa219208SBarry Smith . nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 83aa219208SBarry Smith number of degrees of freedom per node within the DMDA 8447c6ae99SBarry Smith - names - the name of the field (component) 8547c6ae99SBarry Smith 8647c6ae99SBarry Smith Level: intermediate 8747c6ae99SBarry Smith 8847c6ae99SBarry Smith .keywords: distributed array, get, component name 8947c6ae99SBarry Smith 90109c9344SBarry Smith .seealso: DMDAGetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName() 9147c6ae99SBarry Smith @*/ 927087cfbeSBarry Smith PetscErrorCode DMDASetFieldName(DM da,PetscInt nf,const char name[]) 9347c6ae99SBarry Smith { 9447c6ae99SBarry Smith PetscErrorCode ierr; 9547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 9647c6ae99SBarry Smith 9747c6ae99SBarry Smith PetscFunctionBegin; 9847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 9947c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 100c31cb41cSBarry Smith ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr); 10147c6ae99SBarry Smith ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr); 10247c6ae99SBarry Smith PetscFunctionReturn(0); 10347c6ae99SBarry Smith } 10447c6ae99SBarry Smith 10547c6ae99SBarry Smith #undef __FUNCT__ 106aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName" 10747c6ae99SBarry Smith /*@C 108aa219208SBarry Smith DMDAGetFieldName - Gets the names of individual field components in multicomponent 109aa219208SBarry Smith vectors associated with a DMDA. 11047c6ae99SBarry Smith 11147c6ae99SBarry Smith Not Collective 11247c6ae99SBarry Smith 11347c6ae99SBarry Smith Input Parameter: 11447c6ae99SBarry Smith + da - the distributed array 115aa219208SBarry Smith - nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 116aa219208SBarry Smith number of degrees of freedom per node within the DMDA 11747c6ae99SBarry Smith 11847c6ae99SBarry Smith Output Parameter: 11947c6ae99SBarry Smith . names - the name of the field (component) 12047c6ae99SBarry Smith 12147c6ae99SBarry Smith Level: intermediate 12247c6ae99SBarry Smith 12347c6ae99SBarry Smith .keywords: distributed array, get, component name 12447c6ae99SBarry Smith 125109c9344SBarry Smith .seealso: DMDASetFieldName(), DMDASetCoordinateName(), DMDAGetCoordinateName() 12647c6ae99SBarry Smith @*/ 1277087cfbeSBarry Smith PetscErrorCode DMDAGetFieldName(DM da,PetscInt nf,const char **name) 12847c6ae99SBarry Smith { 12947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 13047c6ae99SBarry Smith 13147c6ae99SBarry Smith PetscFunctionBegin; 13247c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 13347c6ae99SBarry Smith PetscValidPointer(name,3); 13447c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 13547c6ae99SBarry Smith *name = dd->fieldname[nf]; 13647c6ae99SBarry Smith PetscFunctionReturn(0); 13747c6ae99SBarry Smith } 13847c6ae99SBarry Smith 13947c6ae99SBarry Smith #undef __FUNCT__ 140109c9344SBarry Smith #define __FUNCT__ "DMDASetCoordinateName" 141109c9344SBarry Smith /*@C 142109c9344SBarry Smith DMDASetCoordinateName - Sets the name of the coordinate directions associated with a DMDA, for example "x" or "y" 143109c9344SBarry Smith 144109c9344SBarry Smith Not Collective 145109c9344SBarry Smith 146109c9344SBarry Smith Input Parameters: 147109c9344SBarry Smith + da - the distributed array 148109c9344SBarry Smith . nf - coordinate number for the DMDA (0, 1, ... dim-1), 149109c9344SBarry Smith - name - the name of the coordinate 150109c9344SBarry Smith 151109c9344SBarry Smith Level: intermediate 152109c9344SBarry Smith 153109c9344SBarry Smith .keywords: distributed array, get, component name 154109c9344SBarry Smith 155109c9344SBarry Smith .seealso: DMDAGetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName() 156109c9344SBarry Smith @*/ 157109c9344SBarry Smith PetscErrorCode DMDASetCoordinateName(DM da,PetscInt nf,const char name[]) 158109c9344SBarry Smith { 159109c9344SBarry Smith PetscErrorCode ierr; 160109c9344SBarry Smith DM_DA *dd = (DM_DA*)da->data; 161109c9344SBarry Smith 162109c9344SBarry Smith PetscFunctionBegin; 163109c9344SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 164109c9344SBarry Smith if (nf < 0 || nf >= dd->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf); 165109c9344SBarry Smith ierr = PetscFree(dd->coordinatename[nf]);CHKERRQ(ierr); 166109c9344SBarry Smith ierr = PetscStrallocpy(name,&dd->coordinatename[nf]);CHKERRQ(ierr); 167109c9344SBarry Smith PetscFunctionReturn(0); 168109c9344SBarry Smith } 169109c9344SBarry Smith 170109c9344SBarry Smith #undef __FUNCT__ 171109c9344SBarry Smith #define __FUNCT__ "DMDAGetCoordinateName" 172109c9344SBarry Smith /*@C 173109c9344SBarry Smith DMDAGetCoordinateName - Gets the name of a coodinate direction associated with a DMDA. 174109c9344SBarry Smith 175109c9344SBarry Smith Not Collective 176109c9344SBarry Smith 177109c9344SBarry Smith Input Parameter: 178109c9344SBarry Smith + da - the distributed array 179109c9344SBarry Smith - nf - number for the DMDA (0, 1, ... dim-1) 180109c9344SBarry Smith 181109c9344SBarry Smith Output Parameter: 182109c9344SBarry Smith . names - the name of the coordinate direction 183109c9344SBarry Smith 184109c9344SBarry Smith Level: intermediate 185109c9344SBarry Smith 186109c9344SBarry Smith .keywords: distributed array, get, component name 187109c9344SBarry Smith 188109c9344SBarry Smith .seealso: DMDASetCoordinateName(), DMDASetFieldName(), DMDAGetFieldName() 189109c9344SBarry Smith @*/ 190109c9344SBarry Smith PetscErrorCode DMDAGetCoordinateName(DM da,PetscInt nf,const char **name) 191109c9344SBarry Smith { 192109c9344SBarry Smith DM_DA *dd = (DM_DA*)da->data; 193109c9344SBarry Smith 194109c9344SBarry Smith PetscFunctionBegin; 195109c9344SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 196109c9344SBarry Smith PetscValidPointer(name,3); 197109c9344SBarry Smith if (nf < 0 || nf >= dd->dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid coordinate number: %D",nf); 198109c9344SBarry Smith *name = dd->coordinatename[nf]; 199109c9344SBarry Smith PetscFunctionReturn(0); 200109c9344SBarry Smith } 201109c9344SBarry Smith 202109c9344SBarry Smith #undef __FUNCT__ 203aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners" 20447c6ae99SBarry Smith /*@ 205aa219208SBarry Smith DMDAGetCorners - Returns the global (x,y,z) indices of the lower left 20647c6ae99SBarry Smith corner of the local region, excluding ghost points. 20747c6ae99SBarry Smith 20847c6ae99SBarry Smith Not Collective 20947c6ae99SBarry Smith 21047c6ae99SBarry Smith Input Parameter: 21147c6ae99SBarry Smith . da - the distributed array 21247c6ae99SBarry Smith 21347c6ae99SBarry Smith Output Parameters: 21447c6ae99SBarry Smith + x,y,z - the corner indices (where y and z are optional; these are used 21547c6ae99SBarry Smith for 2D and 3D problems) 21647c6ae99SBarry Smith - m,n,p - widths in the corresponding directions (where n and p are optional; 21747c6ae99SBarry Smith these are used for 2D and 3D problems) 21847c6ae99SBarry Smith 21947c6ae99SBarry Smith Note: 22047c6ae99SBarry Smith The corner information is independent of the number of degrees of 221aa219208SBarry Smith freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and 22247c6ae99SBarry Smith m, n, p can be thought of as coordinates on a logical grid, where each 22347c6ae99SBarry Smith grid point has (potentially) several degrees of freedom. 22447c6ae99SBarry Smith Any of y, z, n, and p can be passed in as PETSC_NULL if not needed. 22547c6ae99SBarry Smith 22647c6ae99SBarry Smith Level: beginner 22747c6ae99SBarry Smith 22847c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices 22947c6ae99SBarry Smith 230aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges() 23147c6ae99SBarry Smith @*/ 2327087cfbeSBarry Smith PetscErrorCode DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p) 23347c6ae99SBarry Smith { 23447c6ae99SBarry Smith PetscInt w; 23547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 23647c6ae99SBarry Smith 23747c6ae99SBarry Smith PetscFunctionBegin; 23847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 23947c6ae99SBarry Smith /* since the xs, xe ... have all been multiplied by the number of degrees 24047c6ae99SBarry Smith of freedom per cell, w = dd->w, we divide that out before returning.*/ 24147c6ae99SBarry Smith w = dd->w; 242d886c4f4SPeter Brune if (x) *x = dd->xs/w + dd->xo; if (m) *m = (dd->xe - dd->xs)/w; 24347c6ae99SBarry Smith /* the y and z have NOT been multiplied by w */ 244d886c4f4SPeter Brune if (y) *y = dd->ys + dd->yo; if (n) *n = (dd->ye - dd->ys); 245d886c4f4SPeter Brune if (z) *z = dd->zs + dd->zo; if (p) *p = (dd->ze - dd->zs); 24647c6ae99SBarry Smith PetscFunctionReturn(0); 24747c6ae99SBarry Smith } 24847c6ae99SBarry Smith 24947c6ae99SBarry Smith #undef __FUNCT__ 250aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox" 25147c6ae99SBarry Smith /*@ 252aa219208SBarry Smith DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA. 25347c6ae99SBarry Smith 25447c6ae99SBarry Smith Not Collective 25547c6ae99SBarry Smith 25647c6ae99SBarry Smith Input Parameter: 25747c6ae99SBarry Smith . da - the distributed array 25847c6ae99SBarry Smith 25947c6ae99SBarry Smith Output Parameters: 26047c6ae99SBarry Smith + lmin - local minimum coordinates (length dim, optional) 26147c6ae99SBarry Smith - lmax - local maximim coordinates (length dim, optional) 26247c6ae99SBarry Smith 26347c6ae99SBarry Smith Level: beginner 26447c6ae99SBarry Smith 26547c6ae99SBarry Smith .keywords: distributed array, get, coordinates 26647c6ae99SBarry Smith 2672150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetBoundingBox() 26847c6ae99SBarry Smith @*/ 2697087cfbeSBarry Smith PetscErrorCode DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[]) 27047c6ae99SBarry Smith { 27147c6ae99SBarry Smith PetscErrorCode ierr; 27247c6ae99SBarry Smith Vec coords = PETSC_NULL; 27347c6ae99SBarry Smith PetscInt dim,i,j; 27447c6ae99SBarry Smith const PetscScalar *local_coords; 275ea345e14SBarry Smith PetscReal min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL}; 27647c6ae99SBarry Smith PetscInt N,Ni; 27747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 27847c6ae99SBarry Smith 27947c6ae99SBarry Smith PetscFunctionBegin; 28047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 28147c6ae99SBarry Smith dim = dd->dim; 2826636e97aSMatthew G Knepley ierr = DMGetCoordinates(da,&coords);CHKERRQ(ierr); 2837324c66bSJed Brown if (coords) { 28447c6ae99SBarry Smith ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr); 28547c6ae99SBarry Smith ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr); 28647c6ae99SBarry Smith Ni = N/dim; 28747c6ae99SBarry Smith for (i=0; i<Ni; i++) { 2887324c66bSJed Brown for (j=0; j<3; j++) { 2897324c66bSJed Brown min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0; 2902197688cSJed Brown max[j] = j < dim ? PetscMax(max[j],PetscRealPart(local_coords[i*dim+j])) : 0; 29147c6ae99SBarry Smith } 29247c6ae99SBarry Smith } 29347c6ae99SBarry Smith ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr); 2947324c66bSJed Brown } else { /* Just use grid indices */ 2957324c66bSJed Brown DMDALocalInfo info; 2967324c66bSJed Brown ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 2977324c66bSJed Brown min[0] = info.xs; 2987324c66bSJed Brown min[1] = info.ys; 2997324c66bSJed Brown min[2] = info.zs; 3007324c66bSJed Brown max[0] = info.xs + info.xm-1; 3017324c66bSJed Brown max[1] = info.ys + info.ym-1; 3027324c66bSJed Brown max[2] = info.zs + info.zm-1; 3037324c66bSJed Brown } 30447c6ae99SBarry Smith if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);} 30547c6ae99SBarry Smith if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);} 30647c6ae99SBarry Smith PetscFunctionReturn(0); 30747c6ae99SBarry Smith } 30847c6ae99SBarry Smith 30947c6ae99SBarry Smith #undef __FUNCT__ 310aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox" 31147c6ae99SBarry Smith /*@ 312aa219208SBarry Smith DMDAGetBoundingBox - Returns the global bounding box for the DMDA. 31347c6ae99SBarry Smith 314aa219208SBarry Smith Collective on DMDA 31547c6ae99SBarry Smith 31647c6ae99SBarry Smith Input Parameter: 31747c6ae99SBarry Smith . da - the distributed array 31847c6ae99SBarry Smith 31947c6ae99SBarry Smith Output Parameters: 32047c6ae99SBarry Smith + gmin - global minimum coordinates (length dim, optional) 32147c6ae99SBarry Smith - gmax - global maximim coordinates (length dim, optional) 32247c6ae99SBarry Smith 32347c6ae99SBarry Smith Level: beginner 32447c6ae99SBarry Smith 32547c6ae99SBarry Smith .keywords: distributed array, get, coordinates 32647c6ae99SBarry Smith 3272150357eSBarry Smith .seealso: DMDAGetCoordinateDA(), DMGetCoordinates(), DMDAGetLocalBoundingBox() 32847c6ae99SBarry Smith @*/ 3297087cfbeSBarry Smith PetscErrorCode DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[]) 33047c6ae99SBarry Smith { 33147c6ae99SBarry Smith PetscErrorCode ierr; 33247c6ae99SBarry Smith PetscMPIInt count; 33347c6ae99SBarry Smith PetscReal lmin[3],lmax[3]; 33447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 33547c6ae99SBarry Smith 33647c6ae99SBarry Smith PetscFunctionBegin; 33747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 33847c6ae99SBarry Smith count = PetscMPIIntCast(dd->dim); 339aa219208SBarry Smith ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr); 340d9822059SBarry Smith if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);} 341d9822059SBarry Smith if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);} 34247c6ae99SBarry Smith PetscFunctionReturn(0); 34347c6ae99SBarry Smith } 344bc2bf880SBarry Smith 345bc2bf880SBarry Smith #undef __FUNCT__ 346db05f41bSBarry Smith #define __FUNCT__ "DMDAGetReducedDMDA" 347bc2bf880SBarry Smith /*@ 348db05f41bSBarry Smith DMDAGetReducedDMDA - Gets the DMDA with the same layout but with fewer or more fields 349bc2bf880SBarry Smith 350bc2bf880SBarry Smith Collective on DMDA 351bc2bf880SBarry Smith 352bc2bf880SBarry Smith Input Parameter: 353bc2bf880SBarry Smith + da - the distributed array 354bc2bf880SBarry Smith . nfields - number of fields in new DMDA 355bc2bf880SBarry Smith 356bc2bf880SBarry Smith Output Parameter: 357bc2bf880SBarry Smith . nda - the new DMDA 358bc2bf880SBarry Smith 359bc2bf880SBarry Smith Level: intermediate 360bc2bf880SBarry Smith 361bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 362bc2bf880SBarry Smith 3632150357eSBarry Smith .seealso: DMDAGetGhostCorners(), DMSetCoordinates(), DMDASetUniformCoordinates(), DMGetCoordinates(), DMDAGetGhostedCoordinates() 364bc2bf880SBarry Smith @*/ 365db05f41bSBarry Smith PetscErrorCode DMDAGetReducedDMDA(DM da,PetscInt nfields,DM *nda) 366bc2bf880SBarry Smith { 367bc2bf880SBarry Smith PetscErrorCode ierr; 368bc2bf880SBarry Smith DM_DA *dd = (DM_DA*)da->data; 369*95c13181SPeter Brune PetscInt s,m,n,p,M,N,P,dim,Mo,No,Po; 370320964c4SBlaise Bourdin const PetscInt *lx,*ly,*lz; 371bc2bf880SBarry Smith DMDABoundaryType bx,by,bz; 372320964c4SBlaise Bourdin DMDAStencilType stencil_type; 373*95c13181SPeter Brune PetscInt ox,oy,oz; 374*95c13181SPeter Brune PetscInt cl,rl; 375320964c4SBlaise Bourdin 376320964c4SBlaise Bourdin PetscFunctionBegin; 377*95c13181SPeter Brune dim = dd->dim; 378*95c13181SPeter Brune M = dd->M; 379*95c13181SPeter Brune N = dd->N; 380*95c13181SPeter Brune P = dd->P; 381*95c13181SPeter Brune m = dd->m; 382*95c13181SPeter Brune n = dd->n; 383*95c13181SPeter Brune p = dd->p; 384*95c13181SPeter Brune s = dd->s; 385*95c13181SPeter Brune bx = dd->bx; 386*95c13181SPeter Brune by = dd->by; 387*95c13181SPeter Brune bz = dd->bz; 388*95c13181SPeter Brune stencil_type = dd->stencil_type; 389320964c4SBlaise Bourdin ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr); 390320964c4SBlaise Bourdin if (dim == 1) { 391320964c4SBlaise Bourdin ierr = DMDACreate1d(((PetscObject)da)->comm,bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr); 392320964c4SBlaise Bourdin } else if (dim == 2) { 393320964c4SBlaise Bourdin ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr); 394320964c4SBlaise Bourdin } else if (dim == 3) { 395320964c4SBlaise Bourdin ierr = DMDACreate3d(((PetscObject)da)->comm,bx,by,bz,stencil_type,M,N,P,m,n,p,nfields,s,lx,ly,lz,nda);CHKERRQ(ierr); 396bc2bf880SBarry Smith } 3976636e97aSMatthew G Knepley if (da->coordinates) { 3986636e97aSMatthew G Knepley ierr = PetscObjectReference((PetscObject)da->coordinates);CHKERRQ(ierr); 3996636e97aSMatthew G Knepley (*nda)->coordinates = da->coordinates; 400bc2bf880SBarry Smith } 401*95c13181SPeter Brune 402*95c13181SPeter Brune /* allow for getting a reduced DA corresponding to a domain decomposition */ 403*95c13181SPeter Brune ierr = DMDAGetOffset(da,&ox,&oy,&oz,&Mo,&No,&Po);CHKERRQ(ierr); 404*95c13181SPeter Brune ierr = DMDASetOffset(*nda,ox,oy,oz,Mo,No,Po);CHKERRQ(ierr); 405*95c13181SPeter Brune 406*95c13181SPeter Brune /* allow for getting a reduced DA corresponding to a coarsened DA */ 407*95c13181SPeter Brune ierr = DMGetCoarsenLevel(da,&cl);CHKERRQ(ierr); 408*95c13181SPeter Brune ierr = DMGetRefineLevel(da,&rl);CHKERRQ(ierr); 409*95c13181SPeter Brune (*nda)->levelup = rl; 410*95c13181SPeter Brune (*nda)->leveldown = cl; 411*95c13181SPeter Brune 412bc2bf880SBarry Smith PetscFunctionReturn(0); 413bc2bf880SBarry Smith } 414bc2bf880SBarry Smith 415