147c6ae99SBarry Smith #define PETSCDM_DLL 247c6ae99SBarry Smith 347c6ae99SBarry Smith /* 447c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 547c6ae99SBarry Smith */ 647c6ae99SBarry Smith 7e1589f56SBarry Smith #include "private/daimpl.h" /*I "petscdm.h" I*/ 847c6ae99SBarry Smith 947c6ae99SBarry Smith #undef __FUNCT__ 10aa219208SBarry Smith #define __FUNCT__ "DMDASetCoordinates" 1147c6ae99SBarry Smith /*@ 12aa219208SBarry Smith DMDASetCoordinates - Sets into the DMDA a vector that indicates the 1347c6ae99SBarry Smith coordinates of the local nodes (NOT including ghost nodes). 1447c6ae99SBarry Smith 15aa219208SBarry Smith Collective on DMDA 1647c6ae99SBarry Smith 1747c6ae99SBarry Smith Input Parameter: 1847c6ae99SBarry Smith + da - the distributed array 1947c6ae99SBarry Smith - c - coordinate vector 2047c6ae99SBarry Smith 2147c6ae99SBarry Smith Note: 2247c6ae99SBarry Smith The coordinates should NOT include those for all ghost points 2347c6ae99SBarry Smith 2447c6ae99SBarry Smith Level: intermediate 2547c6ae99SBarry Smith 2647c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 2747c6ae99SBarry Smith 28aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetCoordinates(), DMDASetUniformCoordinates(). DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA() 2947c6ae99SBarry Smith @*/ 307087cfbeSBarry Smith PetscErrorCode DMDASetCoordinates(DM da,Vec c) 3147c6ae99SBarry Smith { 3247c6ae99SBarry Smith PetscErrorCode ierr; 3347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 3447c6ae99SBarry Smith 3547c6ae99SBarry Smith PetscFunctionBegin; 3647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 3747c6ae99SBarry Smith PetscValidHeaderSpecific(c,VEC_CLASSID,2); 3847c6ae99SBarry Smith ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 3947c6ae99SBarry Smith if (dd->coordinates) {ierr = VecDestroy(dd->coordinates);CHKERRQ(ierr);} 4047c6ae99SBarry Smith dd->coordinates = c; 4147c6ae99SBarry Smith ierr = VecSetBlockSize(c,dd->dim);CHKERRQ(ierr); 4247c6ae99SBarry Smith if (dd->ghosted_coordinates) { /* The ghosted coordinates are no longer valid */ 4347c6ae99SBarry Smith ierr = VecDestroy(dd->ghosted_coordinates);CHKERRQ(ierr); 4447c6ae99SBarry Smith dd->ghosted_coordinates = PETSC_NULL; 4547c6ae99SBarry Smith } 4647c6ae99SBarry Smith PetscFunctionReturn(0); 4747c6ae99SBarry Smith } 4847c6ae99SBarry Smith 4947c6ae99SBarry Smith #undef __FUNCT__ 50aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinates" 5147c6ae99SBarry Smith /*@ 52aa219208SBarry Smith DMDAGetCoordinates - Gets the node coordinates associated with a DMDA. 5347c6ae99SBarry Smith 5447c6ae99SBarry Smith Not Collective 5547c6ae99SBarry Smith 5647c6ae99SBarry Smith Input Parameter: 5747c6ae99SBarry Smith . da - the distributed array 5847c6ae99SBarry Smith 5947c6ae99SBarry Smith Output Parameter: 6047c6ae99SBarry Smith . c - coordinate vector 6147c6ae99SBarry Smith 6247c6ae99SBarry Smith Note: 6347c6ae99SBarry Smith Each process has only the coordinates for its local nodes (does NOT have the 6447c6ae99SBarry Smith coordinates for the ghost nodes). 6547c6ae99SBarry Smith 6647c6ae99SBarry Smith For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 6747c6ae99SBarry Smith and (x_0,y_0,z_0,x_1,y_1,z_1...) 6847c6ae99SBarry Smith 6947c6ae99SBarry Smith Level: intermediate 7047c6ae99SBarry Smith 7147c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 7247c6ae99SBarry Smith 73aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA() 7447c6ae99SBarry Smith @*/ 757087cfbeSBarry Smith PetscErrorCode DMDAGetCoordinates(DM da,Vec *c) 7647c6ae99SBarry Smith { 7747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 7847c6ae99SBarry Smith PetscFunctionBegin; 7947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 8047c6ae99SBarry Smith PetscValidPointer(c,2); 8147c6ae99SBarry Smith *c = dd->coordinates; 8247c6ae99SBarry Smith PetscFunctionReturn(0); 8347c6ae99SBarry Smith } 8447c6ae99SBarry Smith 8547c6ae99SBarry Smith #undef __FUNCT__ 86aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinateDA" 8747c6ae99SBarry Smith /*@ 88aa219208SBarry Smith DMDAGetCoordinateDA - Gets the DMDA that scatters between global and local DMDA coordinates 8947c6ae99SBarry Smith 90aa219208SBarry Smith Collective on DMDA 9147c6ae99SBarry Smith 9247c6ae99SBarry Smith Input Parameter: 9347c6ae99SBarry Smith . da - the distributed array 9447c6ae99SBarry Smith 9547c6ae99SBarry Smith Output Parameter: 96aa219208SBarry Smith . dac - coordinate DMDA 9747c6ae99SBarry Smith 9847c6ae99SBarry Smith Level: intermediate 9947c6ae99SBarry Smith 10047c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 10147c6ae99SBarry Smith 102aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates() 10347c6ae99SBarry Smith @*/ 1047087cfbeSBarry Smith PetscErrorCode DMDAGetCoordinateDA(DM da,DM *cda) 10547c6ae99SBarry Smith { 10647c6ae99SBarry Smith PetscMPIInt size; 10747c6ae99SBarry Smith PetscErrorCode ierr; 10847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 10947c6ae99SBarry Smith 11047c6ae99SBarry Smith PetscFunctionBegin; 11147c6ae99SBarry Smith if (!dd->da_coordinates) { 11247c6ae99SBarry Smith ierr = MPI_Comm_size(((PetscObject)da)->comm,&size);CHKERRQ(ierr); 11347c6ae99SBarry Smith if (dd->dim == 1) { 11447c6ae99SBarry Smith PetscInt s,m,*lc,l; 115aa219208SBarry Smith DMDAPeriodicType pt; 116aa219208SBarry Smith ierr = DMDAGetInfo(da,0,&m,0,0,0,0,0,0,&s,&pt,0);CHKERRQ(ierr); 117aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&l,0,0);CHKERRQ(ierr); 11847c6ae99SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&lc);CHKERRQ(ierr); 11947c6ae99SBarry Smith ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 120aa219208SBarry Smith ierr = DMDACreate1d(((PetscObject)da)->comm,pt,m,1,s,lc,&dd->da_coordinates);CHKERRQ(ierr); 12147c6ae99SBarry Smith ierr = PetscFree(lc);CHKERRQ(ierr); 12247c6ae99SBarry Smith } else if (dd->dim == 2) { 12347c6ae99SBarry Smith PetscInt i,s,m,*lc,*ld,l,k,n,M,N; 124aa219208SBarry Smith DMDAPeriodicType pt; 125aa219208SBarry Smith ierr = DMDAGetInfo(da,0,&m,&n,0,&M,&N,0,0,&s,&pt,0);CHKERRQ(ierr); 126aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&l,&k,0);CHKERRQ(ierr); 12747c6ae99SBarry Smith ierr = PetscMalloc2(size,PetscInt,&lc,size,PetscInt,&ld);CHKERRQ(ierr); 12847c6ae99SBarry Smith /* only first M values in lc matter */ 12947c6ae99SBarry Smith ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 13047c6ae99SBarry Smith /* every Mth value in ld matters */ 13147c6ae99SBarry Smith ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 13247c6ae99SBarry Smith for ( i=0; i<N; i++) { 13347c6ae99SBarry Smith ld[i] = ld[M*i]; 13447c6ae99SBarry Smith } 135aa219208SBarry Smith ierr = DMDACreate2d(((PetscObject)da)->comm,pt,DMDA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,&dd->da_coordinates);CHKERRQ(ierr); 13647c6ae99SBarry Smith ierr = PetscFree2(lc,ld);CHKERRQ(ierr); 13747c6ae99SBarry Smith } else if (dd->dim == 3) { 13847c6ae99SBarry Smith PetscInt i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p; 139aa219208SBarry Smith DMDAPeriodicType pt; 140aa219208SBarry Smith ierr = DMDAGetInfo(da,0,&m,&n,&p,&M,&N,&P,0,&s,&pt,0);CHKERRQ(ierr); 141aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&l,&k,&q);CHKERRQ(ierr); 14247c6ae99SBarry Smith ierr = PetscMalloc3(size,PetscInt,&lc,size,PetscInt,&ld,size,PetscInt,&le);CHKERRQ(ierr); 14347c6ae99SBarry Smith /* only first M values in lc matter */ 14447c6ae99SBarry Smith ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 14547c6ae99SBarry Smith /* every Mth value in ld matters */ 14647c6ae99SBarry Smith ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 14747c6ae99SBarry Smith for ( i=0; i<N; i++) { 14847c6ae99SBarry Smith ld[i] = ld[M*i]; 14947c6ae99SBarry Smith } 15047c6ae99SBarry Smith ierr = MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 15147c6ae99SBarry Smith for ( i=0; i<P; i++) { 15247c6ae99SBarry Smith le[i] = le[M*N*i]; 15347c6ae99SBarry Smith } 154aa219208SBarry Smith ierr = DMDACreate3d(((PetscObject)da)->comm,pt,DMDA_STENCIL_BOX,m,n,p,M,N,P,3,s,lc,ld,le,&dd->da_coordinates);CHKERRQ(ierr); 15547c6ae99SBarry Smith ierr = PetscFree3(lc,ld,le);CHKERRQ(ierr); 15647c6ae99SBarry Smith } 15747c6ae99SBarry Smith } 15847c6ae99SBarry Smith *cda = dd->da_coordinates; 15947c6ae99SBarry Smith PetscFunctionReturn(0); 16047c6ae99SBarry Smith } 16147c6ae99SBarry Smith 16247c6ae99SBarry Smith 16347c6ae99SBarry Smith #undef __FUNCT__ 164aa219208SBarry Smith #define __FUNCT__ "DMDAGetGhostedCoordinates" 16547c6ae99SBarry Smith /*@ 166aa219208SBarry Smith DMDAGetGhostedCoordinates - Gets the node coordinates associated with a DMDA. 16747c6ae99SBarry Smith 168aa219208SBarry Smith Collective on DMDA 16947c6ae99SBarry Smith 17047c6ae99SBarry Smith Input Parameter: 17147c6ae99SBarry Smith . da - the distributed array 17247c6ae99SBarry Smith 17347c6ae99SBarry Smith Output Parameter: 17447c6ae99SBarry Smith . c - coordinate vector 17547c6ae99SBarry Smith 17647c6ae99SBarry Smith Note: 17747c6ae99SBarry Smith Each process has only the coordinates for its local AND ghost nodes 17847c6ae99SBarry Smith 17947c6ae99SBarry Smith For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 18047c6ae99SBarry Smith and (x_0,y_0,z_0,x_1,y_1,z_1...) 18147c6ae99SBarry Smith 18247c6ae99SBarry Smith Level: intermediate 18347c6ae99SBarry Smith 18447c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 18547c6ae99SBarry Smith 186aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetCoordinateDA() 18747c6ae99SBarry Smith @*/ 1887087cfbeSBarry Smith PetscErrorCode DMDAGetGhostedCoordinates(DM da,Vec *c) 18947c6ae99SBarry Smith { 19047c6ae99SBarry Smith PetscErrorCode ierr; 19147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 19247c6ae99SBarry Smith 19347c6ae99SBarry Smith PetscFunctionBegin; 19447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 19547c6ae99SBarry Smith PetscValidPointer(c,2); 196aa219208SBarry Smith if (!dd->coordinates) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call DMDASetCoordinates() before this call"); 19747c6ae99SBarry Smith if (!dd->ghosted_coordinates) { 1989a42bb27SBarry Smith DM dac; 199aa219208SBarry Smith ierr = DMDAGetCoordinateDA(da,&dac);CHKERRQ(ierr); 200564755cdSBarry Smith ierr = DMCreateLocalVector(dac,&dd->ghosted_coordinates);CHKERRQ(ierr); 2019a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr); 2029a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr); 20347c6ae99SBarry Smith } 20447c6ae99SBarry Smith *c = dd->ghosted_coordinates; 20547c6ae99SBarry Smith PetscFunctionReturn(0); 20647c6ae99SBarry Smith } 20747c6ae99SBarry Smith 20847c6ae99SBarry Smith #undef __FUNCT__ 209aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName" 21047c6ae99SBarry Smith /*@C 211aa219208SBarry Smith DMDASetFieldName - Sets the names of individual field components in multicomponent 212aa219208SBarry Smith vectors associated with a DMDA. 21347c6ae99SBarry Smith 21447c6ae99SBarry Smith Not Collective 21547c6ae99SBarry Smith 21647c6ae99SBarry Smith Input Parameters: 21747c6ae99SBarry Smith + da - the distributed array 218aa219208SBarry Smith . nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 219aa219208SBarry Smith number of degrees of freedom per node within the DMDA 22047c6ae99SBarry Smith - names - the name of the field (component) 22147c6ae99SBarry Smith 22247c6ae99SBarry Smith Level: intermediate 22347c6ae99SBarry Smith 22447c6ae99SBarry Smith .keywords: distributed array, get, component name 22547c6ae99SBarry Smith 226aa219208SBarry Smith .seealso: DMDAGetFieldName() 22747c6ae99SBarry Smith @*/ 2287087cfbeSBarry Smith PetscErrorCode DMDASetFieldName(DM da,PetscInt nf,const char name[]) 22947c6ae99SBarry Smith { 23047c6ae99SBarry Smith PetscErrorCode ierr; 23147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 23247c6ae99SBarry Smith 23347c6ae99SBarry Smith PetscFunctionBegin; 23447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 23547c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 236*c31cb41cSBarry Smith ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr); 23747c6ae99SBarry Smith ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr); 23847c6ae99SBarry Smith PetscFunctionReturn(0); 23947c6ae99SBarry Smith } 24047c6ae99SBarry Smith 24147c6ae99SBarry Smith #undef __FUNCT__ 242aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName" 24347c6ae99SBarry Smith /*@C 244aa219208SBarry Smith DMDAGetFieldName - Gets the names of individual field components in multicomponent 245aa219208SBarry Smith vectors associated with a DMDA. 24647c6ae99SBarry Smith 24747c6ae99SBarry Smith Not Collective 24847c6ae99SBarry Smith 24947c6ae99SBarry Smith Input Parameter: 25047c6ae99SBarry Smith + da - the distributed array 251aa219208SBarry Smith - nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 252aa219208SBarry Smith number of degrees of freedom per node within the DMDA 25347c6ae99SBarry Smith 25447c6ae99SBarry Smith Output Parameter: 25547c6ae99SBarry Smith . names - the name of the field (component) 25647c6ae99SBarry Smith 25747c6ae99SBarry Smith Level: intermediate 25847c6ae99SBarry Smith 25947c6ae99SBarry Smith .keywords: distributed array, get, component name 26047c6ae99SBarry Smith 261aa219208SBarry Smith .seealso: DMDASetFieldName() 26247c6ae99SBarry Smith @*/ 2637087cfbeSBarry Smith PetscErrorCode DMDAGetFieldName(DM da,PetscInt nf,const char **name) 26447c6ae99SBarry Smith { 26547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 26647c6ae99SBarry Smith 26747c6ae99SBarry Smith PetscFunctionBegin; 26847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 26947c6ae99SBarry Smith PetscValidPointer(name,3); 27047c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 27147c6ae99SBarry Smith *name = dd->fieldname[nf]; 27247c6ae99SBarry Smith PetscFunctionReturn(0); 27347c6ae99SBarry Smith } 27447c6ae99SBarry Smith 27547c6ae99SBarry Smith #undef __FUNCT__ 276aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners" 27747c6ae99SBarry Smith /*@ 278aa219208SBarry Smith DMDAGetCorners - Returns the global (x,y,z) indices of the lower left 27947c6ae99SBarry Smith corner of the local region, excluding ghost points. 28047c6ae99SBarry Smith 28147c6ae99SBarry Smith Not Collective 28247c6ae99SBarry Smith 28347c6ae99SBarry Smith Input Parameter: 28447c6ae99SBarry Smith . da - the distributed array 28547c6ae99SBarry Smith 28647c6ae99SBarry Smith Output Parameters: 28747c6ae99SBarry Smith + x,y,z - the corner indices (where y and z are optional; these are used 28847c6ae99SBarry Smith for 2D and 3D problems) 28947c6ae99SBarry Smith - m,n,p - widths in the corresponding directions (where n and p are optional; 29047c6ae99SBarry Smith these are used for 2D and 3D problems) 29147c6ae99SBarry Smith 29247c6ae99SBarry Smith Note: 29347c6ae99SBarry Smith The corner information is independent of the number of degrees of 294aa219208SBarry Smith freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and 29547c6ae99SBarry Smith m, n, p can be thought of as coordinates on a logical grid, where each 29647c6ae99SBarry Smith grid point has (potentially) several degrees of freedom. 29747c6ae99SBarry Smith Any of y, z, n, and p can be passed in as PETSC_NULL if not needed. 29847c6ae99SBarry Smith 29947c6ae99SBarry Smith Level: beginner 30047c6ae99SBarry Smith 30147c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices 30247c6ae99SBarry Smith 303aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges() 30447c6ae99SBarry Smith @*/ 3057087cfbeSBarry Smith PetscErrorCode DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p) 30647c6ae99SBarry Smith { 30747c6ae99SBarry Smith PetscInt w; 30847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 30947c6ae99SBarry Smith 31047c6ae99SBarry Smith PetscFunctionBegin; 31147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 31247c6ae99SBarry Smith /* since the xs, xe ... have all been multiplied by the number of degrees 31347c6ae99SBarry Smith of freedom per cell, w = dd->w, we divide that out before returning.*/ 31447c6ae99SBarry Smith w = dd->w; 31547c6ae99SBarry Smith if (x) *x = dd->xs/w; if(m) *m = (dd->xe - dd->xs)/w; 31647c6ae99SBarry Smith /* the y and z have NOT been multiplied by w */ 31747c6ae99SBarry Smith if (y) *y = dd->ys; if (n) *n = (dd->ye - dd->ys); 31847c6ae99SBarry Smith if (z) *z = dd->zs; if (p) *p = (dd->ze - dd->zs); 31947c6ae99SBarry Smith PetscFunctionReturn(0); 32047c6ae99SBarry Smith } 32147c6ae99SBarry Smith 32247c6ae99SBarry Smith #undef __FUNCT__ 323aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox" 32447c6ae99SBarry Smith /*@ 325aa219208SBarry Smith DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA. 32647c6ae99SBarry Smith 32747c6ae99SBarry Smith Not Collective 32847c6ae99SBarry Smith 32947c6ae99SBarry Smith Input Parameter: 33047c6ae99SBarry Smith . da - the distributed array 33147c6ae99SBarry Smith 33247c6ae99SBarry Smith Output Parameters: 33347c6ae99SBarry Smith + lmin - local minimum coordinates (length dim, optional) 33447c6ae99SBarry Smith - lmax - local maximim coordinates (length dim, optional) 33547c6ae99SBarry Smith 33647c6ae99SBarry Smith Level: beginner 33747c6ae99SBarry Smith 33847c6ae99SBarry Smith .keywords: distributed array, get, coordinates 33947c6ae99SBarry Smith 340aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetBoundingBox() 34147c6ae99SBarry Smith @*/ 3427087cfbeSBarry Smith PetscErrorCode DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[]) 34347c6ae99SBarry Smith { 34447c6ae99SBarry Smith PetscErrorCode ierr; 34547c6ae99SBarry Smith Vec coords = PETSC_NULL; 34647c6ae99SBarry Smith PetscInt dim,i,j; 34747c6ae99SBarry Smith const PetscScalar *local_coords; 34847c6ae99SBarry Smith PetscReal min[3]={PETSC_MAX,PETSC_MAX,PETSC_MAX},max[3]={PETSC_MIN,PETSC_MIN,PETSC_MIN}; 34947c6ae99SBarry Smith PetscInt N,Ni; 35047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 35147c6ae99SBarry Smith 35247c6ae99SBarry Smith PetscFunctionBegin; 35347c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 35447c6ae99SBarry Smith dim = dd->dim; 355aa219208SBarry Smith ierr = DMDAGetCoordinates(da,&coords);CHKERRQ(ierr); 35647c6ae99SBarry Smith ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr); 35747c6ae99SBarry Smith ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr); 35847c6ae99SBarry Smith Ni = N/dim; 35947c6ae99SBarry Smith for (i=0; i<Ni; i++) { 36047c6ae99SBarry Smith for (j=0; j<dim; j++) { 36147c6ae99SBarry Smith min[j] = PetscMin(min[j],PetscRealPart(local_coords[i*dim+j]));CHKERRQ(ierr); 36247c6ae99SBarry Smith max[j] = PetscMax(min[j],PetscRealPart(local_coords[i*dim+j]));CHKERRQ(ierr); 36347c6ae99SBarry Smith } 36447c6ae99SBarry Smith } 36547c6ae99SBarry Smith ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr); 36647c6ae99SBarry Smith if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);} 36747c6ae99SBarry Smith if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);} 36847c6ae99SBarry Smith PetscFunctionReturn(0); 36947c6ae99SBarry Smith } 37047c6ae99SBarry Smith 37147c6ae99SBarry Smith #undef __FUNCT__ 372aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox" 37347c6ae99SBarry Smith /*@ 374aa219208SBarry Smith DMDAGetBoundingBox - Returns the global bounding box for the DMDA. 37547c6ae99SBarry Smith 376aa219208SBarry Smith Collective on DMDA 37747c6ae99SBarry Smith 37847c6ae99SBarry Smith Input Parameter: 37947c6ae99SBarry Smith . da - the distributed array 38047c6ae99SBarry Smith 38147c6ae99SBarry Smith Output Parameters: 38247c6ae99SBarry Smith + gmin - global minimum coordinates (length dim, optional) 38347c6ae99SBarry Smith - gmax - global maximim coordinates (length dim, optional) 38447c6ae99SBarry Smith 38547c6ae99SBarry Smith Level: beginner 38647c6ae99SBarry Smith 38747c6ae99SBarry Smith .keywords: distributed array, get, coordinates 38847c6ae99SBarry Smith 389aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetLocalBoundingBox() 39047c6ae99SBarry Smith @*/ 3917087cfbeSBarry Smith PetscErrorCode DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[]) 39247c6ae99SBarry Smith { 39347c6ae99SBarry Smith PetscErrorCode ierr; 39447c6ae99SBarry Smith PetscMPIInt count; 39547c6ae99SBarry Smith PetscReal lmin[3],lmax[3]; 39647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 39747c6ae99SBarry Smith 39847c6ae99SBarry Smith PetscFunctionBegin; 39947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 40047c6ae99SBarry Smith count = PetscMPIIntCast(dd->dim); 401aa219208SBarry Smith ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr); 40247c6ae99SBarry Smith if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPI_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);} 40347c6ae99SBarry Smith if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPI_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);} 40447c6ae99SBarry Smith PetscFunctionReturn(0); 40547c6ae99SBarry Smith } 406