147c6ae99SBarry Smith 247c6ae99SBarry Smith /* 347c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 447c6ae99SBarry Smith */ 547c6ae99SBarry Smith 6*b45d2f2cSJed Brown #include <petsc-private/daimpl.h> /*I "petscdmda.h" I*/ 747c6ae99SBarry Smith 847c6ae99SBarry Smith #undef __FUNCT__ 99a42bb27SBarry Smith #define __FUNCT__ "DMDALocalToLocalCreate" 1047c6ae99SBarry Smith /* 119a42bb27SBarry Smith DMDALocalToLocalCreate - Creates the local to local scatter 1247c6ae99SBarry Smith 13aa219208SBarry Smith Collective on DMDA 1447c6ae99SBarry Smith 1547c6ae99SBarry Smith Input Parameter: 1647c6ae99SBarry Smith . da - the distributed array 1747c6ae99SBarry Smith 1847c6ae99SBarry Smith */ 197087cfbeSBarry Smith PetscErrorCode DMDALocalToLocalCreate(DM da) 2047c6ae99SBarry Smith { 2147c6ae99SBarry Smith PetscErrorCode ierr; 2247c6ae99SBarry Smith PetscInt *idx,left,j,count,up,down,i,bottom,top,k; 2347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 2447c6ae99SBarry Smith 2547c6ae99SBarry Smith PetscFunctionBegin; 2647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 2747c6ae99SBarry Smith 2847c6ae99SBarry Smith if (dd->ltol) PetscFunctionReturn(0); 2947c6ae99SBarry Smith /* 3047c6ae99SBarry Smith We simply remap the values in the from part of 3147c6ae99SBarry Smith global to local to read from an array with the ghost values 3247c6ae99SBarry Smith rather then from the plain array. 3347c6ae99SBarry Smith */ 3447c6ae99SBarry Smith ierr = VecScatterCopy(dd->gtol,&dd->ltol);CHKERRQ(ierr); 3547c6ae99SBarry Smith ierr = PetscLogObjectParent(da,dd->ltol);CHKERRQ(ierr); 3647c6ae99SBarry Smith if (dd->dim == 1) { 3747c6ae99SBarry Smith left = dd->xs - dd->Xs; 3847c6ae99SBarry Smith ierr = PetscMalloc((dd->xe-dd->xs)*sizeof(PetscInt),&idx);CHKERRQ(ierr); 3947c6ae99SBarry Smith for (j=0; j<dd->xe-dd->xs; j++) { 4047c6ae99SBarry Smith idx[j] = left + j; 4147c6ae99SBarry Smith } 4247c6ae99SBarry Smith } else if (dd->dim == 2) { 4347c6ae99SBarry Smith left = dd->xs - dd->Xs; down = dd->ys - dd->Ys; up = down + dd->ye-dd->ys; 4447c6ae99SBarry Smith ierr = PetscMalloc((dd->xe-dd->xs)*(up - down)*sizeof(PetscInt),&idx);CHKERRQ(ierr); 4547c6ae99SBarry Smith count = 0; 4647c6ae99SBarry Smith for (i=down; i<up; i++) { 4747c6ae99SBarry Smith for (j=0; j<dd->xe-dd->xs; j++) { 4847c6ae99SBarry Smith idx[count++] = left + i*(dd->Xe-dd->Xs) + j; 4947c6ae99SBarry Smith } 5047c6ae99SBarry Smith } 5147c6ae99SBarry Smith } else if (dd->dim == 3) { 5247c6ae99SBarry Smith left = dd->xs - dd->Xs; 5347c6ae99SBarry Smith bottom = dd->ys - dd->Ys; top = bottom + dd->ye-dd->ys ; 5447c6ae99SBarry Smith down = dd->zs - dd->Zs; up = down + dd->ze-dd->zs; 5547c6ae99SBarry Smith count = (dd->xe-dd->xs)*(top-bottom)*(up-down); 5647c6ae99SBarry Smith ierr = PetscMalloc(count*sizeof(PetscInt),&idx);CHKERRQ(ierr); 5747c6ae99SBarry Smith count = 0; 5847c6ae99SBarry Smith for (i=down; i<up; i++) { 5947c6ae99SBarry Smith for (j=bottom; j<top; j++) { 6047c6ae99SBarry Smith for (k=0; k<dd->xe-dd->xs; k++) { 6147c6ae99SBarry Smith idx[count++] = (left+j*(dd->Xe-dd->Xs))+i*(dd->Xe-dd->Xs)*(dd->Ye-dd->Ys) + k; 6247c6ae99SBarry Smith } 6347c6ae99SBarry Smith } 6447c6ae99SBarry Smith } 65aa219208SBarry Smith } else SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_ARG_CORRUPT,"DMDA has invalid dimension %D",dd->dim); 6647c6ae99SBarry Smith 6747c6ae99SBarry Smith ierr = VecScatterRemap(dd->ltol,idx,PETSC_NULL);CHKERRQ(ierr); 6847c6ae99SBarry Smith ierr = PetscFree(idx);CHKERRQ(ierr); 6947c6ae99SBarry Smith PetscFunctionReturn(0); 7047c6ae99SBarry Smith } 7147c6ae99SBarry Smith 7247c6ae99SBarry Smith #undef __FUNCT__ 73aa219208SBarry Smith #define __FUNCT__ "DMDALocalToLocalBegin" 7447c6ae99SBarry Smith /*@ 75aa219208SBarry Smith DMDALocalToLocalBegin - Maps from a local vector (including ghost points 7647c6ae99SBarry Smith that contain irrelevant values) to another local vector where the ghost 77aa219208SBarry Smith points in the second are set correctly. Must be followed by DMDALocalToLocalEnd(). 7847c6ae99SBarry Smith 79aa219208SBarry Smith Neighbor-wise Collective on DMDA and Vec 8047c6ae99SBarry Smith 8147c6ae99SBarry Smith Input Parameters: 8247c6ae99SBarry Smith + da - the distributed array context 8347c6ae99SBarry Smith . g - the original local vector 8447c6ae99SBarry Smith - mode - one of INSERT_VALUES or ADD_VALUES 8547c6ae99SBarry Smith 8647c6ae99SBarry Smith Output Parameter: 8747c6ae99SBarry Smith . l - the local vector with correct ghost values 8847c6ae99SBarry Smith 8947c6ae99SBarry Smith Level: intermediate 9047c6ae99SBarry Smith 9147c6ae99SBarry Smith Notes: 9247c6ae99SBarry Smith The local vectors used here need not be the same as those 93564755cdSBarry Smith obtained from DMCreateLocalVector(), BUT they 9447c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 95aa219208SBarry Smith obtained with VecDuplicate() from the DMDA originating vectors. 9647c6ae99SBarry Smith 9747c6ae99SBarry Smith .keywords: distributed array, local-to-local, begin 9847c6ae99SBarry Smith 99aa219208SBarry Smith .seealso: DMDALocalToLocalEnd(), DMLocalToGlobalBegin() 10047c6ae99SBarry Smith @*/ 1017087cfbeSBarry Smith PetscErrorCode DMDALocalToLocalBegin(DM da,Vec g,InsertMode mode,Vec l) 10247c6ae99SBarry Smith { 10347c6ae99SBarry Smith PetscErrorCode ierr; 10447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 10547c6ae99SBarry Smith 10647c6ae99SBarry Smith PetscFunctionBegin; 10747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 10847c6ae99SBarry Smith if (!dd->ltol) { 1099a42bb27SBarry Smith ierr = DMDALocalToLocalCreate(da);CHKERRQ(ierr); 11047c6ae99SBarry Smith } 11147c6ae99SBarry Smith ierr = VecScatterBegin(dd->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 11247c6ae99SBarry Smith PetscFunctionReturn(0); 11347c6ae99SBarry Smith } 11447c6ae99SBarry Smith 11547c6ae99SBarry Smith #undef __FUNCT__ 116aa219208SBarry Smith #define __FUNCT__ "DMDALocalToLocalEnd" 11747c6ae99SBarry Smith /*@ 118aa219208SBarry Smith DMDALocalToLocalEnd - Maps from a local vector (including ghost points 11947c6ae99SBarry Smith that contain irrelevant values) to another local vector where the ghost 12047c6ae99SBarry Smith points in the second are set correctly. Must be preceeded by 121aa219208SBarry Smith DMDALocalToLocalBegin(). 12247c6ae99SBarry Smith 123aa219208SBarry Smith Neighbor-wise Collective on DMDA and Vec 12447c6ae99SBarry Smith 12547c6ae99SBarry Smith Input Parameters: 12647c6ae99SBarry Smith + da - the distributed array context 12747c6ae99SBarry Smith . g - the original local vector 12847c6ae99SBarry Smith - mode - one of INSERT_VALUES or ADD_VALUES 12947c6ae99SBarry Smith 13047c6ae99SBarry Smith Output Parameter: 13147c6ae99SBarry Smith . l - the local vector with correct ghost values 13247c6ae99SBarry Smith 13347c6ae99SBarry Smith Level: intermediate 13447c6ae99SBarry Smith 13547c6ae99SBarry Smith Note: 13647c6ae99SBarry Smith The local vectors used here need not be the same as those 137564755cdSBarry Smith obtained from DMCreateLocalVector(), BUT they 13847c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 139aa219208SBarry Smith obtained with VecDuplicate() from the DMDA originating vectors. 14047c6ae99SBarry Smith 14147c6ae99SBarry Smith .keywords: distributed array, local-to-local, end 14247c6ae99SBarry Smith 143aa219208SBarry Smith .seealso: DMDALocalToLocalBegin(), DMLocalToGlobalBegin() 14447c6ae99SBarry Smith @*/ 1457087cfbeSBarry Smith PetscErrorCode DMDALocalToLocalEnd(DM da,Vec g,InsertMode mode,Vec l) 14647c6ae99SBarry Smith { 14747c6ae99SBarry Smith PetscErrorCode ierr; 14847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 14947c6ae99SBarry Smith 15047c6ae99SBarry Smith PetscFunctionBegin; 15147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 15247c6ae99SBarry Smith PetscValidHeaderSpecific(g,VEC_CLASSID,2); 15347c6ae99SBarry Smith PetscValidHeaderSpecific(g,VEC_CLASSID,4); 15447c6ae99SBarry Smith ierr = VecScatterEnd(dd->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr); 15547c6ae99SBarry Smith PetscFunctionReturn(0); 15647c6ae99SBarry Smith } 15747c6ae99SBarry Smith 158