1*9a42bb27SBarry Smith 247c6ae99SBarry Smith #define PETSCDM_DLL 347c6ae99SBarry Smith 447c6ae99SBarry Smith #include "private/daimpl.h" /*I "petscda.h" I*/ 547c6ae99SBarry Smith 647c6ae99SBarry Smith #undef __FUNCT__ 7*9a42bb27SBarry Smith #define __FUNCT__ "DMView_DA_2d" 8*9a42bb27SBarry Smith PetscErrorCode DMView_DA_2d(DM da,PetscViewer viewer) 947c6ae99SBarry Smith { 1047c6ae99SBarry Smith PetscErrorCode ierr; 1147c6ae99SBarry Smith PetscMPIInt rank; 12*9a42bb27SBarry Smith PetscBool iascii,isdraw,isbinary; 1347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 14*9a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 15*9a42bb27SBarry Smith PetscBool ismatlab; 16*9a42bb27SBarry 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); 23*9a42bb27SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 24*9a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 25*9a42bb27SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERMATLAB,&ismatlab);CHKERRQ(ierr); 26*9a42bb27SBarry 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) { 3247c6ae99SBarry Smith DALocalInfo info; 3347c6ae99SBarry Smith ierr = DAGetLocalInfo(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); 3747c6ae99SBarry Smith } 3847c6ae99SBarry Smith } else if (isdraw) { 3947c6ae99SBarry Smith PetscDraw draw; 4047c6ae99SBarry Smith double ymin = -1*dd->s-1,ymax = dd->N+dd->s; 4147c6ae99SBarry Smith double xmin = -1*dd->s-1,xmax = dd->M+dd->s; 4247c6ae99SBarry Smith double x,y; 4347c6ae99SBarry Smith PetscInt base,*idx; 4447c6ae99SBarry Smith char node[10]; 4547c6ae99SBarry Smith PetscBool isnull; 4647c6ae99SBarry Smith 4747c6ae99SBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 4847c6ae99SBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); 4947c6ae99SBarry Smith if (!dd->coordinates) { 5047c6ae99SBarry Smith ierr = PetscDrawSetCoordinates(draw,xmin,ymin,xmax,ymax);CHKERRQ(ierr); 5147c6ae99SBarry Smith } 5247c6ae99SBarry Smith ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr); 5347c6ae99SBarry Smith 5447c6ae99SBarry Smith /* first processor draw all node lines */ 5547c6ae99SBarry Smith if (!rank) { 5647c6ae99SBarry Smith ymin = 0.0; ymax = dd->N - 1; 5747c6ae99SBarry Smith for (xmin=0; xmin<dd->M; xmin++) { 5847c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_BLACK);CHKERRQ(ierr); 5947c6ae99SBarry Smith } 6047c6ae99SBarry Smith xmin = 0.0; xmax = dd->M - 1; 6147c6ae99SBarry Smith for (ymin=0; ymin<dd->N; ymin++) { 6247c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_BLACK);CHKERRQ(ierr); 6347c6ae99SBarry Smith } 6447c6ae99SBarry Smith } 6547c6ae99SBarry Smith ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 6647c6ae99SBarry Smith ierr = PetscDrawPause(draw);CHKERRQ(ierr); 6747c6ae99SBarry Smith 6847c6ae99SBarry Smith /* draw my box */ 6947c6ae99SBarry Smith ymin = dd->ys; ymax = dd->ye - 1; xmin = dd->xs/dd->w; 7047c6ae99SBarry Smith xmax =(dd->xe-1)/dd->w; 7147c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_RED);CHKERRQ(ierr); 7247c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_RED);CHKERRQ(ierr); 7347c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmin,ymax,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr); 7447c6ae99SBarry Smith ierr = PetscDrawLine(draw,xmax,ymin,xmax,ymax,PETSC_DRAW_RED);CHKERRQ(ierr); 7547c6ae99SBarry Smith 7647c6ae99SBarry Smith /* put in numbers */ 7747c6ae99SBarry Smith base = (dd->base)/dd->w; 7847c6ae99SBarry Smith for (y=ymin; y<=ymax; y++) { 7947c6ae99SBarry Smith for (x=xmin; x<=xmax; x++) { 8047c6ae99SBarry Smith sprintf(node,"%d",(int)base++); 8147c6ae99SBarry Smith ierr = PetscDrawString(draw,x,y,PETSC_DRAW_BLACK,node);CHKERRQ(ierr); 8247c6ae99SBarry Smith } 8347c6ae99SBarry Smith } 8447c6ae99SBarry Smith 8547c6ae99SBarry Smith ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 8647c6ae99SBarry Smith ierr = PetscDrawPause(draw);CHKERRQ(ierr); 8747c6ae99SBarry Smith /* overlay ghost numbers, useful for error checking */ 8847c6ae99SBarry Smith /* put in numbers */ 8947c6ae99SBarry Smith 9047c6ae99SBarry Smith base = 0; idx = dd->idx; 9147c6ae99SBarry Smith ymin = dd->Ys; ymax = dd->Ye; xmin = dd->Xs; xmax = dd->Xe; 9247c6ae99SBarry Smith for (y=ymin; y<ymax; y++) { 9347c6ae99SBarry Smith for (x=xmin; x<xmax; x++) { 9447c6ae99SBarry Smith if ((base % dd->w) == 0) { 9547c6ae99SBarry Smith sprintf(node,"%d",(int)(idx[base]/dd->w)); 9647c6ae99SBarry Smith ierr = PetscDrawString(draw,x/dd->w,y,PETSC_DRAW_BLUE,node);CHKERRQ(ierr); 9747c6ae99SBarry Smith } 9847c6ae99SBarry Smith base++; 9947c6ae99SBarry Smith } 10047c6ae99SBarry Smith } 10147c6ae99SBarry Smith ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 10247c6ae99SBarry Smith ierr = PetscDrawPause(draw);CHKERRQ(ierr); 103*9a42bb27SBarry Smith } else if (isbinary){ 104*9a42bb27SBarry Smith ierr = DMView_DA_Binary(da,viewer);CHKERRQ(ierr); 105*9a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 106*9a42bb27SBarry Smith } else if (ismatlab) { 107*9a42bb27SBarry Smith ierr = DMView_DA_Matlab(da,viewer);CHKERRQ(ierr); 108*9a42bb27SBarry Smith #endif 109*9a42bb27SBarry Smith } else SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for DA 1d",((PetscObject)viewer)->type_name); 11047c6ae99SBarry Smith PetscFunctionReturn(0); 11147c6ae99SBarry Smith } 11247c6ae99SBarry Smith 11347c6ae99SBarry Smith /* 11447c6ae99SBarry Smith M is number of grid points 11547c6ae99SBarry Smith m is number of processors 11647c6ae99SBarry Smith 11747c6ae99SBarry Smith */ 11847c6ae99SBarry Smith #undef __FUNCT__ 11947c6ae99SBarry Smith #define __FUNCT__ "DASplitComm2d" 12047c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASplitComm2d(MPI_Comm comm,PetscInt M,PetscInt N,PetscInt sw,MPI_Comm *outcomm) 12147c6ae99SBarry Smith { 12247c6ae99SBarry Smith PetscErrorCode ierr; 12347c6ae99SBarry Smith PetscInt m,n = 0,x = 0,y = 0; 12447c6ae99SBarry Smith PetscMPIInt size,csize,rank; 12547c6ae99SBarry Smith 12647c6ae99SBarry Smith PetscFunctionBegin; 12747c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 12847c6ae99SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 12947c6ae99SBarry Smith 13047c6ae99SBarry Smith csize = 4*size; 13147c6ae99SBarry Smith do { 13247c6ae99SBarry 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); 13347c6ae99SBarry Smith csize = csize/4; 13447c6ae99SBarry Smith 13547c6ae99SBarry Smith m = (PetscInt)(0.5 + sqrt(((double)M)*((double)csize)/((double)N))); 13647c6ae99SBarry Smith if (!m) m = 1; 13747c6ae99SBarry Smith while (m > 0) { 13847c6ae99SBarry Smith n = csize/m; 13947c6ae99SBarry Smith if (m*n == csize) break; 14047c6ae99SBarry Smith m--; 14147c6ae99SBarry Smith } 14247c6ae99SBarry Smith if (M > N && m < n) {PetscInt _m = m; m = n; n = _m;} 14347c6ae99SBarry Smith 14447c6ae99SBarry Smith x = M/m + ((M % m) > ((csize-1) % m)); 14547c6ae99SBarry Smith y = (N + (csize-1)/m)/n; 14647c6ae99SBarry Smith } while ((x < 4 || y < 4) && csize > 1); 14747c6ae99SBarry Smith if (size != csize) { 14847c6ae99SBarry Smith MPI_Group entire_group,sub_group; 14947c6ae99SBarry Smith PetscMPIInt i,*groupies; 15047c6ae99SBarry Smith 15147c6ae99SBarry Smith ierr = MPI_Comm_group(comm,&entire_group);CHKERRQ(ierr); 15247c6ae99SBarry Smith ierr = PetscMalloc(csize*sizeof(PetscInt),&groupies);CHKERRQ(ierr); 15347c6ae99SBarry Smith for (i=0; i<csize; i++) { 15447c6ae99SBarry Smith groupies[i] = (rank/csize)*csize + i; 15547c6ae99SBarry Smith } 15647c6ae99SBarry Smith ierr = MPI_Group_incl(entire_group,csize,groupies,&sub_group);CHKERRQ(ierr); 15747c6ae99SBarry Smith ierr = PetscFree(groupies);CHKERRQ(ierr); 15847c6ae99SBarry Smith ierr = MPI_Comm_create(comm,sub_group,outcomm);CHKERRQ(ierr); 15947c6ae99SBarry Smith ierr = MPI_Group_free(&entire_group);CHKERRQ(ierr); 16047c6ae99SBarry Smith ierr = MPI_Group_free(&sub_group);CHKERRQ(ierr); 16147c6ae99SBarry Smith ierr = PetscInfo1(0,"DASplitComm2d:Creating redundant coarse problems of size %d\n",csize);CHKERRQ(ierr); 16247c6ae99SBarry Smith } else { 16347c6ae99SBarry Smith *outcomm = comm; 16447c6ae99SBarry Smith } 16547c6ae99SBarry Smith PetscFunctionReturn(0); 16647c6ae99SBarry Smith } 16747c6ae99SBarry Smith 16847c6ae99SBarry Smith #undef __FUNCT__ 1695dff015aSBarry Smith #define __FUNCT__ "DMGetElements_DA_2d_P1" 170*9a42bb27SBarry Smith PetscErrorCode DMGetElements_DA_2d_P1(DM da,PetscInt *n,const PetscInt *e[]) 17147c6ae99SBarry Smith { 17247c6ae99SBarry Smith PetscErrorCode ierr; 17347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 17447c6ae99SBarry Smith PetscInt i,j,cnt,xs,xe = dd->xe,ys,ye = dd->ye,Xs = dd->Xs, Xe = dd->Xe, Ys = dd->Ys; 17547c6ae99SBarry Smith 17647c6ae99SBarry Smith PetscFunctionBegin; 17747c6ae99SBarry Smith if (!dd->e) { 17847c6ae99SBarry Smith if (dd->xs == Xs) xs = dd->xs; else xs = dd->xs - 1; 17947c6ae99SBarry Smith if (dd->ys == Ys) ys = dd->ys; else ys = dd->ys - 1; 18047c6ae99SBarry Smith dd->ne = 2*(xe - xs - 1)*(ye - ys - 1); 18147c6ae99SBarry Smith ierr = PetscMalloc((1 + 3*dd->ne)*sizeof(PetscInt),&dd->e);CHKERRQ(ierr); 18247c6ae99SBarry Smith cnt = 0; 18347c6ae99SBarry Smith for (j=ys; j<ye-1; j++) { 18447c6ae99SBarry Smith for (i=xs; i<xe-1; i++) { 18547c6ae99SBarry Smith dd->e[cnt] = i - Xs + (j - Ys)*(Xe - Xs); 18647c6ae99SBarry Smith dd->e[cnt+1] = i - Xs + 1 + (j - Ys)*(Xe - Xs); 18747c6ae99SBarry Smith dd->e[cnt+2] = i - Xs + (j - Ys + 1)*(Xe - Xs); 18847c6ae99SBarry Smith 18947c6ae99SBarry Smith dd->e[cnt+3] = i - Xs + 1 + (j - Ys + 1)*(Xe - Xs); 19047c6ae99SBarry Smith dd->e[cnt+4] = i - Xs + (j - Ys + 1)*(Xe - Xs); 19147c6ae99SBarry Smith dd->e[cnt+5] = i - Xs + 1 + (j - Ys)*(Xe - Xs); 19247c6ae99SBarry Smith cnt += 6; 19347c6ae99SBarry Smith } 19447c6ae99SBarry Smith } 19547c6ae99SBarry Smith } 19647c6ae99SBarry Smith *n = dd->ne; 19747c6ae99SBarry Smith *e = dd->e; 19847c6ae99SBarry Smith PetscFunctionReturn(0); 19947c6ae99SBarry Smith } 20047c6ae99SBarry Smith 20147c6ae99SBarry Smith #undef __FUNCT__ 20247c6ae99SBarry Smith #define __FUNCT__ "DASetLocalFunction" 20347c6ae99SBarry Smith /*@C 204*9a42bb27SBarry Smith DASetLocalFunction - Caches in a DM a local function. 20547c6ae99SBarry Smith 20647c6ae99SBarry Smith Logically Collective on DA 20747c6ae99SBarry Smith 20847c6ae99SBarry Smith Input Parameter: 20947c6ae99SBarry Smith + da - initial distributed array 21047c6ae99SBarry Smith - lf - the local function 21147c6ae99SBarry Smith 21247c6ae99SBarry Smith Level: intermediate 21347c6ae99SBarry Smith 21447c6ae99SBarry Smith Notes: The routine SNESDAFormFunction() uses this the cached function to evaluate the user provided function. 21547c6ae99SBarry Smith 21647c6ae99SBarry Smith .keywords: distributed array, refine 21747c6ae99SBarry Smith 218*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunctioni() 21947c6ae99SBarry Smith @*/ 220*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetLocalFunction(DM da,DALocalFunction1 lf) 22147c6ae99SBarry Smith { 22247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 22347c6ae99SBarry Smith PetscFunctionBegin; 22447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 22547c6ae99SBarry Smith dd->lf = lf; 22647c6ae99SBarry Smith PetscFunctionReturn(0); 22747c6ae99SBarry Smith } 22847c6ae99SBarry Smith 22947c6ae99SBarry Smith #undef __FUNCT__ 23047c6ae99SBarry Smith #define __FUNCT__ "DASetLocalFunctioni" 23147c6ae99SBarry Smith /*@C 232*9a42bb27SBarry Smith DASetLocalFunctioni - Caches in a DM a local function that evaluates a single component 23347c6ae99SBarry Smith 23447c6ae99SBarry Smith Logically Collective on DA 23547c6ae99SBarry Smith 23647c6ae99SBarry Smith Input Parameter: 23747c6ae99SBarry Smith + da - initial distributed array 23847c6ae99SBarry Smith - lfi - the local function 23947c6ae99SBarry Smith 24047c6ae99SBarry Smith Level: intermediate 24147c6ae99SBarry Smith 24247c6ae99SBarry Smith .keywords: distributed array, refine 24347c6ae99SBarry Smith 244*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction() 24547c6ae99SBarry Smith @*/ 246*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetLocalFunctioni(DM da,PetscErrorCode (*lfi)(DALocalInfo*,MatStencil*,void*,PetscScalar*,void*)) 24747c6ae99SBarry Smith { 24847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 24947c6ae99SBarry Smith PetscFunctionBegin; 25047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 25147c6ae99SBarry Smith dd->lfi = lfi; 25247c6ae99SBarry Smith PetscFunctionReturn(0); 25347c6ae99SBarry Smith } 25447c6ae99SBarry Smith 25547c6ae99SBarry Smith #undef __FUNCT__ 25647c6ae99SBarry Smith #define __FUNCT__ "DASetLocalFunctionib" 25747c6ae99SBarry Smith /*@C 258*9a42bb27SBarry Smith DASetLocalFunctionib - Caches in a DM a block local function that evaluates a single component 25947c6ae99SBarry Smith 26047c6ae99SBarry Smith Logically Collective on DA 26147c6ae99SBarry Smith 26247c6ae99SBarry Smith Input Parameter: 26347c6ae99SBarry Smith + da - initial distributed array 26447c6ae99SBarry Smith - lfi - the local function 26547c6ae99SBarry Smith 26647c6ae99SBarry Smith Level: intermediate 26747c6ae99SBarry Smith 26847c6ae99SBarry Smith .keywords: distributed array, refine 26947c6ae99SBarry Smith 270*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction() 27147c6ae99SBarry Smith @*/ 272*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetLocalFunctionib(DM da,PetscErrorCode (*lfi)(DALocalInfo*,MatStencil*,void*,PetscScalar*,void*)) 27347c6ae99SBarry Smith { 27447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 27547c6ae99SBarry Smith PetscFunctionBegin; 27647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 27747c6ae99SBarry Smith dd->lfib = lfi; 27847c6ae99SBarry Smith PetscFunctionReturn(0); 27947c6ae99SBarry Smith } 28047c6ae99SBarry Smith 28147c6ae99SBarry Smith #undef __FUNCT__ 28247c6ae99SBarry Smith #define __FUNCT__ "DASetLocalAdicFunction_Private" 283*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicFunction_Private(DM da,DALocalFunction1 ad_lf) 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_lf = ad_lf; 28947c6ae99SBarry Smith PetscFunctionReturn(0); 29047c6ae99SBarry Smith } 29147c6ae99SBarry Smith 29247c6ae99SBarry Smith /*MC 293*9a42bb27SBarry Smith DASetLocalAdicFunctioni - Caches in a DM a local functioni computed by ADIC/ADIFOR 29447c6ae99SBarry Smith 29547c6ae99SBarry Smith Synopsis: 296*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicFunctioni(DM da,PetscInt (ad_lf*)(DALocalInfo*,MatStencil*,void*,void*,void*) 29747c6ae99SBarry Smith 29847c6ae99SBarry Smith Logically Collective on DA 29947c6ae99SBarry Smith 30047c6ae99SBarry Smith Input Parameter: 30147c6ae99SBarry Smith + da - initial distributed array 30247c6ae99SBarry Smith - ad_lfi - the local function as computed by ADIC/ADIFOR 30347c6ae99SBarry Smith 30447c6ae99SBarry Smith Level: intermediate 30547c6ae99SBarry Smith 30647c6ae99SBarry Smith .keywords: distributed array, refine 30747c6ae99SBarry Smith 308*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction(), 30947c6ae99SBarry Smith DASetLocalJacobian(), DASetLocalFunctioni() 31047c6ae99SBarry Smith M*/ 31147c6ae99SBarry Smith 31247c6ae99SBarry Smith #undef __FUNCT__ 31347c6ae99SBarry Smith #define __FUNCT__ "DASetLocalAdicFunctioni_Private" 314*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicFunctioni_Private(DM da,PetscErrorCode (*ad_lfi)(DALocalInfo*,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->adic_lfi = ad_lfi; 32047c6ae99SBarry Smith PetscFunctionReturn(0); 32147c6ae99SBarry Smith } 32247c6ae99SBarry Smith 32347c6ae99SBarry Smith /*MC 324*9a42bb27SBarry Smith DASetLocalAdicMFFunctioni - Caches in a DM a local functioni computed by ADIC/ADIFOR 32547c6ae99SBarry Smith 32647c6ae99SBarry Smith Synopsis: 327*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicFunctioni(DM da,int (ad_lf*)(DALocalInfo*,MatStencil*,void*,void*,void*) 32847c6ae99SBarry Smith 32947c6ae99SBarry Smith Logically Collective on DA 33047c6ae99SBarry Smith 33147c6ae99SBarry Smith Input Parameter: 33247c6ae99SBarry Smith + da - initial distributed array 33347c6ae99SBarry Smith - admf_lfi - the local matrix-free function as computed by ADIC/ADIFOR 33447c6ae99SBarry Smith 33547c6ae99SBarry Smith Level: intermediate 33647c6ae99SBarry Smith 33747c6ae99SBarry Smith .keywords: distributed array, refine 33847c6ae99SBarry Smith 339*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction(), 34047c6ae99SBarry Smith DASetLocalJacobian(), DASetLocalFunctioni() 34147c6ae99SBarry Smith M*/ 34247c6ae99SBarry Smith 34347c6ae99SBarry Smith #undef __FUNCT__ 34447c6ae99SBarry Smith #define __FUNCT__ "DASetLocalAdicMFFunctioni_Private" 345*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicMFFunctioni_Private(DM da,PetscErrorCode (*admf_lfi)(DALocalInfo*,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->adicmf_lfi = admf_lfi; 35147c6ae99SBarry Smith PetscFunctionReturn(0); 35247c6ae99SBarry Smith } 35347c6ae99SBarry Smith 35447c6ae99SBarry Smith /*MC 355*9a42bb27SBarry Smith DASetLocalAdicFunctionib - Caches in a DM a block local functioni computed by ADIC/ADIFOR 35647c6ae99SBarry Smith 35747c6ae99SBarry Smith Synopsis: 358*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicFunctionib(DM da,PetscInt (ad_lf*)(DALocalInfo*,MatStencil*,void*,void*,void*) 35947c6ae99SBarry Smith 36047c6ae99SBarry Smith Logically Collective on DA 36147c6ae99SBarry Smith 36247c6ae99SBarry Smith Input Parameter: 36347c6ae99SBarry Smith + da - initial distributed array 36447c6ae99SBarry Smith - ad_lfi - the local function as computed by ADIC/ADIFOR 36547c6ae99SBarry Smith 36647c6ae99SBarry Smith Level: intermediate 36747c6ae99SBarry Smith 36847c6ae99SBarry Smith .keywords: distributed array, refine 36947c6ae99SBarry Smith 370*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction(), 37147c6ae99SBarry Smith DASetLocalJacobian(), DASetLocalFunctionib() 37247c6ae99SBarry Smith M*/ 37347c6ae99SBarry Smith 37447c6ae99SBarry Smith #undef __FUNCT__ 37547c6ae99SBarry Smith #define __FUNCT__ "DASetLocalAdicFunctionib_Private" 376*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicFunctionib_Private(DM da,PetscErrorCode (*ad_lfi)(DALocalInfo*,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->adic_lfib = ad_lfi; 38247c6ae99SBarry Smith PetscFunctionReturn(0); 38347c6ae99SBarry Smith } 38447c6ae99SBarry Smith 38547c6ae99SBarry Smith /*MC 386*9a42bb27SBarry Smith DASetLocalAdicMFFunctionib - Caches in a DM a block local functioni computed by ADIC/ADIFOR 38747c6ae99SBarry Smith 38847c6ae99SBarry Smith Synopsis: 389*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicFunctionib(DM da,int (ad_lf*)(DALocalInfo*,MatStencil*,void*,void*,void*) 39047c6ae99SBarry Smith 39147c6ae99SBarry Smith Logically Collective on DA 39247c6ae99SBarry Smith 39347c6ae99SBarry Smith Input Parameter: 39447c6ae99SBarry Smith + da - initial distributed array 39547c6ae99SBarry Smith - admf_lfi - the local matrix-free function as computed by ADIC/ADIFOR 39647c6ae99SBarry Smith 39747c6ae99SBarry Smith Level: intermediate 39847c6ae99SBarry Smith 39947c6ae99SBarry Smith .keywords: distributed array, refine 40047c6ae99SBarry Smith 401*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction(), 40247c6ae99SBarry Smith DASetLocalJacobian(), DASetLocalFunctionib() 40347c6ae99SBarry Smith M*/ 40447c6ae99SBarry Smith 40547c6ae99SBarry Smith #undef __FUNCT__ 40647c6ae99SBarry Smith #define __FUNCT__ "DASetLocalAdicMFFunctionib_Private" 407*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicMFFunctionib_Private(DM da,PetscErrorCode (*admf_lfi)(DALocalInfo*,MatStencil*,void*,void*,void*)) 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_lfib = admf_lfi; 41347c6ae99SBarry Smith PetscFunctionReturn(0); 41447c6ae99SBarry Smith } 41547c6ae99SBarry Smith 41647c6ae99SBarry Smith /*MC 417*9a42bb27SBarry Smith DASetLocalAdicMFFunction - Caches in a DM a local function computed by ADIC/ADIFOR 41847c6ae99SBarry Smith 41947c6ae99SBarry Smith Synopsis: 420*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicMFFunction(DM da,DALocalFunction1 ad_lf) 42147c6ae99SBarry Smith 42247c6ae99SBarry Smith Logically Collective on DA 42347c6ae99SBarry Smith 42447c6ae99SBarry Smith Input Parameter: 42547c6ae99SBarry Smith + da - initial distributed array 42647c6ae99SBarry Smith - ad_lf - the local function as computed by ADIC/ADIFOR 42747c6ae99SBarry Smith 42847c6ae99SBarry Smith Level: intermediate 42947c6ae99SBarry Smith 43047c6ae99SBarry Smith .keywords: distributed array, refine 43147c6ae99SBarry Smith 432*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction(), 43347c6ae99SBarry Smith DASetLocalJacobian() 43447c6ae99SBarry Smith M*/ 43547c6ae99SBarry Smith 43647c6ae99SBarry Smith #undef __FUNCT__ 43747c6ae99SBarry Smith #define __FUNCT__ "DASetLocalAdicMFFunction_Private" 438*9a42bb27SBarry Smith PetscErrorCode DASetLocalAdicMFFunction_Private(DM da,DALocalFunction1 ad_lf) 43947c6ae99SBarry Smith { 44047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 44147c6ae99SBarry Smith PetscFunctionBegin; 44247c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 44347c6ae99SBarry Smith dd->adicmf_lf = ad_lf; 44447c6ae99SBarry Smith PetscFunctionReturn(0); 44547c6ae99SBarry Smith } 44647c6ae99SBarry Smith 44747c6ae99SBarry Smith /*@C 448*9a42bb27SBarry Smith DASetLocalJacobian - Caches in a DM a local Jacobian computation function 44947c6ae99SBarry Smith 45047c6ae99SBarry Smith Logically Collective on DA 45147c6ae99SBarry Smith 45247c6ae99SBarry Smith 45347c6ae99SBarry Smith Input Parameter: 45447c6ae99SBarry Smith + da - initial distributed array 45547c6ae99SBarry Smith - lj - the local Jacobian 45647c6ae99SBarry Smith 45747c6ae99SBarry Smith Level: intermediate 45847c6ae99SBarry Smith 45947c6ae99SBarry Smith Notes: The routine SNESDAFormFunction() uses this the cached function to evaluate the user provided function. 46047c6ae99SBarry Smith 46147c6ae99SBarry Smith .keywords: distributed array, refine 46247c6ae99SBarry Smith 463*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalFunction() 46447c6ae99SBarry Smith @*/ 46547c6ae99SBarry Smith #undef __FUNCT__ 46647c6ae99SBarry Smith #define __FUNCT__ "DASetLocalJacobian" 467*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DASetLocalJacobian(DM da,DALocalFunction1 lj) 46847c6ae99SBarry Smith { 46947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 47047c6ae99SBarry Smith PetscFunctionBegin; 47147c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 47247c6ae99SBarry Smith dd->lj = lj; 47347c6ae99SBarry Smith PetscFunctionReturn(0); 47447c6ae99SBarry Smith } 47547c6ae99SBarry Smith 47647c6ae99SBarry Smith #undef __FUNCT__ 47747c6ae99SBarry Smith #define __FUNCT__ "DAGetLocalFunction" 47847c6ae99SBarry Smith /*@C 479*9a42bb27SBarry Smith DAGetLocalFunction - Gets from a DM a local function and its ADIC/ADIFOR Jacobian 48047c6ae99SBarry Smith 48147c6ae99SBarry Smith Note Collective 48247c6ae99SBarry Smith 48347c6ae99SBarry Smith Input Parameter: 48447c6ae99SBarry Smith . da - initial distributed array 48547c6ae99SBarry Smith 48647c6ae99SBarry Smith Output Parameter: 48747c6ae99SBarry Smith . lf - the local function 48847c6ae99SBarry Smith 48947c6ae99SBarry Smith Level: intermediate 49047c6ae99SBarry Smith 49147c6ae99SBarry Smith .keywords: distributed array, refine 49247c6ae99SBarry Smith 493*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalJacobian(), DASetLocalFunction() 49447c6ae99SBarry Smith @*/ 495*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetLocalFunction(DM da,DALocalFunction1 *lf) 49647c6ae99SBarry Smith { 49747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 49847c6ae99SBarry Smith PetscFunctionBegin; 49947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 50047c6ae99SBarry Smith if (lf) *lf = dd->lf; 50147c6ae99SBarry Smith PetscFunctionReturn(0); 50247c6ae99SBarry Smith } 50347c6ae99SBarry Smith 50447c6ae99SBarry Smith #undef __FUNCT__ 50547c6ae99SBarry Smith #define __FUNCT__ "DAGetLocalJacobian" 50647c6ae99SBarry Smith /*@C 507*9a42bb27SBarry Smith DAGetLocalJacobian - Gets from a DM a local jacobian 50847c6ae99SBarry Smith 50947c6ae99SBarry Smith Not Collective 51047c6ae99SBarry Smith 51147c6ae99SBarry Smith Input Parameter: 51247c6ae99SBarry Smith . da - initial distributed array 51347c6ae99SBarry Smith 51447c6ae99SBarry Smith Output Parameter: 51547c6ae99SBarry Smith . lj - the local jacobian 51647c6ae99SBarry Smith 51747c6ae99SBarry Smith Level: intermediate 51847c6ae99SBarry Smith 51947c6ae99SBarry Smith .keywords: distributed array, refine 52047c6ae99SBarry Smith 521*9a42bb27SBarry Smith .seealso: DACreate1d(), DACreate2d(), DACreate3d(), DMDestroy(), DAGetLocalFunction(), DASetLocalJacobian() 52247c6ae99SBarry Smith @*/ 523*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAGetLocalJacobian(DM da,DALocalFunction1 *lj) 52447c6ae99SBarry Smith { 52547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 52647c6ae99SBarry Smith PetscFunctionBegin; 52747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 52847c6ae99SBarry Smith if (lj) *lj = dd->lj; 52947c6ae99SBarry Smith PetscFunctionReturn(0); 53047c6ae99SBarry Smith } 53147c6ae99SBarry Smith 53247c6ae99SBarry Smith #undef __FUNCT__ 53347c6ae99SBarry Smith #define __FUNCT__ "DAFormFunction" 53447c6ae99SBarry Smith /*@ 53547c6ae99SBarry Smith DAFormFunction - Evaluates a user provided function on each processor that 53647c6ae99SBarry Smith share a DA 53747c6ae99SBarry Smith 53847c6ae99SBarry Smith Input Parameters: 539*9a42bb27SBarry Smith + da - the DM that defines the grid 54047c6ae99SBarry Smith . vu - input vector 54147c6ae99SBarry Smith . vfu - output vector 54247c6ae99SBarry Smith - w - any user data 54347c6ae99SBarry Smith 54447c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 54547c6ae99SBarry Smith 54647c6ae99SBarry Smith This should eventually replace DAFormFunction1 54747c6ae99SBarry Smith 54847c6ae99SBarry Smith Level: advanced 54947c6ae99SBarry Smith 55047c6ae99SBarry Smith .seealso: DAComputeJacobian1WithAdic() 55147c6ae99SBarry Smith 55247c6ae99SBarry Smith @*/ 553*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormFunction(DM da,PetscErrorCode (*lf)(void),Vec vu,Vec vfu,void *w) 55447c6ae99SBarry Smith { 55547c6ae99SBarry Smith PetscErrorCode ierr; 55647c6ae99SBarry Smith void *u,*fu; 55747c6ae99SBarry Smith DALocalInfo info; 55847c6ae99SBarry Smith PetscErrorCode (*f)(DALocalInfo*,void*,void*,void*) = (PetscErrorCode (*)(DALocalInfo*,void*,void*,void*))lf; 55947c6ae99SBarry Smith 56047c6ae99SBarry Smith PetscFunctionBegin; 56147c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 56247c6ae99SBarry Smith ierr = DAVecGetArray(da,vu,&u);CHKERRQ(ierr); 56347c6ae99SBarry Smith ierr = DAVecGetArray(da,vfu,&fu);CHKERRQ(ierr); 56447c6ae99SBarry Smith 56547c6ae99SBarry Smith ierr = (*f)(&info,u,fu,w); 56647c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 56747c6ae99SBarry Smith PetscErrorCode pierr = DAVecRestoreArray(da,vu,&u);CHKERRQ(pierr); 56847c6ae99SBarry Smith pierr = DAVecRestoreArray(da,vfu,&fu);CHKERRQ(pierr); 56947c6ae99SBarry Smith } 57047c6ae99SBarry Smith CHKERRQ(ierr); 57147c6ae99SBarry Smith 57247c6ae99SBarry Smith ierr = DAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 57347c6ae99SBarry Smith ierr = DAVecRestoreArray(da,vfu,&fu);CHKERRQ(ierr); 57447c6ae99SBarry Smith PetscFunctionReturn(0); 57547c6ae99SBarry Smith } 57647c6ae99SBarry Smith 57747c6ae99SBarry Smith #undef __FUNCT__ 57847c6ae99SBarry Smith #define __FUNCT__ "DAFormFunctionLocal" 57947c6ae99SBarry Smith /*@C 58047c6ae99SBarry Smith DAFormFunctionLocal - This is a universal function evaluation routine for 581*9a42bb27SBarry Smith a local DM function. 58247c6ae99SBarry Smith 58347c6ae99SBarry Smith Collective on DA 58447c6ae99SBarry Smith 58547c6ae99SBarry Smith Input Parameters: 586*9a42bb27SBarry Smith + da - the DM context 58747c6ae99SBarry Smith . func - The local function 58847c6ae99SBarry Smith . X - input vector 58947c6ae99SBarry Smith . F - function vector 59047c6ae99SBarry Smith - ctx - A user context 59147c6ae99SBarry Smith 59247c6ae99SBarry Smith Level: intermediate 59347c6ae99SBarry Smith 59447c6ae99SBarry Smith .seealso: DASetLocalFunction(), DASetLocalJacobian(), DASetLocalAdicFunction(), DASetLocalAdicMFFunction(), 59547c6ae99SBarry Smith SNESSetFunction(), SNESSetJacobian() 59647c6ae99SBarry Smith 59747c6ae99SBarry Smith @*/ 598*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormFunctionLocal(DM da, DALocalFunction1 func, Vec X, Vec F, void *ctx) 59947c6ae99SBarry Smith { 60047c6ae99SBarry Smith Vec localX; 60147c6ae99SBarry Smith DALocalInfo info; 60247c6ae99SBarry Smith void *u; 60347c6ae99SBarry Smith void *fu; 60447c6ae99SBarry Smith PetscErrorCode ierr; 60547c6ae99SBarry Smith 60647c6ae99SBarry Smith PetscFunctionBegin; 607*9a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); 60847c6ae99SBarry Smith /* 60947c6ae99SBarry Smith Scatter ghost points to local vector, using the 2-step process 610*9a42bb27SBarry Smith DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). 61147c6ae99SBarry Smith */ 612*9a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 613*9a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 61447c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 61547c6ae99SBarry Smith ierr = DAVecGetArray(da,localX,&u);CHKERRQ(ierr); 61647c6ae99SBarry Smith ierr = DAVecGetArray(da,F,&fu);CHKERRQ(ierr); 61747c6ae99SBarry Smith ierr = (*func)(&info,u,fu,ctx); 61847c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 61947c6ae99SBarry Smith PetscErrorCode pierr = DAVecRestoreArray(da,localX,&u);CHKERRQ(pierr); 62047c6ae99SBarry Smith pierr = DAVecRestoreArray(da,F,&fu);CHKERRQ(pierr); 62147c6ae99SBarry Smith } 62247c6ae99SBarry Smith CHKERRQ(ierr); 62347c6ae99SBarry Smith ierr = DAVecRestoreArray(da,localX,&u);CHKERRQ(ierr); 62447c6ae99SBarry Smith ierr = DAVecRestoreArray(da,F,&fu);CHKERRQ(ierr); 62547c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 626*9a42bb27SBarry Smith PetscErrorCode pierr = DMRestoreLocalVector(da,&localX);CHKERRQ(pierr); 62747c6ae99SBarry Smith } 62847c6ae99SBarry Smith CHKERRQ(ierr); 629*9a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); 63047c6ae99SBarry Smith PetscFunctionReturn(0); 63147c6ae99SBarry Smith } 63247c6ae99SBarry Smith 63347c6ae99SBarry Smith #undef __FUNCT__ 63447c6ae99SBarry Smith #define __FUNCT__ "DAFormFunctionLocalGhost" 63547c6ae99SBarry Smith /*@C 63647c6ae99SBarry Smith DAFormFunctionLocalGhost - This is a universal function evaluation routine for 637*9a42bb27SBarry Smith a local DM function, but the ghost values of the output are communicated and added. 63847c6ae99SBarry Smith 63947c6ae99SBarry Smith Collective on DA 64047c6ae99SBarry Smith 64147c6ae99SBarry Smith Input Parameters: 642*9a42bb27SBarry Smith + da - the DM context 64347c6ae99SBarry Smith . func - The local function 64447c6ae99SBarry Smith . X - input vector 64547c6ae99SBarry Smith . F - function vector 64647c6ae99SBarry Smith - ctx - A user context 64747c6ae99SBarry Smith 64847c6ae99SBarry Smith Level: intermediate 64947c6ae99SBarry Smith 65047c6ae99SBarry Smith .seealso: DASetLocalFunction(), DASetLocalJacobian(), DASetLocalAdicFunction(), DASetLocalAdicMFFunction(), 65147c6ae99SBarry Smith SNESSetFunction(), SNESSetJacobian() 65247c6ae99SBarry Smith 65347c6ae99SBarry Smith @*/ 654*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormFunctionLocalGhost(DM da, DALocalFunction1 func, Vec X, Vec F, void *ctx) 65547c6ae99SBarry Smith { 65647c6ae99SBarry Smith Vec localX, localF; 65747c6ae99SBarry Smith DALocalInfo info; 65847c6ae99SBarry Smith void *u; 65947c6ae99SBarry Smith void *fu; 66047c6ae99SBarry Smith PetscErrorCode ierr; 66147c6ae99SBarry Smith 66247c6ae99SBarry Smith PetscFunctionBegin; 663*9a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); 664*9a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localF);CHKERRQ(ierr); 66547c6ae99SBarry Smith /* 66647c6ae99SBarry Smith Scatter ghost points to local vector, using the 2-step process 667*9a42bb27SBarry Smith DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). 66847c6ae99SBarry Smith */ 669*9a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 670*9a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 67147c6ae99SBarry Smith ierr = VecSet(F, 0.0);CHKERRQ(ierr); 67247c6ae99SBarry Smith ierr = VecSet(localF, 0.0);CHKERRQ(ierr); 67347c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 67447c6ae99SBarry Smith ierr = DAVecGetArray(da,localX,&u);CHKERRQ(ierr); 67547c6ae99SBarry Smith ierr = DAVecGetArray(da,localF,&fu);CHKERRQ(ierr); 67647c6ae99SBarry Smith ierr = (*func)(&info,u,fu,ctx); 67747c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 67847c6ae99SBarry Smith PetscErrorCode pierr = DAVecRestoreArray(da,localX,&u);CHKERRQ(pierr); 67947c6ae99SBarry Smith pierr = DAVecRestoreArray(da,localF,&fu);CHKERRQ(pierr); 68047c6ae99SBarry Smith } 68147c6ae99SBarry Smith CHKERRQ(ierr); 682*9a42bb27SBarry Smith ierr = DMLocalToGlobalBegin(da,localF,ADD_VALUES,F);CHKERRQ(ierr); 683*9a42bb27SBarry Smith ierr = DMLocalToGlobalEnd(da,localF,ADD_VALUES,F);CHKERRQ(ierr); 68447c6ae99SBarry Smith ierr = DAVecRestoreArray(da,localX,&u);CHKERRQ(ierr); 68547c6ae99SBarry Smith ierr = DAVecRestoreArray(da,localF,&fu);CHKERRQ(ierr); 68647c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 687*9a42bb27SBarry Smith PetscErrorCode pierr = DMRestoreLocalVector(da,&localX);CHKERRQ(pierr); 688*9a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localF);CHKERRQ(ierr); 68947c6ae99SBarry Smith } 69047c6ae99SBarry Smith CHKERRQ(ierr); 691*9a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); 692*9a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localF);CHKERRQ(ierr); 69347c6ae99SBarry Smith PetscFunctionReturn(0); 69447c6ae99SBarry Smith } 69547c6ae99SBarry Smith 69647c6ae99SBarry Smith #undef __FUNCT__ 69747c6ae99SBarry Smith #define __FUNCT__ "DAFormFunction1" 69847c6ae99SBarry Smith /*@ 69947c6ae99SBarry Smith DAFormFunction1 - Evaluates a user provided function on each processor that 70047c6ae99SBarry Smith share a DA 70147c6ae99SBarry Smith 70247c6ae99SBarry Smith Input Parameters: 703*9a42bb27SBarry Smith + da - the DM that defines the grid 70447c6ae99SBarry Smith . vu - input vector 70547c6ae99SBarry Smith . vfu - output vector 70647c6ae99SBarry Smith - w - any user data 70747c6ae99SBarry Smith 70847c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 70947c6ae99SBarry Smith 71047c6ae99SBarry Smith Level: advanced 71147c6ae99SBarry Smith 71247c6ae99SBarry Smith .seealso: DAComputeJacobian1WithAdic() 71347c6ae99SBarry Smith 71447c6ae99SBarry Smith @*/ 715*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormFunction1(DM da,Vec vu,Vec vfu,void *w) 71647c6ae99SBarry Smith { 71747c6ae99SBarry Smith PetscErrorCode ierr; 71847c6ae99SBarry Smith void *u,*fu; 71947c6ae99SBarry Smith DALocalInfo info; 72047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 72147c6ae99SBarry Smith 72247c6ae99SBarry Smith PetscFunctionBegin; 72347c6ae99SBarry Smith 72447c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 72547c6ae99SBarry Smith ierr = DAVecGetArray(da,vu,&u);CHKERRQ(ierr); 72647c6ae99SBarry Smith ierr = DAVecGetArray(da,vfu,&fu);CHKERRQ(ierr); 72747c6ae99SBarry Smith 72847c6ae99SBarry Smith CHKMEMQ; 72947c6ae99SBarry Smith ierr = (*dd->lf)(&info,u,fu,w); 73047c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 73147c6ae99SBarry Smith PetscErrorCode pierr = DAVecRestoreArray(da,vu,&u);CHKERRQ(pierr); 73247c6ae99SBarry Smith pierr = DAVecRestoreArray(da,vfu,&fu);CHKERRQ(pierr); 73347c6ae99SBarry Smith } 73447c6ae99SBarry Smith CHKERRQ(ierr); 73547c6ae99SBarry Smith CHKMEMQ; 73647c6ae99SBarry Smith 73747c6ae99SBarry Smith ierr = DAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 73847c6ae99SBarry Smith ierr = DAVecRestoreArray(da,vfu,&fu);CHKERRQ(ierr); 73947c6ae99SBarry Smith PetscFunctionReturn(0); 74047c6ae99SBarry Smith } 74147c6ae99SBarry Smith 74247c6ae99SBarry Smith #undef __FUNCT__ 74347c6ae99SBarry Smith #define __FUNCT__ "DAFormFunctioniTest1" 744*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormFunctioniTest1(DM da,void *w) 74547c6ae99SBarry Smith { 74647c6ae99SBarry Smith Vec vu,fu,fui; 74747c6ae99SBarry Smith PetscErrorCode ierr; 74847c6ae99SBarry Smith PetscInt i,n; 74947c6ae99SBarry Smith PetscScalar *ui; 75047c6ae99SBarry Smith PetscRandom rnd; 75147c6ae99SBarry Smith PetscReal norm; 75247c6ae99SBarry Smith 75347c6ae99SBarry Smith PetscFunctionBegin; 754*9a42bb27SBarry Smith ierr = DMGetLocalVector(da,&vu);CHKERRQ(ierr); 75547c6ae99SBarry Smith ierr = PetscRandomCreate(PETSC_COMM_SELF,&rnd);CHKERRQ(ierr); 75647c6ae99SBarry Smith ierr = PetscRandomSetFromOptions(rnd);CHKERRQ(ierr); 75747c6ae99SBarry Smith ierr = VecSetRandom(vu,rnd);CHKERRQ(ierr); 75847c6ae99SBarry Smith ierr = PetscRandomDestroy(rnd);CHKERRQ(ierr); 75947c6ae99SBarry Smith 760*9a42bb27SBarry Smith ierr = DMGetGlobalVector(da,&fu);CHKERRQ(ierr); 761*9a42bb27SBarry Smith ierr = DMGetGlobalVector(da,&fui);CHKERRQ(ierr); 76247c6ae99SBarry Smith 76347c6ae99SBarry Smith ierr = DAFormFunction1(da,vu,fu,w);CHKERRQ(ierr); 76447c6ae99SBarry Smith 76547c6ae99SBarry Smith ierr = VecGetArray(fui,&ui);CHKERRQ(ierr); 76647c6ae99SBarry Smith ierr = VecGetLocalSize(fui,&n);CHKERRQ(ierr); 76747c6ae99SBarry Smith for (i=0; i<n; i++) { 76847c6ae99SBarry Smith ierr = DAFormFunctioni1(da,i,vu,ui+i,w);CHKERRQ(ierr); 76947c6ae99SBarry Smith } 77047c6ae99SBarry Smith ierr = VecRestoreArray(fui,&ui);CHKERRQ(ierr); 77147c6ae99SBarry Smith 77247c6ae99SBarry Smith ierr = VecAXPY(fui,-1.0,fu);CHKERRQ(ierr); 77347c6ae99SBarry Smith ierr = VecNorm(fui,NORM_2,&norm);CHKERRQ(ierr); 77447c6ae99SBarry Smith ierr = PetscPrintf(((PetscObject)da)->comm,"Norm of difference in vectors %G\n",norm);CHKERRQ(ierr); 77547c6ae99SBarry Smith ierr = VecView(fu,0);CHKERRQ(ierr); 77647c6ae99SBarry Smith ierr = VecView(fui,0);CHKERRQ(ierr); 77747c6ae99SBarry Smith 778*9a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&vu);CHKERRQ(ierr); 779*9a42bb27SBarry Smith ierr = DMRestoreGlobalVector(da,&fu);CHKERRQ(ierr); 780*9a42bb27SBarry Smith ierr = DMRestoreGlobalVector(da,&fui);CHKERRQ(ierr); 78147c6ae99SBarry Smith PetscFunctionReturn(0); 78247c6ae99SBarry Smith } 78347c6ae99SBarry Smith 78447c6ae99SBarry Smith #undef __FUNCT__ 78547c6ae99SBarry Smith #define __FUNCT__ "DAFormFunctioni1" 78647c6ae99SBarry Smith /*@ 78747c6ae99SBarry Smith DAFormFunctioni1 - Evaluates a user provided point-wise function 78847c6ae99SBarry Smith 78947c6ae99SBarry Smith Input Parameters: 790*9a42bb27SBarry Smith + da - the DM that defines the grid 79147c6ae99SBarry Smith . i - the component of the function we wish to compute (must be local) 79247c6ae99SBarry Smith . vu - input vector 79347c6ae99SBarry Smith . vfu - output value 79447c6ae99SBarry Smith - w - any user data 79547c6ae99SBarry Smith 79647c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 79747c6ae99SBarry Smith 79847c6ae99SBarry Smith Level: advanced 79947c6ae99SBarry Smith 80047c6ae99SBarry Smith .seealso: DAComputeJacobian1WithAdic() 80147c6ae99SBarry Smith 80247c6ae99SBarry Smith @*/ 803*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormFunctioni1(DM da,PetscInt i,Vec vu,PetscScalar *vfu,void *w) 80447c6ae99SBarry Smith { 80547c6ae99SBarry Smith PetscErrorCode ierr; 80647c6ae99SBarry Smith void *u; 80747c6ae99SBarry Smith DALocalInfo info; 80847c6ae99SBarry Smith MatStencil stencil; 80947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 81047c6ae99SBarry Smith 81147c6ae99SBarry Smith PetscFunctionBegin; 81247c6ae99SBarry Smith 81347c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 81447c6ae99SBarry Smith ierr = DAVecGetArray(da,vu,&u);CHKERRQ(ierr); 81547c6ae99SBarry Smith 81647c6ae99SBarry Smith /* figure out stencil value from i */ 81747c6ae99SBarry Smith stencil.c = i % info.dof; 81847c6ae99SBarry Smith stencil.i = (i % (info.xm*info.dof))/info.dof; 81947c6ae99SBarry Smith stencil.j = (i % (info.xm*info.ym*info.dof))/(info.xm*info.dof); 82047c6ae99SBarry Smith stencil.k = i/(info.xm*info.ym*info.dof); 82147c6ae99SBarry Smith 82247c6ae99SBarry Smith ierr = (*dd->lfi)(&info,&stencil,u,vfu,w);CHKERRQ(ierr); 82347c6ae99SBarry Smith 82447c6ae99SBarry Smith ierr = DAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 82547c6ae99SBarry Smith PetscFunctionReturn(0); 82647c6ae99SBarry Smith } 82747c6ae99SBarry Smith 82847c6ae99SBarry Smith #undef __FUNCT__ 82947c6ae99SBarry Smith #define __FUNCT__ "DAFormFunctionib1" 83047c6ae99SBarry Smith /*@ 83147c6ae99SBarry Smith DAFormFunctionib1 - Evaluates a user provided point-block function 83247c6ae99SBarry Smith 83347c6ae99SBarry Smith Input Parameters: 834*9a42bb27SBarry Smith + da - the DM that defines the grid 83547c6ae99SBarry Smith . i - the component of the function we wish to compute (must be local) 83647c6ae99SBarry Smith . vu - input vector 83747c6ae99SBarry Smith . vfu - output value 83847c6ae99SBarry Smith - w - any user data 83947c6ae99SBarry Smith 84047c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 84147c6ae99SBarry Smith 84247c6ae99SBarry Smith Level: advanced 84347c6ae99SBarry Smith 84447c6ae99SBarry Smith .seealso: DAComputeJacobian1WithAdic() 84547c6ae99SBarry Smith 84647c6ae99SBarry Smith @*/ 847*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormFunctionib1(DM da,PetscInt i,Vec vu,PetscScalar *vfu,void *w) 84847c6ae99SBarry Smith { 84947c6ae99SBarry Smith PetscErrorCode ierr; 85047c6ae99SBarry Smith void *u; 85147c6ae99SBarry Smith DALocalInfo info; 85247c6ae99SBarry Smith MatStencil stencil; 85347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 85447c6ae99SBarry Smith 85547c6ae99SBarry Smith PetscFunctionBegin; 85647c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 85747c6ae99SBarry Smith ierr = DAVecGetArray(da,vu,&u);CHKERRQ(ierr); 85847c6ae99SBarry Smith 85947c6ae99SBarry Smith /* figure out stencil value from i */ 86047c6ae99SBarry Smith stencil.c = i % info.dof; 86147c6ae99SBarry Smith if (stencil.c) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_WRONG,"Point-block functions can only be called for the entire block"); 86247c6ae99SBarry Smith stencil.i = (i % (info.xm*info.dof))/info.dof; 86347c6ae99SBarry Smith stencil.j = (i % (info.xm*info.ym*info.dof))/(info.xm*info.dof); 86447c6ae99SBarry Smith stencil.k = i/(info.xm*info.ym*info.dof); 86547c6ae99SBarry Smith 86647c6ae99SBarry Smith ierr = (*dd->lfib)(&info,&stencil,u,vfu,w);CHKERRQ(ierr); 86747c6ae99SBarry Smith 86847c6ae99SBarry Smith ierr = DAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 86947c6ae99SBarry Smith PetscFunctionReturn(0); 87047c6ae99SBarry Smith } 87147c6ae99SBarry Smith 87247c6ae99SBarry Smith #if defined(new) 87347c6ae99SBarry Smith #undef __FUNCT__ 87447c6ae99SBarry Smith #define __FUNCT__ "DAGetDiagonal_MFFD" 87547c6ae99SBarry Smith /* 87647c6ae99SBarry Smith DAGetDiagonal_MFFD - Gets the diagonal for a matrix free matrix where local 87747c6ae99SBarry Smith function lives on a DA 87847c6ae99SBarry Smith 87947c6ae99SBarry Smith y ~= (F(u + ha) - F(u))/h, 88047c6ae99SBarry Smith where F = nonlinear function, as set by SNESSetFunction() 88147c6ae99SBarry Smith u = current iterate 88247c6ae99SBarry Smith h = difference interval 88347c6ae99SBarry Smith */ 884*9a42bb27SBarry Smith PetscErrorCode DAGetDiagonal_MFFD(DM da,Vec U,Vec a) 88547c6ae99SBarry Smith { 88647c6ae99SBarry Smith PetscScalar h,*aa,*ww,v; 88747c6ae99SBarry Smith PetscReal epsilon = PETSC_SQRT_MACHINE_EPSILON,umin = 100.0*PETSC_SQRT_MACHINE_EPSILON; 88847c6ae99SBarry Smith PetscErrorCode ierr; 88947c6ae99SBarry Smith PetscInt gI,nI; 89047c6ae99SBarry Smith MatStencil stencil; 89147c6ae99SBarry Smith DALocalInfo info; 89247c6ae99SBarry Smith 89347c6ae99SBarry Smith PetscFunctionBegin; 89447c6ae99SBarry Smith ierr = (*ctx->func)(0,U,a,ctx->funcctx);CHKERRQ(ierr); 89547c6ae99SBarry Smith ierr = (*ctx->funcisetbase)(U,ctx->funcctx);CHKERRQ(ierr); 89647c6ae99SBarry Smith 89747c6ae99SBarry Smith ierr = VecGetArray(U,&ww);CHKERRQ(ierr); 89847c6ae99SBarry Smith ierr = VecGetArray(a,&aa);CHKERRQ(ierr); 89947c6ae99SBarry Smith 90047c6ae99SBarry Smith nI = 0; 90147c6ae99SBarry Smith h = ww[gI]; 90247c6ae99SBarry Smith if (h == 0.0) h = 1.0; 90347c6ae99SBarry Smith #if !defined(PETSC_USE_COMPLEX) 90447c6ae99SBarry Smith if (h < umin && h >= 0.0) h = umin; 90547c6ae99SBarry Smith else if (h < 0.0 && h > -umin) h = -umin; 90647c6ae99SBarry Smith #else 90747c6ae99SBarry Smith if (PetscAbsScalar(h) < umin && PetscRealPart(h) >= 0.0) h = umin; 90847c6ae99SBarry Smith else if (PetscRealPart(h) < 0.0 && PetscAbsScalar(h) < umin) h = -umin; 90947c6ae99SBarry Smith #endif 91047c6ae99SBarry Smith h *= epsilon; 91147c6ae99SBarry Smith 91247c6ae99SBarry Smith ww[gI] += h; 91347c6ae99SBarry Smith ierr = (*ctx->funci)(i,w,&v,ctx->funcctx);CHKERRQ(ierr); 91447c6ae99SBarry Smith aa[nI] = (v - aa[nI])/h; 91547c6ae99SBarry Smith ww[gI] -= h; 91647c6ae99SBarry Smith nI++; 91747c6ae99SBarry Smith } 91847c6ae99SBarry Smith ierr = VecRestoreArray(U,&ww);CHKERRQ(ierr); 91947c6ae99SBarry Smith ierr = VecRestoreArray(a,&aa);CHKERRQ(ierr); 92047c6ae99SBarry Smith PetscFunctionReturn(0); 92147c6ae99SBarry Smith } 92247c6ae99SBarry Smith #endif 92347c6ae99SBarry Smith 92447c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC) 92547c6ae99SBarry Smith EXTERN_C_BEGIN 92647c6ae99SBarry Smith #include "adic/ad_utils.h" 92747c6ae99SBarry Smith EXTERN_C_END 92847c6ae99SBarry Smith 92947c6ae99SBarry Smith #undef __FUNCT__ 93047c6ae99SBarry Smith #define __FUNCT__ "DAComputeJacobian1WithAdic" 93147c6ae99SBarry Smith /*@C 93247c6ae99SBarry Smith DAComputeJacobian1WithAdic - Evaluates a adiC provided Jacobian function on each processor that 93347c6ae99SBarry Smith share a DA 93447c6ae99SBarry Smith 93547c6ae99SBarry Smith Input Parameters: 936*9a42bb27SBarry Smith + da - the DM that defines the grid 93747c6ae99SBarry Smith . vu - input vector (ghosted) 93847c6ae99SBarry Smith . J - output matrix 93947c6ae99SBarry Smith - w - any user data 94047c6ae99SBarry Smith 94147c6ae99SBarry Smith Level: advanced 94247c6ae99SBarry Smith 94347c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 94447c6ae99SBarry Smith 94547c6ae99SBarry Smith .seealso: DAFormFunction1() 94647c6ae99SBarry Smith 94747c6ae99SBarry Smith @*/ 948*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAComputeJacobian1WithAdic(DM da,Vec vu,Mat J,void *w) 94947c6ae99SBarry Smith { 95047c6ae99SBarry Smith PetscErrorCode ierr; 95147c6ae99SBarry Smith PetscInt gtdof,tdof; 95247c6ae99SBarry Smith PetscScalar *ustart; 95347c6ae99SBarry Smith DALocalInfo info; 95447c6ae99SBarry Smith void *ad_u,*ad_f,*ad_ustart,*ad_fstart; 95547c6ae99SBarry Smith ISColoring iscoloring; 95647c6ae99SBarry Smith 95747c6ae99SBarry Smith PetscFunctionBegin; 95847c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 95947c6ae99SBarry Smith 96047c6ae99SBarry Smith PetscADResetIndep(); 96147c6ae99SBarry Smith 96247c6ae99SBarry Smith /* get space for derivative objects. */ 96347c6ae99SBarry Smith ierr = DAGetAdicArray(da,PETSC_TRUE,&ad_u,&ad_ustart,>dof);CHKERRQ(ierr); 96447c6ae99SBarry Smith ierr = DAGetAdicArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 96547c6ae99SBarry Smith ierr = VecGetArray(vu,&ustart);CHKERRQ(ierr); 96647c6ae99SBarry Smith ierr = DAGetColoring(da,IS_COLORING_GHOSTED,MATAIJ,&iscoloring);CHKERRQ(ierr); 96747c6ae99SBarry Smith 96847c6ae99SBarry Smith PetscADSetValueAndColor(ad_ustart,gtdof,iscoloring->colors,ustart); 96947c6ae99SBarry Smith 97047c6ae99SBarry Smith ierr = VecRestoreArray(vu,&ustart);CHKERRQ(ierr); 97147c6ae99SBarry Smith ierr = ISColoringDestroy(iscoloring);CHKERRQ(ierr); 97247c6ae99SBarry Smith ierr = PetscADIncrementTotalGradSize(iscoloring->n);CHKERRQ(ierr); 97347c6ae99SBarry Smith PetscADSetIndepDone(); 97447c6ae99SBarry Smith 97547c6ae99SBarry Smith ierr = PetscLogEventBegin(DA_LocalADFunction,0,0,0,0);CHKERRQ(ierr); 97647c6ae99SBarry Smith ierr = (*dd->adic_lf)(&info,ad_u,ad_f,w);CHKERRQ(ierr); 97747c6ae99SBarry Smith ierr = PetscLogEventEnd(DA_LocalADFunction,0,0,0,0);CHKERRQ(ierr); 97847c6ae99SBarry Smith 97947c6ae99SBarry Smith /* stick the values into the matrix */ 98047c6ae99SBarry Smith ierr = MatSetValuesAdic(J,(PetscScalar**)ad_fstart);CHKERRQ(ierr); 98147c6ae99SBarry Smith 98247c6ae99SBarry Smith /* return space for derivative objects. */ 98347c6ae99SBarry Smith ierr = DARestoreAdicArray(da,PETSC_TRUE,&ad_u,&ad_ustart,>dof);CHKERRQ(ierr); 98447c6ae99SBarry Smith ierr = DARestoreAdicArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 98547c6ae99SBarry Smith PetscFunctionReturn(0); 98647c6ae99SBarry Smith } 98747c6ae99SBarry Smith 98847c6ae99SBarry Smith #undef __FUNCT__ 98947c6ae99SBarry Smith #define __FUNCT__ "DAMultiplyByJacobian1WithAdic" 99047c6ae99SBarry Smith /*@C 99147c6ae99SBarry Smith DAMultiplyByJacobian1WithAdic - Applies an ADIC-provided Jacobian function to a vector on 99247c6ae99SBarry Smith each processor that shares a DA. 99347c6ae99SBarry Smith 99447c6ae99SBarry Smith Input Parameters: 995*9a42bb27SBarry Smith + da - the DM that defines the grid 99647c6ae99SBarry Smith . vu - Jacobian is computed at this point (ghosted) 99747c6ae99SBarry Smith . v - product is done on this vector (ghosted) 99847c6ae99SBarry Smith . fu - output vector = J(vu)*v (not ghosted) 99947c6ae99SBarry Smith - w - any user data 100047c6ae99SBarry Smith 100147c6ae99SBarry Smith Notes: 100247c6ae99SBarry Smith This routine does NOT do ghost updates on vu upon entry. 100347c6ae99SBarry Smith 100447c6ae99SBarry Smith Level: advanced 100547c6ae99SBarry Smith 100647c6ae99SBarry Smith .seealso: DAFormFunction1() 100747c6ae99SBarry Smith 100847c6ae99SBarry Smith @*/ 1009*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAMultiplyByJacobian1WithAdic(DM da,Vec vu,Vec v,Vec f,void *w) 101047c6ae99SBarry Smith { 101147c6ae99SBarry Smith PetscErrorCode ierr; 101247c6ae99SBarry Smith PetscInt i,gtdof,tdof; 101347c6ae99SBarry Smith PetscScalar *avu,*av,*af,*ad_vustart,*ad_fstart; 101447c6ae99SBarry Smith DALocalInfo info; 101547c6ae99SBarry Smith void *ad_vu,*ad_f; 101647c6ae99SBarry Smith 101747c6ae99SBarry Smith PetscFunctionBegin; 101847c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 101947c6ae99SBarry Smith 102047c6ae99SBarry Smith /* get space for derivative objects. */ 102147c6ae99SBarry Smith ierr = DAGetAdicMFArray(da,PETSC_TRUE,&ad_vu,&ad_vustart,>dof);CHKERRQ(ierr); 102247c6ae99SBarry Smith ierr = DAGetAdicMFArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 102347c6ae99SBarry Smith 102447c6ae99SBarry Smith /* copy input vector into derivative object */ 102547c6ae99SBarry Smith ierr = VecGetArray(vu,&avu);CHKERRQ(ierr); 102647c6ae99SBarry Smith ierr = VecGetArray(v,&av);CHKERRQ(ierr); 102747c6ae99SBarry Smith for (i=0; i<gtdof; i++) { 102847c6ae99SBarry Smith ad_vustart[2*i] = avu[i]; 102947c6ae99SBarry Smith ad_vustart[2*i+1] = av[i]; 103047c6ae99SBarry Smith } 103147c6ae99SBarry Smith ierr = VecRestoreArray(vu,&avu);CHKERRQ(ierr); 103247c6ae99SBarry Smith ierr = VecRestoreArray(v,&av);CHKERRQ(ierr); 103347c6ae99SBarry Smith 103447c6ae99SBarry Smith PetscADResetIndep(); 103547c6ae99SBarry Smith ierr = PetscADIncrementTotalGradSize(1);CHKERRQ(ierr); 103647c6ae99SBarry Smith PetscADSetIndepDone(); 103747c6ae99SBarry Smith 103847c6ae99SBarry Smith ierr = (*dd->adicmf_lf)(&info,ad_vu,ad_f,w);CHKERRQ(ierr); 103947c6ae99SBarry Smith 104047c6ae99SBarry Smith /* stick the values into the vector */ 104147c6ae99SBarry Smith ierr = VecGetArray(f,&af);CHKERRQ(ierr); 104247c6ae99SBarry Smith for (i=0; i<tdof; i++) { 104347c6ae99SBarry Smith af[i] = ad_fstart[2*i+1]; 104447c6ae99SBarry Smith } 104547c6ae99SBarry Smith ierr = VecRestoreArray(f,&af);CHKERRQ(ierr); 104647c6ae99SBarry Smith 104747c6ae99SBarry Smith /* return space for derivative objects. */ 104847c6ae99SBarry Smith ierr = DARestoreAdicMFArray(da,PETSC_TRUE,&ad_vu,&ad_vustart,>dof);CHKERRQ(ierr); 104947c6ae99SBarry Smith ierr = DARestoreAdicMFArray(da,PETSC_FALSE,&ad_f,&ad_fstart,&tdof);CHKERRQ(ierr); 105047c6ae99SBarry Smith PetscFunctionReturn(0); 105147c6ae99SBarry Smith } 105247c6ae99SBarry Smith #endif 105347c6ae99SBarry Smith 105447c6ae99SBarry Smith #undef __FUNCT__ 105547c6ae99SBarry Smith #define __FUNCT__ "DAComputeJacobian1" 105647c6ae99SBarry Smith /*@ 105747c6ae99SBarry Smith DAComputeJacobian1 - Evaluates a local Jacobian function on each processor that 105847c6ae99SBarry Smith share a DA 105947c6ae99SBarry Smith 106047c6ae99SBarry Smith Input Parameters: 1061*9a42bb27SBarry Smith + da - the DM that defines the grid 106247c6ae99SBarry Smith . vu - input vector (ghosted) 106347c6ae99SBarry Smith . J - output matrix 106447c6ae99SBarry Smith - w - any user data 106547c6ae99SBarry Smith 106647c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 106747c6ae99SBarry Smith 106847c6ae99SBarry Smith Level: advanced 106947c6ae99SBarry Smith 107047c6ae99SBarry Smith .seealso: DAFormFunction1() 107147c6ae99SBarry Smith 107247c6ae99SBarry Smith @*/ 1073*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAComputeJacobian1(DM da,Vec vu,Mat J,void *w) 107447c6ae99SBarry Smith { 107547c6ae99SBarry Smith PetscErrorCode ierr; 107647c6ae99SBarry Smith void *u; 107747c6ae99SBarry Smith DALocalInfo info; 107847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 107947c6ae99SBarry Smith 108047c6ae99SBarry Smith PetscFunctionBegin; 108147c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 108247c6ae99SBarry Smith ierr = DAVecGetArray(da,vu,&u);CHKERRQ(ierr); 108347c6ae99SBarry Smith ierr = (*dd->lj)(&info,u,J,w);CHKERRQ(ierr); 108447c6ae99SBarry Smith ierr = DAVecRestoreArray(da,vu,&u);CHKERRQ(ierr); 108547c6ae99SBarry Smith PetscFunctionReturn(0); 108647c6ae99SBarry Smith } 108747c6ae99SBarry Smith 108847c6ae99SBarry Smith 108947c6ae99SBarry Smith #undef __FUNCT__ 109047c6ae99SBarry Smith #define __FUNCT__ "DAComputeJacobian1WithAdifor" 109147c6ae99SBarry Smith /* 109247c6ae99SBarry Smith DAComputeJacobian1WithAdifor - Evaluates a ADIFOR provided Jacobian local function on each processor that 109347c6ae99SBarry Smith share a DA 109447c6ae99SBarry Smith 109547c6ae99SBarry Smith Input Parameters: 1096*9a42bb27SBarry Smith + da - the DM that defines the grid 109747c6ae99SBarry Smith . vu - input vector (ghosted) 109847c6ae99SBarry Smith . J - output matrix 109947c6ae99SBarry Smith - w - any user data 110047c6ae99SBarry Smith 110147c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu upon entry 110247c6ae99SBarry Smith 110347c6ae99SBarry Smith .seealso: DAFormFunction1() 110447c6ae99SBarry Smith 110547c6ae99SBarry Smith */ 1106*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAComputeJacobian1WithAdifor(DM da,Vec vu,Mat J,void *w) 110747c6ae99SBarry Smith { 110847c6ae99SBarry Smith PetscErrorCode ierr; 110947c6ae99SBarry Smith PetscInt i,Nc,N; 111047c6ae99SBarry Smith ISColoringValue *color; 111147c6ae99SBarry Smith DALocalInfo info; 111247c6ae99SBarry Smith PetscScalar *u,*g_u,*g_f,*f = 0,*p_u; 111347c6ae99SBarry Smith ISColoring iscoloring; 111447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 111547c6ae99SBarry Smith void (*lf)(PetscInt*,DALocalInfo*,PetscScalar*,PetscScalar*,PetscInt*,PetscScalar*,PetscScalar*,PetscInt*,void*,PetscErrorCode*) = 111647c6ae99SBarry Smith (void (*)(PetscInt*,DALocalInfo*,PetscScalar*,PetscScalar*,PetscInt*,PetscScalar*,PetscScalar*,PetscInt*,void*,PetscErrorCode*))*dd->adifor_lf; 111747c6ae99SBarry Smith 111847c6ae99SBarry Smith PetscFunctionBegin; 111947c6ae99SBarry Smith ierr = DAGetColoring(da,IS_COLORING_GHOSTED,MATAIJ,&iscoloring);CHKERRQ(ierr); 112047c6ae99SBarry Smith Nc = iscoloring->n; 112147c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 112247c6ae99SBarry Smith N = info.gxm*info.gym*info.gzm*info.dof; 112347c6ae99SBarry Smith 112447c6ae99SBarry Smith /* get space for derivative objects. */ 112547c6ae99SBarry Smith ierr = PetscMalloc(Nc*info.gxm*info.gym*info.gzm*info.dof*sizeof(PetscScalar),&g_u);CHKERRQ(ierr); 112647c6ae99SBarry Smith ierr = PetscMemzero(g_u,Nc*info.gxm*info.gym*info.gzm*info.dof*sizeof(PetscScalar));CHKERRQ(ierr); 112747c6ae99SBarry Smith p_u = g_u; 112847c6ae99SBarry Smith color = iscoloring->colors; 112947c6ae99SBarry Smith for (i=0; i<N; i++) { 113047c6ae99SBarry Smith p_u[*color++] = 1.0; 113147c6ae99SBarry Smith p_u += Nc; 113247c6ae99SBarry Smith } 113347c6ae99SBarry Smith ierr = ISColoringDestroy(iscoloring);CHKERRQ(ierr); 113447c6ae99SBarry 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); 113547c6ae99SBarry Smith 113647c6ae99SBarry Smith /* Seed the input array g_u with coloring information */ 113747c6ae99SBarry Smith 113847c6ae99SBarry Smith ierr = VecGetArray(vu,&u);CHKERRQ(ierr); 113947c6ae99SBarry Smith (lf)(&Nc,&info,u,g_u,&Nc,f,g_f,&Nc,w,&ierr);CHKERRQ(ierr); 114047c6ae99SBarry Smith ierr = VecRestoreArray(vu,&u);CHKERRQ(ierr); 114147c6ae99SBarry Smith 114247c6ae99SBarry Smith /* stick the values into the matrix */ 114347c6ae99SBarry Smith /* PetscScalarView(Nc*info.xm*info.ym,g_f,0); */ 114447c6ae99SBarry Smith ierr = MatSetValuesAdifor(J,Nc,g_f);CHKERRQ(ierr); 114547c6ae99SBarry Smith 114647c6ae99SBarry Smith /* return space for derivative objects. */ 114747c6ae99SBarry Smith ierr = PetscFree(g_u);CHKERRQ(ierr); 114847c6ae99SBarry Smith ierr = PetscFree2(g_f,f);CHKERRQ(ierr); 114947c6ae99SBarry Smith PetscFunctionReturn(0); 115047c6ae99SBarry Smith } 115147c6ae99SBarry Smith 115247c6ae99SBarry Smith #undef __FUNCT__ 115347c6ae99SBarry Smith #define __FUNCT__ "DAFormJacobianLocal" 115447c6ae99SBarry Smith /*@C 115547c6ae99SBarry Smith DAFormjacobianLocal - This is a universal Jacobian evaluation routine for 1156*9a42bb27SBarry Smith a local DM function. 115747c6ae99SBarry Smith 115847c6ae99SBarry Smith Collective on DA 115947c6ae99SBarry Smith 116047c6ae99SBarry Smith Input Parameters: 1161*9a42bb27SBarry Smith + da - the DM context 116247c6ae99SBarry Smith . func - The local function 116347c6ae99SBarry Smith . X - input vector 116447c6ae99SBarry Smith . J - Jacobian matrix 116547c6ae99SBarry Smith - ctx - A user context 116647c6ae99SBarry Smith 116747c6ae99SBarry Smith Level: intermediate 116847c6ae99SBarry Smith 116947c6ae99SBarry Smith .seealso: DASetLocalFunction(), DASetLocalJacobian(), DASetLocalAdicFunction(), DASetLocalAdicMFFunction(), 117047c6ae99SBarry Smith SNESSetFunction(), SNESSetJacobian() 117147c6ae99SBarry Smith 117247c6ae99SBarry Smith @*/ 1173*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAFormJacobianLocal(DM da, DALocalFunction1 func, Vec X, Mat J, void *ctx) 117447c6ae99SBarry Smith { 117547c6ae99SBarry Smith Vec localX; 117647c6ae99SBarry Smith DALocalInfo info; 117747c6ae99SBarry Smith void *u; 117847c6ae99SBarry Smith PetscErrorCode ierr; 117947c6ae99SBarry Smith 118047c6ae99SBarry Smith PetscFunctionBegin; 1181*9a42bb27SBarry Smith ierr = DMGetLocalVector(da,&localX);CHKERRQ(ierr); 118247c6ae99SBarry Smith /* 118347c6ae99SBarry Smith Scatter ghost points to local vector, using the 2-step process 1184*9a42bb27SBarry Smith DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). 118547c6ae99SBarry Smith */ 1186*9a42bb27SBarry Smith ierr = DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 1187*9a42bb27SBarry Smith ierr = DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX);CHKERRQ(ierr); 118847c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 118947c6ae99SBarry Smith ierr = DAVecGetArray(da,localX,&u);CHKERRQ(ierr); 119047c6ae99SBarry Smith ierr = (*func)(&info,u,J,ctx); 119147c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 119247c6ae99SBarry Smith PetscErrorCode pierr = DAVecRestoreArray(da,localX,&u);CHKERRQ(pierr); 119347c6ae99SBarry Smith } 119447c6ae99SBarry Smith CHKERRQ(ierr); 119547c6ae99SBarry Smith ierr = DAVecRestoreArray(da,localX,&u);CHKERRQ(ierr); 119647c6ae99SBarry Smith if (PetscExceptionValue(ierr)) { 1197*9a42bb27SBarry Smith PetscErrorCode pierr = DMRestoreLocalVector(da,&localX);CHKERRQ(pierr); 119847c6ae99SBarry Smith } 119947c6ae99SBarry Smith CHKERRQ(ierr); 1200*9a42bb27SBarry Smith ierr = DMRestoreLocalVector(da,&localX);CHKERRQ(ierr); 120147c6ae99SBarry Smith PetscFunctionReturn(0); 120247c6ae99SBarry Smith } 120347c6ae99SBarry Smith 120447c6ae99SBarry Smith #undef __FUNCT__ 120547c6ae99SBarry Smith #define __FUNCT__ "DAMultiplyByJacobian1WithAD" 120647c6ae99SBarry Smith /*@C 120747c6ae99SBarry Smith DAMultiplyByJacobian1WithAD - Applies a Jacobian function supplied by ADIFOR or ADIC 120847c6ae99SBarry Smith to a vector on each processor that shares a DA. 120947c6ae99SBarry Smith 121047c6ae99SBarry Smith Input Parameters: 1211*9a42bb27SBarry Smith + da - the DM that defines the grid 121247c6ae99SBarry Smith . vu - Jacobian is computed at this point (ghosted) 121347c6ae99SBarry Smith . v - product is done on this vector (ghosted) 121447c6ae99SBarry Smith . fu - output vector = J(vu)*v (not ghosted) 121547c6ae99SBarry Smith - w - any user data 121647c6ae99SBarry Smith 121747c6ae99SBarry Smith Notes: 121847c6ae99SBarry Smith This routine does NOT do ghost updates on vu and v upon entry. 121947c6ae99SBarry Smith 122047c6ae99SBarry Smith Automatically calls DAMultiplyByJacobian1WithAdifor() or DAMultiplyByJacobian1WithAdic() 122147c6ae99SBarry Smith depending on whether DASetLocalAdicMFFunction() or DASetLocalAdiforMFFunction() was called. 122247c6ae99SBarry Smith 122347c6ae99SBarry Smith Level: advanced 122447c6ae99SBarry Smith 122547c6ae99SBarry Smith .seealso: DAFormFunction1(), DAMultiplyByJacobian1WithAdifor(), DAMultiplyByJacobian1WithAdic() 122647c6ae99SBarry Smith 122747c6ae99SBarry Smith @*/ 1228*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAMultiplyByJacobian1WithAD(DM da,Vec u,Vec v,Vec f,void *w) 122947c6ae99SBarry Smith { 123047c6ae99SBarry Smith PetscErrorCode ierr; 123147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 123247c6ae99SBarry Smith 123347c6ae99SBarry Smith PetscFunctionBegin; 123447c6ae99SBarry Smith if (dd->adicmf_lf) { 123547c6ae99SBarry Smith #if defined(PETSC_HAVE_ADIC) 123647c6ae99SBarry Smith ierr = DAMultiplyByJacobian1WithAdic(da,u,v,f,w);CHKERRQ(ierr); 123747c6ae99SBarry Smith #else 123847c6ae99SBarry Smith SETERRQ(((PetscObject)da)->comm,PETSC_ERR_SUP_SYS,"Requires ADIC to be installed and cannot use complex numbers"); 123947c6ae99SBarry Smith #endif 124047c6ae99SBarry Smith } else if (dd->adiformf_lf) { 124147c6ae99SBarry Smith ierr = DAMultiplyByJacobian1WithAdifor(da,u,v,f,w);CHKERRQ(ierr); 124247c6ae99SBarry Smith } else { 124347c6ae99SBarry Smith SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ORDER,"Must call DASetLocalAdiforMFFunction() or DASetLocalAdicMFFunction() before using"); 124447c6ae99SBarry Smith } 124547c6ae99SBarry Smith PetscFunctionReturn(0); 124647c6ae99SBarry Smith } 124747c6ae99SBarry Smith 124847c6ae99SBarry Smith 124947c6ae99SBarry Smith #undef __FUNCT__ 125047c6ae99SBarry Smith #define __FUNCT__ "DAMultiplyByJacobian1WithAdifor" 125147c6ae99SBarry Smith /*@C 125247c6ae99SBarry Smith DAMultiplyByJacobian1WithAdifor - Applies a ADIFOR provided Jacobian function on each processor that 1253*9a42bb27SBarry Smith share a DM to a vector 125447c6ae99SBarry Smith 125547c6ae99SBarry Smith Input Parameters: 1256*9a42bb27SBarry Smith + da - the DM that defines the grid 125747c6ae99SBarry Smith . vu - Jacobian is computed at this point (ghosted) 125847c6ae99SBarry Smith . v - product is done on this vector (ghosted) 125947c6ae99SBarry Smith . fu - output vector = J(vu)*v (not ghosted) 126047c6ae99SBarry Smith - w - any user data 126147c6ae99SBarry Smith 126247c6ae99SBarry Smith Notes: Does NOT do ghost updates on vu and v upon entry 126347c6ae99SBarry Smith 126447c6ae99SBarry Smith Level: advanced 126547c6ae99SBarry Smith 126647c6ae99SBarry Smith .seealso: DAFormFunction1() 126747c6ae99SBarry Smith 126847c6ae99SBarry Smith @*/ 1269*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DAMultiplyByJacobian1WithAdifor(DM da,Vec u,Vec v,Vec f,void *w) 127047c6ae99SBarry Smith { 127147c6ae99SBarry Smith PetscErrorCode ierr; 127247c6ae99SBarry Smith PetscScalar *au,*av,*af,*awork; 127347c6ae99SBarry Smith Vec work; 127447c6ae99SBarry Smith DALocalInfo info; 127547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 127647c6ae99SBarry Smith void (*lf)(DALocalInfo*,PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,void*,PetscErrorCode*) = 127747c6ae99SBarry Smith (void (*)(DALocalInfo*,PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,void*,PetscErrorCode*))*dd->adiformf_lf; 127847c6ae99SBarry Smith 127947c6ae99SBarry Smith PetscFunctionBegin; 128047c6ae99SBarry Smith ierr = DAGetLocalInfo(da,&info);CHKERRQ(ierr); 128147c6ae99SBarry Smith 1282*9a42bb27SBarry Smith ierr = DMGetGlobalVector(da,&work);CHKERRQ(ierr); 128347c6ae99SBarry Smith ierr = VecGetArray(u,&au);CHKERRQ(ierr); 128447c6ae99SBarry Smith ierr = VecGetArray(v,&av);CHKERRQ(ierr); 128547c6ae99SBarry Smith ierr = VecGetArray(f,&af);CHKERRQ(ierr); 128647c6ae99SBarry Smith ierr = VecGetArray(work,&awork);CHKERRQ(ierr); 128747c6ae99SBarry Smith (lf)(&info,au,av,awork,af,w,&ierr);CHKERRQ(ierr); 128847c6ae99SBarry Smith ierr = VecRestoreArray(u,&au);CHKERRQ(ierr); 128947c6ae99SBarry Smith ierr = VecRestoreArray(v,&av);CHKERRQ(ierr); 129047c6ae99SBarry Smith ierr = VecRestoreArray(f,&af);CHKERRQ(ierr); 129147c6ae99SBarry Smith ierr = VecRestoreArray(work,&awork);CHKERRQ(ierr); 1292*9a42bb27SBarry Smith ierr = DMRestoreGlobalVector(da,&work);CHKERRQ(ierr); 129347c6ae99SBarry Smith 129447c6ae99SBarry Smith PetscFunctionReturn(0); 129547c6ae99SBarry Smith } 129647c6ae99SBarry Smith 129747c6ae99SBarry Smith EXTERN_C_BEGIN 129847c6ae99SBarry Smith #undef __FUNCT__ 1299*9a42bb27SBarry Smith #define __FUNCT__ "DMSetUp_DA_2D" 1300*9a42bb27SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DMSetUp_DA_2D(DM da) 130147c6ae99SBarry Smith { 130247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 130347c6ae99SBarry Smith const PetscInt M = dd->M; 130447c6ae99SBarry Smith const PetscInt N = dd->N; 130547c6ae99SBarry Smith PetscInt m = dd->m; 130647c6ae99SBarry Smith PetscInt n = dd->n; 130747c6ae99SBarry Smith const PetscInt dof = dd->w; 130847c6ae99SBarry Smith const PetscInt s = dd->s; 130947c6ae99SBarry Smith const DAPeriodicType wrap = dd->wrap; 131047c6ae99SBarry Smith const DAStencilType stencil_type = dd->stencil_type; 131147c6ae99SBarry Smith PetscInt *lx = dd->lx; 131247c6ae99SBarry Smith PetscInt *ly = dd->ly; 131347c6ae99SBarry Smith MPI_Comm comm; 131447c6ae99SBarry Smith PetscMPIInt rank,size; 131547c6ae99SBarry Smith PetscInt xs,xe,ys,ye,x,y,Xs,Xe,Ys,Ye,start,end; 131647c6ae99SBarry Smith PetscInt up,down,left,i,n0,n1,n2,n3,n5,n6,n7,n8,*idx,nn; 131747c6ae99SBarry Smith PetscInt xbase,*bases,*ldims,j,x_t,y_t,s_t,base,count; 131847c6ae99SBarry Smith PetscInt s_x,s_y; /* s proportionalized to w */ 131947c6ae99SBarry Smith PetscInt sn0 = 0,sn2 = 0,sn6 = 0,sn8 = 0; 132047c6ae99SBarry Smith Vec local,global; 132147c6ae99SBarry Smith VecScatter ltog,gtol; 132247c6ae99SBarry Smith IS to,from; 132347c6ae99SBarry Smith PetscErrorCode ierr; 132447c6ae99SBarry Smith 132547c6ae99SBarry Smith PetscFunctionBegin; 132647c6ae99SBarry Smith ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); 132747c6ae99SBarry Smith 132847c6ae99SBarry Smith if (dof < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must have 1 or more degrees of freedom per node: %D",dof); 132947c6ae99SBarry Smith if (s < 0) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Stencil width cannot be negative: %D",s); 133047c6ae99SBarry Smith 133147c6ae99SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 133247c6ae99SBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 133347c6ae99SBarry Smith 1334264ace61SBarry Smith da->ops->getelements = DMGetElements_DA_2d_P1; 133547c6ae99SBarry Smith 133647c6ae99SBarry Smith dd->dim = 2; 133747c6ae99SBarry Smith dd->elementtype = DA_ELEMENT_P1; 133847c6ae99SBarry Smith ierr = PetscMalloc(dof*sizeof(char*),&dd->fieldname);CHKERRQ(ierr); 133947c6ae99SBarry Smith ierr = PetscMemzero(dd->fieldname,dof*sizeof(char*));CHKERRQ(ierr); 134047c6ae99SBarry Smith 134147c6ae99SBarry Smith if (m != PETSC_DECIDE) { 134247c6ae99SBarry Smith if (m < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in X direction: %D",m); 134347c6ae99SBarry Smith else if (m > size) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in X direction: %D %d",m,size); 134447c6ae99SBarry Smith } 134547c6ae99SBarry Smith if (n != PETSC_DECIDE) { 134647c6ae99SBarry Smith if (n < 1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Non-positive number of processors in Y direction: %D",n); 134747c6ae99SBarry Smith else if (n > size) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Too many processors in Y direction: %D %d",n,size); 134847c6ae99SBarry Smith } 134947c6ae99SBarry Smith 135047c6ae99SBarry Smith if (m == PETSC_DECIDE || n == PETSC_DECIDE) { 135147c6ae99SBarry Smith if (n != PETSC_DECIDE) { 135247c6ae99SBarry Smith m = size/n; 135347c6ae99SBarry Smith } else if (m != PETSC_DECIDE) { 135447c6ae99SBarry Smith n = size/m; 135547c6ae99SBarry Smith } else { 135647c6ae99SBarry Smith /* try for squarish distribution */ 135747c6ae99SBarry Smith m = (PetscInt)(0.5 + sqrt(((double)M)*((double)size)/((double)N))); 135847c6ae99SBarry Smith if (!m) m = 1; 135947c6ae99SBarry Smith while (m > 0) { 136047c6ae99SBarry Smith n = size/m; 136147c6ae99SBarry Smith if (m*n == size) break; 136247c6ae99SBarry Smith m--; 136347c6ae99SBarry Smith } 136447c6ae99SBarry Smith if (M > N && m < n) {PetscInt _m = m; m = n; n = _m;} 136547c6ae99SBarry Smith } 136647c6ae99SBarry 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 "); 136747c6ae99SBarry Smith } else if (m*n != size) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Given Bad partition"); 136847c6ae99SBarry Smith 136947c6ae99SBarry Smith if (M < m) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in x direction is too fine! %D %D",M,m); 137047c6ae99SBarry Smith if (N < n) SETERRQ2(comm,PETSC_ERR_ARG_OUTOFRANGE,"Partition in y direction is too fine! %D %D",N,n); 137147c6ae99SBarry Smith 137247c6ae99SBarry Smith /* 137347c6ae99SBarry Smith Determine locally owned region 137447c6ae99SBarry Smith xs is the first local node number, x is the number of local nodes 137547c6ae99SBarry Smith */ 137647c6ae99SBarry Smith if (!lx) { 137747c6ae99SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt), &dd->lx);CHKERRQ(ierr); 137847c6ae99SBarry Smith lx = dd->lx; 137947c6ae99SBarry Smith for (i=0; i<m; i++) { 138047c6ae99SBarry Smith lx[i] = M/m + ((M % m) > i); 138147c6ae99SBarry Smith } 138247c6ae99SBarry Smith } 138347c6ae99SBarry Smith x = lx[rank % m]; 138447c6ae99SBarry Smith xs = 0; 138547c6ae99SBarry Smith for (i=0; i<(rank % m); i++) { 138647c6ae99SBarry Smith xs += lx[i]; 138747c6ae99SBarry Smith } 138847c6ae99SBarry Smith #if defined(PETSC_USE_DEBUG) 138947c6ae99SBarry Smith left = xs; 139047c6ae99SBarry Smith for (i=(rank % m); i<m; i++) { 139147c6ae99SBarry Smith left += lx[i]; 139247c6ae99SBarry Smith } 139347c6ae99SBarry 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); 139447c6ae99SBarry Smith #endif 139547c6ae99SBarry Smith 139647c6ae99SBarry Smith /* 139747c6ae99SBarry Smith Determine locally owned region 139847c6ae99SBarry Smith ys is the first local node number, y is the number of local nodes 139947c6ae99SBarry Smith */ 140047c6ae99SBarry Smith if (!ly) { 140147c6ae99SBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt), &dd->ly);CHKERRQ(ierr); 140247c6ae99SBarry Smith ly = dd->ly; 140347c6ae99SBarry Smith for (i=0; i<n; i++) { 140447c6ae99SBarry Smith ly[i] = N/n + ((N % n) > i); 140547c6ae99SBarry Smith } 140647c6ae99SBarry Smith } 140747c6ae99SBarry Smith y = ly[rank/m]; 140847c6ae99SBarry Smith ys = 0; 140947c6ae99SBarry Smith for (i=0; i<(rank/m); i++) { 141047c6ae99SBarry Smith ys += ly[i]; 141147c6ae99SBarry Smith } 141247c6ae99SBarry Smith #if defined(PETSC_USE_DEBUG) 141347c6ae99SBarry Smith left = ys; 141447c6ae99SBarry Smith for (i=(rank/m); i<n; i++) { 141547c6ae99SBarry Smith left += ly[i]; 141647c6ae99SBarry Smith } 141747c6ae99SBarry 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); 141847c6ae99SBarry Smith #endif 141947c6ae99SBarry Smith 142047c6ae99SBarry 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); 142147c6ae99SBarry 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); 142247c6ae99SBarry Smith xe = xs + x; 142347c6ae99SBarry Smith ye = ys + y; 142447c6ae99SBarry Smith 142547c6ae99SBarry Smith /* determine ghost region */ 142647c6ae99SBarry Smith /* Assume No Periodicity */ 142747c6ae99SBarry Smith if (xs-s > 0) Xs = xs - s; else Xs = 0; 142847c6ae99SBarry Smith if (ys-s > 0) Ys = ys - s; else Ys = 0; 142947c6ae99SBarry Smith if (xe+s <= M) Xe = xe + s; else Xe = M; 143047c6ae99SBarry Smith if (ye+s <= N) Ye = ye + s; else Ye = N; 143147c6ae99SBarry Smith 143247c6ae99SBarry Smith /* X Periodic */ 143347c6ae99SBarry Smith if (DAXPeriodic(wrap)){ 143447c6ae99SBarry Smith Xs = xs - s; 143547c6ae99SBarry Smith Xe = xe + s; 143647c6ae99SBarry Smith } 143747c6ae99SBarry Smith 143847c6ae99SBarry Smith /* Y Periodic */ 143947c6ae99SBarry Smith if (DAYPeriodic(wrap)){ 144047c6ae99SBarry Smith Ys = ys - s; 144147c6ae99SBarry Smith Ye = ye + s; 144247c6ae99SBarry Smith } 144347c6ae99SBarry Smith 144447c6ae99SBarry Smith /* Resize all X parameters to reflect w */ 144547c6ae99SBarry Smith x *= dof; 144647c6ae99SBarry Smith xs *= dof; 144747c6ae99SBarry Smith xe *= dof; 144847c6ae99SBarry Smith Xs *= dof; 144947c6ae99SBarry Smith Xe *= dof; 145047c6ae99SBarry Smith s_x = s*dof; 145147c6ae99SBarry Smith s_y = s; 145247c6ae99SBarry Smith 145347c6ae99SBarry Smith /* determine starting point of each processor */ 145447c6ae99SBarry Smith nn = x*y; 145547c6ae99SBarry Smith ierr = PetscMalloc2(size+1,PetscInt,&bases,size,PetscInt,&ldims);CHKERRQ(ierr); 145647c6ae99SBarry Smith ierr = MPI_Allgather(&nn,1,MPIU_INT,ldims,1,MPIU_INT,comm);CHKERRQ(ierr); 145747c6ae99SBarry Smith bases[0] = 0; 145847c6ae99SBarry Smith for (i=1; i<=size; i++) { 145947c6ae99SBarry Smith bases[i] = ldims[i-1]; 146047c6ae99SBarry Smith } 146147c6ae99SBarry Smith for (i=1; i<=size; i++) { 146247c6ae99SBarry Smith bases[i] += bases[i-1]; 146347c6ae99SBarry Smith } 146447c6ae99SBarry Smith 146547c6ae99SBarry Smith /* allocate the base parallel and sequential vectors */ 146647c6ae99SBarry Smith dd->Nlocal = x*y; 146747c6ae99SBarry Smith ierr = VecCreateMPIWithArray(comm,dd->Nlocal,PETSC_DECIDE,0,&global);CHKERRQ(ierr); 146847c6ae99SBarry Smith ierr = VecSetBlockSize(global,dof);CHKERRQ(ierr); 146947c6ae99SBarry Smith dd->nlocal = (Xe-Xs)*(Ye-Ys); 147047c6ae99SBarry Smith ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,dd->nlocal,0,&local);CHKERRQ(ierr); 147147c6ae99SBarry Smith ierr = VecSetBlockSize(local,dof);CHKERRQ(ierr); 147247c6ae99SBarry Smith 147347c6ae99SBarry Smith 147447c6ae99SBarry Smith /* generate appropriate vector scatters */ 147547c6ae99SBarry Smith /* local to global inserts non-ghost point region into global */ 147647c6ae99SBarry Smith ierr = VecGetOwnershipRange(global,&start,&end);CHKERRQ(ierr); 147747c6ae99SBarry Smith ierr = ISCreateStride(comm,x*y,start,1,&to);CHKERRQ(ierr); 147847c6ae99SBarry Smith 147947c6ae99SBarry Smith left = xs - Xs; down = ys - Ys; up = down + y; 148047c6ae99SBarry Smith ierr = PetscMalloc(x*(up - down)*sizeof(PetscInt),&idx);CHKERRQ(ierr); 148147c6ae99SBarry Smith count = 0; 148247c6ae99SBarry Smith for (i=down; i<up; i++) { 148347c6ae99SBarry Smith for (j=0; j<x/dof; j++) { 148447c6ae99SBarry Smith idx[count++] = (left + i*(Xe-Xs) + j*dof)/dof; 148547c6ae99SBarry Smith } 148647c6ae99SBarry Smith } 148747c6ae99SBarry Smith ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&from);CHKERRQ(ierr); 148847c6ae99SBarry Smith 148947c6ae99SBarry Smith ierr = VecScatterCreate(local,from,global,to,<og);CHKERRQ(ierr); 149047c6ae99SBarry Smith ierr = PetscLogObjectParent(dd,ltog);CHKERRQ(ierr); 149147c6ae99SBarry Smith ierr = ISDestroy(from);CHKERRQ(ierr); 149247c6ae99SBarry Smith ierr = ISDestroy(to);CHKERRQ(ierr); 149347c6ae99SBarry Smith 149447c6ae99SBarry Smith /* global to local must include ghost points */ 149547c6ae99SBarry Smith if (stencil_type == DA_STENCIL_BOX) { 149647c6ae99SBarry Smith ierr = ISCreateStride(comm,(Xe-Xs)*(Ye-Ys),0,1,&to);CHKERRQ(ierr); 149747c6ae99SBarry Smith } else { 149847c6ae99SBarry Smith /* must drop into cross shape region */ 149947c6ae99SBarry Smith /* ---------| 150047c6ae99SBarry Smith | top | 150147c6ae99SBarry Smith |--- ---| 150247c6ae99SBarry Smith | middle | 150347c6ae99SBarry Smith | | 150447c6ae99SBarry Smith ---- ---- 150547c6ae99SBarry Smith | bottom | 150647c6ae99SBarry Smith ----------- 150747c6ae99SBarry Smith Xs xs xe Xe */ 150847c6ae99SBarry Smith /* bottom */ 150947c6ae99SBarry Smith left = xs - Xs; down = ys - Ys; up = down + y; 151047c6ae99SBarry Smith count = down*(xe-xs) + (up-down)*(Xe-Xs) + (Ye-Ys-up)*(xe-xs); 151147c6ae99SBarry Smith ierr = PetscMalloc(count*sizeof(PetscInt)/dof,&idx);CHKERRQ(ierr); 151247c6ae99SBarry Smith count = 0; 151347c6ae99SBarry Smith for (i=0; i<down; i++) { 151447c6ae99SBarry Smith for (j=0; j<xe-xs; j += dof) { 151547c6ae99SBarry Smith idx[count++] = left + i*(Xe-Xs) + j; 151647c6ae99SBarry Smith } 151747c6ae99SBarry Smith } 151847c6ae99SBarry Smith /* middle */ 151947c6ae99SBarry Smith for (i=down; i<up; i++) { 152047c6ae99SBarry Smith for (j=0; j<Xe-Xs; j += dof) { 152147c6ae99SBarry Smith idx[count++] = i*(Xe-Xs) + j; 152247c6ae99SBarry Smith } 152347c6ae99SBarry Smith } 152447c6ae99SBarry Smith /* top */ 152547c6ae99SBarry Smith for (i=up; i<Ye-Ys; i++) { 152647c6ae99SBarry Smith for (j=0; j<xe-xs; j += dof) { 152747c6ae99SBarry Smith idx[count++] = (left + i*(Xe-Xs) + j); 152847c6ae99SBarry Smith } 152947c6ae99SBarry Smith } 153047c6ae99SBarry Smith for (i=0; i<count; i++) idx[i] = idx[i]/dof; 153147c6ae99SBarry Smith ierr = ISCreateBlock(comm,dof,count,idx,PETSC_OWN_POINTER,&to);CHKERRQ(ierr); 153247c6ae99SBarry Smith } 153347c6ae99SBarry Smith 153447c6ae99SBarry Smith 153547c6ae99SBarry Smith /* determine who lies on each side of us stored in n6 n7 n8 153647c6ae99SBarry Smith n3 n5 153747c6ae99SBarry Smith n0 n1 n2 153847c6ae99SBarry Smith */ 153947c6ae99SBarry Smith 154047c6ae99SBarry Smith /* Assume the Non-Periodic Case */ 154147c6ae99SBarry Smith n1 = rank - m; 154247c6ae99SBarry Smith if (rank % m) { 154347c6ae99SBarry Smith n0 = n1 - 1; 154447c6ae99SBarry Smith } else { 154547c6ae99SBarry Smith n0 = -1; 154647c6ae99SBarry Smith } 154747c6ae99SBarry Smith if ((rank+1) % m) { 154847c6ae99SBarry Smith n2 = n1 + 1; 154947c6ae99SBarry Smith n5 = rank + 1; 155047c6ae99SBarry Smith n8 = rank + m + 1; if (n8 >= m*n) n8 = -1; 155147c6ae99SBarry Smith } else { 155247c6ae99SBarry Smith n2 = -1; n5 = -1; n8 = -1; 155347c6ae99SBarry Smith } 155447c6ae99SBarry Smith if (rank % m) { 155547c6ae99SBarry Smith n3 = rank - 1; 155647c6ae99SBarry Smith n6 = n3 + m; if (n6 >= m*n) n6 = -1; 155747c6ae99SBarry Smith } else { 155847c6ae99SBarry Smith n3 = -1; n6 = -1; 155947c6ae99SBarry Smith } 156047c6ae99SBarry Smith n7 = rank + m; if (n7 >= m*n) n7 = -1; 156147c6ae99SBarry Smith 156247c6ae99SBarry Smith 156347c6ae99SBarry Smith /* Modify for Periodic Cases */ 156447c6ae99SBarry Smith if (wrap == DA_YPERIODIC) { /* Handle Top and Bottom Sides */ 156547c6ae99SBarry Smith if (n1 < 0) n1 = rank + m * (n-1); 156647c6ae99SBarry Smith if (n7 < 0) n7 = rank - m * (n-1); 156747c6ae99SBarry Smith if ((n3 >= 0) && (n0 < 0)) n0 = size - m + rank - 1; 156847c6ae99SBarry Smith if ((n3 >= 0) && (n6 < 0)) n6 = (rank%m)-1; 156947c6ae99SBarry Smith if ((n5 >= 0) && (n2 < 0)) n2 = size - m + rank + 1; 157047c6ae99SBarry Smith if ((n5 >= 0) && (n8 < 0)) n8 = (rank%m)+1; 157147c6ae99SBarry Smith } else if (wrap == DA_XPERIODIC) { /* Handle Left and Right Sides */ 157247c6ae99SBarry Smith if (n3 < 0) n3 = rank + (m-1); 157347c6ae99SBarry Smith if (n5 < 0) n5 = rank - (m-1); 157447c6ae99SBarry Smith if ((n1 >= 0) && (n0 < 0)) n0 = rank-1; 157547c6ae99SBarry Smith if ((n1 >= 0) && (n2 < 0)) n2 = rank-2*m+1; 157647c6ae99SBarry Smith if ((n7 >= 0) && (n6 < 0)) n6 = rank+2*m-1; 157747c6ae99SBarry Smith if ((n7 >= 0) && (n8 < 0)) n8 = rank+1; 157847c6ae99SBarry Smith } else if (wrap == DA_XYPERIODIC) { 157947c6ae99SBarry Smith 158047c6ae99SBarry Smith /* Handle all four corners */ 158147c6ae99SBarry Smith if ((n6 < 0) && (n7 < 0) && (n3 < 0)) n6 = m-1; 158247c6ae99SBarry Smith if ((n8 < 0) && (n7 < 0) && (n5 < 0)) n8 = 0; 158347c6ae99SBarry Smith if ((n2 < 0) && (n5 < 0) && (n1 < 0)) n2 = size-m; 158447c6ae99SBarry Smith if ((n0 < 0) && (n3 < 0) && (n1 < 0)) n0 = size-1; 158547c6ae99SBarry Smith 158647c6ae99SBarry Smith /* Handle Top and Bottom Sides */ 158747c6ae99SBarry Smith if (n1 < 0) n1 = rank + m * (n-1); 158847c6ae99SBarry Smith if (n7 < 0) n7 = rank - m * (n-1); 158947c6ae99SBarry Smith if ((n3 >= 0) && (n0 < 0)) n0 = size - m + rank - 1; 159047c6ae99SBarry Smith if ((n3 >= 0) && (n6 < 0)) n6 = (rank%m)-1; 159147c6ae99SBarry Smith if ((n5 >= 0) && (n2 < 0)) n2 = size - m + rank + 1; 159247c6ae99SBarry Smith if ((n5 >= 0) && (n8 < 0)) n8 = (rank%m)+1; 159347c6ae99SBarry Smith 159447c6ae99SBarry Smith /* Handle Left and Right Sides */ 159547c6ae99SBarry Smith if (n3 < 0) n3 = rank + (m-1); 159647c6ae99SBarry Smith if (n5 < 0) n5 = rank - (m-1); 159747c6ae99SBarry Smith if ((n1 >= 0) && (n0 < 0)) n0 = rank-1; 159847c6ae99SBarry Smith if ((n1 >= 0) && (n2 < 0)) n2 = rank-2*m+1; 159947c6ae99SBarry Smith if ((n7 >= 0) && (n6 < 0)) n6 = rank+2*m-1; 160047c6ae99SBarry Smith if ((n7 >= 0) && (n8 < 0)) n8 = rank+1; 160147c6ae99SBarry Smith } 160247c6ae99SBarry Smith ierr = PetscMalloc(9*sizeof(PetscInt),&dd->neighbors);CHKERRQ(ierr); 160347c6ae99SBarry Smith dd->neighbors[0] = n0; 160447c6ae99SBarry Smith dd->neighbors[1] = n1; 160547c6ae99SBarry Smith dd->neighbors[2] = n2; 160647c6ae99SBarry Smith dd->neighbors[3] = n3; 160747c6ae99SBarry Smith dd->neighbors[4] = rank; 160847c6ae99SBarry Smith dd->neighbors[5] = n5; 160947c6ae99SBarry Smith dd->neighbors[6] = n6; 161047c6ae99SBarry Smith dd->neighbors[7] = n7; 161147c6ae99SBarry Smith dd->neighbors[8] = n8; 161247c6ae99SBarry Smith 161347c6ae99SBarry Smith if (stencil_type == DA_STENCIL_STAR) { 161447c6ae99SBarry Smith /* save corner processor numbers */ 161547c6ae99SBarry Smith sn0 = n0; sn2 = n2; sn6 = n6; sn8 = n8; 161647c6ae99SBarry Smith n0 = n2 = n6 = n8 = -1; 161747c6ae99SBarry Smith } 161847c6ae99SBarry Smith 161947c6ae99SBarry Smith ierr = PetscMalloc((x+2*s_x)*(y+2*s_y)*sizeof(PetscInt),&idx);CHKERRQ(ierr); 162047c6ae99SBarry Smith ierr = PetscLogObjectMemory(da,(x+2*s_x)*(y+2*s_y)*sizeof(PetscInt));CHKERRQ(ierr); 162147c6ae99SBarry Smith nn = 0; 162247c6ae99SBarry Smith 162347c6ae99SBarry Smith xbase = bases[rank]; 162447c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 162547c6ae99SBarry Smith if (n0 >= 0) { /* left below */ 162647c6ae99SBarry Smith x_t = lx[n0 % m]*dof; 162747c6ae99SBarry Smith y_t = ly[(n0/m)]; 162847c6ae99SBarry Smith s_t = bases[n0] + x_t*y_t - (s_y-i)*x_t - s_x; 162947c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 163047c6ae99SBarry Smith } 163147c6ae99SBarry Smith if (n1 >= 0) { /* directly below */ 163247c6ae99SBarry Smith x_t = x; 163347c6ae99SBarry Smith y_t = ly[(n1/m)]; 163447c6ae99SBarry Smith s_t = bases[n1] + x_t*y_t - (s_y+1-i)*x_t; 163547c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 163647c6ae99SBarry Smith } 163747c6ae99SBarry Smith if (n2 >= 0) { /* right below */ 163847c6ae99SBarry Smith x_t = lx[n2 % m]*dof; 163947c6ae99SBarry Smith y_t = ly[(n2/m)]; 164047c6ae99SBarry Smith s_t = bases[n2] + x_t*y_t - (s_y+1-i)*x_t; 164147c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 164247c6ae99SBarry Smith } 164347c6ae99SBarry Smith } 164447c6ae99SBarry Smith 164547c6ae99SBarry Smith for (i=0; i<y; i++) { 164647c6ae99SBarry Smith if (n3 >= 0) { /* directly left */ 164747c6ae99SBarry Smith x_t = lx[n3 % m]*dof; 164847c6ae99SBarry Smith /* y_t = y; */ 164947c6ae99SBarry Smith s_t = bases[n3] + (i+1)*x_t - s_x; 165047c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 165147c6ae99SBarry Smith } 165247c6ae99SBarry Smith 165347c6ae99SBarry Smith for (j=0; j<x; j++) { idx[nn++] = xbase++; } /* interior */ 165447c6ae99SBarry Smith 165547c6ae99SBarry Smith if (n5 >= 0) { /* directly right */ 165647c6ae99SBarry Smith x_t = lx[n5 % m]*dof; 165747c6ae99SBarry Smith /* y_t = y; */ 165847c6ae99SBarry Smith s_t = bases[n5] + (i)*x_t; 165947c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 166047c6ae99SBarry Smith } 166147c6ae99SBarry Smith } 166247c6ae99SBarry Smith 166347c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 166447c6ae99SBarry Smith if (n6 >= 0) { /* left above */ 166547c6ae99SBarry Smith x_t = lx[n6 % m]*dof; 166647c6ae99SBarry Smith /* y_t = ly[(n6/m)]; */ 166747c6ae99SBarry Smith s_t = bases[n6] + (i)*x_t - s_x; 166847c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 166947c6ae99SBarry Smith } 167047c6ae99SBarry Smith if (n7 >= 0) { /* directly above */ 167147c6ae99SBarry Smith x_t = x; 167247c6ae99SBarry Smith /* y_t = ly[(n7/m)]; */ 167347c6ae99SBarry Smith s_t = bases[n7] + (i-1)*x_t; 167447c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 167547c6ae99SBarry Smith } 167647c6ae99SBarry Smith if (n8 >= 0) { /* right above */ 167747c6ae99SBarry Smith x_t = lx[n8 % m]*dof; 167847c6ae99SBarry Smith /* y_t = ly[(n8/m)]; */ 167947c6ae99SBarry Smith s_t = bases[n8] + (i-1)*x_t; 168047c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 168147c6ae99SBarry Smith } 168247c6ae99SBarry Smith } 168347c6ae99SBarry Smith 168447c6ae99SBarry Smith base = bases[rank]; 168547c6ae99SBarry Smith { 168647c6ae99SBarry Smith PetscInt nnn = nn/dof,*iidx; 168747c6ae99SBarry Smith ierr = PetscMalloc(nnn*sizeof(PetscInt),&iidx);CHKERRQ(ierr); 168847c6ae99SBarry Smith for (i=0; i<nnn; i++) { 168947c6ae99SBarry Smith iidx[i] = idx[dof*i]/dof; 169047c6ae99SBarry Smith } 169147c6ae99SBarry Smith ierr = ISCreateBlock(comm,dof,nnn,iidx,PETSC_OWN_POINTER,&from);CHKERRQ(ierr); 169247c6ae99SBarry Smith } 169347c6ae99SBarry Smith ierr = VecScatterCreate(global,from,local,to,>ol);CHKERRQ(ierr); 169447c6ae99SBarry Smith ierr = PetscLogObjectParent(da,gtol);CHKERRQ(ierr); 169547c6ae99SBarry Smith ierr = ISDestroy(to);CHKERRQ(ierr); 169647c6ae99SBarry Smith ierr = ISDestroy(from);CHKERRQ(ierr); 169747c6ae99SBarry Smith 169847c6ae99SBarry Smith if (stencil_type == DA_STENCIL_STAR) { 169947c6ae99SBarry Smith /* 170047c6ae99SBarry Smith Recompute the local to global mappings, this time keeping the 170147c6ae99SBarry Smith information about the cross corner processor numbers. 170247c6ae99SBarry Smith */ 170347c6ae99SBarry Smith n0 = sn0; n2 = sn2; n6 = sn6; n8 = sn8; 170447c6ae99SBarry Smith nn = 0; 170547c6ae99SBarry Smith xbase = bases[rank]; 170647c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 170747c6ae99SBarry Smith if (n0 >= 0) { /* left below */ 170847c6ae99SBarry Smith x_t = lx[n0 % m]*dof; 170947c6ae99SBarry Smith y_t = ly[(n0/m)]; 171047c6ae99SBarry Smith s_t = bases[n0] + x_t*y_t - (s_y-i)*x_t - s_x; 171147c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 171247c6ae99SBarry Smith } 171347c6ae99SBarry Smith if (n1 >= 0) { /* directly below */ 171447c6ae99SBarry Smith x_t = x; 171547c6ae99SBarry Smith y_t = ly[(n1/m)]; 171647c6ae99SBarry Smith s_t = bases[n1] + x_t*y_t - (s_y+1-i)*x_t; 171747c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 171847c6ae99SBarry Smith } 171947c6ae99SBarry Smith if (n2 >= 0) { /* right below */ 172047c6ae99SBarry Smith x_t = lx[n2 % m]*dof; 172147c6ae99SBarry Smith y_t = ly[(n2/m)]; 172247c6ae99SBarry Smith s_t = bases[n2] + x_t*y_t - (s_y+1-i)*x_t; 172347c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 172447c6ae99SBarry Smith } 172547c6ae99SBarry Smith } 172647c6ae99SBarry Smith 172747c6ae99SBarry Smith for (i=0; i<y; i++) { 172847c6ae99SBarry Smith if (n3 >= 0) { /* directly left */ 172947c6ae99SBarry Smith x_t = lx[n3 % m]*dof; 173047c6ae99SBarry Smith /* y_t = y; */ 173147c6ae99SBarry Smith s_t = bases[n3] + (i+1)*x_t - s_x; 173247c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 173347c6ae99SBarry Smith } 173447c6ae99SBarry Smith 173547c6ae99SBarry Smith for (j=0; j<x; j++) { idx[nn++] = xbase++; } /* interior */ 173647c6ae99SBarry Smith 173747c6ae99SBarry Smith if (n5 >= 0) { /* directly right */ 173847c6ae99SBarry Smith x_t = lx[n5 % m]*dof; 173947c6ae99SBarry Smith /* y_t = y; */ 174047c6ae99SBarry Smith s_t = bases[n5] + (i)*x_t; 174147c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 174247c6ae99SBarry Smith } 174347c6ae99SBarry Smith } 174447c6ae99SBarry Smith 174547c6ae99SBarry Smith for (i=1; i<=s_y; i++) { 174647c6ae99SBarry Smith if (n6 >= 0) { /* left above */ 174747c6ae99SBarry Smith x_t = lx[n6 % m]*dof; 174847c6ae99SBarry Smith /* y_t = ly[(n6/m)]; */ 174947c6ae99SBarry Smith s_t = bases[n6] + (i)*x_t - s_x; 175047c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 175147c6ae99SBarry Smith } 175247c6ae99SBarry Smith if (n7 >= 0) { /* directly above */ 175347c6ae99SBarry Smith x_t = x; 175447c6ae99SBarry Smith /* y_t = ly[(n7/m)]; */ 175547c6ae99SBarry Smith s_t = bases[n7] + (i-1)*x_t; 175647c6ae99SBarry Smith for (j=0; j<x_t; j++) { idx[nn++] = s_t++;} 175747c6ae99SBarry Smith } 175847c6ae99SBarry Smith if (n8 >= 0) { /* right above */ 175947c6ae99SBarry Smith x_t = lx[n8 % m]*dof; 176047c6ae99SBarry Smith /* y_t = ly[(n8/m)]; */ 176147c6ae99SBarry Smith s_t = bases[n8] + (i-1)*x_t; 176247c6ae99SBarry Smith for (j=0; j<s_x; j++) { idx[nn++] = s_t++;} 176347c6ae99SBarry Smith } 176447c6ae99SBarry Smith } 176547c6ae99SBarry Smith } 176647c6ae99SBarry Smith ierr = PetscFree2(bases,ldims);CHKERRQ(ierr); 176747c6ae99SBarry Smith 176847c6ae99SBarry Smith dd->m = m; dd->n = n; 176947c6ae99SBarry Smith dd->xs = xs; dd->xe = xe; dd->ys = ys; dd->ye = ye; dd->zs = 0; dd->ze = 1; 177047c6ae99SBarry Smith dd->Xs = Xs; dd->Xe = Xe; dd->Ys = Ys; dd->Ye = Ye; dd->Zs = 0; dd->Ze = 1; 177147c6ae99SBarry Smith 177247c6ae99SBarry Smith ierr = VecDestroy(local);CHKERRQ(ierr); 177347c6ae99SBarry Smith ierr = VecDestroy(global);CHKERRQ(ierr); 177447c6ae99SBarry Smith 177547c6ae99SBarry Smith dd->gtol = gtol; 177647c6ae99SBarry Smith dd->ltog = ltog; 177747c6ae99SBarry Smith dd->idx = idx; 177847c6ae99SBarry Smith dd->Nl = nn; 177947c6ae99SBarry Smith dd->base = base; 1780*9a42bb27SBarry Smith da->ops->view = DMView_DA_2d; 178147c6ae99SBarry Smith 178247c6ae99SBarry Smith /* 178347c6ae99SBarry Smith Set the local to global ordering in the global vector, this allows use 178447c6ae99SBarry Smith of VecSetValuesLocal(). 178547c6ae99SBarry Smith */ 178647c6ae99SBarry Smith ierr = ISLocalToGlobalMappingCreate(comm,nn,idx,PETSC_OWN_POINTER,&dd->ltogmap);CHKERRQ(ierr); 178747c6ae99SBarry Smith ierr = ISLocalToGlobalMappingBlock(dd->ltogmap,dd->w,&dd->ltogmapb);CHKERRQ(ierr); 178847c6ae99SBarry Smith ierr = PetscLogObjectParent(da,dd->ltogmap);CHKERRQ(ierr); 178947c6ae99SBarry Smith 179047c6ae99SBarry Smith dd->ltol = PETSC_NULL; 179147c6ae99SBarry Smith dd->ao = PETSC_NULL; 179247c6ae99SBarry Smith 179347c6ae99SBarry Smith PetscFunctionReturn(0); 179447c6ae99SBarry Smith } 179547c6ae99SBarry Smith EXTERN_C_END 179647c6ae99SBarry Smith 179747c6ae99SBarry Smith #undef __FUNCT__ 179847c6ae99SBarry Smith #define __FUNCT__ "DACreate2d" 179947c6ae99SBarry Smith /*@C 180047c6ae99SBarry Smith DACreate2d - Creates an object that will manage the communication of two-dimensional 180147c6ae99SBarry Smith regular array data that is distributed across some processors. 180247c6ae99SBarry Smith 180347c6ae99SBarry Smith Collective on MPI_Comm 180447c6ae99SBarry Smith 180547c6ae99SBarry Smith Input Parameters: 180647c6ae99SBarry Smith + comm - MPI communicator 180747c6ae99SBarry Smith . wrap - type of periodicity should the array have. 180847c6ae99SBarry Smith Use one of DA_NONPERIODIC, DA_XPERIODIC, DA_YPERIODIC, or DA_XYPERIODIC. 180947c6ae99SBarry Smith . stencil_type - stencil type. Use either DA_STENCIL_BOX or DA_STENCIL_STAR. 181047c6ae99SBarry 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 181147c6ae99SBarry Smith from the command line with -da_grid_x <M> -da_grid_y <N>) 181247c6ae99SBarry Smith . m,n - corresponding number of processors in each dimension 181347c6ae99SBarry Smith (or PETSC_DECIDE to have calculated) 181447c6ae99SBarry Smith . dof - number of degrees of freedom per node 181547c6ae99SBarry Smith . s - stencil width 181647c6ae99SBarry Smith - lx, ly - arrays containing the number of nodes in each cell along 181747c6ae99SBarry Smith the x and y coordinates, or PETSC_NULL. If non-null, these 181847c6ae99SBarry Smith must be of length as m and n, and the corresponding 181947c6ae99SBarry Smith m and n cannot be PETSC_DECIDE. The sum of the lx[] entries 182047c6ae99SBarry Smith must be M, and the sum of the ly[] entries must be N. 182147c6ae99SBarry Smith 182247c6ae99SBarry Smith Output Parameter: 182347c6ae99SBarry Smith . da - the resulting distributed array object 182447c6ae99SBarry Smith 182547c6ae99SBarry Smith Options Database Key: 1826*9a42bb27SBarry Smith + -da_view - Calls DMView() at the conclusion of DACreate2d() 182747c6ae99SBarry Smith . -da_grid_x <nx> - number of grid points in x direction, if M < 0 182847c6ae99SBarry Smith . -da_grid_y <ny> - number of grid points in y direction, if N < 0 182947c6ae99SBarry Smith . -da_processors_x <nx> - number of processors in x direction 183047c6ae99SBarry Smith . -da_processors_y <ny> - number of processors in y direction 183147c6ae99SBarry Smith . -da_refine_x - refinement ratio in x direction 183247c6ae99SBarry Smith - -da_refine_y - refinement ratio in y direction 183347c6ae99SBarry Smith 183447c6ae99SBarry Smith Level: beginner 183547c6ae99SBarry Smith 183647c6ae99SBarry Smith Notes: 183747c6ae99SBarry Smith The stencil type DA_STENCIL_STAR with width 1 corresponds to the 183847c6ae99SBarry Smith standard 5-pt stencil, while DA_STENCIL_BOX with width 1 denotes 183947c6ae99SBarry Smith the standard 9-pt stencil. 184047c6ae99SBarry Smith 184147c6ae99SBarry Smith The array data itself is NOT stored in the DA, it is stored in Vec objects; 184247c6ae99SBarry Smith The appropriate vector objects can be obtained with calls to DACreateGlobalVector() 184347c6ae99SBarry Smith and DACreateLocalVector() and calls to VecDuplicate() if more are needed. 184447c6ae99SBarry Smith 184547c6ae99SBarry Smith .keywords: distributed array, create, two-dimensional 184647c6ae99SBarry Smith 1847*9a42bb27SBarry Smith .seealso: DMDestroy(), DMView(), DACreate1d(), DACreate3d(), DMGlobalToLocalBegin(), DAGetRefinementFactor(), 1848*9a42bb27SBarry Smith DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DALocalToLocalBegin(), DALocalToLocalEnd(), DASetRefinementFactor(), 1849*9a42bb27SBarry Smith DAGetInfo(), DACreateGlobalVector(), DACreateLocalVector(), DACreateNaturalVector(), DALoad(), DAGetOwnershipRanges() 185047c6ae99SBarry Smith 185147c6ae99SBarry Smith @*/ 185247c6ae99SBarry Smith PetscErrorCode PETSCDM_DLLEXPORT DACreate2d(MPI_Comm comm,DAPeriodicType wrap,DAStencilType stencil_type, 1853*9a42bb27SBarry Smith PetscInt M,PetscInt N,PetscInt m,PetscInt n,PetscInt dof,PetscInt s,const PetscInt lx[],const PetscInt ly[],DM *da) 185447c6ae99SBarry Smith { 185547c6ae99SBarry Smith PetscErrorCode ierr; 185647c6ae99SBarry Smith 185747c6ae99SBarry Smith PetscFunctionBegin; 185847c6ae99SBarry Smith ierr = DACreate(comm, da);CHKERRQ(ierr); 185947c6ae99SBarry Smith ierr = DASetDim(*da, 2);CHKERRQ(ierr); 186047c6ae99SBarry Smith ierr = DASetSizes(*da, M, N, 1);CHKERRQ(ierr); 186147c6ae99SBarry Smith ierr = DASetNumProcs(*da, m, n, PETSC_DECIDE);CHKERRQ(ierr); 186247c6ae99SBarry Smith ierr = DASetPeriodicity(*da, wrap);CHKERRQ(ierr); 186347c6ae99SBarry Smith ierr = DASetDof(*da, dof);CHKERRQ(ierr); 186447c6ae99SBarry Smith ierr = DASetStencilType(*da, stencil_type);CHKERRQ(ierr); 186547c6ae99SBarry Smith ierr = DASetStencilWidth(*da, s);CHKERRQ(ierr); 186647c6ae99SBarry Smith ierr = DASetOwnershipRanges(*da, lx, ly, PETSC_NULL);CHKERRQ(ierr); 186747c6ae99SBarry Smith /* This violates the behavior for other classes, but right now users expect negative dimensions to be handled this way */ 1868*9a42bb27SBarry Smith ierr = DMSetFromOptions(*da);CHKERRQ(ierr); 1869*9a42bb27SBarry Smith ierr = DMSetUp(*da);CHKERRQ(ierr); 187047c6ae99SBarry Smith PetscFunctionReturn(0); 187147c6ae99SBarry Smith } 1872