19a42bb27SBarry Smith 247c6ae99SBarry Smith #define PETSCDM_DLL 347c6ae99SBarry Smith 4e1589f56SBarry Smith #include "private/daimpl.h" /*I "petscdm.h" I*/ 547c6ae99SBarry Smith 647c6ae99SBarry Smith #undef __FUNCT__ 79a42bb27SBarry Smith #define __FUNCT__ "DMView_DA_2d" 89a42bb27SBarry Smith PetscErrorCode DMView_DA_2d(DM da,PetscViewer viewer) 947c6ae99SBarry Smith { 1047c6ae99SBarry Smith PetscErrorCode ierr; 1147c6ae99SBarry Smith PetscMPIInt rank; 129a42bb27SBarry Smith PetscBool iascii,isdraw,isbinary; 1347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 149a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 159a42bb27SBarry Smith PetscBool ismatlab; 169a42bb27SBarry Smith #endif 1747c6ae99SBarry Smith 1847c6ae99SBarry Smith PetscFunctionBegin; 1947c6ae99SBarry Smith ierr = MPI_Comm_rank(((PetscObject)da)->comm,&rank);CHKERRQ(ierr); 2047c6ae99SBarry Smith 2147c6ae99SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2247c6ae99SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 239a42bb27SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 249a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 259a42bb27SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERMATLAB,&ismatlab);CHKERRQ(ierr); 269a42bb27SBarry Smith #endif 2747c6ae99SBarry Smith if (iascii) { 2847c6ae99SBarry Smith PetscViewerFormat format; 2947c6ae99SBarry Smith 3047c6ae99SBarry Smith ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 3147c6ae99SBarry Smith if (format != PETSC_VIEWER_ASCII_VTK && format != PETSC_VIEWER_ASCII_VTK_CELL) { 32aa219208SBarry Smith DMDALocalInfo info; 33aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 3447c6ae99SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Processor [%d] M %D N %D m %D n %D w %D s %D\n",rank,dd->M,dd->N,dd->m,dd->n,dd->w,dd->s);CHKERRQ(ierr); 3547c6ae99SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"X range of indices: %D %D, Y range of indices: %D %D\n",info.xs,info.xs+info.xm,info.ys,info.ys+info.ym);CHKERRQ(ierr); 3647c6ae99SBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 373da9ae13SJed Brown } else { 383da9ae13SJed Brown ierr = DMView_DA_VTK(da,viewer);CHKERRQ(ierr); 3947c6ae99SBarry Smith } 4047c6ae99SBarry Smith } else if (isdraw) { 4147c6ae99SBarry Smith PetscDraw draw; 4247c6ae99SBarry Smith double ymin = -1*dd->s-1,ymax = dd->N+dd->s; 4347c6ae99SBarry Smith double xmin = -1*dd->s-1,xmax = dd->M+dd->s; 4447c6ae99SBarry Smith double x,y; 4547c6ae99SBarry Smith PetscInt base,*idx; 4647c6ae99SBarry Smith char node[10]; 4747c6ae99SBarry Smith PetscBool isnull; 4847c6ae99SBarry Smith 4947c6ae99SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 5047c6ae99SBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 5147c6ae99SBarry Smith if (!dd->coordinates) { 5247c6ae99SBarry Smith ierr = PetscDrawSetCoordinates(draw,xmin,ymin,xmax,ymax);CHKERRQ(ierr); 5347c6ae99SBarry Smith } 5447c6ae99SBarry Smith ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr); 5547c6ae99SBarry Smith 5647c6ae99SBarry Smith /* first processor draw all node lines */ 5747c6ae99SBarry Smith if (!rank) { 5847c6ae99SBarry Smith ymin = 0.0; ymax = dd->N - 1; 5947c6ae99SBarry Smith for (xmin=0; xmin<dd->M; xmin++) { 6047c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_BLACK);CHKERRQ(ierr); 6147c6ae99SBarry Smith } 6247c6ae99SBarry Smith xmin = 0.0; xmax = dd->M - 1; 6347c6ae99SBarry Smith for (ymin=0; ymin<dd->N; ymin++) { 6447c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_BLACK);CHKERRQ(ierr); 6547c6ae99SBarry Smith } 6647c6ae99SBarry Smith } 6747c6ae99SBarry Smith ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 6847c6ae99SBarry Smith ierr = PetscDrawPause(draw);CHKERRQ(ierr); 6947c6ae99SBarry Smith 7047c6ae99SBarry Smith /* draw my box */ 7147c6ae99SBarry Smith ymin = dd->ys; ymax = dd->ye - 1; xmin = dd->xs/dd->w; 7247c6ae99SBarry Smith xmax =(dd->xe-1)/dd->w; 7347c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_RED);CHKERRQ(ierr); 7447c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_RED);CHKERRQ(ierr); 7547c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymax,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr); 7647c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmax,ymin,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr); 7747c6ae99SBarry Smith 7847c6ae99SBarry Smith /* put in numbers */ 7947c6ae99SBarry Smith base = (dd->base)/dd->w; 8047c6ae99SBarry Smith for (y=ymin; y<=ymax; y++) { 8147c6ae99SBarry Smith for (x=xmin; x<=xmax; x++) { 8247c6ae99SBarry Smith sprintf(node,"%d",(int)base++); 8347c6ae99SBarry Smith ierr = PetscDrawString(draw,x,y,PETSC_DRAW_BLACK,node);CHKERRQ(ierr); 8447c6ae99SBarry Smith } 8547c6ae99SBarry Smith } 8647c6ae99SBarry Smith 8747c6ae99SBarry Smith ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 8847c6ae99SBarry Smith ierr = PetscDrawPause(draw);CHKERRQ(ierr); 8947c6ae99SBarry Smith /* overlay ghost numbers, useful for error checking */ 9047c6ae99SBarry Smith /* put in numbers */ 9147c6ae99SBarry Smith 9247c6ae99SBarry Smith base = 0; idx = dd->idx; 9347c6ae99SBarry Smith ymin = dd->Ys; ymax = dd->Ye; xmin = dd->Xs; xmax = dd->Xe; 9447c6ae99SBarry Smith for (y=ymin; y<ymax; y++) { 9547c6ae99SBarry Smith for (x=xmin; x<xmax; x++) { 9647c6ae99SBarry Smith if ((base % dd->w) == 0) { 9747c6ae99SBarry Smith sprintf(node,"%d",(int)(idx[base]/dd->w)); 9847c6ae99SBarry Smith ierr = PetscDrawString(draw,x/dd->w,y,PETSC_DRAW_BLUE,node);CHKERRQ(ierr); 9947c6ae99SBarry Smith } 10047c6ae99SBarry Smith base++; 10147c6ae99SBarry Smith } 10247c6ae99SBarry Smith } 10347c6ae99SBarry Smith ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 10447c6ae99SBarry Smith ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1059a42bb27SBarry Smith } else if (isbinary){ 1069a42bb27SBarry Smith ierr = DMView_DA_Binary(da,viewer);CHKERRQ(ierr); 1079a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 1089a42bb27SBarry Smith } else if (ismatlab) { 1099a42bb27SBarry Smith ierr = DMView_DA_Matlab(da,viewer);CHKERRQ(ierr); 1109a42bb27SBarry Smith #endif 111aa219208SBarry Smith } else SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for DMDA 1d",((PetscObject)viewer)->type_name); 11247c6ae99SBarry Smith PetscFunctionReturn(0); 11347c6ae99SBarry Smith } 11447c6ae99SBarry Smith 11547c6ae99SBarry Smith /* 11647c6ae99SBarry Smith M is number of grid points 11747c6ae99SBarry Smith m is number of processors 11847c6ae99SBarry Smith 11947c6ae99SBarry Smith */ 12047c6ae99SBarry Smith #undef __FUNCT__ 121aa219208SBarry Smith #define __FUNCT__ "DMDASplitComm2d" 1227087cfbeSBarry Smith PetscErrorCode DMDASplitComm2d(MPI_Comm comm,PetscInt M,PetscInt N,PetscInt sw,MPI_Comm *outcomm) 12347c6ae99SBarry Smith { 12447c6ae99SBarry Smith PetscErrorCode ierr; 12547c6ae99SBarry Smith PetscInt m,n = 0,x = 0,y = 0; 12647c6ae99SBarry Smith PetscMPIInt size,csize,rank; 12747c6ae99SBarry Smith 12847c6ae99SBarry Smith PetscFunctionBegin; 12947c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 13047c6ae99SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 13147c6ae99SBarry Smith 13247c6ae99SBarry Smith csize = 4*size; 13347c6ae99SBarry Smith do { 13447c6ae99SBarry Smith if (csize % 4) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Cannot split communicator of size %d tried %d %D %D",size,csize,x,y); 13547c6ae99SBarry Smith csize = csize/4; 13647c6ae99SBarry Smith 13747c6ae99SBarry Smith m = (PetscInt)(0.5 + sqrt(((double)M)*((double)csize)/((double)N))); 13847c6ae99SBarry Smith if (!m) m = 1; 13947c6ae99SBarry Smith while (m > 0) { 14047c6ae99SBarry Smith n = csize/m; 14147c6ae99SBarry Smith if (m*n == csize) break; 14247c6ae99SBarry Smith m--; 14347c6ae99SBarry Smith } 14447c6ae99SBarry Smith if (M > N && m < n) {PetscInt _m = m; m = n; n = _m;} 14547c6ae99SBarry Smith 14647c6ae99SBarry Smith x = M/m + ((M % m) > ((csize-1) % m)); 14747c6ae99SBarry Smith y = (N + (csize-1)/m)/n; 14847c6ae99SBarry Smith } while ((x < 4 || y < 4) && csize > 1); 14947c6ae99SBarry Smith if (size != csize) { 15047c6ae99SBarry Smith MPI_Group entire_group,sub_group; 15147c6ae99SBarry Smith PetscMPIInt i,*groupies; 15247c6ae99SBarry Smith 15347c6ae99SBarry Smith ierr = MPI_Comm_group(comm,&entire_group);CHKERRQ(ierr); 15447c6ae99SBarry Smith ierr = PetscMalloc(csize*sizeof(PetscInt),&groupies);CHKERRQ(ierr); 15547c6ae99SBarry Smith for (i=0; i<csize; i++) { 15647c6ae99SBarry Smith groupies[i] = (rank/csize)*csize + i; 15747c6ae99SBarry Smith } 15847c6ae99SBarry Smith ierr = MPI_Group_incl(entire_group,csize,groupies,&sub_group);CHKERRQ(ierr); 15947c6ae99SBarry Smith ierr = PetscFree(groupies);CHKERRQ(ierr); 16047c6ae99SBarry Smith ierr = MPI_Comm_create(comm,sub_group,outcomm);CHKERRQ(ierr); 16147c6ae99SBarry Smith ierr = MPI_Group_free(&entire_group);CHKERRQ(ierr); 16247c6ae99SBarry Smith ierr = MPI_Group_free(&sub_group);CHKERRQ(ierr); 163aa219208SBarry Smith ierr = PetscInfo1(0,"DMDASplitComm2d:Creating redundant coarse problems of size %d\n",csize);CHKERRQ(ierr); 16447c6ae99SBarry Smith } else { 16547c6ae99SBarry Smith *outcomm = comm; 16647c6ae99SBarry Smith } 16747c6ae99SBarry Smith PetscFunctionReturn(0); 16847c6ae99SBarry Smith } 16947c6ae99SBarry Smith 17047c6ae99SBarry Smith #undef __FUNCT__ 171aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalFunction" 17247c6ae99SBarry Smith /*@C 173aa219208SBarry Smith DMDASetLocalFunction - Caches in a DM a local function. 17447c6ae99SBarry Smith 175aa219208SBarry Smith Logically Collective on DMDA 17647c6ae99SBarry Smith 17747c6ae99SBarry Smith Input Parameter: 17847c6ae99SBarry Smith + da - initial distributed array 17947c6ae99SBarry Smith - lf - the local function 18047c6ae99SBarry Smith 18147c6ae99SBarry Smith Level: intermediate 18247c6ae99SBarry Smith 18347c6ae99SBarry Smith Notes: The routine SNESDAFormFunction() uses this the cached function to evaluate the user provided function. 18447c6ae99SBarry Smith 18547c6ae99SBarry Smith .keywords: distributed array, refine 18647c6ae99SBarry Smith 187aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunctioni() 18847c6ae99SBarry Smith @*/ 1897087cfbeSBarry Smith PetscErrorCode DMDASetLocalFunction(DM da,DMDALocalFunction1 lf) 19047c6ae99SBarry Smith { 19147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 19247c6ae99SBarry Smith PetscFunctionBegin; 19347c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 19447c6ae99SBarry Smith dd->lf = lf; 19547c6ae99SBarry Smith PetscFunctionReturn(0); 19647c6ae99SBarry Smith } 19747c6ae99SBarry Smith 19847c6ae99SBarry Smith #undef __FUNCT__ 199aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalFunctioni" 20047c6ae99SBarry Smith /*@C 201aa219208SBarry Smith DMDASetLocalFunctioni - Caches in a DM a local function that evaluates a single component 20247c6ae99SBarry Smith 203aa219208SBarry Smith Logically Collective on DMDA 20447c6ae99SBarry Smith 20547c6ae99SBarry Smith Input Parameter: 20647c6ae99SBarry Smith + da - initial distributed array 20747c6ae99SBarry Smith - lfi - the local function 20847c6ae99SBarry Smith 20947c6ae99SBarry Smith Level: intermediate 21047c6ae99SBarry Smith 21147c6ae99SBarry Smith .keywords: distributed array, refine 21247c6ae99SBarry Smith 213aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction() 21447c6ae99SBarry Smith @*/ 2157087cfbeSBarry Smith PetscErrorCode DMDASetLocalFunctioni(DM da,PetscErrorCode (*lfi)(DMDALocalInfo*,MatStencil*,void*,PetscScalar*,void*)) 21647c6ae99SBarry Smith { 21747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 21847c6ae99SBarry Smith PetscFunctionBegin; 21947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 22047c6ae99SBarry Smith dd->lfi = lfi; 22147c6ae99SBarry Smith PetscFunctionReturn(0); 22247c6ae99SBarry Smith } 22347c6ae99SBarry Smith 22447c6ae99SBarry Smith #undef __FUNCT__ 225aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalFunctionib" 22647c6ae99SBarry Smith /*@C 227aa219208SBarry Smith DMDASetLocalFunctionib - Caches in a DM a block local function that evaluates a single component 22847c6ae99SBarry Smith 229aa219208SBarry Smith Logically Collective on DMDA 23047c6ae99SBarry Smith 23147c6ae99SBarry Smith Input Parameter: 23247c6ae99SBarry Smith + da - initial distributed array 23347c6ae99SBarry Smith - lfi - the local function 23447c6ae99SBarry Smith 23547c6ae99SBarry Smith Level: intermediate 23647c6ae99SBarry Smith 23747c6ae99SBarry Smith .keywords: distributed array, refine 23847c6ae99SBarry Smith 239aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction() 24047c6ae99SBarry Smith @*/ 2417087cfbeSBarry Smith PetscErrorCode DMDASetLocalFunctionib(DM da,PetscErrorCode (*lfi)(DMDALocalInfo*,MatStencil*,void*,PetscScalar*,void*)) 24247c6ae99SBarry Smith { 24347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 24447c6ae99SBarry Smith PetscFunctionBegin; 24547c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 24647c6ae99SBarry Smith dd->lfib = lfi; 24747c6ae99SBarry Smith PetscFunctionReturn(0); 24847c6ae99SBarry Smith } 24947c6ae99SBarry Smith 25047c6ae99SBarry Smith #undef __FUNCT__ 251aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicFunction_Private" 252aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunction_Private(DM da,DMDALocalFunction1 ad_lf) 25347c6ae99SBarry Smith { 25447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 25547c6ae99SBarry Smith PetscFunctionBegin; 25647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 25747c6ae99SBarry Smith dd->adic_lf = ad_lf; 25847c6ae99SBarry Smith PetscFunctionReturn(0); 25947c6ae99SBarry Smith } 26047c6ae99SBarry Smith 26147c6ae99SBarry Smith /*MC 262aa219208SBarry Smith DMDASetLocalAdicFunctioni - Caches in a DM a local functioni computed by ADIC/ADIFOR 26347c6ae99SBarry Smith 26447c6ae99SBarry Smith Synopsis: 265aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctioni(DM da,PetscInt (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*) 26647c6ae99SBarry Smith 267aa219208SBarry Smith Logically Collective on DMDA 26847c6ae99SBarry Smith 26947c6ae99SBarry Smith Input Parameter: 27047c6ae99SBarry Smith + da - initial distributed array 27147c6ae99SBarry Smith - ad_lfi - the local function as computed by ADIC/ADIFOR 27247c6ae99SBarry Smith 27347c6ae99SBarry Smith Level: intermediate 27447c6ae99SBarry Smith 27547c6ae99SBarry Smith .keywords: distributed array, refine 27647c6ae99SBarry Smith 277aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(), 278aa219208SBarry Smith DMDASetLocalJacobian(), DMDASetLocalFunctioni() 27947c6ae99SBarry Smith M*/ 28047c6ae99SBarry Smith 28147c6ae99SBarry Smith #undef __FUNCT__ 282aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicFunctioni_Private" 283aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctioni_Private(DM da,PetscErrorCode (*ad_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*)) 28447c6ae99SBarry Smith { 28547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 28647c6ae99SBarry Smith PetscFunctionBegin; 28747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 28847c6ae99SBarry Smith dd->adic_lfi = ad_lfi; 28947c6ae99SBarry Smith PetscFunctionReturn(0); 29047c6ae99SBarry Smith } 29147c6ae99SBarry Smith 29247c6ae99SBarry Smith /*MC 293aa219208SBarry Smith DMDASetLocalAdicMFFunctioni - Caches in a DM a local functioni computed by ADIC/ADIFOR 29447c6ae99SBarry Smith 29547c6ae99SBarry Smith Synopsis: 296aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctioni(DM da,int (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*) 29747c6ae99SBarry Smith 298aa219208SBarry Smith Logically Collective on DMDA 29947c6ae99SBarry Smith 30047c6ae99SBarry Smith Input Parameter: 30147c6ae99SBarry Smith + da - initial distributed array 30247c6ae99SBarry Smith - admf_lfi - the local matrix-free function as computed by ADIC/ADIFOR 30347c6ae99SBarry Smith 30447c6ae99SBarry Smith Level: intermediate 30547c6ae99SBarry Smith 30647c6ae99SBarry Smith .keywords: distributed array, refine 30747c6ae99SBarry Smith 308aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(), 309aa219208SBarry Smith DMDASetLocalJacobian(), DMDASetLocalFunctioni() 31047c6ae99SBarry Smith M*/ 31147c6ae99SBarry Smith 31247c6ae99SBarry Smith #undef __FUNCT__ 313aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicMFFunctioni_Private" 314aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicMFFunctioni_Private(DM da,PetscErrorCode (*admf_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*)) 31547c6ae99SBarry Smith { 31647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 31747c6ae99SBarry Smith PetscFunctionBegin; 31847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 31947c6ae99SBarry Smith dd->adicmf_lfi = admf_lfi; 32047c6ae99SBarry Smith PetscFunctionReturn(0); 32147c6ae99SBarry Smith } 32247c6ae99SBarry Smith 32347c6ae99SBarry Smith /*MC 324aa219208SBarry Smith DMDASetLocalAdicFunctionib - Caches in a DM a block local functioni computed by ADIC/ADIFOR 32547c6ae99SBarry Smith 32647c6ae99SBarry Smith Synopsis: 327aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctionib(DM da,PetscInt (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*) 32847c6ae99SBarry Smith 329aa219208SBarry Smith Logically Collective on DMDA 33047c6ae99SBarry Smith 33147c6ae99SBarry Smith Input Parameter: 33247c6ae99SBarry Smith + da - initial distributed array 33347c6ae99SBarry Smith - ad_lfi - the local function as computed by ADIC/ADIFOR 33447c6ae99SBarry Smith 33547c6ae99SBarry Smith Level: intermediate 33647c6ae99SBarry Smith 33747c6ae99SBarry Smith .keywords: distributed array, refine 33847c6ae99SBarry Smith 339aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(), 340aa219208SBarry Smith DMDASetLocalJacobian(), DMDASetLocalFunctionib() 34147c6ae99SBarry Smith M*/ 34247c6ae99SBarry Smith 34347c6ae99SBarry Smith #undef __FUNCT__ 344aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicFunctionib_Private" 345aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctionib_Private(DM da,PetscErrorCode (*ad_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*)) 34647c6ae99SBarry Smith { 34747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 34847c6ae99SBarry Smith PetscFunctionBegin; 34947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 35047c6ae99SBarry Smith dd->adic_lfib = ad_lfi; 35147c6ae99SBarry Smith PetscFunctionReturn(0); 35247c6ae99SBarry Smith } 35347c6ae99SBarry Smith 35447c6ae99SBarry Smith /*MC 355aa219208SBarry Smith DMDASetLocalAdicMFFunctionib - Caches in a DM a block local functioni computed by ADIC/ADIFOR 35647c6ae99SBarry Smith 35747c6ae99SBarry Smith Synopsis: 358aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicFunctionib(DM da,int (ad_lf*)(DMDALocalInfo*,MatStencil*,void*,void*,void*) 35947c6ae99SBarry Smith 360aa219208SBarry Smith Logically Collective on DMDA 36147c6ae99SBarry Smith 36247c6ae99SBarry Smith Input Parameter: 36347c6ae99SBarry Smith + da - initial distributed array 36447c6ae99SBarry Smith - admf_lfi - the local matrix-free function as computed by ADIC/ADIFOR 36547c6ae99SBarry Smith 36647c6ae99SBarry Smith Level: intermediate 36747c6ae99SBarry Smith 36847c6ae99SBarry Smith .keywords: distributed array, refine 36947c6ae99SBarry Smith 370aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(), 371aa219208SBarry Smith DMDASetLocalJacobian(), DMDASetLocalFunctionib() 37247c6ae99SBarry Smith M*/ 37347c6ae99SBarry Smith 37447c6ae99SBarry Smith #undef __FUNCT__ 375aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicMFFunctionib_Private" 376aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicMFFunctionib_Private(DM da,PetscErrorCode (*admf_lfi)(DMDALocalInfo*,MatStencil*,void*,void*,void*)) 37747c6ae99SBarry Smith { 37847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 37947c6ae99SBarry Smith PetscFunctionBegin; 38047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 38147c6ae99SBarry Smith dd->adicmf_lfib = admf_lfi; 38247c6ae99SBarry Smith PetscFunctionReturn(0); 38347c6ae99SBarry Smith } 38447c6ae99SBarry Smith 38547c6ae99SBarry Smith /*MC 386aa219208SBarry Smith DMDASetLocalAdicMFFunction - Caches in a DM a local function computed by ADIC/ADIFOR 38747c6ae99SBarry Smith 38847c6ae99SBarry Smith Synopsis: 389aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicMFFunction(DM da,DMDALocalFunction1 ad_lf) 39047c6ae99SBarry Smith 391aa219208SBarry Smith Logically Collective on DMDA 39247c6ae99SBarry Smith 39347c6ae99SBarry Smith Input Parameter: 39447c6ae99SBarry Smith + da - initial distributed array 39547c6ae99SBarry Smith - ad_lf - the local function as computed by ADIC/ADIFOR 39647c6ae99SBarry Smith 39747c6ae99SBarry Smith Level: intermediate 39847c6ae99SBarry Smith 39947c6ae99SBarry Smith .keywords: distributed array, refine 40047c6ae99SBarry Smith 401aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction(), 402aa219208SBarry Smith DMDASetLocalJacobian() 40347c6ae99SBarry Smith M*/ 40447c6ae99SBarry Smith 40547c6ae99SBarry Smith #undef __FUNCT__ 406aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalAdicMFFunction_Private" 407aa219208SBarry Smith PetscErrorCode DMDASetLocalAdicMFFunction_Private(DM da,DMDALocalFunction1 ad_lf) 40847c6ae99SBarry Smith { 40947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 41047c6ae99SBarry Smith PetscFunctionBegin; 41147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 41247c6ae99SBarry Smith dd->adicmf_lf = ad_lf; 41347c6ae99SBarry Smith PetscFunctionReturn(0); 41447c6ae99SBarry Smith } 41547c6ae99SBarry Smith 41647c6ae99SBarry Smith /*@C 417aa219208SBarry Smith DMDASetLocalJacobian - Caches in a DM a local Jacobian computation function 41847c6ae99SBarry Smith 419aa219208SBarry Smith Logically Collective on DMDA 42047c6ae99SBarry Smith 42147c6ae99SBarry Smith 42247c6ae99SBarry Smith Input Parameter: 42347c6ae99SBarry Smith + da - initial distributed array 42447c6ae99SBarry Smith - lj - the local Jacobian 42547c6ae99SBarry Smith 42647c6ae99SBarry Smith Level: intermediate 42747c6ae99SBarry Smith 42847c6ae99SBarry Smith Notes: The routine SNESDAFormFunction() uses this the cached function to evaluate the user provided function. 42947c6ae99SBarry Smith 43047c6ae99SBarry Smith .keywords: distributed array, refine 43147c6ae99SBarry Smith 432aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalFunction() 43347c6ae99SBarry Smith @*/ 43447c6ae99SBarry Smith #undef __FUNCT__ 435aa219208SBarry Smith #define __FUNCT__ "DMDASetLocalJacobian" 4367087cfbeSBarry Smith PetscErrorCode DMDASetLocalJacobian(DM da,DMDALocalFunction1 lj) 43747c6ae99SBarry Smith { 43847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 43947c6ae99SBarry Smith PetscFunctionBegin; 44047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 44147c6ae99SBarry Smith dd->lj = lj; 44247c6ae99SBarry Smith PetscFunctionReturn(0); 44347c6ae99SBarry Smith } 44447c6ae99SBarry Smith 44547c6ae99SBarry Smith #undef __FUNCT__ 446aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalFunction" 44747c6ae99SBarry Smith /*@C 448aa219208SBarry Smith DMDAGetLocalFunction - Gets from a DM a local function and its ADIC/ADIFOR Jacobian 44947c6ae99SBarry Smith 45047c6ae99SBarry Smith Note Collective 45147c6ae99SBarry Smith 45247c6ae99SBarry Smith Input Parameter: 45347c6ae99SBarry Smith . da - initial distributed array 45447c6ae99SBarry Smith 45547c6ae99SBarry Smith Output Parameter: 45647c6ae99SBarry Smith . lf - the local function 45747c6ae99SBarry Smith 45847c6ae99SBarry Smith Level: intermediate 45947c6ae99SBarry Smith 46047c6ae99SBarry Smith .keywords: distributed array, refine 46147c6ae99SBarry Smith 462aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalJacobian(), DMDASetLocalFunction() 46347c6ae99SBarry Smith @*/ 4647087cfbeSBarry Smith PetscErrorCode DMDAGetLocalFunction(DM da,DMDALocalFunction1 *lf) 46547c6ae99SBarry Smith { 46647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 46747c6ae99SBarry Smith PetscFunctionBegin; 46847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 46947c6ae99SBarry Smith if (lf) *lf = dd->lf; 47047c6ae99SBarry Smith PetscFunctionReturn(0); 47147c6ae99SBarry Smith } 47247c6ae99SBarry Smith 47347c6ae99SBarry Smith #undef __FUNCT__ 474aa219208SBarry Smith #define __FUNCT__ "DMDAGetLocalJacobian" 47547c6ae99SBarry Smith /*@C 476aa219208SBarry Smith DMDAGetLocalJacobian - Gets from a DM a local jacobian 47747c6ae99SBarry Smith 47847c6ae99SBarry Smith Not Collective 47947c6ae99SBarry Smith 48047c6ae99SBarry Smith Input Parameter: 48147c6ae99SBarry Smith . da - initial distributed array 48247c6ae99SBarry Smith 48347c6ae99SBarry Smith Output Parameter: 48447c6ae99SBarry Smith . lj - the local jacobian 48547c6ae99SBarry Smith 48647c6ae99SBarry Smith Level: intermediate 48747c6ae99SBarry Smith 48847c6ae99SBarry Smith .keywords: distributed array, refine 48947c6ae99SBarry Smith 490aa219208SBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDAGetLocalFunction(), DMDASetLocalJacobian() 49147c6ae99SBarry Smith @*/ 4927087cfbeSBarry Smith PetscErrorCode DMDAGetLocalJacobian(DM da,DMDALocalFunction1 *lj) 49347c6ae99SBarry Smith { 49447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 49547c6ae99SBarry Smith PetscFunctionBegin; 49647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 49747c6ae99SBarry Smith if (lj) *lj = dd->lj; 49847c6ae99SBarry Smith PetscFunctionReturn(0); 49947c6ae99SBarry Smith } 50047c6ae99SBarry Smith 50147c6ae99SBarry Smith #undef __FUNCT__ 502aa219208SBarry Smith #define __FUNCT__ "DMDAFormFunction" 50347c6ae99SBarry Smith /*@ 504aa219208SBarry Smith DMDAFormFunction - Evaluates a user provided function on each processor that 505aa219208SBarry Smith share a DMDA 50647c6ae99SBarry Smith 50747c6ae99SBarry Smith Input Parameters: 5089a42bb27SBarry Smith + da - the DM that defines the grid 50947c6ae99SBarry Smith . vu - input vector 51047c6ae99SBarry Smith . vfu - output vector 51147c6ae99SBarry Smith - w - any user data 51247c6ae99SBarry Smith 51347c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 51447c6ae99SBarry Smith 515aa219208SBarry Smith This should eventually replace DMDAFormFunction1 51647c6ae99SBarry Smith 51747c6ae99SBarry Smith Level: advanced 51847c6ae99SBarry Smith 519aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic() 52047c6ae99SBarry Smith 52147c6ae99SBarry Smith @*/ 5227087cfbeSBarry Smith PetscErrorCode DMDAFormFunction(DM da,PetscErrorCode (*lf)(void),Vec vu,Vec vfu,void *w) 52347c6ae99SBarry Smith { 52447c6ae99SBarry Smith PetscErrorCode ierr; 52547c6ae99SBarry Smith void *u,*fu; 526aa219208SBarry Smith DMDALocalInfo info; 527aa219208SBarry Smith PetscErrorCode (*f)(DMDALocalInfo*,void*,void*,void*) = (PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))lf; 52847c6ae99SBarry Smith 52947c6ae99SBarry Smith PetscFunctionBegin; 530aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 531aa219208SBarry Smith ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr); 532aa219208SBarry Smith ierr = DMDAVecGetArray(da,vfu,&fu);CHKERRQ(ierr); 53347c6ae99SBarry Smith 53439d508bbSBarry Smith ierr = (*f)(&info,u,fu,w);CHKERRQ(ierr); 53547c6ae99SBarry Smith 536aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 537aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,vfu,&fu);CHKERRQ(ierr); 53847c6ae99SBarry Smith PetscFunctionReturn(0); 53947c6ae99SBarry Smith } 54047c6ae99SBarry Smith 54147c6ae99SBarry Smith #undef __FUNCT__ 542aa219208SBarry Smith #define __FUNCT__ "DMDAFormFunctionLocal" 54347c6ae99SBarry Smith /*@C 544aa219208SBarry Smith DMDAFormFunctionLocal - This is a universal function evaluation routine for 5459a42bb27SBarry Smith a local DM function. 54647c6ae99SBarry Smith 547aa219208SBarry Smith Collective on DMDA 54847c6ae99SBarry Smith 54947c6ae99SBarry Smith Input Parameters: 5509a42bb27SBarry Smith + da - the DM context 55147c6ae99SBarry Smith . func - The local function 55247c6ae99SBarry Smith . X - input vector 55347c6ae99SBarry Smith . F - function vector 55447c6ae99SBarry Smith - ctx - A user context 55547c6ae99SBarry Smith 55647c6ae99SBarry Smith Level: intermediate 55747c6ae99SBarry Smith 558aa219208SBarry Smith .seealso: DMDASetLocalFunction(), DMDASetLocalJacobian(), DMDASetLocalAdicFunction(), DMDASetLocalAdicMFFunction(), 55947c6ae99SBarry Smith SNESSetFunction(), SNESSetJacobian() 56047c6ae99SBarry Smith 56147c6ae99SBarry Smith @*/ 5627087cfbeSBarry Smith PetscErrorCode DMDAFormFunctionLocal(DM da, DMDALocalFunction1 func, Vec X, Vec F, void *ctx) 56347c6ae99SBarry Smith { 56447c6ae99SBarry Smith Vec localX; 565aa219208SBarry Smith DMDALocalInfo info; 56647c6ae99SBarry Smith void *u; 56747c6ae99SBarry Smith void *fu; 56847c6ae99SBarry Smith PetscErrorCode ierr; 56947c6ae99SBarry Smith 57047c6ae99SBarry Smith PetscFunctionBegin; 5719a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); 57247c6ae99SBarry Smith /* 57347c6ae99SBarry Smith Scatter ghost points to local vector, using the 2-step process 5749a42bb27SBarry Smith DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). 57547c6ae99SBarry Smith */ 5769a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 5779a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 578aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 579aa219208SBarry Smith ierr = DMDAVecGetArray(da,localX,&u);CHKERRQ(ierr); 580aa219208SBarry Smith ierr = DMDAVecGetArray(da,F,&fu);CHKERRQ(ierr); 58139d508bbSBarry Smith ierr = (*func)(&info,u,fu,ctx);CHKERRQ(ierr); 582aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,localX,&u);CHKERRQ(ierr); 583aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,F,&fu);CHKERRQ(ierr); 5849a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); 58547c6ae99SBarry Smith PetscFunctionReturn(0); 58647c6ae99SBarry Smith } 58747c6ae99SBarry Smith 58847c6ae99SBarry Smith #undef __FUNCT__ 589aa219208SBarry Smith #define __FUNCT__ "DMDAFormFunctionLocalGhost" 59047c6ae99SBarry Smith /*@C 591aa219208SBarry Smith DMDAFormFunctionLocalGhost - This is a universal function evaluation routine for 5929a42bb27SBarry Smith a local DM function, but the ghost values of the output are communicated and added. 59347c6ae99SBarry Smith 594aa219208SBarry Smith Collective on DMDA 59547c6ae99SBarry Smith 59647c6ae99SBarry Smith Input Parameters: 5979a42bb27SBarry Smith + da - the DM context 59847c6ae99SBarry Smith . func - The local function 59947c6ae99SBarry Smith . X - input vector 60047c6ae99SBarry Smith . F - function vector 60147c6ae99SBarry Smith - ctx - A user context 60247c6ae99SBarry Smith 60347c6ae99SBarry Smith Level: intermediate 60447c6ae99SBarry Smith 605aa219208SBarry Smith .seealso: DMDASetLocalFunction(), DMDASetLocalJacobian(), DMDASetLocalAdicFunction(), DMDASetLocalAdicMFFunction(), 60647c6ae99SBarry Smith SNESSetFunction(), SNESSetJacobian() 60747c6ae99SBarry Smith 60847c6ae99SBarry Smith @*/ 6097087cfbeSBarry Smith PetscErrorCode DMDAFormFunctionLocalGhost(DM da, DMDALocalFunction1 func, Vec X, Vec F, void *ctx) 61047c6ae99SBarry Smith { 61147c6ae99SBarry Smith Vec localX, localF; 612aa219208SBarry Smith DMDALocalInfo info; 61347c6ae99SBarry Smith void *u; 61447c6ae99SBarry Smith void *fu; 61547c6ae99SBarry Smith PetscErrorCode ierr; 61647c6ae99SBarry Smith 61747c6ae99SBarry Smith PetscFunctionBegin; 6189a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); 6199a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localF);CHKERRQ(ierr); 62047c6ae99SBarry Smith /* 62147c6ae99SBarry Smith Scatter ghost points to local vector, using the 2-step process 6229a42bb27SBarry Smith DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). 62347c6ae99SBarry Smith */ 6249a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 6259a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 62647c6ae99SBarry Smith ierr = VecSet(F, 0.0);CHKERRQ(ierr); 62747c6ae99SBarry Smith ierr = VecSet(localF, 0.0);CHKERRQ(ierr); 628aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 629aa219208SBarry Smith ierr = DMDAVecGetArray(da,localX,&u);CHKERRQ(ierr); 630aa219208SBarry Smith ierr = DMDAVecGetArray(da,localF,&fu);CHKERRQ(ierr); 63139d508bbSBarry Smith ierr = (*func)(&info,u,fu,ctx);CHKERRQ(ierr); 6329a42bb27SBarry Smith ierr = DMLocalToGlobalBegin(da,localF,ADD_VALUES,F);CHKERRQ(ierr); 6339a42bb27SBarry Smith ierr = DMLocalToGlobalEnd(da,localF,ADD_VALUES,F);CHKERRQ(ierr); 634aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,localX,&u);CHKERRQ(ierr); 635aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,localF,&fu);CHKERRQ(ierr); 6369a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); 6379a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localF);CHKERRQ(ierr); 63847c6ae99SBarry Smith PetscFunctionReturn(0); 63947c6ae99SBarry Smith } 64047c6ae99SBarry Smith 64147c6ae99SBarry Smith #undef __FUNCT__ 642aa219208SBarry Smith #define __FUNCT__ "DMDAFormFunction1" 64347c6ae99SBarry Smith /*@ 644aa219208SBarry Smith DMDAFormFunction1 - Evaluates a user provided function on each processor that 645aa219208SBarry Smith share a DMDA 64647c6ae99SBarry Smith 64747c6ae99SBarry Smith Input Parameters: 6489a42bb27SBarry Smith + da - the DM that defines the grid 64947c6ae99SBarry Smith . vu - input vector 65047c6ae99SBarry Smith . vfu - output vector 65147c6ae99SBarry Smith - w - any user data 65247c6ae99SBarry Smith 65347c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 65447c6ae99SBarry Smith 65547c6ae99SBarry Smith Level: advanced 65647c6ae99SBarry Smith 657aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic() 65847c6ae99SBarry Smith 65947c6ae99SBarry Smith @*/ 6607087cfbeSBarry Smith PetscErrorCode DMDAFormFunction1(DM da,Vec vu,Vec vfu,void *w) 66147c6ae99SBarry Smith { 66247c6ae99SBarry Smith PetscErrorCode ierr; 66347c6ae99SBarry Smith void *u,*fu; 664aa219208SBarry Smith DMDALocalInfo info; 66547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 66647c6ae99SBarry Smith 66747c6ae99SBarry Smith PetscFunctionBegin; 668aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 669aa219208SBarry Smith ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr); 670aa219208SBarry Smith ierr = DMDAVecGetArray(da,vfu,&fu);CHKERRQ(ierr); 67147c6ae99SBarry Smith 67247c6ae99SBarry Smith CHKMEMQ; 67339d508bbSBarry Smith ierr = (*dd->lf)(&info,u,fu,w);CHKERRQ(ierr); 67447c6ae99SBarry Smith CHKMEMQ; 67547c6ae99SBarry Smith 676aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 677aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,vfu,&fu);CHKERRQ(ierr); 67847c6ae99SBarry Smith PetscFunctionReturn(0); 67947c6ae99SBarry Smith } 68047c6ae99SBarry Smith 68147c6ae99SBarry Smith #undef __FUNCT__ 682aa219208SBarry Smith #define __FUNCT__ "DMDAFormFunctioniTest1" 6837087cfbeSBarry Smith PetscErrorCode DMDAFormFunctioniTest1(DM da,void *w) 68447c6ae99SBarry Smith { 68547c6ae99SBarry Smith Vec vu,fu,fui; 68647c6ae99SBarry Smith PetscErrorCode ierr; 68747c6ae99SBarry Smith PetscInt i,n; 68847c6ae99SBarry Smith PetscScalar *ui; 68947c6ae99SBarry Smith PetscRandom rnd; 69047c6ae99SBarry Smith PetscReal norm; 69147c6ae99SBarry Smith 69247c6ae99SBarry Smith PetscFunctionBegin; 6939a42bb27SBarry Smith ierr = DMGetLocalVector(da,&vu);CHKERRQ(ierr); 69447c6ae99SBarry Smith ierr = PetscRandomCreate(PETSC_COMM_SELF,&rnd);CHKERRQ(ierr); 69547c6ae99SBarry Smith ierr = PetscRandomSetFromOptions(rnd);CHKERRQ(ierr); 69647c6ae99SBarry Smith ierr = VecSetRandom(vu,rnd);CHKERRQ(ierr); 69747c6ae99SBarry Smith ierr = PetscRandomDestroy(rnd);CHKERRQ(ierr); 69847c6ae99SBarry Smith 6999a42bb27SBarry Smith ierr = DMGetGlobalVector(da,&fu);CHKERRQ(ierr); 7009a42bb27SBarry Smith ierr = DMGetGlobalVector(da,&fui);CHKERRQ(ierr); 70147c6ae99SBarry Smith 702aa219208SBarry Smith ierr = DMDAFormFunction1(da,vu,fu,w);CHKERRQ(ierr); 70347c6ae99SBarry Smith 70447c6ae99SBarry Smith ierr = VecGetArray(fui,&ui);CHKERRQ(ierr); 70547c6ae99SBarry Smith ierr = VecGetLocalSize(fui,&n);CHKERRQ(ierr); 70647c6ae99SBarry Smith for (i=0; i<n; i++) { 707aa219208SBarry Smith ierr = DMDAFormFunctioni1(da,i,vu,ui+i,w);CHKERRQ(ierr); 70847c6ae99SBarry Smith } 70947c6ae99SBarry Smith ierr = VecRestoreArray(fui,&ui);CHKERRQ(ierr); 71047c6ae99SBarry Smith 71147c6ae99SBarry Smith ierr = VecAXPY(fui,-1.0,fu);CHKERRQ(ierr); 71247c6ae99SBarry Smith ierr = VecNorm(fui,NORM_2,&norm);CHKERRQ(ierr); 71347c6ae99SBarry Smith ierr = PetscPrintf(((PetscObject)da)->comm,"Norm of difference in vectors %G\n",norm);CHKERRQ(ierr); 71447c6ae99SBarry Smith ierr = VecView(fu,0);CHKERRQ(ierr); 71547c6ae99SBarry Smith ierr = VecView(fui,0);CHKERRQ(ierr); 71647c6ae99SBarry Smith 7179a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&vu);CHKERRQ(ierr); 7189a42bb27SBarry Smith ierr = DMRestoreGlobalVector(da,&fu);CHKERRQ(ierr); 7199a42bb27SBarry Smith ierr = DMRestoreGlobalVector(da,&fui);CHKERRQ(ierr); 72047c6ae99SBarry Smith PetscFunctionReturn(0); 72147c6ae99SBarry Smith } 72247c6ae99SBarry Smith 72347c6ae99SBarry Smith #undef __FUNCT__ 724aa219208SBarry Smith #define __FUNCT__ "DMDAFormFunctioni1" 72547c6ae99SBarry Smith /*@ 726aa219208SBarry Smith DMDAFormFunctioni1 - Evaluates a user provided point-wise function 72747c6ae99SBarry Smith 72847c6ae99SBarry Smith Input Parameters: 7299a42bb27SBarry Smith + da - the DM that defines the grid 73047c6ae99SBarry Smith . i - the component of the function we wish to compute (must be local) 73147c6ae99SBarry Smith . vu - input vector 73247c6ae99SBarry Smith . vfu - output value 73347c6ae99SBarry Smith - w - any user data 73447c6ae99SBarry Smith 73547c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 73647c6ae99SBarry Smith 73747c6ae99SBarry Smith Level: advanced 73847c6ae99SBarry Smith 739aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic() 74047c6ae99SBarry Smith 74147c6ae99SBarry Smith @*/ 7427087cfbeSBarry Smith PetscErrorCode DMDAFormFunctioni1(DM da,PetscInt i,Vec vu,PetscScalar *vfu,void *w) 74347c6ae99SBarry Smith { 74447c6ae99SBarry Smith PetscErrorCode ierr; 74547c6ae99SBarry Smith void *u; 746aa219208SBarry Smith DMDALocalInfo info; 74747c6ae99SBarry Smith MatStencil stencil; 74847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 74947c6ae99SBarry Smith 75047c6ae99SBarry Smith PetscFunctionBegin; 75147c6ae99SBarry Smith 752aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 753aa219208SBarry Smith ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr); 75447c6ae99SBarry Smith 75547c6ae99SBarry Smith /* figure out stencil value from i */ 75647c6ae99SBarry Smith stencil.c = i % info.dof; 75747c6ae99SBarry Smith stencil.i = (i % (info.xm*info.dof))/info.dof; 75847c6ae99SBarry Smith stencil.j = (i % (info.xm*info.ym*info.dof))/(info.xm*info.dof); 75947c6ae99SBarry Smith stencil.k = i/(info.xm*info.ym*info.dof); 76047c6ae99SBarry Smith 76147c6ae99SBarry Smith ierr = (*dd->lfi)(&info,&stencil,u,vfu,w);CHKERRQ(ierr); 76247c6ae99SBarry Smith 763aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 76447c6ae99SBarry Smith PetscFunctionReturn(0); 76547c6ae99SBarry Smith } 76647c6ae99SBarry Smith 76747c6ae99SBarry Smith #undef __FUNCT__ 768aa219208SBarry Smith #define __FUNCT__ "DMDAFormFunctionib1" 76947c6ae99SBarry Smith /*@ 770aa219208SBarry Smith DMDAFormFunctionib1 - Evaluates a user provided point-block function 77147c6ae99SBarry Smith 77247c6ae99SBarry Smith Input Parameters: 7739a42bb27SBarry Smith + da - the DM that defines the grid 77447c6ae99SBarry Smith . i - the component of the function we wish to compute (must be local) 77547c6ae99SBarry Smith . vu - input vector 77647c6ae99SBarry Smith . vfu - output value 77747c6ae99SBarry Smith - w - any user data 77847c6ae99SBarry Smith 77947c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 78047c6ae99SBarry Smith 78147c6ae99SBarry Smith Level: advanced 78247c6ae99SBarry Smith 783aa219208SBarry Smith .seealso: DMDAComputeJacobian1WithAdic() 78447c6ae99SBarry Smith 78547c6ae99SBarry Smith @*/ 7867087cfbeSBarry Smith PetscErrorCode DMDAFormFunctionib1(DM da,PetscInt i,Vec vu,PetscScalar *vfu,void *w) 78747c6ae99SBarry Smith { 78847c6ae99SBarry Smith PetscErrorCode ierr; 78947c6ae99SBarry Smith void *u; 790aa219208SBarry Smith DMDALocalInfo info; 79147c6ae99SBarry Smith MatStencil stencil; 79247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 79347c6ae99SBarry Smith 79447c6ae99SBarry Smith PetscFunctionBegin; 795aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 796aa219208SBarry Smith ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr); 79747c6ae99SBarry Smith 79847c6ae99SBarry Smith /* figure out stencil value from i */ 79947c6ae99SBarry Smith stencil.c = i % info.dof; 80047c6ae99SBarry Smith if (stencil.c) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Point-block functions can only be called for the entire block"); 80147c6ae99SBarry Smith stencil.i = (i % (info.xm*info.dof))/info.dof; 80247c6ae99SBarry Smith stencil.j = (i % (info.xm*info.ym*info.dof))/(info.xm*info.dof); 80347c6ae99SBarry Smith stencil.k = i/(info.xm*info.ym*info.dof); 80447c6ae99SBarry Smith 80547c6ae99SBarry Smith ierr = (*dd->lfib)(&info,&stencil,u,vfu,w);CHKERRQ(ierr); 80647c6ae99SBarry Smith 807aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 80847c6ae99SBarry Smith PetscFunctionReturn(0); 80947c6ae99SBarry Smith } 81047c6ae99SBarry Smith 81147c6ae99SBarry Smith #if defined(new) 81247c6ae99SBarry Smith #undef __FUNCT__ 813aa219208SBarry Smith #define __FUNCT__ "DMDAGetDiagonal_MFFD" 81447c6ae99SBarry Smith /* 815aa219208SBarry Smith DMDAGetDiagonal_MFFD - Gets the diagonal for a matrix free matrix where local 816aa219208SBarry Smith function lives on a DMDA 81747c6ae99SBarry Smith 81847c6ae99SBarry Smith y ~= (F(u + ha) - F(u))/h, 81947c6ae99SBarry Smith where F = nonlinear function, as set by SNESSetFunction() 82047c6ae99SBarry Smith u = current iterate 82147c6ae99SBarry Smith h = difference interval 82247c6ae99SBarry Smith */ 823aa219208SBarry Smith PetscErrorCode DMDAGetDiagonal_MFFD(DM da,Vec U,Vec a) 82447c6ae99SBarry Smith { 82547c6ae99SBarry Smith PetscScalar h,*aa,*ww,v; 82647c6ae99SBarry Smith PetscReal epsilon = PETSC_SQRT_MACHINE_EPSILON,umin = 100.0*PETSC_SQRT_MACHINE_EPSILON; 82747c6ae99SBarry Smith PetscErrorCode ierr; 82847c6ae99SBarry Smith PetscInt gI,nI; 82947c6ae99SBarry Smith MatStencil stencil; 830aa219208SBarry Smith DMDALocalInfo info; 83147c6ae99SBarry Smith 83247c6ae99SBarry Smith PetscFunctionBegin; 83347c6ae99SBarry Smith ierr = (*ctx->func)(0,U,a,ctx->funcctx);CHKERRQ(ierr); 83447c6ae99SBarry Smith ierr = (*ctx->funcisetbase)(U,ctx->funcctx);CHKERRQ(ierr); 83547c6ae99SBarry Smith 83647c6ae99SBarry Smith ierr = VecGetArray(U,&ww);CHKERRQ(ierr); 83747c6ae99SBarry Smith ierr = VecGetArray(a,&aa);CHKERRQ(ierr); 83847c6ae99SBarry Smith 83947c6ae99SBarry Smith nI = 0; 84047c6ae99SBarry Smith h = ww[gI]; 84147c6ae99SBarry Smith if (h == 0.0) h = 1.0; 84247c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX) 84347c6ae99SBarry Smith if (h < umin && h >= 0.0) h = umin; 84447c6ae99SBarry Smith else if (h < 0.0 && h > -umin) h = -umin; 84547c6ae99SBarry Smith #else 84647c6ae99SBarry Smith if (PetscAbsScalar(h) < umin && PetscRealPart(h) >= 0.0) h = umin; 84747c6ae99SBarry Smith else if (PetscRealPart(h) < 0.0 && PetscAbsScalar(h) < umin) h = -umin; 84847c6ae99SBarry Smith #endif 84947c6ae99SBarry Smith h *= epsilon; 85047c6ae99SBarry Smith 85147c6ae99SBarry Smith ww[gI] += h; 85247c6ae99SBarry Smith ierr = (*ctx->funci)(i,w,&v,ctx->funcctx);CHKERRQ(ierr); 85347c6ae99SBarry Smith aa[nI] = (v - aa[nI])/h; 85447c6ae99SBarry Smith ww[gI] -= h; 85547c6ae99SBarry Smith nI++; 85647c6ae99SBarry Smith } 85747c6ae99SBarry Smith ierr = VecRestoreArray(U,&ww);CHKERRQ(ierr); 85847c6ae99SBarry Smith ierr = VecRestoreArray(a,&aa);CHKERRQ(ierr); 85947c6ae99SBarry Smith PetscFunctionReturn(0); 86047c6ae99SBarry Smith } 86147c6ae99SBarry Smith #endif 86247c6ae99SBarry Smith 86347c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC) 86447c6ae99SBarry Smith EXTERN_C_BEGIN 86547c6ae99SBarry Smith #include "adic/ad_utils.h" 86647c6ae99SBarry Smith EXTERN_C_END 86747c6ae99SBarry Smith 86847c6ae99SBarry Smith #undef __FUNCT__ 869aa219208SBarry Smith #define __FUNCT__ "DMDAComputeJacobian1WithAdic" 87047c6ae99SBarry Smith /*@C 871aa219208SBarry Smith DMDAComputeJacobian1WithAdic - Evaluates a adiC provided Jacobian function on each processor that 872aa219208SBarry Smith share a DMDA 87347c6ae99SBarry Smith 87447c6ae99SBarry Smith Input Parameters: 8759a42bb27SBarry Smith + da - the DM that defines the grid 87647c6ae99SBarry Smith . vu - input vector (ghosted) 87747c6ae99SBarry Smith . J - output matrix 87847c6ae99SBarry Smith - w - any user data 87947c6ae99SBarry Smith 88047c6ae99SBarry Smith Level: advanced 88147c6ae99SBarry Smith 88247c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 88347c6ae99SBarry Smith 884aa219208SBarry Smith .seealso: DMDAFormFunction1() 88547c6ae99SBarry Smith 88647c6ae99SBarry Smith @*/ 8877087cfbeSBarry Smith PetscErrorCode DMDAComputeJacobian1WithAdic(DM da,Vec vu,Mat J,void *w) 88847c6ae99SBarry Smith { 88947c6ae99SBarry Smith PetscErrorCode ierr; 89047c6ae99SBarry Smith PetscInt gtdof,tdof; 89147c6ae99SBarry Smith PetscScalar *ustart; 892aa219208SBarry Smith DMDALocalInfo info; 89347c6ae99SBarry Smith void *ad_u,*ad_f,*ad_ustart,*ad_fstart; 89447c6ae99SBarry Smith ISColoring iscoloring; 89547c6ae99SBarry Smith 89647c6ae99SBarry Smith PetscFunctionBegin; 897aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 89847c6ae99SBarry Smith 89947c6ae99SBarry Smith PetscADResetIndep(); 90047c6ae99SBarry Smith 90147c6ae99SBarry Smith /* get space for derivative objects. */ 902aa219208SBarry Smith ierr = DMDAGetAdicArray(da,PETSC_TRUE,&ad_u,&ad_ustart,>dof);CHKERRQ(ierr); 903aa219208SBarry Smith ierr = DMDAGetAdicArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 90447c6ae99SBarry Smith ierr = VecGetArray(vu,&ustart);CHKERRQ(ierr); 90594013140SBarry Smith ierr = DMGetColoring(da,IS_COLORING_GHOSTED,MATAIJ,&iscoloring);CHKERRQ(ierr); 90647c6ae99SBarry Smith 90747c6ae99SBarry Smith PetscADSetValueAndColor(ad_ustart,gtdof,iscoloring->colors,ustart); 90847c6ae99SBarry Smith 90947c6ae99SBarry Smith ierr = VecRestoreArray(vu,&ustart);CHKERRQ(ierr); 91047c6ae99SBarry Smith ierr = ISColoringDestroy(iscoloring);CHKERRQ(ierr); 91147c6ae99SBarry Smith ierr = PetscADIncrementTotalGradSize(iscoloring->n);CHKERRQ(ierr); 91247c6ae99SBarry Smith PetscADSetIndepDone(); 91347c6ae99SBarry Smith 914aa219208SBarry Smith ierr = PetscLogEventBegin(DMDA_LocalADFunction,0,0,0,0);CHKERRQ(ierr); 91547c6ae99SBarry Smith ierr = (*dd->adic_lf)(&info,ad_u,ad_f,w);CHKERRQ(ierr); 916aa219208SBarry Smith ierr = PetscLogEventEnd(DMDA_LocalADFunction,0,0,0,0);CHKERRQ(ierr); 91747c6ae99SBarry Smith 91847c6ae99SBarry Smith /* stick the values into the matrix */ 91947c6ae99SBarry Smith ierr = MatSetValuesAdic(J,(PetscScalar**)ad_fstart);CHKERRQ(ierr); 92047c6ae99SBarry Smith 92147c6ae99SBarry Smith /* return space for derivative objects. */ 922aa219208SBarry Smith ierr = DMDARestoreAdicArray(da,PETSC_TRUE,&ad_u,&ad_ustart,>dof);CHKERRQ(ierr); 923aa219208SBarry Smith ierr = DMDARestoreAdicArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 92447c6ae99SBarry Smith PetscFunctionReturn(0); 92547c6ae99SBarry Smith } 92647c6ae99SBarry Smith 92747c6ae99SBarry Smith #undef __FUNCT__ 928aa219208SBarry Smith #define __FUNCT__ "DMDAMultiplyByJacobian1WithAdic" 92947c6ae99SBarry Smith /*@C 930aa219208SBarry Smith DMDAMultiplyByJacobian1WithAdic - Applies an ADIC-provided Jacobian function to a vector on 931aa219208SBarry Smith each processor that shares a DMDA. 93247c6ae99SBarry Smith 93347c6ae99SBarry Smith Input Parameters: 9349a42bb27SBarry Smith + da - the DM that defines the grid 93547c6ae99SBarry Smith . vu - Jacobian is computed at this point (ghosted) 93647c6ae99SBarry Smith . v - product is done on this vector (ghosted) 93747c6ae99SBarry Smith . fu - output vector = J(vu)*v (not ghosted) 93847c6ae99SBarry Smith - w - any user data 93947c6ae99SBarry Smith 94047c6ae99SBarry Smith Notes: 94147c6ae99SBarry Smith This routine does NOT do ghost updates on vu upon entry. 94247c6ae99SBarry Smith 94347c6ae99SBarry Smith Level: advanced 94447c6ae99SBarry Smith 945aa219208SBarry Smith .seealso: DMDAFormFunction1() 94647c6ae99SBarry Smith 94747c6ae99SBarry Smith @*/ 9487087cfbeSBarry Smith PetscErrorCode DMDAMultiplyByJacobian1WithAdic(DM da,Vec vu,Vec v,Vec f,void *w) 94947c6ae99SBarry Smith { 95047c6ae99SBarry Smith PetscErrorCode ierr; 95147c6ae99SBarry Smith PetscInt i,gtdof,tdof; 95247c6ae99SBarry Smith PetscScalar *avu,*av,*af,*ad_vustart,*ad_fstart; 953aa219208SBarry Smith DMDALocalInfo info; 95447c6ae99SBarry Smith void *ad_vu,*ad_f; 95547c6ae99SBarry Smith 95647c6ae99SBarry Smith PetscFunctionBegin; 957aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 95847c6ae99SBarry Smith 95947c6ae99SBarry Smith /* get space for derivative objects. */ 960aa219208SBarry Smith ierr = DMDAGetAdicMFArray(da,PETSC_TRUE,&ad_vu,&ad_vustart,>dof);CHKERRQ(ierr); 961aa219208SBarry Smith ierr = DMDAGetAdicMFArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 96247c6ae99SBarry Smith 96347c6ae99SBarry Smith /* copy input vector into derivative object */ 96447c6ae99SBarry Smith ierr = VecGetArray(vu,&avu);CHKERRQ(ierr); 96547c6ae99SBarry Smith ierr = VecGetArray(v,&av);CHKERRQ(ierr); 96647c6ae99SBarry Smith for (i=0; i<gtdof; i++) { 96747c6ae99SBarry Smith ad_vustart[2*i] = avu[i]; 96847c6ae99SBarry Smith ad_vustart[2*i+1] = av[i]; 96947c6ae99SBarry Smith } 97047c6ae99SBarry Smith ierr = VecRestoreArray(vu,&avu);CHKERRQ(ierr); 97147c6ae99SBarry Smith ierr = VecRestoreArray(v,&av);CHKERRQ(ierr); 97247c6ae99SBarry Smith 97347c6ae99SBarry Smith PetscADResetIndep(); 97447c6ae99SBarry Smith ierr = PetscADIncrementTotalGradSize(1);CHKERRQ(ierr); 97547c6ae99SBarry Smith PetscADSetIndepDone(); 97647c6ae99SBarry Smith 97747c6ae99SBarry Smith ierr = (*dd->adicmf_lf)(&info,ad_vu,ad_f,w);CHKERRQ(ierr); 97847c6ae99SBarry Smith 97947c6ae99SBarry Smith /* stick the values into the vector */ 98047c6ae99SBarry Smith ierr = VecGetArray(f,&af);CHKERRQ(ierr); 98147c6ae99SBarry Smith for (i=0; i<tdof; i++) { 98247c6ae99SBarry Smith af[i] = ad_fstart[2*i+1]; 98347c6ae99SBarry Smith } 98447c6ae99SBarry Smith ierr = VecRestoreArray(f,&af);CHKERRQ(ierr); 98547c6ae99SBarry Smith 98647c6ae99SBarry Smith /* return space for derivative objects. */ 987aa219208SBarry Smith ierr = DMDARestoreAdicMFArray(da,PETSC_TRUE,&ad_vu,&ad_vustart,>dof);CHKERRQ(ierr); 988aa219208SBarry Smith ierr = DMDARestoreAdicMFArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 98947c6ae99SBarry Smith PetscFunctionReturn(0); 99047c6ae99SBarry Smith } 99147c6ae99SBarry Smith #endif 99247c6ae99SBarry Smith 99347c6ae99SBarry Smith #undef __FUNCT__ 994aa219208SBarry Smith #define __FUNCT__ "DMDAComputeJacobian1" 99547c6ae99SBarry Smith /*@ 996aa219208SBarry Smith DMDAComputeJacobian1 - Evaluates a local Jacobian function on each processor that 997aa219208SBarry Smith share a DMDA 99847c6ae99SBarry Smith 99947c6ae99SBarry Smith Input Parameters: 10009a42bb27SBarry Smith + da - the DM that defines the grid 100147c6ae99SBarry Smith . vu - input vector (ghosted) 100247c6ae99SBarry Smith . J - output matrix 100347c6ae99SBarry Smith - w - any user data 100447c6ae99SBarry Smith 100547c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 100647c6ae99SBarry Smith 100747c6ae99SBarry Smith Level: advanced 100847c6ae99SBarry Smith 1009aa219208SBarry Smith .seealso: DMDAFormFunction1() 101047c6ae99SBarry Smith 101147c6ae99SBarry Smith @*/ 10127087cfbeSBarry Smith PetscErrorCode DMDAComputeJacobian1(DM da,Vec vu,Mat J,void *w) 101347c6ae99SBarry Smith { 101447c6ae99SBarry Smith PetscErrorCode ierr; 101547c6ae99SBarry Smith void *u; 1016aa219208SBarry Smith DMDALocalInfo info; 101747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 101847c6ae99SBarry Smith 101947c6ae99SBarry Smith PetscFunctionBegin; 1020aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 1021aa219208SBarry Smith ierr = DMDAVecGetArray(da,vu,&u);CHKERRQ(ierr); 102247c6ae99SBarry Smith ierr = (*dd->lj)(&info,u,J,w);CHKERRQ(ierr); 1023aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 102447c6ae99SBarry Smith PetscFunctionReturn(0); 102547c6ae99SBarry Smith } 102647c6ae99SBarry Smith 102747c6ae99SBarry Smith 102847c6ae99SBarry Smith #undef __FUNCT__ 1029aa219208SBarry Smith #define __FUNCT__ "DMDAComputeJacobian1WithAdifor" 103047c6ae99SBarry Smith /* 1031aa219208SBarry Smith DMDAComputeJacobian1WithAdifor - Evaluates a ADIFOR provided Jacobian local function on each processor that 1032aa219208SBarry Smith share a DMDA 103347c6ae99SBarry Smith 103447c6ae99SBarry Smith Input Parameters: 10359a42bb27SBarry Smith + da - the DM that defines the grid 103647c6ae99SBarry Smith . vu - input vector (ghosted) 103747c6ae99SBarry Smith . J - output matrix 103847c6ae99SBarry Smith - w - any user data 103947c6ae99SBarry Smith 104047c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 104147c6ae99SBarry Smith 1042aa219208SBarry Smith .seealso: DMDAFormFunction1() 104347c6ae99SBarry Smith 104447c6ae99SBarry Smith */ 10457087cfbeSBarry Smith PetscErrorCode DMDAComputeJacobian1WithAdifor(DM da,Vec vu,Mat J,void *w) 104647c6ae99SBarry Smith { 104747c6ae99SBarry Smith PetscErrorCode ierr; 104847c6ae99SBarry Smith PetscInt i,Nc,N; 104947c6ae99SBarry Smith ISColoringValue *color; 1050aa219208SBarry Smith DMDALocalInfo info; 105147c6ae99SBarry Smith PetscScalar *u,*g_u,*g_f,*f = 0,*p_u; 105247c6ae99SBarry Smith ISColoring iscoloring; 105347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 1054aa219208SBarry Smith void (*lf)(PetscInt*,DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscInt*,PetscScalar*,PetscScalar*,PetscInt*,void*,PetscErrorCode*) = 1055aa219208SBarry Smith (void (*)(PetscInt*,DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscInt*,PetscScalar*,PetscScalar*,PetscInt*,void*,PetscErrorCode*))*dd->adifor_lf; 105647c6ae99SBarry Smith 105747c6ae99SBarry Smith PetscFunctionBegin; 105894013140SBarry Smith ierr = DMGetColoring(da,IS_COLORING_GHOSTED,MATAIJ,&iscoloring);CHKERRQ(ierr); 105947c6ae99SBarry Smith Nc = iscoloring->n; 1060aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 106147c6ae99SBarry Smith N = info.gxm*info.gym*info.gzm*info.dof; 106247c6ae99SBarry Smith 106347c6ae99SBarry Smith /* get space for derivative objects. */ 106447c6ae99SBarry Smith ierr = PetscMalloc(Nc*info.gxm*info.gym*info.gzm*info.dof*sizeof(PetscScalar),&g_u);CHKERRQ(ierr); 106547c6ae99SBarry Smith ierr = PetscMemzero(g_u,Nc*info.gxm*info.gym*info.gzm*info.dof*sizeof(PetscScalar));CHKERRQ(ierr); 106647c6ae99SBarry Smith p_u = g_u; 106747c6ae99SBarry Smith color = iscoloring->colors; 106847c6ae99SBarry Smith for (i=0; i<N; i++) { 106947c6ae99SBarry Smith p_u[*color++] = 1.0; 107047c6ae99SBarry Smith p_u += Nc; 107147c6ae99SBarry Smith } 107247c6ae99SBarry Smith ierr = ISColoringDestroy(iscoloring);CHKERRQ(ierr); 107347c6ae99SBarry Smith ierr = PetscMalloc2(Nc*info.xm*info.ym*info.zm*info.dof,PetscScalar,&g_f,info.xm*info.ym*info.zm*info.dof,PetscScalar,&f);CHKERRQ(ierr); 107447c6ae99SBarry Smith 107547c6ae99SBarry Smith /* Seed the input array g_u with coloring information */ 107647c6ae99SBarry Smith 107747c6ae99SBarry Smith ierr = VecGetArray(vu,&u);CHKERRQ(ierr); 107847c6ae99SBarry Smith (lf)(&Nc,&info,u,g_u,&Nc,f,g_f,&Nc,w,&ierr);CHKERRQ(ierr); 107947c6ae99SBarry Smith ierr = VecRestoreArray(vu,&u);CHKERRQ(ierr); 108047c6ae99SBarry Smith 108147c6ae99SBarry Smith /* stick the values into the matrix */ 108247c6ae99SBarry Smith /* PetscScalarView(Nc*info.xm*info.ym,g_f,0); */ 108347c6ae99SBarry Smith ierr = MatSetValuesAdifor(J,Nc,g_f);CHKERRQ(ierr); 108447c6ae99SBarry Smith 108547c6ae99SBarry Smith /* return space for derivative objects. */ 108647c6ae99SBarry Smith ierr = PetscFree(g_u);CHKERRQ(ierr); 108747c6ae99SBarry Smith ierr = PetscFree2(g_f,f);CHKERRQ(ierr); 108847c6ae99SBarry Smith PetscFunctionReturn(0); 108947c6ae99SBarry Smith } 109047c6ae99SBarry Smith 109147c6ae99SBarry Smith #undef __FUNCT__ 1092aa219208SBarry Smith #define __FUNCT__ "DMDAFormJacobianLocal" 109347c6ae99SBarry Smith /*@C 1094aa219208SBarry Smith DMDAFormjacobianLocal - This is a universal Jacobian evaluation routine for 10959a42bb27SBarry Smith a local DM function. 109647c6ae99SBarry Smith 1097aa219208SBarry Smith Collective on DMDA 109847c6ae99SBarry Smith 109947c6ae99SBarry Smith Input Parameters: 11009a42bb27SBarry Smith + da - the DM context 110147c6ae99SBarry Smith . func - The local function 110247c6ae99SBarry Smith . X - input vector 110347c6ae99SBarry Smith . J - Jacobian matrix 110447c6ae99SBarry Smith - ctx - A user context 110547c6ae99SBarry Smith 110647c6ae99SBarry Smith Level: intermediate 110747c6ae99SBarry Smith 1108aa219208SBarry Smith .seealso: DMDASetLocalFunction(), DMDASetLocalJacobian(), DMDASetLocalAdicFunction(), DMDASetLocalAdicMFFunction(), 110947c6ae99SBarry Smith SNESSetFunction(), SNESSetJacobian() 111047c6ae99SBarry Smith 111147c6ae99SBarry Smith @*/ 11127087cfbeSBarry Smith PetscErrorCode DMDAFormJacobianLocal(DM da, DMDALocalFunction1 func, Vec X, Mat J, void *ctx) 111347c6ae99SBarry Smith { 111447c6ae99SBarry Smith Vec localX; 1115aa219208SBarry Smith DMDALocalInfo info; 111647c6ae99SBarry Smith void *u; 111747c6ae99SBarry Smith PetscErrorCode ierr; 111847c6ae99SBarry Smith 111947c6ae99SBarry Smith PetscFunctionBegin; 11209a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); 112147c6ae99SBarry Smith /* 112247c6ae99SBarry Smith Scatter ghost points to local vector, using the 2-step process 11239a42bb27SBarry Smith DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). 112447c6ae99SBarry Smith */ 11259a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 11269a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 1127aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 1128aa219208SBarry Smith ierr = DMDAVecGetArray(da,localX,&u);CHKERRQ(ierr); 112939d508bbSBarry Smith ierr = (*func)(&info,u,J,ctx);CHKERRQ(ierr); 1130aa219208SBarry Smith ierr = DMDAVecRestoreArray(da,localX,&u);CHKERRQ(ierr); 11319a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); 113247c6ae99SBarry Smith PetscFunctionReturn(0); 113347c6ae99SBarry Smith } 113447c6ae99SBarry Smith 113547c6ae99SBarry Smith #undef __FUNCT__ 1136aa219208SBarry Smith #define __FUNCT__ "DMDAMultiplyByJacobian1WithAD" 113747c6ae99SBarry Smith /*@C 1138aa219208SBarry Smith DMDAMultiplyByJacobian1WithAD - Applies a Jacobian function supplied by ADIFOR or ADIC 1139aa219208SBarry Smith to a vector on each processor that shares a DMDA. 114047c6ae99SBarry Smith 114147c6ae99SBarry Smith Input Parameters: 11429a42bb27SBarry Smith + da - the DM that defines the grid 114347c6ae99SBarry Smith . vu - Jacobian is computed at this point (ghosted) 114447c6ae99SBarry Smith . v - product is done on this vector (ghosted) 114547c6ae99SBarry Smith . fu - output vector = J(vu)*v (not ghosted) 114647c6ae99SBarry Smith - w - any user data 114747c6ae99SBarry Smith 114847c6ae99SBarry Smith Notes: 114947c6ae99SBarry Smith This routine does NOT do ghost updates on vu and v upon entry. 115047c6ae99SBarry Smith 1151aa219208SBarry Smith Automatically calls DMDAMultiplyByJacobian1WithAdifor() or DMDAMultiplyByJacobian1WithAdic() 1152aa219208SBarry Smith depending on whether DMDASetLocalAdicMFFunction() or DMDASetLocalAdiforMFFunction() was called. 115347c6ae99SBarry Smith 115447c6ae99SBarry Smith Level: advanced 115547c6ae99SBarry Smith 1156aa219208SBarry Smith .seealso: DMDAFormFunction1(), DMDAMultiplyByJacobian1WithAdifor(), DMDAMultiplyByJacobian1WithAdic() 115747c6ae99SBarry Smith 115847c6ae99SBarry Smith @*/ 11597087cfbeSBarry Smith PetscErrorCode DMDAMultiplyByJacobian1WithAD(DM da,Vec u,Vec v,Vec f,void *w) 116047c6ae99SBarry Smith { 116147c6ae99SBarry Smith PetscErrorCode ierr; 116247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 116347c6ae99SBarry Smith 116447c6ae99SBarry Smith PetscFunctionBegin; 116547c6ae99SBarry Smith if (dd->adicmf_lf) { 116647c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC) 1167aa219208SBarry Smith ierr = DMDAMultiplyByJacobian1WithAdic(da,u,v,f,w);CHKERRQ(ierr); 116847c6ae99SBarry Smith #else 116947c6ae99SBarry Smith SETERRQ(((PetscObject)da)->comm,PETSC_ERR_SUP_SYS,"Requires ADIC to be installed and cannot use complex numbers"); 117047c6ae99SBarry Smith #endif 117147c6ae99SBarry Smith } else if (dd->adiformf_lf) { 1172aa219208SBarry Smith ierr = DMDAMultiplyByJacobian1WithAdifor(da,u,v,f,w);CHKERRQ(ierr); 117347c6ae99SBarry Smith } else { 1174aa219208SBarry Smith SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ORDER,"Must call DMDASetLocalAdiforMFFunction() or DMDASetLocalAdicMFFunction() before using"); 117547c6ae99SBarry Smith } 117647c6ae99SBarry Smith PetscFunctionReturn(0); 117747c6ae99SBarry Smith } 117847c6ae99SBarry Smith 117947c6ae99SBarry Smith 118047c6ae99SBarry Smith #undef __FUNCT__ 1181aa219208SBarry Smith #define __FUNCT__ "DMDAMultiplyByJacobian1WithAdifor" 118247c6ae99SBarry Smith /*@C 1183aa219208SBarry Smith DMDAMultiplyByJacobian1WithAdifor - Applies a ADIFOR provided Jacobian function on each processor that 11849a42bb27SBarry Smith share a DM to a vector 118547c6ae99SBarry Smith 118647c6ae99SBarry Smith Input Parameters: 11879a42bb27SBarry Smith + da - the DM that defines the grid 118847c6ae99SBarry Smith . vu - Jacobian is computed at this point (ghosted) 118947c6ae99SBarry Smith . v - product is done on this vector (ghosted) 119047c6ae99SBarry Smith . fu - output vector = J(vu)*v (not ghosted) 119147c6ae99SBarry Smith - w - any user data 119247c6ae99SBarry Smith 119347c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu and v upon entry 119447c6ae99SBarry Smith 119547c6ae99SBarry Smith Level: advanced 119647c6ae99SBarry Smith 1197aa219208SBarry Smith .seealso: DMDAFormFunction1() 119847c6ae99SBarry Smith 119947c6ae99SBarry Smith @*/ 12007087cfbeSBarry Smith PetscErrorCode DMDAMultiplyByJacobian1WithAdifor(DM da,Vec u,Vec v,Vec f,void *w) 120147c6ae99SBarry Smith { 120247c6ae99SBarry Smith PetscErrorCode ierr; 120347c6ae99SBarry Smith PetscScalar *au,*av,*af,*awork; 120447c6ae99SBarry Smith Vec work; 1205aa219208SBarry Smith DMDALocalInfo info; 120647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 1207aa219208SBarry Smith void (*lf)(DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,void*,PetscErrorCode*) = 1208aa219208SBarry Smith (void (*)(DMDALocalInfo*,PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,void*,PetscErrorCode*))*dd->adiformf_lf; 120947c6ae99SBarry Smith 121047c6ae99SBarry Smith PetscFunctionBegin; 1211aa219208SBarry Smith ierr = DMDAGetLocalInfo(da,&info);CHKERRQ(ierr); 121247c6ae99SBarry Smith 12139a42bb27SBarry Smith ierr = DMGetGlobalVector(da,&work);CHKERRQ(ierr); 121447c6ae99SBarry Smith ierr = VecGetArray(u,&au);CHKERRQ(ierr); 121547c6ae99SBarry Smith ierr = VecGetArray(v,&av);CHKERRQ(ierr); 121647c6ae99SBarry Smith ierr = VecGetArray(f,&af);CHKERRQ(ierr); 121747c6ae99SBarry Smith ierr = VecGetArray(work,&awork);CHKERRQ(ierr); 121847c6ae99SBarry Smith (lf)(&info,au,av,awork,af,w,&ierr);CHKERRQ(ierr); 121947c6ae99SBarry Smith ierr = VecRestoreArray(u,&au);CHKERRQ(ierr); 122047c6ae99SBarry Smith ierr = VecRestoreArray(v,&av);CHKERRQ(ierr); 122147c6ae99SBarry Smith ierr = VecRestoreArray(f,&af);CHKERRQ(ierr); 122247c6ae99SBarry Smith ierr = VecRestoreArray(work,&awork);CHKERRQ(ierr); 12239a42bb27SBarry Smith ierr = DMRestoreGlobalVector(da,&work);CHKERRQ(ierr); 122447c6ae99SBarry Smith 122547c6ae99SBarry Smith PetscFunctionReturn(0); 122647c6ae99SBarry Smith } 122747c6ae99SBarry Smith 122847c6ae99SBarry Smith #undef __FUNCT__ 12299a42bb27SBarry Smith #define __FUNCT__ "DMSetUp_DA_2D" 12307087cfbeSBarry Smith PetscErrorCode DMSetUp_DA_2D(DM da) 123147c6ae99SBarry Smith { 123247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 123347c6ae99SBarry Smith const PetscInt M = dd->M; 123447c6ae99SBarry Smith const PetscInt N = dd->N; 123547c6ae99SBarry Smith PetscInt m = dd->m; 123647c6ae99SBarry Smith PetscInt n = dd->n; 123747c6ae99SBarry Smith const PetscInt dof = dd->w; 123847c6ae99SBarry Smith const PetscInt s = dd->s; 1239aa219208SBarry Smith const DMDAPeriodicType wrap = dd->wrap; 1240aa219208SBarry Smith const DMDAStencilType stencil_type = dd->stencil_type; 124147c6ae99SBarry Smith PetscInt *lx = dd->lx; 124247c6ae99SBarry Smith PetscInt *ly = dd->ly; 124347c6ae99SBarry Smith MPI_Comm comm; 124447c6ae99SBarry Smith PetscMPIInt rank,size; 1245*ce00eea3SSatish Balay PetscInt xs,xe,ys,ye,x,y,Xs,Xe,Ys,Ye,start,end,IXs,IXe,IYs,IYe; 1246*ce00eea3SSatish Balay PetscInt up,down,left,right,i,n0,n1,n2,n3,n5,n6,n7,n8,*idx,nn,*idx_cpy; 1247*ce00eea3SSatish Balay const PetscInt *idx_full; 1248*ce00eea3SSatish Balay PetscInt xbase,*bases,*ldims,j,x_t,y_t,s_t,base,count,count_dbg; 124947c6ae99SBarry Smith PetscInt s_x,s_y; /* s proportionalized to w */ 125047c6ae99SBarry Smith PetscInt sn0 = 0,sn2 = 0,sn6 = 0,sn8 = 0; 125147c6ae99SBarry Smith Vec local,global; 125247c6ae99SBarry Smith VecScatter ltog,gtol; 1253*ce00eea3SSatish Balay IS to,from,ltogis; 125447c6ae99SBarry Smith PetscErrorCode ierr; 125547c6ae99SBarry Smith 125647c6ae99SBarry Smith PetscFunctionBegin; 125747c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 125847c6ae99SBarry Smith 125947c6ae99SBarry Smith if (dof < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have 1 or more degrees of freedom per node: %D",dof); 126047c6ae99SBarry Smith if (s < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Stencil width cannot be negative: %D",s); 126147c6ae99SBarry Smith 126247c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 126347c6ae99SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 126447c6ae99SBarry Smith 126547c6ae99SBarry Smith dd->dim = 2; 126647c6ae99SBarry Smith ierr = PetscMalloc(dof*sizeof(char*),&dd->fieldname);CHKERRQ(ierr); 126747c6ae99SBarry Smith ierr = PetscMemzero(dd->fieldname,dof*sizeof(char*));CHKERRQ(ierr); 126847c6ae99SBarry Smith 126947c6ae99SBarry Smith if (m != PETSC_DECIDE) { 127047c6ae99SBarry Smith if (m < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in X direction: %D",m); 127147c6ae99SBarry Smith else if (m > size) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in X direction: %D %d",m,size); 127247c6ae99SBarry Smith } 127347c6ae99SBarry Smith if (n != PETSC_DECIDE) { 127447c6ae99SBarry Smith if (n < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in Y direction: %D",n); 127547c6ae99SBarry Smith else if (n > size) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in Y direction: %D %d",n,size); 127647c6ae99SBarry Smith } 127747c6ae99SBarry Smith 127847c6ae99SBarry Smith if (m == PETSC_DECIDE || n == PETSC_DECIDE) { 127947c6ae99SBarry Smith if (n != PETSC_DECIDE) { 128047c6ae99SBarry Smith m = size/n; 128147c6ae99SBarry Smith } else if (m != PETSC_DECIDE) { 128247c6ae99SBarry Smith n = size/m; 128347c6ae99SBarry Smith } else { 128447c6ae99SBarry Smith /* try for squarish distribution */ 128547c6ae99SBarry Smith m = (PetscInt)(0.5 + sqrt(((double)M)*((double)size)/((double)N))); 128647c6ae99SBarry Smith if (!m) m = 1; 128747c6ae99SBarry Smith while (m > 0) { 128847c6ae99SBarry Smith n = size/m; 128947c6ae99SBarry Smith if (m*n == size) break; 129047c6ae99SBarry Smith m--; 129147c6ae99SBarry Smith } 129247c6ae99SBarry Smith if (M > N && m < n) {PetscInt _m = m; m = n; n = _m;} 129347c6ae99SBarry Smith } 129447c6ae99SBarry Smith if (m*n != size) SETERRQ(comm,PETSC_ERR_PLIB,"Unable to create partition, check the size of the communicator and input m and n "); 129547c6ae99SBarry Smith } else if (m*n != size) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Given Bad partition"); 129647c6ae99SBarry Smith 129747c6ae99SBarry Smith if (M < m) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in x direction is too fine! %D %D",M,m); 129847c6ae99SBarry Smith if (N < n) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in y direction is too fine! %D %D",N,n); 129947c6ae99SBarry Smith 130047c6ae99SBarry Smith /* 130147c6ae99SBarry Smith Determine locally owned region 130247c6ae99SBarry Smith xs is the first local node number, x is the number of local nodes 130347c6ae99SBarry Smith */ 130447c6ae99SBarry Smith if (!lx) { 130547c6ae99SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt), &dd->lx);CHKERRQ(ierr); 130647c6ae99SBarry Smith lx = dd->lx; 130747c6ae99SBarry Smith for (i=0; i<m; i++) { 130847c6ae99SBarry Smith lx[i] = M/m + ((M % m) > i); 130947c6ae99SBarry Smith } 131047c6ae99SBarry Smith } 131147c6ae99SBarry Smith x = lx[rank % m]; 131247c6ae99SBarry Smith xs = 0; 131347c6ae99SBarry Smith for (i=0; i<(rank % m); i++) { 131447c6ae99SBarry Smith xs += lx[i]; 131547c6ae99SBarry Smith } 131647c6ae99SBarry Smith #if defined(PETSC_USE_DEBUG) 131747c6ae99SBarry Smith left = xs; 131847c6ae99SBarry Smith for (i=(rank % m); i<m; i++) { 131947c6ae99SBarry Smith left += lx[i]; 132047c6ae99SBarry Smith } 132147c6ae99SBarry Smith if (left != M) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Sum of lx across processors not equal to M: %D %D",left,M); 132247c6ae99SBarry Smith #endif 132347c6ae99SBarry Smith 132447c6ae99SBarry Smith /* 132547c6ae99SBarry Smith Determine locally owned region 132647c6ae99SBarry Smith ys is the first local node number, y is the number of local nodes 132747c6ae99SBarry Smith */ 132847c6ae99SBarry Smith if (!ly) { 132947c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt), &dd->ly);CHKERRQ(ierr); 133047c6ae99SBarry Smith ly = dd->ly; 133147c6ae99SBarry Smith for (i=0; i<n; i++) { 133247c6ae99SBarry Smith ly[i] = N/n + ((N % n) > i); 133347c6ae99SBarry Smith } 133447c6ae99SBarry Smith } 133547c6ae99SBarry Smith y = ly[rank/m]; 133647c6ae99SBarry Smith ys = 0; 133747c6ae99SBarry Smith for (i=0; i<(rank/m); i++) { 133847c6ae99SBarry Smith ys += ly[i]; 133947c6ae99SBarry Smith } 134047c6ae99SBarry Smith #if defined(PETSC_USE_DEBUG) 134147c6ae99SBarry Smith left = ys; 134247c6ae99SBarry Smith for (i=(rank/m); i<n; i++) { 134347c6ae99SBarry Smith left += ly[i]; 134447c6ae99SBarry Smith } 134547c6ae99SBarry Smith if (left != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Sum of ly across processors not equal to N: %D %D",left,N); 134647c6ae99SBarry Smith #endif 134747c6ae99SBarry Smith 134847c6ae99SBarry Smith if (x < s) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local x-width of domain x %D is smaller than stencil width s %D",x,s); 134947c6ae99SBarry Smith if (y < s) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local y-width of domain y %D is smaller than stencil width s %D",y,s); 135047c6ae99SBarry Smith xe = xs + x; 135147c6ae99SBarry Smith ye = ys + y; 135247c6ae99SBarry Smith 1353*ce00eea3SSatish Balay /* determine ghost region (Xs) and region scattered into (IXs) */ 135447c6ae99SBarry Smith /* Assume No Periodicity */ 1355*ce00eea3SSatish Balay if (xs-s > 0) { Xs = xs - s; IXs = xs - s; } else { Xs = 0; IXs = 0; } 1356*ce00eea3SSatish Balay if (xe+s <= M) { Xe = xe + s; IXe = xe + s; } else { Xe = M; IXe = M; } 1357*ce00eea3SSatish Balay if (ys-s > 0) { Ys = ys - s; IYs = ys - s; } else { Ys = 0; IYs = 0; } 1358*ce00eea3SSatish Balay if (ye+s <= N) { Ye = ye + s; IYe = ye + s; } else { Ye = N; IYe = N; } 135947c6ae99SBarry Smith 1360*ce00eea3SSatish Balay /* fix for periodicity/ghosted */ 1361*ce00eea3SSatish Balay if (DMDAXGhosted(wrap)) { Xs = xs - s; Xe = xe + s; } 1362*ce00eea3SSatish Balay if (DMDAXPeriodic(wrap)) { IXs = xs - s; IXe = xe + s; } 1363*ce00eea3SSatish Balay if (DMDAYGhosted(wrap)) { Ys = ys - s; Ye = ye + s; } 1364*ce00eea3SSatish Balay if (DMDAYPeriodic(wrap)) { IYs = ys - s; IYe = ye + s; } 136547c6ae99SBarry Smith 136647c6ae99SBarry Smith /* Resize all X parameters to reflect w */ 1367*ce00eea3SSatish Balay s_x = s; 136847c6ae99SBarry Smith s_y = s; 136947c6ae99SBarry Smith 137047c6ae99SBarry Smith /* determine starting point of each processor */ 137147c6ae99SBarry Smith nn = x*y; 137247c6ae99SBarry Smith ierr = PetscMalloc2(size+1,PetscInt,&bases,size,PetscInt,&ldims);CHKERRQ(ierr); 137347c6ae99SBarry Smith ierr = MPI_Allgather(&nn,1,MPIU_INT,ldims,1,MPIU_INT,comm);CHKERRQ(ierr); 137447c6ae99SBarry Smith bases[0] = 0; 137547c6ae99SBarry Smith for (i=1; i<=size; i++) { 137647c6ae99SBarry Smith bases[i] = ldims[i-1]; 137747c6ae99SBarry Smith } 137847c6ae99SBarry Smith for (i=1; i<=size; i++) { 137947c6ae99SBarry Smith bases[i] += bases[i-1]; 138047c6ae99SBarry Smith } 1381*ce00eea3SSatish Balay base = bases[rank]*dof; 138247c6ae99SBarry Smith 138347c6ae99SBarry Smith /* allocate the base parallel and sequential vectors */ 1384*ce00eea3SSatish Balay dd->Nlocal = x*y*dof; 138547c6ae99SBarry Smith ierr = VecCreateMPIWithArray(comm,dd->Nlocal,PETSC_DECIDE,0,&global);CHKERRQ(ierr); 138647c6ae99SBarry Smith ierr = VecSetBlockSize(global,dof);CHKERRQ(ierr); 1387*ce00eea3SSatish Balay dd->nlocal = (Xe-Xs)*(Ye-Ys)*dof; 138847c6ae99SBarry Smith ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,dd->nlocal,0,&local);CHKERRQ(ierr); 138947c6ae99SBarry Smith ierr = VecSetBlockSize(local,dof);CHKERRQ(ierr); 139047c6ae99SBarry Smith 139147c6ae99SBarry Smith /* generate appropriate vector scatters */ 139247c6ae99SBarry Smith /* local to global inserts non-ghost point region into global */ 139347c6ae99SBarry Smith ierr = VecGetOwnershipRange(global,&start,&end);CHKERRQ(ierr); 1394*ce00eea3SSatish Balay ierr = ISCreateStride(comm,x*y*dof,start,1,&to);CHKERRQ(ierr); 139547c6ae99SBarry Smith 1396*ce00eea3SSatish Balay count_dbg = x*y; 1397*ce00eea3SSatish Balay ierr = PetscMalloc(x*y*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1398*ce00eea3SSatish Balay left = xs - Xs; right = left + x; 1399*ce00eea3SSatish Balay down = ys - Ys; up = down + y; 140047c6ae99SBarry Smith count = 0; 140147c6ae99SBarry Smith for (i=down; i<up; i++) { 1402*ce00eea3SSatish Balay for (j=left; j<right; j++) { 1403*ce00eea3SSatish Balay idx[count++] = i*(Xe-Xs) + j; 140447c6ae99SBarry Smith } 140547c6ae99SBarry Smith } 1406*ce00eea3SSatish Balay if (count != count_dbg) { 1407*ce00eea3SSatish Balay SETERRQ(((PetscObject)da)->comm, PETSC_ERR_SUP,"count != count_dbg"); 1408*ce00eea3SSatish Balay PetscFunctionReturn(1); 1409*ce00eea3SSatish Balay } 141047c6ae99SBarry Smith 1411*ce00eea3SSatish Balay ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&from);CHKERRQ(ierr); 141247c6ae99SBarry Smith ierr = VecScatterCreate(local,from,global,to,<og);CHKERRQ(ierr); 141347c6ae99SBarry Smith ierr = PetscLogObjectParent(dd,ltog);CHKERRQ(ierr); 141447c6ae99SBarry Smith ierr = ISDestroy(from);CHKERRQ(ierr); 141547c6ae99SBarry Smith ierr = ISDestroy(to);CHKERRQ(ierr); 141647c6ae99SBarry Smith 1417*ce00eea3SSatish Balay /* global to local must include ghost points within the domain, 1418*ce00eea3SSatish Balay but not ghost points outside the domain that aren't periodic */ 1419aa219208SBarry Smith if (stencil_type == DMDA_STENCIL_BOX) { 1420*ce00eea3SSatish Balay count_dbg = (IXe-IXs)*(IYe-IYs); 1421*ce00eea3SSatish Balay ierr = PetscMalloc(count_dbg*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1422*ce00eea3SSatish Balay 1423*ce00eea3SSatish Balay left = IXs - Xs; right = left + (IXe-IXs); 1424*ce00eea3SSatish Balay down = IYs - Ys; up = down + (IYe-IYs); 1425*ce00eea3SSatish Balay count = 0; 1426*ce00eea3SSatish Balay for (i=down; i<up; i++) { 1427*ce00eea3SSatish Balay for (j=left; j<right; j++) { 1428*ce00eea3SSatish Balay idx[count++] = j + i*(Xe-Xs); 1429*ce00eea3SSatish Balay } 1430*ce00eea3SSatish Balay } 1431*ce00eea3SSatish Balay if (count != count_dbg) { 1432*ce00eea3SSatish Balay SETERRQ(((PetscObject)da)->comm, PETSC_ERR_SUP,"count != count_dbg"); 1433*ce00eea3SSatish Balay PetscFunctionReturn(1); 1434*ce00eea3SSatish Balay } 1435*ce00eea3SSatish Balay ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&to);CHKERRQ(ierr); 1436*ce00eea3SSatish Balay 143747c6ae99SBarry Smith } else { 143847c6ae99SBarry Smith /* must drop into cross shape region */ 143947c6ae99SBarry Smith /* ---------| 144047c6ae99SBarry Smith | top | 1441*ce00eea3SSatish Balay |--- ---| up 144247c6ae99SBarry Smith | middle | 144347c6ae99SBarry Smith | | 1444*ce00eea3SSatish Balay ---- ---- down 144547c6ae99SBarry Smith | bottom | 144647c6ae99SBarry Smith ----------- 144747c6ae99SBarry Smith Xs xs xe Xe */ 1448*ce00eea3SSatish Balay count_dbg = (ys-IYs)*x + y*(IXe-IXs) + (IYe-ye)*x; 1449*ce00eea3SSatish Balay ierr = PetscMalloc(count_dbg*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1450*ce00eea3SSatish Balay 1451*ce00eea3SSatish Balay left = xs - Xs; right = left + x; 1452*ce00eea3SSatish Balay down = ys - Ys; up = down + y; 145347c6ae99SBarry Smith count = 0; 1454*ce00eea3SSatish Balay /* bottom */ 1455*ce00eea3SSatish Balay for (i=(IYs-Ys); i<down; i++) { 1456*ce00eea3SSatish Balay for (j=left; j<right; j++) { 1457*ce00eea3SSatish Balay idx[count++] = j + i*(Xe-Xs); 145847c6ae99SBarry Smith } 145947c6ae99SBarry Smith } 146047c6ae99SBarry Smith /* middle */ 146147c6ae99SBarry Smith for (i=down; i<up; i++) { 1462*ce00eea3SSatish Balay for (j=(IXs-Xs); j<(IXe-Xs); j++) { 1463*ce00eea3SSatish Balay idx[count++] = j + i*(Xe-Xs); 146447c6ae99SBarry Smith } 146547c6ae99SBarry Smith } 146647c6ae99SBarry Smith /* top */ 1467*ce00eea3SSatish Balay for (i=up; i<up+IYe-ye; i++) { 1468*ce00eea3SSatish Balay for (j=left; j<right; j++) { 1469*ce00eea3SSatish Balay idx[count++] = j + i*(Xe-Xs); 147047c6ae99SBarry Smith } 147147c6ae99SBarry Smith } 1472*ce00eea3SSatish Balay if (count != count_dbg) { 1473*ce00eea3SSatish Balay SETERRQ(((PetscObject)da)->comm, PETSC_ERR_SUP,"count != count_dbg"); 1474*ce00eea3SSatish Balay PetscFunctionReturn(1); 1475*ce00eea3SSatish Balay } 147647c6ae99SBarry Smith ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&to);CHKERRQ(ierr); 147747c6ae99SBarry Smith } 147847c6ae99SBarry Smith 147947c6ae99SBarry Smith 148047c6ae99SBarry Smith /* determine who lies on each side of us stored in n6 n7 n8 148147c6ae99SBarry Smith n3 n5 148247c6ae99SBarry Smith n0 n1 n2 148347c6ae99SBarry Smith */ 148447c6ae99SBarry Smith 148547c6ae99SBarry Smith /* Assume the Non-Periodic Case */ 148647c6ae99SBarry Smith n1 = rank - m; 148747c6ae99SBarry Smith if (rank % m) { 148847c6ae99SBarry Smith n0 = n1 - 1; 148947c6ae99SBarry Smith } else { 149047c6ae99SBarry Smith n0 = -1; 149147c6ae99SBarry Smith } 149247c6ae99SBarry Smith if ((rank+1) % m) { 149347c6ae99SBarry Smith n2 = n1 + 1; 149447c6ae99SBarry Smith n5 = rank + 1; 149547c6ae99SBarry Smith n8 = rank + m + 1; if (n8 >= m*n) n8 = -1; 149647c6ae99SBarry Smith } else { 149747c6ae99SBarry Smith n2 = -1; n5 = -1; n8 = -1; 149847c6ae99SBarry Smith } 149947c6ae99SBarry Smith if (rank % m) { 150047c6ae99SBarry Smith n3 = rank - 1; 150147c6ae99SBarry Smith n6 = n3 + m; if (n6 >= m*n) n6 = -1; 150247c6ae99SBarry Smith } else { 150347c6ae99SBarry Smith n3 = -1; n6 = -1; 150447c6ae99SBarry Smith } 150547c6ae99SBarry Smith n7 = rank + m; if (n7 >= m*n) n7 = -1; 150647c6ae99SBarry Smith 1507*ce00eea3SSatish Balay if (DMDAXPeriodic(wrap) && DMDAYPeriodic(wrap)) { 150847c6ae99SBarry Smith /* Modify for Periodic Cases */ 150947c6ae99SBarry Smith /* Handle all four corners */ 151047c6ae99SBarry Smith if ((n6 < 0) && (n7 < 0) && (n3 < 0)) n6 = m-1; 151147c6ae99SBarry Smith if ((n8 < 0) && (n7 < 0) && (n5 < 0)) n8 = 0; 151247c6ae99SBarry Smith if ((n2 < 0) && (n5 < 0) && (n1 < 0)) n2 = size-m; 151347c6ae99SBarry Smith if ((n0 < 0) && (n3 < 0) && (n1 < 0)) n0 = size-1; 151447c6ae99SBarry Smith 151547c6ae99SBarry Smith /* Handle Top and Bottom Sides */ 151647c6ae99SBarry Smith if (n1 < 0) n1 = rank + m * (n-1); 151747c6ae99SBarry Smith if (n7 < 0) n7 = rank - m * (n-1); 151847c6ae99SBarry Smith if ((n3 >= 0) && (n0 < 0)) n0 = size - m + rank - 1; 151947c6ae99SBarry Smith if ((n3 >= 0) && (n6 < 0)) n6 = (rank%m)-1; 152047c6ae99SBarry Smith if ((n5 >= 0) && (n2 < 0)) n2 = size - m + rank + 1; 152147c6ae99SBarry Smith if ((n5 >= 0) && (n8 < 0)) n8 = (rank%m)+1; 152247c6ae99SBarry Smith 152347c6ae99SBarry Smith /* Handle Left and Right Sides */ 152447c6ae99SBarry Smith if (n3 < 0) n3 = rank + (m-1); 152547c6ae99SBarry Smith if (n5 < 0) n5 = rank - (m-1); 152647c6ae99SBarry Smith if ((n1 >= 0) && (n0 < 0)) n0 = rank-1; 152747c6ae99SBarry Smith if ((n1 >= 0) && (n2 < 0)) n2 = rank-2*m+1; 152847c6ae99SBarry Smith if ((n7 >= 0) && (n6 < 0)) n6 = rank+2*m-1; 152947c6ae99SBarry Smith if ((n7 >= 0) && (n8 < 0)) n8 = rank+1; 1530*ce00eea3SSatish Balay } else if (DMDAYPeriodic(wrap)) { /* Handle Top and Bottom Sides */ 1531*ce00eea3SSatish Balay if (n1 < 0) n1 = rank + m * (n-1); 1532*ce00eea3SSatish Balay if (n7 < 0) n7 = rank - m * (n-1); 1533*ce00eea3SSatish Balay if ((n3 >= 0) && (n0 < 0)) n0 = size - m + rank - 1; 1534*ce00eea3SSatish Balay if ((n3 >= 0) && (n6 < 0)) n6 = (rank%m)-1; 1535*ce00eea3SSatish Balay if ((n5 >= 0) && (n2 < 0)) n2 = size - m + rank + 1; 1536*ce00eea3SSatish Balay if ((n5 >= 0) && (n8 < 0)) n8 = (rank%m)+1; 1537*ce00eea3SSatish Balay } else if (DMDAXPeriodic(wrap)) { /* Handle Left and Right Sides */ 1538*ce00eea3SSatish Balay if (n3 < 0) n3 = rank + (m-1); 1539*ce00eea3SSatish Balay if (n5 < 0) n5 = rank - (m-1); 1540*ce00eea3SSatish Balay if ((n1 >= 0) && (n0 < 0)) n0 = rank-1; 1541*ce00eea3SSatish Balay if ((n1 >= 0) && (n2 < 0)) n2 = rank-2*m+1; 1542*ce00eea3SSatish Balay if ((n7 >= 0) && (n6 < 0)) n6 = rank+2*m-1; 1543*ce00eea3SSatish Balay if ((n7 >= 0) && (n8 < 0)) n8 = rank+1; 154447c6ae99SBarry Smith } 1545*ce00eea3SSatish Balay 154647c6ae99SBarry Smith ierr = PetscMalloc(9*sizeof(PetscInt),&dd->neighbors);CHKERRQ(ierr); 154747c6ae99SBarry Smith dd->neighbors[0] = n0; 154847c6ae99SBarry Smith dd->neighbors[1] = n1; 154947c6ae99SBarry Smith dd->neighbors[2] = n2; 155047c6ae99SBarry Smith dd->neighbors[3] = n3; 155147c6ae99SBarry Smith dd->neighbors[4] = rank; 155247c6ae99SBarry Smith dd->neighbors[5] = n5; 155347c6ae99SBarry Smith dd->neighbors[6] = n6; 155447c6ae99SBarry Smith dd->neighbors[7] = n7; 155547c6ae99SBarry Smith dd->neighbors[8] = n8; 155647c6ae99SBarry Smith 1557aa219208SBarry Smith if (stencil_type == DMDA_STENCIL_STAR) { 155847c6ae99SBarry Smith /* save corner processor numbers */ 155947c6ae99SBarry Smith sn0 = n0; sn2 = n2; sn6 = n6; sn8 = n8; 156047c6ae99SBarry Smith n0 = n2 = n6 = n8 = -1; 156147c6ae99SBarry Smith } 156247c6ae99SBarry Smith 1563*ce00eea3SSatish Balay ierr = PetscMalloc((Xe-Xs)*(Ye-Ys)*sizeof(PetscInt),&idx);CHKERRQ(ierr); 1564*ce00eea3SSatish Balay ierr = PetscLogObjectMemory(da,(Xe-Xs)*(Ye-Ys)*sizeof(PetscInt));CHKERRQ(ierr); 156547c6ae99SBarry Smith 1566*ce00eea3SSatish Balay nn = 0; 156747c6ae99SBarry Smith xbase = bases[rank]; 156847c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 156947c6ae99SBarry Smith if (n0 >= 0) { /* left below */ 1570*ce00eea3SSatish Balay x_t = lx[n0 % m]; 157147c6ae99SBarry Smith y_t = ly[(n0/m)]; 157247c6ae99SBarry Smith s_t = bases[n0] + x_t*y_t - (s_y-i)*x_t - s_x; 157347c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 157447c6ae99SBarry Smith } 157547c6ae99SBarry Smith if (n1 >= 0) { /* directly below */ 157647c6ae99SBarry Smith x_t = x; 157747c6ae99SBarry Smith y_t = ly[(n1/m)]; 157847c6ae99SBarry Smith s_t = bases[n1] + x_t*y_t - (s_y+1-i)*x_t; 157947c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 158047c6ae99SBarry Smith } 158147c6ae99SBarry Smith if (n2 >= 0) { /* right below */ 1582*ce00eea3SSatish Balay x_t = lx[n2 % m]; 158347c6ae99SBarry Smith y_t = ly[(n2/m)]; 158447c6ae99SBarry Smith s_t = bases[n2] + x_t*y_t - (s_y+1-i)*x_t; 158547c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 158647c6ae99SBarry Smith } 158747c6ae99SBarry Smith } 158847c6ae99SBarry Smith 158947c6ae99SBarry Smith for (i=0; i<y; i++) { 159047c6ae99SBarry Smith if (n3 >= 0) { /* directly left */ 1591*ce00eea3SSatish Balay x_t = lx[n3 % m]; 159247c6ae99SBarry Smith /* y_t = y; */ 159347c6ae99SBarry Smith s_t = bases[n3] + (i+1)*x_t - s_x; 159447c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 159547c6ae99SBarry Smith } 159647c6ae99SBarry Smith 159747c6ae99SBarry Smith for (j=0; j<x; j++) { idx[nn++] = xbase++; } /* interior */ 159847c6ae99SBarry Smith 159947c6ae99SBarry Smith if (n5 >= 0) { /* directly right */ 1600*ce00eea3SSatish Balay x_t = lx[n5 % m]; 160147c6ae99SBarry Smith /* y_t = y; */ 160247c6ae99SBarry Smith s_t = bases[n5] + (i)*x_t; 160347c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 160447c6ae99SBarry Smith } 160547c6ae99SBarry Smith } 160647c6ae99SBarry Smith 160747c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 160847c6ae99SBarry Smith if (n6 >= 0) { /* left above */ 1609*ce00eea3SSatish Balay x_t = lx[n6 % m]; 161047c6ae99SBarry Smith /* y_t = ly[(n6/m)]; */ 161147c6ae99SBarry Smith s_t = bases[n6] + (i)*x_t - s_x; 161247c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 161347c6ae99SBarry Smith } 161447c6ae99SBarry Smith if (n7 >= 0) { /* directly above */ 161547c6ae99SBarry Smith x_t = x; 161647c6ae99SBarry Smith /* y_t = ly[(n7/m)]; */ 161747c6ae99SBarry Smith s_t = bases[n7] + (i-1)*x_t; 161847c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 161947c6ae99SBarry Smith } 162047c6ae99SBarry Smith if (n8 >= 0) { /* right above */ 1621*ce00eea3SSatish Balay x_t = lx[n8 % m]; 162247c6ae99SBarry Smith /* y_t = ly[(n8/m)]; */ 162347c6ae99SBarry Smith s_t = bases[n8] + (i-1)*x_t; 162447c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 162547c6ae99SBarry Smith } 162647c6ae99SBarry Smith } 162747c6ae99SBarry Smith 1628*ce00eea3SSatish Balay ierr = ISCreateBlock(comm,dof,nn,idx,PETSC_COPY_VALUES,&from);CHKERRQ(ierr); 162947c6ae99SBarry Smith ierr = VecScatterCreate(global,from,local,to,>ol);CHKERRQ(ierr); 163047c6ae99SBarry Smith ierr = PetscLogObjectParent(da,gtol);CHKERRQ(ierr); 163147c6ae99SBarry Smith ierr = ISDestroy(to);CHKERRQ(ierr); 163247c6ae99SBarry Smith ierr = ISDestroy(from);CHKERRQ(ierr); 163347c6ae99SBarry Smith 1634aa219208SBarry Smith if (stencil_type == DMDA_STENCIL_STAR) { 1635*ce00eea3SSatish Balay n0 = sn0; n2 = sn2; n6 = sn6; n8 = sn8; 1636*ce00eea3SSatish Balay } 1637*ce00eea3SSatish Balay 1638*ce00eea3SSatish Balay if ((stencil_type == DMDA_STENCIL_STAR) || 1639*ce00eea3SSatish Balay (!DMDAXPeriodic(wrap) && DMDAXGhosted(wrap)) || 1640*ce00eea3SSatish Balay (!DMDAYPeriodic(wrap) && DMDAYGhosted(wrap))) { 164147c6ae99SBarry Smith /* 164247c6ae99SBarry Smith Recompute the local to global mappings, this time keeping the 1643*ce00eea3SSatish Balay information about the cross corner processor numbers and any ghosted 1644*ce00eea3SSatish Balay but not periodic indices. 164547c6ae99SBarry Smith */ 164647c6ae99SBarry Smith nn = 0; 164747c6ae99SBarry Smith xbase = bases[rank]; 164847c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 164947c6ae99SBarry Smith if (n0 >= 0) { /* left below */ 1650*ce00eea3SSatish Balay x_t = lx[n0 % m]; 165147c6ae99SBarry Smith y_t = ly[(n0/m)]; 165247c6ae99SBarry Smith s_t = bases[n0] + x_t*y_t - (s_y-i)*x_t - s_x; 165347c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 1654*ce00eea3SSatish Balay } else if (xs-Xs > 0 && ys-Ys > 0) { 1655*ce00eea3SSatish Balay for (j=0; j<s_x; j++) { idx[nn++] = -1;} 165647c6ae99SBarry Smith } 165747c6ae99SBarry Smith if (n1 >= 0) { /* directly below */ 165847c6ae99SBarry Smith x_t = x; 165947c6ae99SBarry Smith y_t = ly[(n1/m)]; 166047c6ae99SBarry Smith s_t = bases[n1] + x_t*y_t - (s_y+1-i)*x_t; 166147c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 1662*ce00eea3SSatish Balay } else if (ys-Ys > 0) { 1663*ce00eea3SSatish Balay for (j=0; j<x; j++) { idx[nn++] = -1;} 166447c6ae99SBarry Smith } 166547c6ae99SBarry Smith if (n2 >= 0) { /* right below */ 1666*ce00eea3SSatish Balay x_t = lx[n2 % m]; 166747c6ae99SBarry Smith y_t = ly[(n2/m)]; 166847c6ae99SBarry Smith s_t = bases[n2] + x_t*y_t - (s_y+1-i)*x_t; 166947c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 1670*ce00eea3SSatish Balay } else if (Xe-xe> 0 && ys-Ys > 0) { 1671*ce00eea3SSatish Balay for (j=0; j<s_x; j++) { idx[nn++] = -1;} 167247c6ae99SBarry Smith } 167347c6ae99SBarry Smith } 167447c6ae99SBarry Smith 167547c6ae99SBarry Smith for (i=0; i<y; i++) { 167647c6ae99SBarry Smith if (n3 >= 0) { /* directly left */ 1677*ce00eea3SSatish Balay x_t = lx[n3 % m]; 167847c6ae99SBarry Smith /* y_t = y; */ 167947c6ae99SBarry Smith s_t = bases[n3] + (i+1)*x_t - s_x; 168047c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 1681*ce00eea3SSatish Balay } else if (xs-Xs > 0) { 1682*ce00eea3SSatish Balay for (j=0; j<s_x; j++) { idx[nn++] = -1;} 168347c6ae99SBarry Smith } 168447c6ae99SBarry Smith 168547c6ae99SBarry Smith for (j=0; j<x; j++) { idx[nn++] = xbase++; } /* interior */ 168647c6ae99SBarry Smith 168747c6ae99SBarry Smith if (n5 >= 0) { /* directly right */ 1688*ce00eea3SSatish Balay x_t = lx[n5 % m]; 168947c6ae99SBarry Smith /* y_t = y; */ 169047c6ae99SBarry Smith s_t = bases[n5] + (i)*x_t; 169147c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 1692*ce00eea3SSatish Balay } else if (Xe-xe > 0) { 1693*ce00eea3SSatish Balay for (j=0; j<s_x; j++) { idx[nn++] = -1;} 169447c6ae99SBarry Smith } 169547c6ae99SBarry Smith } 169647c6ae99SBarry Smith 169747c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 169847c6ae99SBarry Smith if (n6 >= 0) { /* left above */ 1699*ce00eea3SSatish Balay x_t = lx[n6 % m]; 170047c6ae99SBarry Smith /* y_t = ly[(n6/m)]; */ 170147c6ae99SBarry Smith s_t = bases[n6] + (i)*x_t - s_x; 170247c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 1703*ce00eea3SSatish Balay } else if (xs-Xs > 0 && Ye-ye > 0) { 1704*ce00eea3SSatish Balay for (j=0; j<s_x; j++) { idx[nn++] = -1;} 170547c6ae99SBarry Smith } 170647c6ae99SBarry Smith if (n7 >= 0) { /* directly above */ 170747c6ae99SBarry Smith x_t = x; 170847c6ae99SBarry Smith /* y_t = ly[(n7/m)]; */ 170947c6ae99SBarry Smith s_t = bases[n7] + (i-1)*x_t; 171047c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 1711*ce00eea3SSatish Balay } else if (Ye-ye > 0) { 1712*ce00eea3SSatish Balay for (j=0; j<x; j++) { idx[nn++] = -1;} 171347c6ae99SBarry Smith } 171447c6ae99SBarry Smith if (n8 >= 0) { /* right above */ 1715*ce00eea3SSatish Balay x_t = lx[n8 % m]; 171647c6ae99SBarry Smith /* y_t = ly[(n8/m)]; */ 171747c6ae99SBarry Smith s_t = bases[n8] + (i-1)*x_t; 171847c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 1719*ce00eea3SSatish Balay } else if (Xe-xe > 0 && Ye-ye > 0) { 1720*ce00eea3SSatish Balay for (j=0; j<s_x; j++) { idx[nn++] = -1;} 172147c6ae99SBarry Smith } 172247c6ae99SBarry Smith } 172347c6ae99SBarry Smith } 1724*ce00eea3SSatish Balay /* 1725*ce00eea3SSatish Balay Set the local to global ordering in the global vector, this allows use 1726*ce00eea3SSatish Balay of VecSetValuesLocal(). 1727*ce00eea3SSatish Balay */ 1728*ce00eea3SSatish Balay if (nn != (Xe-Xs)*(Ye-Ys)) { 1729*ce00eea3SSatish Balay SETERRQ(((PetscObject)da)->comm, PETSC_ERR_SUP,"nn != count_dbg"); 1730*ce00eea3SSatish Balay PetscFunctionReturn(1); 1731*ce00eea3SSatish Balay } 1732*ce00eea3SSatish Balay ierr = ISCreateBlock(comm,dof,nn,idx,PETSC_OWN_POINTER,<ogis);CHKERRQ(ierr); 1733*ce00eea3SSatish Balay ierr = PetscMalloc(nn*dof*sizeof(PetscInt),&idx_cpy);CHKERRQ(ierr); 1734*ce00eea3SSatish Balay /* ierr = PetscLogObjectMemory(da,nn*dof*sizeof(PetscInt));CHKERRQ(ierr);*/ 1735*ce00eea3SSatish Balay ierr = ISGetIndices(ltogis, &idx_full); 1736*ce00eea3SSatish Balay ierr = PetscMemcpy(idx_cpy,idx_full,nn*dof*sizeof(PetscInt));CHKERRQ(ierr); 1737*ce00eea3SSatish Balay CHKMEMQ; 1738*ce00eea3SSatish Balay ierr = ISRestoreIndices(ltogis, &idx_full); 1739*ce00eea3SSatish Balay ierr = ISLocalToGlobalMappingCreateIS(ltogis,&da->ltogmap);CHKERRQ(ierr); 1740*ce00eea3SSatish Balay ierr = PetscLogObjectParent(da,da->ltogmap);CHKERRQ(ierr); 1741*ce00eea3SSatish Balay ierr = ISDestroy(ltogis);CHKERRQ(ierr); 1742*ce00eea3SSatish Balay ierr = ISLocalToGlobalMappingBlock(da->ltogmap,dd->w,&da->ltogmapb);CHKERRQ(ierr); 1743*ce00eea3SSatish Balay ierr = PetscLogObjectParent(da,da->ltogmap);CHKERRQ(ierr); 174447c6ae99SBarry Smith 1745*ce00eea3SSatish Balay ierr = PetscFree2(bases,ldims);CHKERRQ(ierr); 174647c6ae99SBarry Smith dd->m = m; dd->n = n; 1747*ce00eea3SSatish Balay /* note petsc expects xs/xe/Xs/Xe to be multiplied by #dofs in many places */ 1748*ce00eea3SSatish Balay dd->xs = xs*dof; dd->xe = xe*dof; dd->ys = ys; dd->ye = ye; dd->zs = 0; dd->ze = 1; 1749*ce00eea3SSatish Balay dd->Xs = Xs*dof; dd->Xe = Xe*dof; dd->Ys = Ys; dd->Ye = Ye; dd->Zs = 0; dd->Ze = 1; 175047c6ae99SBarry Smith 175147c6ae99SBarry Smith ierr = VecDestroy(local);CHKERRQ(ierr); 175247c6ae99SBarry Smith ierr = VecDestroy(global);CHKERRQ(ierr); 175347c6ae99SBarry Smith 175447c6ae99SBarry Smith dd->gtol = gtol; 175547c6ae99SBarry Smith dd->ltog = ltog; 1756*ce00eea3SSatish Balay dd->idx = idx_cpy; 1757*ce00eea3SSatish Balay dd->Nl = nn*dof; 175847c6ae99SBarry Smith dd->base = base; 17599a42bb27SBarry Smith da->ops->view = DMView_DA_2d; 176047c6ae99SBarry Smith dd->ltol = PETSC_NULL; 176147c6ae99SBarry Smith dd->ao = PETSC_NULL; 176247c6ae99SBarry Smith 176347c6ae99SBarry Smith PetscFunctionReturn(0); 176447c6ae99SBarry Smith } 176547c6ae99SBarry Smith 176647c6ae99SBarry Smith #undef __FUNCT__ 1767aa219208SBarry Smith #define __FUNCT__ "DMDACreate2d" 176847c6ae99SBarry Smith /*@C 1769aa219208SBarry Smith DMDACreate2d - Creates an object that will manage the communication of two-dimensional 177047c6ae99SBarry Smith regular array data that is distributed across some processors. 177147c6ae99SBarry Smith 177247c6ae99SBarry Smith Collective on MPI_Comm 177347c6ae99SBarry Smith 177447c6ae99SBarry Smith Input Parameters: 177547c6ae99SBarry Smith + comm - MPI communicator 177647c6ae99SBarry Smith . wrap - type of periodicity should the array have. 1777aa219208SBarry Smith Use one of DMDA_NONPERIODIC, DMDA_XPERIODIC, DMDA_YPERIODIC, or DMDA_XYPERIODIC. 1778aa219208SBarry Smith . stencil_type - stencil type. Use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR. 177947c6ae99SBarry Smith . M,N - global dimension in each direction of the array (use -M and or -N to indicate that it may be set to a different value 178047c6ae99SBarry Smith from the command line with -da_grid_x <M> -da_grid_y <N>) 178147c6ae99SBarry Smith . m,n - corresponding number of processors in each dimension 178247c6ae99SBarry Smith (or PETSC_DECIDE to have calculated) 178347c6ae99SBarry Smith . dof - number of degrees of freedom per node 178447c6ae99SBarry Smith . s - stencil width 178547c6ae99SBarry Smith - lx, ly - arrays containing the number of nodes in each cell along 178647c6ae99SBarry Smith the x and y coordinates, or PETSC_NULL. If non-null, these 178747c6ae99SBarry Smith must be of length as m and n, and the corresponding 178847c6ae99SBarry Smith m and n cannot be PETSC_DECIDE. The sum of the lx[] entries 178947c6ae99SBarry Smith must be M, and the sum of the ly[] entries must be N. 179047c6ae99SBarry Smith 179147c6ae99SBarry Smith Output Parameter: 179247c6ae99SBarry Smith . da - the resulting distributed array object 179347c6ae99SBarry Smith 179447c6ae99SBarry Smith Options Database Key: 1795aa219208SBarry Smith + -da_view - Calls DMView() at the conclusion of DMDACreate2d() 179647c6ae99SBarry Smith . -da_grid_x <nx> - number of grid points in x direction, if M < 0 179747c6ae99SBarry Smith . -da_grid_y <ny> - number of grid points in y direction, if N < 0 179847c6ae99SBarry Smith . -da_processors_x <nx> - number of processors in x direction 179947c6ae99SBarry Smith . -da_processors_y <ny> - number of processors in y direction 180047c6ae99SBarry Smith . -da_refine_x - refinement ratio in x direction 180147c6ae99SBarry Smith - -da_refine_y - refinement ratio in y direction 180247c6ae99SBarry Smith 180347c6ae99SBarry Smith Level: beginner 180447c6ae99SBarry Smith 180547c6ae99SBarry Smith Notes: 1806aa219208SBarry Smith The stencil type DMDA_STENCIL_STAR with width 1 corresponds to the 1807aa219208SBarry Smith standard 5-pt stencil, while DMDA_STENCIL_BOX with width 1 denotes 180847c6ae99SBarry Smith the standard 9-pt stencil. 180947c6ae99SBarry Smith 1810aa219208SBarry Smith The array data itself is NOT stored in the DMDA, it is stored in Vec objects; 1811564755cdSBarry Smith The appropriate vector objects can be obtained with calls to DMCreateGlobalVector() 1812564755cdSBarry Smith and DMCreateLocalVector() and calls to VecDuplicate() if more are needed. 181347c6ae99SBarry Smith 181447c6ae99SBarry Smith .keywords: distributed array, create, two-dimensional 181547c6ae99SBarry Smith 1816aa219208SBarry Smith .seealso: DMDestroy(), DMView(), DMDACreate1d(), DMDACreate3d(), DMGlobalToLocalBegin(), DMDAGetRefinementFactor(), 1817aa219208SBarry Smith DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMDALocalToLocalBegin(), DMDALocalToLocalEnd(), DMDASetRefinementFactor(), 1818aa219208SBarry Smith DMDAGetInfo(), DMCreateGlobalVector(), DMCreateLocalVector(), DMDACreateNaturalVector(), DMDALoad(), DMDAGetOwnershipRanges() 181947c6ae99SBarry Smith 182047c6ae99SBarry Smith @*/ 18217087cfbeSBarry Smith PetscErrorCode DMDACreate2d(MPI_Comm comm,DMDAPeriodicType wrap,DMDAStencilType stencil_type, 18229a42bb27SBarry Smith PetscInt M,PetscInt N,PetscInt m,PetscInt n,PetscInt dof,PetscInt s,const PetscInt lx[],const PetscInt ly[],DM *da) 182347c6ae99SBarry Smith { 182447c6ae99SBarry Smith PetscErrorCode ierr; 182547c6ae99SBarry Smith 182647c6ae99SBarry Smith PetscFunctionBegin; 1827aa219208SBarry Smith ierr = DMDACreate(comm, da);CHKERRQ(ierr); 1828aa219208SBarry Smith ierr = DMDASetDim(*da, 2);CHKERRQ(ierr); 1829aa219208SBarry Smith ierr = DMDASetSizes(*da, M, N, 1);CHKERRQ(ierr); 1830aa219208SBarry Smith ierr = DMDASetNumProcs(*da, m, n, PETSC_DECIDE);CHKERRQ(ierr); 1831aa219208SBarry Smith ierr = DMDASetPeriodicity(*da, wrap);CHKERRQ(ierr); 1832aa219208SBarry Smith ierr = DMDASetDof(*da, dof);CHKERRQ(ierr); 1833aa219208SBarry Smith ierr = DMDASetStencilType(*da, stencil_type);CHKERRQ(ierr); 1834aa219208SBarry Smith ierr = DMDASetStencilWidth(*da, s);CHKERRQ(ierr); 1835aa219208SBarry Smith ierr = DMDASetOwnershipRanges(*da, lx, ly, PETSC_NULL);CHKERRQ(ierr); 183647c6ae99SBarry Smith /* This violates the behavior for other classes, but right now users expect negative dimensions to be handled this way */ 18379a42bb27SBarry Smith ierr = DMSetFromOptions(*da);CHKERRQ(ierr); 18389a42bb27SBarry Smith ierr = DMSetUp(*da);CHKERRQ(ierr); 18397242296bSJed Brown ierr = DMView_DA_Private(*da);CHKERRQ(ierr); 184047c6ae99SBarry Smith PetscFunctionReturn(0); 184147c6ae99SBarry Smith } 1842