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__ 9aa219208SBarry Smith #define __FUNCT__ "DMDASetCoordinates" 1047c6ae99SBarry Smith /*@ 11aa219208SBarry Smith DMDASetCoordinates - Sets into the DMDA a vector that indicates the 1247c6ae99SBarry Smith coordinates of the local nodes (NOT including ghost nodes). 1347c6ae99SBarry Smith 14aa219208SBarry Smith Collective on DMDA 1547c6ae99SBarry Smith 1647c6ae99SBarry Smith Input Parameter: 1747c6ae99SBarry Smith + da - the distributed array 1847c6ae99SBarry Smith - c - coordinate vector 1947c6ae99SBarry Smith 2047c6ae99SBarry Smith Note: 2147c6ae99SBarry Smith The coordinates should NOT include those for all ghost points 2247c6ae99SBarry Smith 2347c6ae99SBarry Smith Level: intermediate 2447c6ae99SBarry Smith 2547c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 2647c6ae99SBarry Smith 27ce00eea3SSatish Balay .seealso: DMDASetGhostCoordinates(), DMDAGetGhostCorners(), DMDAGetCoordinates(), DMDASetUniformCoordinates(). DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA() 2847c6ae99SBarry Smith @*/ 297087cfbeSBarry Smith PetscErrorCode DMDASetCoordinates(DM da,Vec c) 3047c6ae99SBarry Smith { 3147c6ae99SBarry Smith PetscErrorCode ierr; 3247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 33401ddaa8SBarry Smith PetscInt bs; 3447c6ae99SBarry Smith 3547c6ae99SBarry Smith PetscFunctionBegin; 3647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 3747c6ae99SBarry Smith PetscValidHeaderSpecific(c,VEC_CLASSID,2); 38401ddaa8SBarry Smith ierr = VecGetBlockSize(c,&bs);CHKERRQ(ierr); 39401ddaa8SBarry Smith if (bs != dd->dim) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_INCOMP,"Block size of vector must match dimension of DMDA"); 4047c6ae99SBarry Smith ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 4196e147daSBarry Smith ierr = VecDestroy(&dd->coordinates);CHKERRQ(ierr); 4247c6ae99SBarry Smith dd->coordinates = c; 43fcfd50ebSBarry Smith ierr = VecDestroy(&dd->ghosted_coordinates);CHKERRQ(ierr); 4447c6ae99SBarry Smith PetscFunctionReturn(0); 4547c6ae99SBarry Smith } 4647c6ae99SBarry Smith 4747c6ae99SBarry Smith #undef __FUNCT__ 48ce00eea3SSatish Balay #define __FUNCT__ "DMDASetGhostedCoordinates" 49ce00eea3SSatish Balay /*@ 50ce00eea3SSatish Balay DMDASetGhostedCoordinates - Sets into the DMDA a vector that indicates the 51ce00eea3SSatish Balay coordinates of the local nodes, including ghost nodes. 52ce00eea3SSatish Balay 53ce00eea3SSatish Balay Collective on DMDA 54ce00eea3SSatish Balay 55ce00eea3SSatish Balay Input Parameter: 56ce00eea3SSatish Balay + da - the distributed array 57ce00eea3SSatish Balay - c - coordinate vector 58ce00eea3SSatish Balay 59ce00eea3SSatish Balay Note: 60ce00eea3SSatish Balay The coordinates of interior ghost points can be set using DMDASetCoordinates() 61ce00eea3SSatish Balay followed by DMDAGetGhostedCoordinates(). This is intended to enable the setting 62ce00eea3SSatish Balay of ghost coordinates outside of the domain. 63ce00eea3SSatish Balay 64ce00eea3SSatish Balay Non-ghosted coordinates, if set, are assumed still valid. 65ce00eea3SSatish Balay 66ce00eea3SSatish Balay Level: intermediate 67ce00eea3SSatish Balay 68ce00eea3SSatish Balay .keywords: distributed array, get, corners, nodes, local indices, coordinates 69ce00eea3SSatish Balay 70ce00eea3SSatish Balay .seealso: DMDASetCoordinates(), DMDAGetGhostCorners(), DMDAGetCoordinates(), DMDASetUniformCoordinates(). DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA() 71ce00eea3SSatish Balay @*/ 72ce00eea3SSatish Balay PetscErrorCode DMDASetGhostedCoordinates(DM da,Vec c) 73ce00eea3SSatish Balay { 74ce00eea3SSatish Balay PetscErrorCode ierr; 75ce00eea3SSatish Balay DM_DA *dd = (DM_DA*)da->data; 76401ddaa8SBarry Smith PetscInt bs; 77ce00eea3SSatish Balay 78ce00eea3SSatish Balay PetscFunctionBegin; 79ce00eea3SSatish Balay PetscValidHeaderSpecific(da,DM_CLASSID,1); 80ce00eea3SSatish Balay PetscValidHeaderSpecific(c,VEC_CLASSID,2); 81401ddaa8SBarry Smith ierr = VecGetBlockSize(c,&bs);CHKERRQ(ierr); 82401ddaa8SBarry Smith if (bs != dd->dim) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_INCOMP,"Block size of vector must match dimension of DMDA"); 83ce00eea3SSatish Balay ierr = PetscObjectReference((PetscObject)c);CHKERRQ(ierr); 8496e147daSBarry Smith ierr = VecDestroy(&dd->ghosted_coordinates);CHKERRQ(ierr); 85ce00eea3SSatish Balay dd->ghosted_coordinates = c; 86ce00eea3SSatish Balay PetscFunctionReturn(0); 87ce00eea3SSatish Balay } 88ce00eea3SSatish Balay 89ce00eea3SSatish Balay #undef __FUNCT__ 90aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinates" 9147c6ae99SBarry Smith /*@ 92aa219208SBarry Smith DMDAGetCoordinates - Gets the node coordinates associated with a DMDA. 9347c6ae99SBarry Smith 9447c6ae99SBarry Smith Not Collective 9547c6ae99SBarry Smith 9647c6ae99SBarry Smith Input Parameter: 9747c6ae99SBarry Smith . da - the distributed array 9847c6ae99SBarry Smith 9947c6ae99SBarry Smith Output Parameter: 10047c6ae99SBarry Smith . c - coordinate vector 10147c6ae99SBarry Smith 10247c6ae99SBarry Smith Note: 10347c6ae99SBarry Smith Each process has only the coordinates for its local nodes (does NOT have the 10447c6ae99SBarry Smith coordinates for the ghost nodes). 10547c6ae99SBarry Smith 10647c6ae99SBarry Smith For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 10747c6ae99SBarry Smith and (x_0,y_0,z_0,x_1,y_1,z_1...) 10847c6ae99SBarry Smith 10947c6ae99SBarry Smith Level: intermediate 11047c6ae99SBarry Smith 11147c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 11247c6ae99SBarry Smith 113aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetGhostedCoordinates(), DMDAGetCoordinateDA() 11447c6ae99SBarry Smith @*/ 1157087cfbeSBarry Smith PetscErrorCode DMDAGetCoordinates(DM da,Vec *c) 11647c6ae99SBarry Smith { 11747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 11847c6ae99SBarry Smith PetscFunctionBegin; 11947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 12047c6ae99SBarry Smith PetscValidPointer(c,2); 12147c6ae99SBarry Smith *c = dd->coordinates; 12247c6ae99SBarry Smith PetscFunctionReturn(0); 12347c6ae99SBarry Smith } 12447c6ae99SBarry Smith 12547c6ae99SBarry Smith #undef __FUNCT__ 126aa219208SBarry Smith #define __FUNCT__ "DMDAGetCoordinateDA" 12747c6ae99SBarry Smith /*@ 128aa219208SBarry Smith DMDAGetCoordinateDA - Gets the DMDA that scatters between global and local DMDA coordinates 12947c6ae99SBarry Smith 130aa219208SBarry Smith Collective on DMDA 13147c6ae99SBarry Smith 13247c6ae99SBarry Smith Input Parameter: 13347c6ae99SBarry Smith . da - the distributed array 13447c6ae99SBarry Smith 13547c6ae99SBarry Smith Output Parameter: 136aa219208SBarry Smith . dac - coordinate DMDA 13747c6ae99SBarry Smith 13847c6ae99SBarry Smith Level: intermediate 13947c6ae99SBarry Smith 14047c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 14147c6ae99SBarry Smith 142aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates() 14347c6ae99SBarry Smith @*/ 1447087cfbeSBarry Smith PetscErrorCode DMDAGetCoordinateDA(DM da,DM *cda) 14547c6ae99SBarry Smith { 14647c6ae99SBarry Smith PetscMPIInt size; 14747c6ae99SBarry Smith PetscErrorCode ierr; 14847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 14947c6ae99SBarry Smith 15047c6ae99SBarry Smith PetscFunctionBegin; 15147c6ae99SBarry Smith if (!dd->da_coordinates) { 15247c6ae99SBarry Smith ierr = MPI_Comm_size(((PetscObject)da)->comm,&size);CHKERRQ(ierr); 15347c6ae99SBarry Smith if (dd->dim == 1) { 15447c6ae99SBarry Smith PetscInt s,m,*lc,l; 1551321219cSEthan Coon DMDABoundaryType bx; 1561321219cSEthan Coon ierr = DMDAGetInfo(da,0,&m,0,0,0,0,0,0,&s,&bx,0,0,0);CHKERRQ(ierr); 157aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&l,0,0);CHKERRQ(ierr); 15847c6ae99SBarry Smith ierr = PetscMalloc(size*sizeof(PetscInt),&lc);CHKERRQ(ierr); 15947c6ae99SBarry Smith ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 1601321219cSEthan Coon ierr = DMDACreate1d(((PetscObject)da)->comm,bx,m,1,s,lc,&dd->da_coordinates);CHKERRQ(ierr); 16147c6ae99SBarry Smith ierr = PetscFree(lc);CHKERRQ(ierr); 16247c6ae99SBarry Smith } else if (dd->dim == 2) { 16347c6ae99SBarry Smith PetscInt i,s,m,*lc,*ld,l,k,n,M,N; 1641321219cSEthan Coon DMDABoundaryType bx,by; 1651321219cSEthan Coon ierr = DMDAGetInfo(da,0,&m,&n,0,&M,&N,0,0,&s,&bx,&by,0,0);CHKERRQ(ierr); 166aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&l,&k,0);CHKERRQ(ierr); 16747c6ae99SBarry Smith ierr = PetscMalloc2(size,PetscInt,&lc,size,PetscInt,&ld);CHKERRQ(ierr); 16847c6ae99SBarry Smith /* only first M values in lc matter */ 16947c6ae99SBarry Smith ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 17047c6ae99SBarry Smith /* every Mth value in ld matters */ 17147c6ae99SBarry Smith ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 17247c6ae99SBarry Smith for ( i=0; i<N; i++) { 17347c6ae99SBarry Smith ld[i] = ld[M*i]; 17447c6ae99SBarry Smith } 1751321219cSEthan Coon ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,DMDA_STENCIL_BOX,m,n,M,N,2,s,lc,ld,&dd->da_coordinates);CHKERRQ(ierr); 17647c6ae99SBarry Smith ierr = PetscFree2(lc,ld);CHKERRQ(ierr); 17747c6ae99SBarry Smith } else if (dd->dim == 3) { 17847c6ae99SBarry Smith PetscInt i,s,m,*lc,*ld,*le,l,k,q,n,M,N,P,p; 1791321219cSEthan Coon DMDABoundaryType bx,by,bz; 1801321219cSEthan Coon ierr = DMDAGetInfo(da,0,&m,&n,&p,&M,&N,&P,0,&s,&bx,&by,&bz,0);CHKERRQ(ierr); 181aa219208SBarry Smith ierr = DMDAGetCorners(da,0,0,0,&l,&k,&q);CHKERRQ(ierr); 18247c6ae99SBarry Smith ierr = PetscMalloc3(size,PetscInt,&lc,size,PetscInt,&ld,size,PetscInt,&le);CHKERRQ(ierr); 18347c6ae99SBarry Smith /* only first M values in lc matter */ 18447c6ae99SBarry Smith ierr = MPI_Allgather(&l,1,MPIU_INT,lc,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 18547c6ae99SBarry Smith /* every Mth value in ld matters */ 18647c6ae99SBarry Smith ierr = MPI_Allgather(&k,1,MPIU_INT,ld,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 18747c6ae99SBarry Smith for ( i=0; i<N; i++) { 18847c6ae99SBarry Smith ld[i] = ld[M*i]; 18947c6ae99SBarry Smith } 19047c6ae99SBarry Smith ierr = MPI_Allgather(&q,1,MPIU_INT,le,1,MPIU_INT,((PetscObject)da)->comm);CHKERRQ(ierr); 19147c6ae99SBarry Smith for ( i=0; i<P; i++) { 19247c6ae99SBarry Smith le[i] = le[M*N*i]; 19347c6ae99SBarry Smith } 1941321219cSEthan Coon ierr = DMDACreate3d(((PetscObject)da)->comm,bx,by,bz,DMDA_STENCIL_BOX,m,n,p,M,N,P,3,s,lc,ld,le,&dd->da_coordinates);CHKERRQ(ierr); 19547c6ae99SBarry Smith ierr = PetscFree3(lc,ld,le);CHKERRQ(ierr); 19647c6ae99SBarry Smith } 19747c6ae99SBarry Smith } 19847c6ae99SBarry Smith *cda = dd->da_coordinates; 19947c6ae99SBarry Smith PetscFunctionReturn(0); 20047c6ae99SBarry Smith } 20147c6ae99SBarry Smith 20247c6ae99SBarry Smith 20347c6ae99SBarry Smith #undef __FUNCT__ 204aa219208SBarry Smith #define __FUNCT__ "DMDAGetGhostedCoordinates" 20547c6ae99SBarry Smith /*@ 206aa219208SBarry Smith DMDAGetGhostedCoordinates - Gets the node coordinates associated with a DMDA. 20747c6ae99SBarry Smith 208aa219208SBarry Smith Collective on DMDA 20947c6ae99SBarry Smith 21047c6ae99SBarry Smith Input Parameter: 21147c6ae99SBarry Smith . da - the distributed array 21247c6ae99SBarry Smith 21347c6ae99SBarry Smith Output Parameter: 21447c6ae99SBarry Smith . c - coordinate vector 21547c6ae99SBarry Smith 21647c6ae99SBarry Smith Note: 21747c6ae99SBarry Smith Each process has only the coordinates for its local AND ghost nodes 21847c6ae99SBarry Smith 21947c6ae99SBarry Smith For two and three dimensions coordinates are interlaced (x_0,y_0,x_1,y_1,...) 22047c6ae99SBarry Smith and (x_0,y_0,z_0,x_1,y_1,z_1...) 22147c6ae99SBarry Smith 22247c6ae99SBarry Smith Level: intermediate 22347c6ae99SBarry Smith 22447c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 22547c6ae99SBarry Smith 226aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetCoordinateDA() 22747c6ae99SBarry Smith @*/ 2287087cfbeSBarry Smith PetscErrorCode DMDAGetGhostedCoordinates(DM da,Vec *c) 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 PetscValidPointer(c,2); 236aa219208SBarry Smith if (!dd->coordinates) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"You must call DMDASetCoordinates() before this call"); 23747c6ae99SBarry Smith if (!dd->ghosted_coordinates) { 2389a42bb27SBarry Smith DM dac; 239aa219208SBarry Smith ierr = DMDAGetCoordinateDA(da,&dac);CHKERRQ(ierr); 240564755cdSBarry Smith ierr = DMCreateLocalVector(dac,&dd->ghosted_coordinates);CHKERRQ(ierr); 2419a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr); 2429a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(dac,dd->coordinates,INSERT_VALUES,dd->ghosted_coordinates);CHKERRQ(ierr); 24347c6ae99SBarry Smith } 24447c6ae99SBarry Smith *c = dd->ghosted_coordinates; 24547c6ae99SBarry Smith PetscFunctionReturn(0); 24647c6ae99SBarry Smith } 24747c6ae99SBarry Smith 24847c6ae99SBarry Smith #undef __FUNCT__ 249aa219208SBarry Smith #define __FUNCT__ "DMDASetFieldName" 25047c6ae99SBarry Smith /*@C 251aa219208SBarry Smith DMDASetFieldName - Sets the names of individual field components in multicomponent 252aa219208SBarry Smith vectors associated with a DMDA. 25347c6ae99SBarry Smith 25447c6ae99SBarry Smith Not Collective 25547c6ae99SBarry Smith 25647c6ae99SBarry Smith Input Parameters: 25747c6ae99SBarry Smith + da - the distributed array 258aa219208SBarry Smith . nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 259aa219208SBarry Smith number of degrees of freedom per node within the DMDA 26047c6ae99SBarry Smith - names - the name of the field (component) 26147c6ae99SBarry Smith 26247c6ae99SBarry Smith Level: intermediate 26347c6ae99SBarry Smith 26447c6ae99SBarry Smith .keywords: distributed array, get, component name 26547c6ae99SBarry Smith 266aa219208SBarry Smith .seealso: DMDAGetFieldName() 26747c6ae99SBarry Smith @*/ 2687087cfbeSBarry Smith PetscErrorCode DMDASetFieldName(DM da,PetscInt nf,const char name[]) 26947c6ae99SBarry Smith { 27047c6ae99SBarry Smith PetscErrorCode ierr; 27147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 27247c6ae99SBarry Smith 27347c6ae99SBarry Smith PetscFunctionBegin; 27447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 27547c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 276c31cb41cSBarry Smith ierr = PetscFree(dd->fieldname[nf]);CHKERRQ(ierr); 27747c6ae99SBarry Smith ierr = PetscStrallocpy(name,&dd->fieldname[nf]);CHKERRQ(ierr); 27847c6ae99SBarry Smith PetscFunctionReturn(0); 27947c6ae99SBarry Smith } 28047c6ae99SBarry Smith 28147c6ae99SBarry Smith #undef __FUNCT__ 282aa219208SBarry Smith #define __FUNCT__ "DMDAGetFieldName" 28347c6ae99SBarry Smith /*@C 284aa219208SBarry Smith DMDAGetFieldName - Gets the names of individual field components in multicomponent 285aa219208SBarry Smith vectors associated with a DMDA. 28647c6ae99SBarry Smith 28747c6ae99SBarry Smith Not Collective 28847c6ae99SBarry Smith 28947c6ae99SBarry Smith Input Parameter: 29047c6ae99SBarry Smith + da - the distributed array 291aa219208SBarry Smith - nf - field number for the DMDA (0, 1, ... dof-1), where dof indicates the 292aa219208SBarry Smith number of degrees of freedom per node within the DMDA 29347c6ae99SBarry Smith 29447c6ae99SBarry Smith Output Parameter: 29547c6ae99SBarry Smith . names - the name of the field (component) 29647c6ae99SBarry Smith 29747c6ae99SBarry Smith Level: intermediate 29847c6ae99SBarry Smith 29947c6ae99SBarry Smith .keywords: distributed array, get, component name 30047c6ae99SBarry Smith 301aa219208SBarry Smith .seealso: DMDASetFieldName() 30247c6ae99SBarry Smith @*/ 3037087cfbeSBarry Smith PetscErrorCode DMDAGetFieldName(DM da,PetscInt nf,const char **name) 30447c6ae99SBarry Smith { 30547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 30647c6ae99SBarry Smith 30747c6ae99SBarry Smith PetscFunctionBegin; 30847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 30947c6ae99SBarry Smith PetscValidPointer(name,3); 31047c6ae99SBarry Smith if (nf < 0 || nf >= dd->w) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid field number: %D",nf); 31147c6ae99SBarry Smith *name = dd->fieldname[nf]; 31247c6ae99SBarry Smith PetscFunctionReturn(0); 31347c6ae99SBarry Smith } 31447c6ae99SBarry Smith 31547c6ae99SBarry Smith #undef __FUNCT__ 316aa219208SBarry Smith #define __FUNCT__ "DMDAGetCorners" 31747c6ae99SBarry Smith /*@ 318aa219208SBarry Smith DMDAGetCorners - Returns the global (x,y,z) indices of the lower left 31947c6ae99SBarry Smith corner of the local region, excluding ghost points. 32047c6ae99SBarry Smith 32147c6ae99SBarry Smith Not Collective 32247c6ae99SBarry Smith 32347c6ae99SBarry Smith Input Parameter: 32447c6ae99SBarry Smith . da - the distributed array 32547c6ae99SBarry Smith 32647c6ae99SBarry Smith Output Parameters: 32747c6ae99SBarry Smith + x,y,z - the corner indices (where y and z are optional; these are used 32847c6ae99SBarry Smith for 2D and 3D problems) 32947c6ae99SBarry Smith - m,n,p - widths in the corresponding directions (where n and p are optional; 33047c6ae99SBarry Smith these are used for 2D and 3D problems) 33147c6ae99SBarry Smith 33247c6ae99SBarry Smith Note: 33347c6ae99SBarry Smith The corner information is independent of the number of degrees of 334aa219208SBarry Smith freedom per node set with the DMDACreateXX() routine. Thus the x, y, z, and 33547c6ae99SBarry Smith m, n, p can be thought of as coordinates on a logical grid, where each 33647c6ae99SBarry Smith grid point has (potentially) several degrees of freedom. 33747c6ae99SBarry Smith Any of y, z, n, and p can be passed in as PETSC_NULL if not needed. 33847c6ae99SBarry Smith 33947c6ae99SBarry Smith Level: beginner 34047c6ae99SBarry Smith 34147c6ae99SBarry Smith .keywords: distributed array, get, corners, nodes, local indices 34247c6ae99SBarry Smith 343aa219208SBarry Smith .seealso: DMDAGetGhostCorners(), DMDAGetOwnershipRanges() 34447c6ae99SBarry Smith @*/ 3457087cfbeSBarry Smith PetscErrorCode DMDAGetCorners(DM da,PetscInt *x,PetscInt *y,PetscInt *z,PetscInt *m,PetscInt *n,PetscInt *p) 34647c6ae99SBarry Smith { 34747c6ae99SBarry Smith PetscInt w; 34847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 34947c6ae99SBarry Smith 35047c6ae99SBarry Smith PetscFunctionBegin; 35147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 35247c6ae99SBarry Smith /* since the xs, xe ... have all been multiplied by the number of degrees 35347c6ae99SBarry Smith of freedom per cell, w = dd->w, we divide that out before returning.*/ 35447c6ae99SBarry Smith w = dd->w; 35547c6ae99SBarry Smith if (x) *x = dd->xs/w; if(m) *m = (dd->xe - dd->xs)/w; 35647c6ae99SBarry Smith /* the y and z have NOT been multiplied by w */ 35747c6ae99SBarry Smith if (y) *y = dd->ys; if (n) *n = (dd->ye - dd->ys); 35847c6ae99SBarry Smith if (z) *z = dd->zs; if (p) *p = (dd->ze - dd->zs); 35947c6ae99SBarry Smith PetscFunctionReturn(0); 36047c6ae99SBarry Smith } 36147c6ae99SBarry Smith 36247c6ae99SBarry Smith #undef __FUNCT__ 363aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalBoundingBox" 36447c6ae99SBarry Smith /*@ 365aa219208SBarry Smith DMDAGetLocalBoundingBox - Returns the local bounding box for the DMDA. 36647c6ae99SBarry Smith 36747c6ae99SBarry Smith Not Collective 36847c6ae99SBarry Smith 36947c6ae99SBarry Smith Input Parameter: 37047c6ae99SBarry Smith . da - the distributed array 37147c6ae99SBarry Smith 37247c6ae99SBarry Smith Output Parameters: 37347c6ae99SBarry Smith + lmin - local minimum coordinates (length dim, optional) 37447c6ae99SBarry Smith - lmax - local maximim coordinates (length dim, optional) 37547c6ae99SBarry Smith 37647c6ae99SBarry Smith Level: beginner 37747c6ae99SBarry Smith 37847c6ae99SBarry Smith .keywords: distributed array, get, coordinates 37947c6ae99SBarry Smith 380aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetBoundingBox() 38147c6ae99SBarry Smith @*/ 3827087cfbeSBarry Smith PetscErrorCode DMDAGetLocalBoundingBox(DM da,PetscReal lmin[],PetscReal lmax[]) 38347c6ae99SBarry Smith { 38447c6ae99SBarry Smith PetscErrorCode ierr; 38547c6ae99SBarry Smith Vec coords = PETSC_NULL; 38647c6ae99SBarry Smith PetscInt dim,i,j; 38747c6ae99SBarry Smith const PetscScalar *local_coords; 388ea345e14SBarry Smith PetscReal min[3]={PETSC_MAX_REAL,PETSC_MAX_REAL,PETSC_MAX_REAL},max[3]={PETSC_MIN_REAL,PETSC_MIN_REAL,PETSC_MIN_REAL}; 38947c6ae99SBarry Smith PetscInt N,Ni; 39047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 39147c6ae99SBarry Smith 39247c6ae99SBarry Smith PetscFunctionBegin; 39347c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 39447c6ae99SBarry Smith dim = dd->dim; 395aa219208SBarry Smith ierr = DMDAGetCoordinates(da,&coords);CHKERRQ(ierr); 3967324c66bSJed Brown if (coords) { 39747c6ae99SBarry Smith ierr = VecGetArrayRead(coords,&local_coords);CHKERRQ(ierr); 39847c6ae99SBarry Smith ierr = VecGetLocalSize(coords,&N);CHKERRQ(ierr); 39947c6ae99SBarry Smith Ni = N/dim; 40047c6ae99SBarry Smith for (i=0; i<Ni; i++) { 4017324c66bSJed Brown for (j=0; j<3; j++) { 4027324c66bSJed Brown min[j] = j < dim ? PetscMin(min[j],PetscRealPart(local_coords[i*dim+j])) : 0; 4037324c66bSJed Brown max[j] = j < dim ? PetscMax(min[j],PetscRealPart(local_coords[i*dim+j])) : 0; 40447c6ae99SBarry Smith } 40547c6ae99SBarry Smith } 40647c6ae99SBarry Smith ierr = VecRestoreArrayRead(coords,&local_coords);CHKERRQ(ierr); 4077324c66bSJed Brown } else { /* Just use grid indices */ 4087324c66bSJed Brown DMDALocalInfo info; 4097324c66bSJed Brown ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 4107324c66bSJed Brown min[0] = info.xs; 4117324c66bSJed Brown min[1] = info.ys; 4127324c66bSJed Brown min[2] = info.zs; 4137324c66bSJed Brown max[0] = info.xs + info.xm-1; 4147324c66bSJed Brown max[1] = info.ys + info.ym-1; 4157324c66bSJed Brown max[2] = info.zs + info.zm-1; 4167324c66bSJed Brown } 41747c6ae99SBarry Smith if (lmin) {ierr = PetscMemcpy(lmin,min,dim*sizeof(PetscReal));CHKERRQ(ierr);} 41847c6ae99SBarry Smith if (lmax) {ierr = PetscMemcpy(lmax,max,dim*sizeof(PetscReal));CHKERRQ(ierr);} 41947c6ae99SBarry Smith PetscFunctionReturn(0); 42047c6ae99SBarry Smith } 42147c6ae99SBarry Smith 42247c6ae99SBarry Smith #undef __FUNCT__ 423aa219208SBarry Smith #define __FUNCT__ "DMDAGetBoundingBox" 42447c6ae99SBarry Smith /*@ 425aa219208SBarry Smith DMDAGetBoundingBox - Returns the global bounding box for the DMDA. 42647c6ae99SBarry Smith 427aa219208SBarry Smith Collective on DMDA 42847c6ae99SBarry Smith 42947c6ae99SBarry Smith Input Parameter: 43047c6ae99SBarry Smith . da - the distributed array 43147c6ae99SBarry Smith 43247c6ae99SBarry Smith Output Parameters: 43347c6ae99SBarry Smith + gmin - global minimum coordinates (length dim, optional) 43447c6ae99SBarry Smith - gmax - global maximim coordinates (length dim, optional) 43547c6ae99SBarry Smith 43647c6ae99SBarry Smith Level: beginner 43747c6ae99SBarry Smith 43847c6ae99SBarry Smith .keywords: distributed array, get, coordinates 43947c6ae99SBarry Smith 440aa219208SBarry Smith .seealso: DMDAGetCoordinateDA(), DMDAGetCoordinates(), DMDAGetLocalBoundingBox() 44147c6ae99SBarry Smith @*/ 4427087cfbeSBarry Smith PetscErrorCode DMDAGetBoundingBox(DM da,PetscReal gmin[],PetscReal gmax[]) 44347c6ae99SBarry Smith { 44447c6ae99SBarry Smith PetscErrorCode ierr; 44547c6ae99SBarry Smith PetscMPIInt count; 44647c6ae99SBarry Smith PetscReal lmin[3],lmax[3]; 44747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 44847c6ae99SBarry Smith 44947c6ae99SBarry Smith PetscFunctionBegin; 45047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 45147c6ae99SBarry Smith count = PetscMPIIntCast(dd->dim); 452aa219208SBarry Smith ierr = DMDAGetLocalBoundingBox(da,lmin,lmax);CHKERRQ(ierr); 453d9822059SBarry Smith if (gmin) {ierr = MPI_Allreduce(lmin,gmin,count,MPIU_REAL,MPIU_MIN,((PetscObject)da)->comm);CHKERRQ(ierr);} 454d9822059SBarry Smith if (gmax) {ierr = MPI_Allreduce(lmax,gmax,count,MPIU_REAL,MPIU_MAX,((PetscObject)da)->comm);CHKERRQ(ierr);} 45547c6ae99SBarry Smith PetscFunctionReturn(0); 45647c6ae99SBarry Smith } 457bc2bf880SBarry Smith 458bc2bf880SBarry Smith #undef __FUNCT__ 459bc2bf880SBarry Smith #define __FUNCT__ "DMDAGetReducedDA" 460bc2bf880SBarry Smith /*@ 461bc2bf880SBarry Smith DMDAGetReducedDA - Gets the DMDA with the same layout but with fewer or more fields 462bc2bf880SBarry Smith 463bc2bf880SBarry Smith Collective on DMDA 464bc2bf880SBarry Smith 465bc2bf880SBarry Smith Input Parameter: 466bc2bf880SBarry Smith + da - the distributed array 467bc2bf880SBarry Smith . nfields - number of fields in new DMDA 468bc2bf880SBarry Smith 469bc2bf880SBarry Smith Output Parameter: 470bc2bf880SBarry Smith . nda - the new DMDA 471bc2bf880SBarry Smith 472bc2bf880SBarry Smith Level: intermediate 473bc2bf880SBarry Smith 474bc2bf880SBarry Smith .keywords: distributed array, get, corners, nodes, local indices, coordinates 475bc2bf880SBarry Smith 476bc2bf880SBarry Smith .seealso: DMDAGetGhostCorners(), DMDASetCoordinates(), DMDASetUniformCoordinates(), DMDAGetCoordinates(), DMDAGetGhostedCoordinates() 477bc2bf880SBarry Smith @*/ 478bc2bf880SBarry Smith PetscErrorCode DMDAGetReducedDA(DM da,PetscInt nfields,DM *nda) 479bc2bf880SBarry Smith { 480bc2bf880SBarry Smith PetscErrorCode ierr; 481bc2bf880SBarry Smith DM_DA *dd = (DM_DA*)da->data; 482bc2bf880SBarry Smith 483*320964c4SBlaise Bourdin PetscInt s,m,n,p,M,N,P,dim; 484*320964c4SBlaise Bourdin const PetscInt *lx,*ly,*lz; 485bc2bf880SBarry Smith DMDABoundaryType bx,by,bz; 486*320964c4SBlaise Bourdin DMDAStencilType stencil_type; 487*320964c4SBlaise Bourdin 488*320964c4SBlaise Bourdin PetscFunctionBegin; 489*320964c4SBlaise Bourdin ierr = DMDAGetInfo(da,&dim,&M,&N,&P,&m,&n,&p,0,&s,&bx,&by,&bz,&stencil_type);CHKERRQ(ierr); 490*320964c4SBlaise Bourdin ierr = DMDAGetOwnershipRanges(da,&lx,&ly,&lz);CHKERRQ(ierr); 491*320964c4SBlaise Bourdin if (dim == 1) { 492*320964c4SBlaise Bourdin ierr = DMDACreate1d(((PetscObject)da)->comm,bx,M,nfields,s,dd->lx,nda);CHKERRQ(ierr); 493*320964c4SBlaise Bourdin } else if (dim == 2) { 494*320964c4SBlaise Bourdin ierr = DMDACreate2d(((PetscObject)da)->comm,bx,by,stencil_type,M,N,m,n,nfields,s,lx,ly,nda);CHKERRQ(ierr); 495*320964c4SBlaise Bourdin } else if (dim == 3) { 496*320964c4SBlaise 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); 497bc2bf880SBarry Smith } 498bc2bf880SBarry Smith if (dd->coordinates) { 499bc2bf880SBarry Smith DM_DA *ndd = (DM_DA*)(*nda)->data; 500bc2bf880SBarry Smith ierr = PetscObjectReference((PetscObject)dd->coordinates);CHKERRQ(ierr); 501bc2bf880SBarry Smith ndd->coordinates = dd->coordinates; 502bc2bf880SBarry Smith } 503bc2bf880SBarry Smith PetscFunctionReturn(0); 504bc2bf880SBarry Smith } 505bc2bf880SBarry Smith 506