PetscErrorCode FluidFieldDivergence(FluidField f) { DALocalInfo info; Vec u,v,w; // Local, ghosted vectors PetscErrorCode ierr; PetscFunctionBegin; PetscLogEventBegin(EVENT_FluidFieldDivergence,0,0,0,0); // PetscLogEventRegister(&EVENT_FluidFieldDivergence,"FluidFieldDivergence", 0); ierr = DAGetLocalInfo(f->da,&info); CHKERRQ(ierr); ierr = DAGetLocalVector(f->da,&u); CHKERRQ(ierr); ierr = DAGetLocalVector(f->da,&v); CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(f->da,f->u,INSERT_VALUES,u); CHKERRQ(ierr); ierr = DAGlobalToLocalEnd( f->da,f->u,INSERT_VALUES,u); CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(f->da,f->v,INSERT_VALUES,v); CHKERRQ(ierr); //TODO: interleaving work with communication here a possible source of optimization? ierr = DAGlobalToLocalEnd( f->da,f->v,INSERT_VALUES,v); CHKERRQ(ierr); if( f->is3D ) { ierr = DAGetLocalVector(f->da,&w); CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(f->da,f->w,INSERT_VALUES,w); CHKERRQ(ierr); ierr = DAGlobalToLocalEnd( f->da,f->w,INSERT_VALUES,w); CHKERRQ(ierr); FluidFieldDivergence_3D(info, f->d, u, v, w, f->div); ierr = DARestoreLocalVector(f->da,&w); CHKERRQ(ierr); } else { FluidFieldDivergence_2D(info, f->d, u, v, f->div); } ierr = DARestoreLocalVector(f->da,&u); CHKERRQ(ierr); ierr = DARestoreLocalVector(f->da,&v); CHKERRQ(ierr); PetscLogEventEnd(EVENT_FluidFieldDivergence,0,0,0,0); PetscFunctionReturn(0); }
PetscErrorCode FormFunction(SNES snes,Vec X,Vec F,void *ctx) { PetscErrorCode ierr; DMMG dmmg = (DMMG)ctx; AppCtx *user = (AppCtx*)dmmg->user; DA da2 = (DA)dmmg->dm; DALocalInfo info2; Field2 **x2,**f2; Vec X2; PetscFunctionBegin; ierr = DAGetLocalInfo(da2,&info2);CHKERRQ(ierr); /* Get local vectors to hold ghosted parts of X */ ierr = DAGetLocalVector(da2,&X2);CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da2,X,INSERT_VALUES,X2);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da2,X,INSERT_VALUES,X2);CHKERRQ(ierr); /* Access the array inside of X1 */ ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr); /* Access the subvectors in F. These are not ghosted so directly access the memory locations in F */ ierr = DAVecGetArray(da2,F,(void**)&f2);CHKERRQ(ierr); /* Evaluate local user provided function */ ierr = FormFunctionLocal2(&info2,0,x2,f2,(void**)user);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,F,(void**)&f2);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DARestoreLocalVector(da2,&X2);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscViewer viewer; DA da; Vec global,local,global2; PetscMPIInt rank; PetscTruth flg; /* Every PETSc routine should begin with the PetscInitialize() routine. argc, argv - These command line arguments are taken to extract the options supplied to PETSc and options supplied to MPI. help - When PETSc executable is invoked with the option -help, it prints the various options that can be applied at runtime. The user can use the "help" variable place additional help messages in this printout. */ ierr = PetscInitialize(&argc,&argv,(char *)0,help);CHKERRQ(ierr); /* Create a DA and an associated vector */ ierr = DACreate2d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_BOX,100,90,PETSC_DECIDE,PETSC_DECIDE,2,1,PETSC_NULL,PETSC_NULL,&da);CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr); ierr = VecSet(global,-1.0);CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = VecScale(local,rank+1);CHKERRQ(ierr); ierr = DALocalToGlobal(da,local,ADD_VALUES,global);CHKERRQ(ierr); /* Write output file with PetscViewerHDF5 viewer. */ ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD,"hdf5output",FILE_MODE_WRITE,&viewer); CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); ierr = VecDuplicate(global,&global2);CHKERRQ(ierr); ierr = VecCopy(global,global2);CHKERRQ(ierr); ierr = PetscViewerHDF5Open(PETSC_COMM_WORLD,"hdf5output",FILE_MODE_READ,&viewer); CHKERRQ(ierr); ierr = VecLoadIntoVector(viewer,global);CHKERRQ(ierr); ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); ierr = VecEqual(global,global2,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Vectors are equal\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD,"Vectors are not equal\n");CHKERRQ(ierr); } /* clean up and exit */ ierr = DADestroy(da);CHKERRQ(ierr); ierr = VecDestroy(local);CHKERRQ(ierr); ierr = VecDestroy(global);CHKERRQ(ierr); ierr = VecDestroy(global2);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscErrorCode equation(SNES snes, Vec soln_vec, Vec fun_vec, void* ptr) { //data structure will be contained in ptr Data* data = (Data*) ptr; Params P = data->P; DA da = data->da; DALocalInfo info; PetscFunctionBegin; DAGetLocalInfo(da, &info); Vec sv_local; //need local vector containing ghost point information DACreateLocalVector(da, &sv_local); DAGlobalToLocalBegin(da, soln_vec, INSERT_VALUES, sv_local); DAGlobalToLocalEnd(da, soln_vec, INSERT_VALUES, sv_local); //to evaluate fuction, the sv_local soln_vec need to be converted into Field arrays Field **X; Field **F; DAVecGetArray(da, sv_local, &X); DAVecGetArray(da, fun_vec, &F); //since sv_local is local vector, X will have access to ghost points PetscInt i, j, Ny = P.Ny; PetscScalar hx = P.hx; hy = P.hy; x, y; for(i=info.xs; i<info.xs + info.xm; i++){ for(j=info.ys; j<info.ys+info.ym; j++){ x = i *hx; y = j *hy; if(j==0) { F[j][i].u = X[j][i].u - 0.5*(sin(2*PETSC_PI*x) + 1); F[j][i].v = X[j][i].v ; } else if (j== Ny-1){ F[j][i].u = X[j][i].u; F[j][i].v = X[j][i].v - 0.5*(sin(2*PETSC_PI*x) + 1); } else { F[j][i].u = lap(u) + X[j][i].u * X[j][i].v ; F[j][i].v = lap(v) - X[j][i].u * X[j][i].v ; } } } DAVecRestoreArray(da, fun_vec, &F); DAVecRestoreArray(da, sv_local, &X); VecDestory(sv_local); PetscFuntionReturn(0); }
PetscErrorCode FormFunction1(SNES snes,Vec X,Vec F,void *ptr) { AppCtx *user = (AppCtx*)ptr; PetscErrorCode ierr; PetscInt i,j,k,loc,mx,my,mz,xs,ys,zs,xm,ym,zm,Xs,Ys,Zs,Xm,Ym,Zm,base1,base2; PetscReal two = 2.0,one = 1.0,lambda,Hx,Hy,Hz,HxHzdHy,HyHzdHx,HxHydHz; PetscScalar u,uxx,uyy,sc,*x,*f,uzz; Vec localX = user->localX,localF = user->localF; mx = user->mx; my = user->my; mz = user->mz; lambda = user->param; Hx = one / (PetscReal)(mx-1); Hy = one / (PetscReal)(my-1); Hz = one / (PetscReal)(mz-1); sc = Hx*Hy*Hz*lambda; HxHzdHy = Hx*Hz/Hy; HyHzdHx = Hy*Hz/Hx; HxHydHz = Hx*Hy/Hz; ierr = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); ierr = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); ierr = VecGetArray(localX,&x);CHKERRQ(ierr); ierr = VecGetArray(localF,&f);CHKERRQ(ierr); ierr = DAGetCorners(user->da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DAGetGhostCorners(user->da,&Xs,&Ys,&Zs,&Xm,&Ym,&Zm);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++) { base1 = (Xm*Ym)*(k-Zs); for (j=ys; j<ys+ym; j++) { base2 = base1 + (j-Ys)*Xm; for (i=xs; i<xs+xm; i++) { loc = base2 + (i-Xs); if (i == 0 || j == 0 || k== 0 || i == mx-1 || j == my-1 || k == mz-1) { f[loc] = x[loc]; } else { u = x[loc]; uxx = (two*u - x[loc-1] - x[loc+1])*HyHzdHx; uyy = (two*u - x[loc-Xm] - x[loc+Xm])*HxHzdHy; uzz = (two*u - x[loc-Xm*Ym] - x[loc+Xm*Ym])*HxHydHz; f[loc] = uxx + uyy + uzz - sc*PetscExpScalar(u); } } } } ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr); ierr = VecRestoreArray(localF,&f);CHKERRQ(ierr); /* stick values into global vector */ ierr = DALocalToGlobal(user->da,localF,INSERT_VALUES,F);CHKERRQ(ierr); ierr = PetscLogFlops(11.0*ym*xm*zm);CHKERRQ(ierr); return 0; }
PetscErrorCode ComputeFunction(SNES snes,Vec x,Vec f,void *ctx) { PetscInt i,Mx,xs,xm; PetscScalar *xx,*ff,hx; DA da = (DA) ctx; Vec xlocal; DAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); DAGetLocalVector(da,&xlocal);DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal); DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal); DAVecGetArray(da,xlocal,&xx); DAVecGetArray(da,f,&ff); DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL); for (i=xs; i<xs+xm; i++) { if (i == 0 || i == Mx-1) ff[i] = xx[i]/hx; else ff[i] = (2.0*xx[i] - xx[i-1] - xx[i+1])/hx - hx*PetscExpScalar(xx[i]); } DAVecRestoreArray(da,xlocal,&xx); DARestoreLocalVector(da,&xlocal);DAVecRestoreArray(da,f,&ff); return 0;}
static PetscErrorCode TestQ2Q1DA( void ) { DA Q2_da,Q1_da,cda; PetscInt mx,my,mz; Vec coords,gcoords,gcoords2; PetscErrorCode ierr; mx=7; my=11; mz=13; ierr=DACreate3d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_BOX,mx,my,mz,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,3,2,0,0,0,&Q2_da);CHKERRQ(ierr); ierr = DASetUniformCoordinates(Q2_da,-1.0,1.0,-2.0,2.0,-3.0,3.0);CHKERRQ(ierr); ierr = DAGetCoordinates(Q2_da,&coords);CHKERRQ(ierr); ierr = DACreate3d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_BOX,mx,my,mz,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,3,1,0,0,0,&Q1_da);CHKERRQ(ierr); ierr = DASetCoordinates(Q1_da,coords);CHKERRQ(ierr); ierr = VecDestroy(coords);CHKERRQ(ierr); /* Get ghost coordinates one way */ ierr = DAGetGhostedCoordinates(Q1_da,&gcoords);CHKERRQ(ierr); /* And another */ ierr = DAGetCoordinates(Q1_da,&coords);CHKERRQ(ierr); ierr = DAGetCoordinateDA(Q1_da,&cda);CHKERRQ(ierr); ierr = DAGetLocalVector(cda,&gcoords2);CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(cda,coords,INSERT_VALUES,gcoords2);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(cda,coords,INSERT_VALUES,gcoords2);CHKERRQ(ierr); ierr = CompareGhostedCoords(gcoords,gcoords2);CHKERRQ(ierr); ierr = DARestoreLocalVector(cda,&gcoords2);CHKERRQ(ierr); ierr = DADestroy(cda);CHKERRQ(ierr); ierr = VecScale(coords,10.0);CHKERRQ(ierr); ierr = VecScale(gcoords,10.0);CHKERRQ(ierr); ierr = DAGetGhostedCoordinates(Q1_da,&gcoords2);CHKERRQ(ierr); ierr = CompareGhostedCoords(gcoords,gcoords2);CHKERRQ(ierr); ierr = VecDestroy(coords);CHKERRQ(ierr); ierr = VecDestroy(gcoords2);CHKERRQ(ierr); ierr = VecDestroy(gcoords);CHKERRQ(ierr); ierr = DADestroy(Q2_da);CHKERRQ(ierr); ierr = DADestroy(Q1_da);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ComputeJacobian(SNES snes,Vec x,Mat *J,Mat *B,MatStructure *flag,void *ctx){ DA da = (DA) ctx; PetscInt i,Mx,xm,xs; PetscScalar hx,*xx; Vec xlocal; DAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); DAGetLocalVector(da,&xlocal);DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal); DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal); DAVecGetArray(da,xlocal,&xx); DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL); for (i=xs; i<xs+xm; i++) { if (i == 0 || i == Mx-1) { MatSetValue(*J,i,i,1.0/hx,INSERT_VALUES);} else { MatSetValue(*J,i,i-1,-1.0/hx,INSERT_VALUES); MatSetValue(*J,i,i,2.0/hx - hx*PetscExpScalar(xx[i]),INSERT_VALUES); MatSetValue(*J,i,i+1,-1.0/hx,INSERT_VALUES); } } MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY); *flag = SAME_NONZERO_PATTERN; DAVecRestoreArray(da,xlocal,&xx);DARestoreLocalVector(da,&xlocal); return 0;}
PetscErrorCode FormFunction1(SNES snes,Vec X,Vec F,void *ctx) { PetscErrorCode ierr; DMMG dmmg = (DMMG)ctx; AppCtx *user = (AppCtx*)dmmg->user; DA da1 = (DA)dmmg->dm; DALocalInfo info1; Field1 **x1,**f1; Vec X1; Field2 **x2; PetscFunctionBegin; ierr = DAGetLocalInfo(da1,&info1);CHKERRQ(ierr); /* Get local vectors to hold ghosted parts of X */ ierr = DAGetLocalVector(da1,&X1);CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da1,X,INSERT_VALUES,X1);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da1,X,INSERT_VALUES,X1);CHKERRQ(ierr); /* Access the arrays inside X1 */ ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr); /* Access the subvectors in F. These are not ghosted so directly access the memory locations in F */ ierr = DAVecGetArray(da1,F,(void**)&f1);CHKERRQ(ierr); /* Evaluate local user provided function */ if (user->nsolve){ x2 = user->x2; ierr = FormFunctionLocal1(&info1,x1,x2,f1,(void**)user);CHKERRQ(ierr); } else { ierr = FormFunctionLocal1(&info1,x1,0,f1,(void**)user);CHKERRQ(ierr); } ierr = DAVecRestoreArray(da1,F,(void**)&f1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DARestoreLocalVector(da1,&X1);CHKERRQ(ierr); PetscFunctionReturn(0); }
int FormBratuFunction(SNES snes, Vec v, Vec f, void* ctx) { UserBratuCtx* bratu = (UserBratuCtx *) ctx; DA da = bratu->da; double lambda = bratu->lambda; double h = bratu->h; Vec lv; int i,j; int lli, llj, ni, nj; const double **varr; double **fvarr; DAGetCorners(da, &lli, &llj, 0, &ni, &nj, 0); DAGetLocalVector(da, &lv); DAGlobalToLocalBegin(da, v, INSERT_VALUES, lv); DAGlobalToLocalEnd(da, v, INSERT_VALUES,lv); DAVecGetArray(da, lv, (void**) &varr); DAVecGetArray(da, f, (void**) &fvarr); for(j=llj; j<llj+nj; j++){ for(i=lli; i<lli+ni; i++){ if(i==0 || j==0 ||i=bratu->n+1 || j==bratu->n+1){ fvarr[j][i] = 0.0; } else{ fvarr[j][i] = -(varr[j-1][i] + varr[j][i-1] + varr[j+1][i] + varr[j][i+1] - 4*varr[j][i])/(h*h) - lambda*exp(varr[j][i]); } } } DAVecRestoreArray(da, f, (void**) &fvarr); DAVecRestoreArray(da, lv, (void**) &varr); DARestoreLocalVector(da, &lv); return 0; }
int main(int argc,char **argv) { PetscMPIInt rank; PetscInt M = -10,N = -8; PetscErrorCode ierr; PetscTruth flg = PETSC_FALSE; DA da; PetscViewer viewer; Vec local,global; PetscScalar value; DAPeriodicType ptype = DA_NONPERIODIC; DAStencilType stype = DA_STENCIL_BOX; #if defined(PETSC_HAVE_MATLAB_ENGINE) PetscViewer mviewer; #endif ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",300,0,300,300,&viewer);CHKERRQ(ierr); #if defined(PETSC_HAVE_MATLAB_ENGINE) ierr = PetscViewerMatlabOpen(PETSC_COMM_WORLD,"tmp.mat",FILE_MODE_WRITE,&mviewer);CHKERRQ(ierr); #endif ierr = PetscOptionsGetTruth(PETSC_NULL,"-star_stencil",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) stype = DA_STENCIL_STAR; /* Create distributed array and get vectors */ ierr = DACreate2d(PETSC_COMM_WORLD,ptype,stype,M,N,PETSC_DECIDE,PETSC_DECIDE,1,1,PETSC_NULL,PETSC_NULL,&da);CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr); value = -3.0; ierr = VecSet(global,value);CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); value = rank+1; ierr = VecScale(local,value);CHKERRQ(ierr); ierr = DALocalToGlobal(da,local,ADD_VALUES,global);CHKERRQ(ierr); flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL, "-view_global", &flg,PETSC_NULL);CHKERRQ(ierr); if (flg) { /* view global vector in natural ordering */ ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = DAView(da,viewer);CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); #if defined(PETSC_HAVE_MATLAB_ENGINE) ierr = DAView(da,mviewer);CHKERRQ(ierr); ierr = VecView(global,mviewer);CHKERRQ(ierr); #endif /* Free memory */ #if defined(PETSC_HAVE_MATLAB_ENGINE) ierr = PetscViewerDestroy(mviewer);CHKERRQ(ierr); #endif ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); ierr = VecDestroy(local);CHKERRQ(ierr); ierr = VecDestroy(global);CHKERRQ(ierr); ierr = DADestroy(da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
/* FormFunctionGradient - Evaluates the function and corresponding gradient. Input Parameters: . taoapp - the TAO_APPLICATION context . XX - input vector . userCtx - optional user-defined context, as set by TaoSetFunctionGradient() Output Parameters: . fcn - the newly evaluated function . GG - vector containing the newly evaluated gradient */ int FormFunctionGradient(TAO_APPLICATION taoapp, Vec X, double *fcn,Vec G,void *userCtx){ AppCtx * user = (AppCtx *) userCtx; int info; PetscInt i,j; PetscInt mx=user->mx, my=user->my; PetscInt xs,xm,gxs,gxm,ys,ym,gys,gym; double ft=0; double hx=1.0/(mx+1),hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy, area=0.5*hx*hy; double rhx=mx+1, rhy=my+1; double f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb; double df1dxc,df2dxc,df3dxc,df4dxc,df5dxc,df6dxc; PetscScalar **g, **x; Vec localX; /* Get local mesh boundaries */ info = DAGetLocalVector(user->da,&localX);CHKERRQ(info); info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info); /* Scatter ghost points to local vector */ info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); /* Get pointers to vector data */ info = DAVecGetArray(user->da,localX,(void**)&x); info = DAVecGetArray(user->da,G,(void**)&g); /* Compute function and gradient over the locally owned part of the mesh */ for (j=ys; j<ys+ym; j++){ for (i=xs; i< xs+xm; i++){ xc = x[j][i]; xlt=xrb=xl=xr=xb=xt=xc; if (i==0){ /* left side */ xl= user->left[j-ys+1]; xlt = user->left[j-ys+2]; } else { xl = x[j][i-1]; } if (j==0){ /* bottom side */ xb=user->bottom[i-xs+1]; xrb =user->bottom[i-xs+2]; } else { xb = x[j-1][i]; } if (i+1 == gxs+gxm){ /* right side */ xr=user->right[j-ys+1]; xrb = user->right[j-ys]; } else { xr = x[j][i+1]; } if (j+1==gys+gym){ /* top side */ xt=user->top[i-xs+1]; xlt = user->top[i-xs]; }else { xt = x[j+1][i]; } if (i>gxs && j+1<gys+gym){ xlt = x[j+1][i-1]; } if (j>gys && i+1<gxs+gxm){ xrb = x[j-1][i+1]; } d1 = (xc-xl); d2 = (xc-xr); d3 = (xc-xt); d4 = (xc-xb); d5 = (xr-xrb); d6 = (xrb-xb); d7 = (xlt-xl); d8 = (xt-xlt); df1dxc = d1*hydhx; df2dxc = ( d1*hydhx + d4*hxdhy ); df3dxc = d3*hxdhy; df4dxc = ( d2*hydhx + d3*hxdhy ); df5dxc = d2*hydhx; df6dxc = d4*hxdhy; d1 *= rhx; d2 *= rhx; d3 *= rhy; d4 *= rhy; d5 *= rhy; d6 *= rhx; d7 *= rhy; d8 *= rhx; f1 = sqrt( 1.0 + d1*d1 + d7*d7); f2 = sqrt( 1.0 + d1*d1 + d4*d4); f3 = sqrt( 1.0 + d3*d3 + d8*d8); f4 = sqrt( 1.0 + d3*d3 + d2*d2); f5 = sqrt( 1.0 + d2*d2 + d5*d5); f6 = sqrt( 1.0 + d4*d4 + d6*d6); f2 = sqrt( 1.0 + d1*d1 + d4*d4); f4 = sqrt( 1.0 + d3*d3 + d2*d2); ft = ft + (f2 + f4); df1dxc /= f1; df2dxc /= f2; df3dxc /= f3; df4dxc /= f4; df5dxc /= f5; df6dxc /= f6; g[j][i] = (df1dxc+df2dxc+df3dxc+df4dxc+df5dxc+df6dxc ) * 0.5; } } /* Compute triangular areas along the border of the domain. */ if (xs==0){ /* left side */ for (j=ys; j<ys+ym; j++){ d3=(user->left[j-ys+1] - user->left[j-ys+2])*rhy; d2=(user->left[j-ys+1] - x[j][0]) *rhx; ft = ft+sqrt( 1.0 + d3*d3 + d2*d2); } } if (ys==0){ /* bottom side */ for (i=xs; i<xs+xm; i++){ d2=(user->bottom[i+1-xs]-user->bottom[i-xs+2])*rhx; d3=(user->bottom[i-xs+1]-x[0][i])*rhy; ft = ft+sqrt( 1.0 + d3*d3 + d2*d2); } } if (xs+xm==mx){ /* right side */ for (j=ys; j< ys+ym; j++){ d1=(x[j][mx-1] - user->right[j-ys+1])*rhx; d4=(user->right[j-ys]-user->right[j-ys+1])*rhy; ft = ft+sqrt( 1.0 + d1*d1 + d4*d4); } } if (ys+ym==my){ /* top side */ for (i=xs; i<xs+xm; i++){ d1=(x[my-1][i] - user->top[i-xs+1])*rhy; d4=(user->top[i-xs+1] - user->top[i-xs])*rhx; ft = ft+sqrt( 1.0 + d1*d1 + d4*d4); } } if (ys==0 && xs==0){ d1=(user->left[0]-user->left[1])/hy; d2=(user->bottom[0]-user->bottom[1])*rhx; ft +=sqrt( 1.0 + d1*d1 + d2*d2); } if (ys+ym == my && xs+xm == mx){ d1=(user->right[ym+1] - user->right[ym])*rhy; d2=(user->top[xm+1] - user->top[xm])*rhx; ft +=sqrt( 1.0 + d1*d1 + d2*d2); } ft=ft*area; info = MPI_Allreduce(&ft,fcn,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);CHKERRQ(info); /* Restore vectors */ info = DAVecRestoreArray(user->da,localX,(void**)&x); info = DAVecRestoreArray(user->da,G,(void**)&g); /* Scatter values to global vector */ info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info); info = PetscLogFlops(67*xm*ym); CHKERRQ(info); return 0; }
/* QuadraticH - Evaluates Hessian matrix. Input Parameters: . user - user-defined context, as set by TaoSetHessian() . X - input vector Output Parameter: . H - Hessian matrix */ int QuadraticH(AppCtx *user, Vec X, Mat Hessian) { int info; PetscInt i,j,k; PetscInt mx=user->mx, my=user->my; PetscInt xs,xm,gxs,gxm,ys,ym,gys,gym; double hx=1.0/(mx+1), hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy; double f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb; double hl,hr,ht,hb,hc,htl,hbr; PetscScalar **x, v[7]; MatStencil col[7],row; Vec localX; PetscTruth assembled; /* Get local mesh boundaries */ info = DAGetLocalVector(user->da,&localX);CHKERRQ(info); info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info); /* Scatter ghost points to local vector */ info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); /* Get pointers to vector data */ info = DAVecGetArray(user->da,localX,(void**)&x); /* Initialize matrix entries to zero */ info = MatAssembled(Hessian,&assembled); CHKERRQ(info); if (assembled){info = MatZeroEntries(Hessian); CHKERRQ(info);} /* Set various matrix options */ info = MatSetOption(Hessian,MAT_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE); CHKERRQ(info); /* Compute Hessian over the locally owned part of the mesh */ for (j=ys; j<ys+ym; j++){ for (i=xs; i< xs+xm; i++){ xc = x[j][i]; xlt=xrb=xl=xr=xb=xt=xc; /* Left side */ if (i==0){ xl = user->left[j-ys+1]; xlt = user->left[j-ys+2]; } else { xl = x[j][i-1]; } if (j==0){ xb = user->bottom[i-xs+1]; xrb = user->bottom[i-xs+2]; } else { xb = x[j-1][i]; } if (i+1 == mx){ xr = user->right[j-ys+1]; xrb = user->right[j-ys]; } else { xr = x[j][i+1]; } if (j+1==my){ xt = user->top[i-xs+1]; xlt = user->top[i-xs]; }else { xt = x[j+1][i]; } if (i>0 && j+1<my){ xlt = x[j+1][i-1]; } if (j>0 && i+1<mx){ xrb = x[j-1][i+1]; } d1 = (xc-xl)/hx; d2 = (xc-xr)/hx; d3 = (xc-xt)/hy; d4 = (xc-xb)/hy; d5 = (xrb-xr)/hy; d6 = (xrb-xb)/hx; d7 = (xlt-xl)/hy; d8 = (xlt-xt)/hx; f1 = sqrt( 1.0 + d1*d1 + d7*d7); f2 = sqrt( 1.0 + d1*d1 + d4*d4); f3 = sqrt( 1.0 + d3*d3 + d8*d8); f4 = sqrt( 1.0 + d3*d3 + d2*d2); f5 = sqrt( 1.0 + d2*d2 + d5*d5); f6 = sqrt( 1.0 + d4*d4 + d6*d6); hl = (-hydhx*(1.0+d7*d7)+d1*d7)/(f1*f1*f1)+ (-hydhx*(1.0+d4*d4)+d1*d4)/(f2*f2*f2); hr = (-hydhx*(1.0+d5*d5)+d2*d5)/(f5*f5*f5)+ (-hydhx*(1.0+d3*d3)+d2*d3)/(f4*f4*f4); ht = (-hxdhy*(1.0+d8*d8)+d3*d8)/(f3*f3*f3)+ (-hxdhy*(1.0+d2*d2)+d2*d3)/(f4*f4*f4); hb = (-hxdhy*(1.0+d6*d6)+d4*d6)/(f6*f6*f6)+ (-hxdhy*(1.0+d1*d1)+d1*d4)/(f2*f2*f2); hbr = -d2*d5/(f5*f5*f5) - d4*d6/(f6*f6*f6); htl = -d1*d7/(f1*f1*f1) - d3*d8/(f3*f3*f3); hc = hydhx*(1.0+d7*d7)/(f1*f1*f1) + hxdhy*(1.0+d8*d8)/(f3*f3*f3) + hydhx*(1.0+d5*d5)/(f5*f5*f5) + hxdhy*(1.0+d6*d6)/(f6*f6*f6) + (hxdhy*(1.0+d1*d1)+hydhx*(1.0+d4*d4)-2*d1*d4)/(f2*f2*f2) + (hxdhy*(1.0+d2*d2)+hydhx*(1.0+d3*d3)-2*d2*d3)/(f4*f4*f4); hl/=2.0; hr/=2.0; ht/=2.0; hb/=2.0; hbr/=2.0; htl/=2.0; hc/=2.0; row.j = j; row.i = i; k=0; if (j>0){ v[k]=hb; col[k].j = j - 1; col[k].i = i; k++; } if (j>0 && i < mx -1){ v[k]=hbr; col[k].j = j - 1; col[k].i = i+1; k++; } if (i>0){ v[k]= hl; col[k].j = j; col[k].i = i-1; k++; } v[k]= hc; col[k].j = j; col[k].i = i; k++; if (i < mx-1 ){ v[k]= hr; col[k].j = j; col[k].i = i+1; k++; } if (i>0 && j < my-1 ){ v[k]= htl; col[k].j = j+1; col[k].i = i-1; k++; } if (j < my-1 ){ v[k]= ht; col[k].j = j+1; col[k].i = i; k++; } /* Set matrix values using local numbering, which was defined earlier, in the main routine. */ info = MatSetValuesStencil(Hessian,1,&row,k,col,v,INSERT_VALUES); CHKERRQ(info); } } /* Restore vectors */ info = DAVecRestoreArray(user->da,localX,(void**)&x); info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info); /* Assemble the matrix */ info = MatAssemblyBegin(Hessian,MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = MatAssemblyEnd(Hessian,MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = PetscLogFlops(199*xm*ym); CHKERRQ(info); return 0; }
void Solve_Distance_Explicit(UserCtx *user) { DALocalInfo info; PetscInt xs, xe, ys, ye, zs, ze; // Local grid information PetscInt mx, my, mz; // Dimensions in three directions PetscInt i, j, k; PetscInt lxs, lxe, lys, lye, lzs, lze; PetscReal ***level; DAGetLocalInfo(user->da, &info); mx = info.mx; my = info.my; mz = info.mz; xs = info.xs; xe = xs + info.xm; ys = info.ys; ye = ys + info.ym; zs = info.zs; ze = zs + info.zm; lxs = xs; lxe = xe; lys = ys; lye = ye; lzs = zs; lze = ze; if (xs==0) lxs = xs+1; if (ys==0) lys = ys+1; if (zs==0) lzs = zs+1; if (xe==mx) lxe = xe-1; if (ye==my) lye = ye-1; if (ze==mz) lze = ze-1; DAGlobalToLocalBegin(user->da, LevelSet, INSERT_VALUES, user->lLevelset); DAGlobalToLocalEnd(user->da, LevelSet, INSERT_VALUES, user->lLevelset); DAVecGetArray(user->da, user->lLevelset, &level); if(xs==0 || xe==mx) { int from, to; for (k=lzs; k<lze; k++) for (j=lys; j<lye; j++) { if(xs==0) { i = 1, from = i, to = 0; if(i_periodic) from = mx-2; else if(ii_periodic) from = -2; level[k][j][to] = level[k][j][from]; } if(xe==mx) { i = mx-2, from = i, to = mx-1; if(i_periodic) from = 1; else if(ii_periodic) from = mx+1; level[k][j][to] = level[k][j][from]; } } } if(ys==0 || ye==my) { int from, to; for (k=lzs; k<lze; k++) for (i=lxs; i<lxe; i++) { if(ys==0) { j = 1, from = j, to = 0; if(j_periodic) from = my-2; else if(jj_periodic) from = -2; level[k][to][i] = level[k][from][i]; } if(ye==my) { j = my-2, from = j, to = my-1; if(j_periodic) from = 1; else if(jj_periodic) from = my+1; level[k][to][i] = level[k][from][i]; } } } if(zs==0 || ze==mz) { int from, to; for (j=lys; j<lye; j++) for (i=lxs; i<lxe; i++) { if(zs==0) { k = 1, from = k, to = 0; if(k_periodic) from = mz-2; else if(kk_periodic) from = -2; level[to][j][i] = level[from][j][i]; } if(ze==mz) { k = mz-2, from = k, to = mz-1; if(k_periodic) from = 1; else if(kk_periodic) from = mz+1; level[to][j][i] = level[from][j][i]; } } } DAVecRestoreArray(user->da, user->lLevelset, &level); Vec Rhs; VecDuplicate(user->P, &Rhs); Distance_Function_RHS(user, Rhs, 1); VecAXPY(LevelSet, dtau, Rhs); VecDestroy(Rhs); return; }
void Compute_Distance_Function(UserCtx *user) { DALocalInfo info; PetscInt i, j, k; DAGetLocalInfo(user->da, &info); PetscInt mx = info.mx, my = info.my, mz = info.mz; PetscInt xs = info.xs, xe = xs + info.xm; PetscInt ys = info.ys, ye = ys + info.ym; PetscInt zs = info.zs, ze = zs + info.zm; PetscInt lxs = xs, lxe = xe; PetscInt lys = ys, lye = ye; PetscInt lzs = zs, lze = ze; PetscReal ***level; if (xs==0) lxs = xs+1; if (ys==0) lys = ys+1; if (zs==0) lzs = zs+1; if (xe==mx) lxe = xe-1; if (ye==my) lye = ye-1; if (ze==mz) lze = ze-1; int iter=0; Init_LevelSet_Vectors(user); Distance_Function_IC(user); Vec D; double norm=100, norm_old; dtau = dx_min*0.25; //dtau = dx_min * 0.5; VecDuplicate(LevelSet, &D); do { norm_old = norm; PetscPrintf(PETSC_COMM_WORLD, "\nSolving Distance %d... (dtau=%f)\n", iter, dtau); //Solve_Distance_Explicit(user); Solve_Distance(user, iter); VecWAXPY(D, -1., LevelSet_o, LevelSet); VecNorm(D, NORM_INFINITY, &norm); PetscPrintf(PETSC_COMM_WORLD, "\nNorm=%.5e\n\n", norm); PetscReal ***level; DAVecGetArray(user->da, LevelSet, &level); for (k=zs; k<ze; k++) for (j=ys; j<ye; j++) for (i=xs; i<xe; i++) if(level[k][j][i]<0) level[k][j][i]=0.01; DAVecRestoreArray(user->da, LevelSet, &level); if(iter > 10 && (fabs(norm)<1.e-5 || iter>1000) ) break; //if(iter>10 && iter%50==0) dtau *=1.04; VecCopy(LevelSet, LevelSet_o); iter++; } while(1); VecDestroy(D); Vec lLevelset; PetscReal ***llevel; VecDuplicate(user->lP, &lLevelset); DAGlobalToLocalBegin(user->da, LevelSet, INSERT_VALUES, lLevelset); DAGlobalToLocalEnd(user->da, LevelSet, INSERT_VALUES, lLevelset); DAVecGetArray(user->da, LevelSet, &level); DAVecGetArray(user->da, lLevelset, &llevel); for (k=zs; k<ze; k++) for (j=ys; j<ye; j++) for (i=xs; i<xe; i++) { int c=k, b=j, a=i, flag=0; // Neumann conditions if(i==0) a=1, flag=1; if(i==mx-1) a=mx-2, flag=1; if(j==0) b=1, flag=1; if(j==my-1) b=my-2, flag=1; if(k==0) c=1, flag=1; if(k==mz-1) c=mz-2, flag=1; if(i_periodic && i==0) a=mx-2, flag=1; else if(i_periodic && i==mx-1) a=1, flag=1; if(j_periodic && j==0) b=my-2, flag=1; else if(j_periodic && j==my-1) b=1, flag=1; if(k_periodic && k==0) c=mz-2, flag=1; else if(k_periodic && k==mz-1) c=1, flag=1; if(ii_periodic && i==0) a=-2, flag=1; else if(ii_periodic && i==mx-1) a=mx+1, flag=1; if(jj_periodic && j==0) b=-2, flag=1; else if(jj_periodic && j==my-1) b=my+1, flag=1; if(kk_periodic && k==0) c=-2, flag=1; else if(kk_periodic && k==mz-1) c=mz+1, flag=1; if(flag) level[k][j][i] = llevel[c][b][a]; } DAVecRestoreArray(user->da, LevelSet, &level); DAVecRestoreArray(user->da, lLevelset, &llevel); VecDestroy(lLevelset); VecCopy(LevelSet, user->Distance); Destroy_LevelSet_Vectors(user); };
/* FormResidual - Evaluates nonlinear function, F(x). Input Parameters: . ot - the OT context . X - input vector . ptr - optional user-defined context, as set by OTSetFunction() Output Parameter: . F - function vector */ int FormResidual(TAO_SOLVER ot,Vec X,Vec F,void *ptr) { AppCtx *user = (AppCtx *) ptr; int info, i, j, row, mx, my, xs, ys, xm, ym, gxs, gys, gxm, gym; double two = 2.0, one = 1.0, lambda,hx, hy, hxdhy, hydhx,sc; PetscScalar u, uxx, uyy, *x,*f; Vec localX=user->localX,localF=user->localF; mx = user->mx; my = user->my; lambda = user->param; hx = one/(double)(mx-1); hy = one/(double)(my-1); sc = hx*hy*lambda; hxdhy = hx/hy; hydhx = hy/hx; /* Scatter ghost points to local vector, using the 2-step process DAGlobalToLocalBegin(), DAGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ // info = DAGetLocalVector(user->da,&(user->localX)); CHKERRQ(info); info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); /* Get pointers to vector data */ info = VecGetArray(localX,&x); CHKERRQ(info); info = VecGetArray(localF,&f); CHKERRQ(info); /* Get local grid boundaries */ info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info); /* Compute function over the locally owned part of the grid */ for (j=ys; j<ys+ym; j++) { row = (j - gys)*gxm + xs - gxs - 1; for (i=xs; i<xs+xm; i++) { row++; if (i == 0 || j == 0 || i == mx-1 || j == my-1 ) { f[row] = x[row]; continue; } u = x[row]; uxx = (two*u - x[row-1] - x[row+1])*hydhx; uyy = (two*u - x[row-gxm] - x[row+gxm])*hxdhy; f[row] = uxx + uyy - sc*exp(u); } } /* Restore vectors */ info = VecRestoreArray(localX,&x); CHKERRQ(info); info = VecRestoreArray(localF,&f); CHKERRQ(info); /* Insert values into global vector */ info = DALocalToGlobal(user->da,localF,INSERT_VALUES,F); CHKERRQ(info); PetscLogFlops(11*ym*xm); return 0; }
void Distance_Function_RHS (UserCtx *user, Vec Levelset_RHS, int wall_distance) { DA da = user->da, fda = user->fda; DALocalInfo info = user->info; PetscInt xs, xe, ys, ye, zs, ze; PetscInt mx, my, mz; PetscInt i, j, k; PetscReal dpdc, dpde, dpdz; Vec Csi = user->lCsi, Eta = user->lEta, Zet = user->lZet; Vec Aj = user->lAj; Cmpnts ***csi, ***eta, ***zet; PetscReal ***aj, ***level, ***level0, ***rhs, ***grad_level; PetscInt lxs, lys, lzs, lxe, lye, lze; PetscReal ***nvert; Vec L, lLevelset0; // grad level, level0 xs = info.xs; xe = xs + info.xm; ys = info.ys; ye = ys + info.ym; zs = info.zs; ze = zs + info.zm; lxs = xs; lxe = xe; lys = ys; lye = ye; lzs = zs; lze = ze; mx = info.mx; my = info.my; mz = info.mz; if (xs==0) lxs = xs+1; if (ys==0) lys = ys+1; if (zs==0) lzs = zs+1; if (xe==mx) lxe = xe-1; if (ye==my) lye = ye-1; if (ze==mz) lze = ze-1; VecSet(Levelset_RHS, 0); VecDuplicate(user->lP, &L); VecDuplicate(user->lP, &lLevelset0); DAGlobalToLocalBegin(user->da, LevelSet0, INSERT_VALUES, lLevelset0); DAGlobalToLocalEnd(user->da, LevelSet0, INSERT_VALUES, lLevelset0); DAVecGetArray(fda, Csi, &csi); DAVecGetArray(fda, Eta, &eta); DAVecGetArray(fda, Zet, &zet); DAVecGetArray(da, Aj, &aj); DAVecGetArray(da, user->lNvert, &nvert); DAVecGetArray(da, user->lLevelset, &level); DAVecGetArray(da, lLevelset0, &level0); DAVecGetArray(da, Levelset_RHS, &rhs); DAVecGetArray(da, L, &grad_level); for (k=lzs; k<lze; k++) for (j=lys; j<lye; j++) for (i=lxs; i<lxe; i++) { double dldc, dlde, dldz; double dl_dx, dl_dy, dl_dz; double csi0=csi[k][j][i].x,csi1=csi[k][j][i].y, csi2=csi[k][j][i].z; double eta0=eta[k][j][i].x,eta1=eta[k][j][i].y, eta2=eta[k][j][i].z; double zet0=zet[k][j][i].x,zet1=zet[k][j][i].y, zet2=zet[k][j][i].z; double ajc = aj[k][j][i]; double dx=pow(1./aj[k][j][i],1./3.); if(dthick_set) dx = dthick; double sgn = sign1(level0[k][j][i], dx); //if(wall_distance) sgn = sign(level0[k][j][i]); //Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sgn, wall_distance, level, nvert, &dldc, &dlde, &dldz); Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sign(level0[k][j][i]), wall_distance, level, nvert, &dldc, &dlde, &dldz); //100521 Compute_dscalar_dxyz (csi0, csi1, csi2, eta0, eta1, eta2, zet0, zet1, zet2, ajc, dldc, dlde, dldz, &dl_dx, &dl_dy, &dl_dz); grad_level[k][j][i] = sqrt( dl_dx*dl_dx + dl_dy*dl_dy + dl_dz*dl_dz ); if(nvert[k][j][i]>0.1) grad_level[k][j][i]=0; } DAVecRestoreArray(da, L, &grad_level); DALocalToLocalBegin(user->da, L, INSERT_VALUES, L); DALocalToLocalEnd(user->da, L, INSERT_VALUES, L); DAVecGetArray(da, L, &grad_level); // Neumann, periodic conditions if(xs==0 || xe==mx) { int from, to; for (k=lzs; k<lze; k++) for (j=lys; j<lye; j++) { if(xs==0) { i = 1, from = i, to = 0; if(i_periodic) from = mx-2; else if(ii_periodic) from = -2; grad_level[k][j][to] = grad_level[k][j][from]; } if(xe==mx) { i = mx-2, from = i, to = mx-1; if(i_periodic) from = 1; else if(ii_periodic) from = mx+1; grad_level[k][j][to] = grad_level[k][j][from]; } } } if(ys==0 || ye==my) { int from, to; for (k=lzs; k<lze; k++) for (i=lxs; i<lxe; i++) { if(ys==0) { j = 1, from = j, to = 0; if(j_periodic) from = my-2; else if(jj_periodic) from = -2; grad_level[k][to][i] = grad_level[k][from][i]; } if(ye==my) { j = my-2, from = j, to = my-1; if(j_periodic) from = 1; else if(jj_periodic) from = my+1; grad_level[k][to][i] = grad_level[k][from][i]; } } } if(zs==0 || ze==mz) { int from, to; for (j=lys; j<lye; j++) for (i=lxs; i<lxe; i++) { if(zs==0) { k = 1, from = k, to = 0; if(k_periodic) from = mz-2; else if(kk_periodic) from = -2; grad_level[to][j][i] = grad_level[from][j][i]; } if(ze==mz) { k = mz-2, from = k, to = mz-1; if(k_periodic) from = 1; else if(kk_periodic) from = mz+1; grad_level[to][j][i] = grad_level[from][j][i]; } } } DAVecRestoreArray(da, L, &grad_level); DALocalToLocalBegin(user->da, L, INSERT_VALUES, L); DALocalToLocalEnd(user->da, L, INSERT_VALUES, L); DAVecGetArray(da, L, &grad_level); for(k=zs; k<ze; k++) for(j=ys; j<ye; j++) for(i=xs; i<xe; i++) { if (i<= 0 || i>= mx-1 || j<=0 || j>=my-1 || k<=0 || k>=mz-1 || nvert[k][j][i]>1.1){ rhs[k][j][i]=0.; continue; } if(nvert[k][j][i]>0.1) { rhs[k][j][i]=0.; continue; } if(wall_distance) { if(nvert[k][j][i]>0.1) { rhs[k][j][i]=0.; continue; } if(i <= 1 && (user->bctype[0]==1 || user->bctype[0]==-1 || user->bctype[0]==-2)) { rhs[k][j][i]=0.; continue; } if(i >= mx-2 && (user->bctype[1]==1 || user->bctype[1]==-1 || user->bctype[1]==-2)) { rhs[k][j][i]=0.; continue; } if(j <=1 && (user->bctype[2]==1 || user->bctype[2]==-1 || user->bctype[2]==-2)) { rhs[k][j][i]=0.; continue; } if(j >=my-2 && (user->bctype[3]==1 || user->bctype[3]==-1 || user->bctype[3]==-2 || user->bctype[3]==12)) { rhs[k][j][i]=0.; continue; } if(k<=1 && (user->bctype[4]==1 || user->bctype[4]==-1 || user->bctype[4]==-2)) { rhs[k][j][i]=0.; continue; } if(k>=mz-2 && (user->bctype[5]==1 || user->bctype[5]==-1 || user->bctype[5]==-2)){ rhs[k][j][i]=0.; continue; } } else if( !wall_distance && user->bctype[4]==5 && user->bctype[5]==4) { //if ( fix_inlet && k==1 ) { rhs[k][j][i] = 0; continue; } //haha if ( fix_outlet && k==mz-2 ) { rhs[k][j][i] = 0; continue; } // important to stabilize outlet } double dx=pow(1./aj[k][j][i],1./3.); if(dthick_set) dx = dthick; double sgn = sign1(level0[k][j][i],dx); //if(wall_distance) sgn = sign(level0[k][j][i]); double denom[3][3][3], num[3][3][3], weight[3][3][3]; for(int p=-1; p<=1; p++) for(int q=-1; q<=1; q++) for(int r=-1; r<=1; r++) { int R=r+1, Q=q+1, P=p+1; int K=k+r, J=j+q, I=i+p; double phi = level[K][J][I], grad = grad_level[K][J][I], dx=pow(1./aj[K][J][I],1./3.); if(dthick_set) dx = dthick; double f = dH(phi,dx) * grad; double _sgn = sign1( level0[K][J][I], dx ); //if(wall_distance) _sgn = sign(level0[K][J][I]); num[R][Q][P] = dH(phi,dx) * _sgn * ( 1. - grad ); denom[R][Q][P] = dH(phi,dx) * f; } for(int p=-1; p<=1; p++) for(int q=-1; q<=1; q++) for(int r=-1; r<=1; r++) { int R=r+1, Q=q+1, P=p+1; int K=k+r, J=j+q, I=i+p; if( (!i_periodic && !ii_periodic && (I==0 || I==mx-1 ) ) || (!j_periodic && !jj_periodic && (J==0 || J==my-1 ) ) || (!k_periodic && !kk_periodic && (K==0 || K==mz-1) ) || nvert[K][J][I]>0.1) { num[R][Q][P] = num[1][1][1]; denom[R][Q][P] = denom[1][1][1]; } } get_weight (i, j, k, mx, my, mz, aj, nvert, 0.1, weight); double numerator = integrate_testfilter(num, weight); double denominator = integrate_testfilter(denom, weight); double correction; if( fabs(denominator)<1.e-10 ) correction=0; else { double grad = grad_level[k][j][i]; double phi = level[k][j][i]; double dx=pow(1./aj[k][j][i],1./3.); if(dthick_set) dx = dthick; double f = dH(phi,dx) * grad; correction = - numerator / denominator; correction *= dH(phi,dx) * grad; } double dlevel_dx, dlevel_dy, dlevel_dz; double dldc, dlde, dldz; double csi0 = csi[k][j][i].x, csi1 = csi[k][j][i].y, csi2 = csi[k][j][i].z; double eta0 = eta[k][j][i].x, eta1 = eta[k][j][i].y, eta2 = eta[k][j][i].z; double zet0 = zet[k][j][i].x, zet1 = zet[k][j][i].y, zet2 = zet[k][j][i].z; double ajc = aj[k][j][i]; //Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sgn, wall_distance, level, nvert, &dldc, &dlde, &dldz); Compute_dlevel_center_levelset (i, j, k, mx, my, mz, sign(level0[k][j][i]), wall_distance, level, nvert, &dldc, &dlde, &dldz); //100521 Compute_dscalar_dxyz (csi0, csi1, csi2, eta0, eta1, eta2, zet0, zet1, zet2, ajc, dldc, dlde, dldz, &dlevel_dx, &dlevel_dy, &dlevel_dz); rhs[k][j][i] = sgn * ( 1. - sqrt( dlevel_dx*dlevel_dx + dlevel_dy*dlevel_dy + dlevel_dz*dlevel_dz ) ); if(nvert[k][j][i+1]+nvert[k][j][i-1]+nvert[k][j+1][i]+nvert[k][j-1][i]+nvert[k+1][j][i]+nvert[k-1][j][i]>0.1) { // correction = 0; } if(!wall_distance) rhs[k][j][i] += correction; // Sussman Fetami } DAVecRestoreArray(da, L, &grad_level); DAVecRestoreArray(fda, Csi, &csi); DAVecRestoreArray(fda, Eta, &eta); DAVecRestoreArray(fda, Zet, &zet); DAVecRestoreArray(da, Aj, &aj); DAVecRestoreArray(da, user->lNvert, &nvert); DAVecRestoreArray(da, user->lLevelset, &level); DAVecRestoreArray(da, lLevelset0, &level0); DAVecRestoreArray(da, Levelset_RHS, &rhs); VecDestroy(L); VecDestroy(lLevelset0); }
/* Here is my custom preconditioner Capital vectors: X, X1 are global vectors Small vectors: x, x1 are local ghosted vectors Prefixed a: ax1, aY1 are arrays that access the vector values (either local (ax1) or global aY1) */ PetscErrorCode MyPCApply(PC pc,Vec X,Vec Y) { AppCtx *app; PetscErrorCode ierr; Vec X1,X2,X3,x1,x2,Y1,Y2,Y3; DALocalInfo info1,info2,info3; DA da1,da2,da3; PetscInt i,j; FluidField *ax1,*aY1; PetscScalar **ax2,**aY2; PetscFunctionBegin; ierr = PCShellGetContext(pc,(void**)&app); CHKERRQ(ierr); /* obtain information about the three meshes */ ierr = DMCompositeGetEntries(app->pack,&da1,&da2,&da3); CHKERRQ(ierr); ierr = DAGetLocalInfo(da1,&info1); CHKERRQ(ierr); ierr = DAGetLocalInfo(da2,&info2); CHKERRQ(ierr); ierr = DAGetLocalInfo(da3,&info3); CHKERRQ(ierr); /* get ghosted version of fluid and thermal conduction, global for phi and C */ ierr = DMCompositeGetAccess(app->pack,X,&X1,&X2,&X3); CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(app->pack,&x1,&x2,PETSC_NULL); CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,x1); CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,x1); CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da2,X2,INSERT_VALUES,x2); CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da2,X2,INSERT_VALUES,x2); CHKERRQ(ierr); /* get global version of result vector */ ierr = DMCompositeGetAccess(app->pack,Y,&Y1,&Y2,&Y3); CHKERRQ(ierr); /* pull out the phi and C values */ ierr = VecStrideGather(X3,0,app->dx,INSERT_VALUES); CHKERRQ(ierr); ierr = VecStrideGather(X3,1,app->c,INSERT_VALUES); CHKERRQ(ierr); /* update C via formula 38; put back into return vector */ ierr = VecAXPY(app->c,0.0,app->dx); CHKERRQ(ierr); ierr = VecScale(app->c,1.0); CHKERRQ(ierr); ierr = VecStrideScatter(app->c,1,Y3,INSERT_VALUES); CHKERRQ(ierr); /* form the right hand side of the phi equation; solve system; put back into return vector */ ierr = VecAXPBY(app->dx,0.0,1.0,app->c); CHKERRQ(ierr); ierr = DMMGSolve(app->fdmmg); CHKERRQ(ierr); ierr = VecStrideScatter(app->dy,0,Y3,INSERT_VALUES); CHKERRQ(ierr); /* access the ghosted x1 and x2 as arrays */ ierr = DAVecGetArray(da1,x1,&ax1); CHKERRQ(ierr); ierr = DAVecGetArray(da2,x2,&ax2); CHKERRQ(ierr); /* access global y1 and y2 as arrays */ ierr = DAVecGetArray(da1,Y1,&aY1); CHKERRQ(ierr); ierr = DAVecGetArray(da2,Y2,&aY2); CHKERRQ(ierr); for (i=info1.xs; i<info1.xs+info1.xm; i++) { aY1[i].prss = ax1[i].prss; aY1[i].ergg = ax1[i].ergg; aY1[i].ergf = ax1[i].ergf; aY1[i].alfg = ax1[i].alfg; aY1[i].velg = ax1[i].velg; aY1[i].velf = ax1[i].velf; } for (j=info2.ys; j<info2.ys+info2.ym; j++) { for (i=info2.xs; i<info2.xs+info2.xm; i++) { aY2[j][i] = ax2[j][i]; } } ierr = DAVecRestoreArray(da1,x1,&ax1); CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,x2,&ax2); CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,Y1,&aY1); CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,Y2,&aY2); CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(app->pack,&x1,&x2,PETSC_NULL); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(app->pack,X,&X1,&X2,&X3); CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(app->pack,Y,&Y1,&Y2,&Y3); CHKERRQ(ierr); PetscFunctionReturn(0); }
static int TaoDA2dLoopADFunctionGradient(TAO_APPLICATION tao, DA da, Vec X, double *f, Vec G, void * ctx) { TaoDA2D1DOFADICFGCtx *myapp = (TaoDA2D1DOFADICFGCtx*) ctx; MPI_Comm comm; Vec localX, localG; int info, i, j, coor[2]; int xs, xm, gxs, gxm, xe, ys, ym, gys, gym, ye; PetscScalar **x, **g; PetscScalar floc = 0.0; PetscScalar zero = 0.0; DERIV_TYPE adF,*adX=myapp->adX; info = DAGetLocalVector(da, &localX); CHKERRQ(info); info = DAGetLocalVector(da, &localG); CHKERRQ(info); info = VecSet(G, zero); CHKERRQ(info); info = VecSet(localG, zero); CHKERRQ(info); info = DAGlobalToLocalBegin(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAGlobalToLocalEnd(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info); info = DAVecGetArray(da, localG, (void**)&g); CHKERRQ(info); info = DAGetCorners(da, &xs, &ys, PETSC_NULL, &xm, &ym, PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(da, &gxs, &gys, PETSC_NULL, &gxm, &gym, PETSC_NULL); CHKERRQ(info); xe = gxs + gxm - 1; ye = gys + gym - 1; for (j = ys; j < ye; j++) { for (i = xs; i < xe; i++) { DERIV_val(adX[0]) = x[j][i]; DERIV_val(adX[1]) = x[j][i+1]; DERIV_val(adX[2]) = x[j+1][i]; DERIV_val(adX[3]) = x[j+1][i+1]; coor[0] = i; coor[1] = j; info = myapp->computeadicfunctiongradient(coor,adX,&adF,myapp->elementfgctx); CHKERRQ(info); floc += DERIV_val(adF); g[j][i] += DERIV_grad(adF)[0]; g[j][i+1] += DERIV_grad(adF)[1]; g[j+1][i] += DERIV_grad(adF)[2]; g[j+1][i+1] += DERIV_grad(adF)[3]; } } PetscLogFlops((ye-ys)*(xe-xs)*(myapp->elementfgflops + 5)); PetscObjectGetComm((PetscObject)da,&comm); CHKERRQ(info); info = MPI_Allreduce(&floc, f, 1, MPI_DOUBLE, MPI_SUM, comm); CHKERRQ(info); info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info); info = DAVecRestoreArray(da, localG, (void**)&g); CHKERRQ(info); info = DALocalToGlobalBegin(da, localG, G); CHKERRQ(info); info = DALocalToGlobalEnd(da, localG, G); CHKERRQ(info); info = DARestoreLocalVector(da, &localX); CHKERRQ(info); info = DARestoreLocalVector(da, &localG); CHKERRQ(info); PetscFunctionReturn(0); } /* TaoDA2dLoopADFunctionGradient */
/* WholeMSurfHessian - Evaluates Hessian over the whole grid Input: daapplication - TAO application object da - distributed array X - the current point, at which the function and gradient are evaluated ptr - user-defined application context Output: H - Hessian at X */ static int WholeMSurfHessian(TAO_APPLICATION daapplication, DA da, Vec X, Mat H, void *ptr) { AppCtx *user = (AppCtx*)ptr; Vec localX; int info; PetscInt i, j, ind[4]; PetscInt xs, xm, gxs, gxm, xe, ys, ym, gys, gym, ye; double smallH[4][4]; double **x; double hx, hy, area, byhxhx, byhyhy; double dvdx, dvdy, flow, fup; double areadivf, areadivf3; PetscTruth assembled; hx = user->hx; hy = user->hy; area = user->area; byhxhx = 1.0 / (hx * hx); byhyhy = 1.0 / (hy * hy); info = DAGetLocalVector(da, &localX); CHKERRQ(info); info = MatAssembled(H,&assembled); CHKERRQ(info); if (assembled){info = MatZeroEntries(H); CHKERRQ(info);} info = DAGlobalToLocalBegin(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAGlobalToLocalEnd(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info); info = DAGetCorners(da, &xs, &ys, TAO_NULL, &xm, &ym, TAO_NULL); CHKERRQ(info); info = DAGetGhostCorners(da, &gxs, &gys, TAO_NULL, &gxm, &gym, TAO_NULL); CHKERRQ(info); xe = gxs + gxm - 1; ye = gys + gym - 1; for (j = ys; j < ye; j++) { for (i = xs; i < xe; i++) { /* 0 is 0,0; 1 is 1,0; 2 is 0,1; 3 is 1,1 */ dvdx = (x[j][i] - x[j][i+1]) / hx; /* lower triangle contribution */ dvdy = (x[j][i] - x[j+1][i]) / hy; flow = sqrt( 1 + dvdx * dvdx + dvdy * dvdy ); dvdx = dvdx / hx; dvdy = dvdy / hy; areadivf = area / flow; areadivf3 = areadivf / (flow * flow); smallH[0][0] = areadivf * (byhxhx + byhyhy) - areadivf3 * (dvdx + dvdy) * (dvdx + dvdy); smallH[0][1] = areadivf * (-byhxhx) + areadivf3 * (dvdx + dvdy) * (dvdx); smallH[0][2] = areadivf * (-byhyhy) + areadivf3 * (dvdx + dvdy) * (dvdy); smallH[0][3] = 0.0; smallH[1][1] = areadivf * byhxhx - areadivf3 * dvdx * dvdx; smallH[1][2] = areadivf3 * (-dvdx) * dvdy; smallH[2][2] = areadivf * byhyhy - areadivf3 * dvdy * dvdy; /* upper triangle contribution */ dvdx = (x[j+1][i+1] - x[j+1][i]) / hx; dvdy = (x[j+1][i+1] - x[j][i+1]) / hy; fup = sqrt( 1 + dvdx * dvdx + dvdy * dvdy ); dvdx = dvdx / hx; dvdy = dvdy / hy; areadivf = area / fup; areadivf3 = areadivf / (fup * fup); smallH[1][1] += areadivf * byhyhy - areadivf3 * dvdy * dvdy; smallH[1][2] += areadivf3 * (-dvdy) * dvdx; smallH[2][2] += areadivf * byhxhx - areadivf3 * (dvdx * dvdx); smallH[1][3] = areadivf * (-byhyhy) + areadivf3 * (dvdx + dvdy) * dvdy; smallH[2][3] = areadivf * (-byhxhx) + areadivf3 * (dvdx + dvdy) * dvdx; smallH[3][3] = areadivf * (byhxhx + byhyhy) - areadivf3 * (dvdx + dvdy) * (dvdx + dvdy); smallH[1][0] = smallH[0][1]; smallH[2][0] = smallH[0][2]; smallH[3][0] = smallH[0][3]; smallH[2][1] = smallH[1][2]; smallH[3][1] = smallH[1][3]; smallH[3][2] = smallH[2][3]; ind[0] = (j-gys) * gxm + (i-gxs); ind[1] = ind[0] + 1; ind[2] = ind[0] + gxm; ind[3] = ind[2] + 1; info = MatSetValuesLocal(H,4,ind,4,ind,(PetscScalar*)smallH,ADD_VALUES); CHKERRQ(info); } } info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info); info = MatAssemblyBegin(H, MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = MatAssemblyEnd(H, MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = MatSetOption(H, MAT_SYMMETRIC, PETSC_TRUE); CHKERRQ(info); info = DARestoreLocalVector(da, &localX); CHKERRQ(info); info = PetscLogFlops((xe-xs) * (ye-ys) * 83 + 4); CHKERRQ(info); return 0; } /* WholeMSurfHessian */
int main(int argc,char **argv) { PetscMPIInt size,rank; PetscInt M=8,dof=1,stencil_width=1,i,start,end,P=5,N = 6,m=PETSC_DECIDE,n=PETSC_DECIDE,p=PETSC_DECIDE,pt = 0,st = 0; PetscErrorCode ierr; PetscTruth flg2,flg3,flg; DAPeriodicType periodic = DA_NONPERIODIC; DAStencilType stencil_type = DA_STENCIL_STAR; DA da; SDA sda; Vec local,global,local_copy; PetscScalar value,*in,*out; PetscReal norm,work; PetscViewer viewer; char filename[PETSC_MAX_PATH_LEN]; FILE *file; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-N",&N,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-P",&P,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-dof",&dof,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-stencil_width",&stencil_width,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-periodic",&pt,PETSC_NULL);CHKERRQ(ierr); periodic = (DAPeriodicType) pt; ierr = PetscOptionsGetInt(PETSC_NULL,"-stencil_type",&st,PETSC_NULL);CHKERRQ(ierr); stencil_type = (DAStencilType) st; ierr = PetscOptionsHasName(PETSC_NULL,"-1d",&flg2);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-2d",&flg2);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-3d",&flg3);CHKERRQ(ierr); if (flg2) { ierr = DACreate2d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,m,n,dof,stencil_width,0,0,&da);CHKERRQ(ierr); ierr = SDACreate2d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,m,n,dof,stencil_width,0,0,&sda);CHKERRQ(ierr); } else if (flg3) { ierr = DACreate3d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,P,m,n,p,dof,stencil_width,0,0,0,&da);CHKERRQ(ierr); ierr = SDACreate3d(PETSC_COMM_WORLD,periodic,stencil_type,M,N,P,m,n,p,dof,stencil_width,0,0,0,&sda);CHKERRQ(ierr); } else { ierr = DACreate1d(PETSC_COMM_WORLD,periodic,M,dof,stencil_width,PETSC_NULL,&da);CHKERRQ(ierr); ierr = SDACreate1d(PETSC_COMM_WORLD,periodic,M,dof,stencil_width,PETSC_NULL,&sda);CHKERRQ(ierr); } ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr); ierr = VecDuplicate(local,&local_copy);CHKERRQ(ierr); /* zero out vectors so that ghostpoints are zero */ value = 0; ierr = VecSet(local,value);CHKERRQ(ierr); ierr = VecSet(local_copy,value);CHKERRQ(ierr); ierr = VecGetOwnershipRange(global,&start,&end);CHKERRQ(ierr); for (i=start; i<end; i++) { value = i + 1; ierr = VecSetValues(global,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(global);CHKERRQ(ierr); ierr = VecAssemblyEnd(global);CHKERRQ(ierr); ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL,"-same_array",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) { /* test the case where the input and output array is the same */ ierr = VecCopy(local,local_copy);CHKERRQ(ierr); ierr = VecGetArray(local_copy,&in);CHKERRQ(ierr); ierr = VecRestoreArray(local_copy,PETSC_NULL);CHKERRQ(ierr); ierr = SDALocalToLocalBegin(sda,in,INSERT_VALUES,in);CHKERRQ(ierr); ierr = SDALocalToLocalEnd(sda,in,INSERT_VALUES,in);CHKERRQ(ierr); } else { ierr = VecGetArray(local,&out);CHKERRQ(ierr); ierr = VecRestoreArray(local,PETSC_NULL);CHKERRQ(ierr); ierr = VecGetArray(local_copy,&in);CHKERRQ(ierr); ierr = VecRestoreArray(local_copy,PETSC_NULL);CHKERRQ(ierr); ierr = SDALocalToLocalBegin(sda,out,INSERT_VALUES,in);CHKERRQ(ierr); ierr = SDALocalToLocalEnd(sda,out,INSERT_VALUES,in);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL,"-save",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) { ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); sprintf(filename,"local.%d",rank); ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIGetPointer(viewer,&file);CHKERRQ(ierr); ierr = VecView(local,viewer);CHKERRQ(ierr); fprintf(file,"Vector with correct ghost points\n"); ierr = VecView(local_copy,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); } ierr = VecAXPY(local_copy,-1.0,local);CHKERRQ(ierr); ierr = VecNorm(local_copy,NORM_MAX,&work);CHKERRQ(ierr); ierr = MPI_Allreduce(&work,&norm,1,MPIU_REAL,MPI_MAX,PETSC_COMM_WORLD);CHKERRQ(ierr); if (norm != 0.0) { ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of difference %G should be zero\n",norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," Number of processors %d\n",size);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," M,N,P,dof %D %D %D %D\n",M,N,P,dof);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," stencil_width %D stencil_type %d periodic %d\n",stencil_width,(int)stencil_type,(int)periodic);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," dimension %d\n",1 + (int) flg2 + (int) flg3);CHKERRQ(ierr); } ierr = DADestroy(da);CHKERRQ(ierr); ierr = SDADestroy(sda);CHKERRQ(ierr); ierr = VecDestroy(local_copy);CHKERRQ(ierr); ierr = VecDestroy(local);CHKERRQ(ierr); ierr = VecDestroy(global);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { PetscInt M = 13,dof=1,s=1,wrap=0,i,n,j; PetscErrorCode ierr; DA da; PetscViewer viewer; Vec local,locala,global,coors; PetscScalar *x,*alocal; PetscDraw draw; char fname[16]; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); /* Create viewers */ ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",PETSC_DECIDE,PETSC_DECIDE,600,200,&viewer);CHKERRQ(ierr); ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr); /* Read options */ ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-dof",&dof,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-s",&s,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-periodic",&wrap,PETSC_NULL);CHKERRQ(ierr); /* Create distributed array and get vectors */ ierr = DACreate1d(PETSC_COMM_WORLD,(DAPeriodicType)wrap,M,dof,s,PETSC_NULL,&da);CHKERRQ(ierr); ierr = DASetUniformCoordinates(da,0.0,1.0,0.0,0.0,0.0,0.0);CHKERRQ(ierr); for (i=0; i<dof; i++) { sprintf(fname,"Field %d",(int)i); ierr = DASetFieldName(da,i,fname); } ierr = DAView(da,viewer);CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DACreateLocalVector(da,&local);CHKERRQ(ierr); ierr = DACreateLocalVector(da,&locala);CHKERRQ(ierr); ierr = DAGetCoordinates(da,&coors);CHKERRQ(ierr); ierr = VecGetArray(coors,&x);CHKERRQ(ierr); /* Set values into global vectors */ ierr = VecGetArray(global,&alocal);CHKERRQ(ierr); ierr = VecGetLocalSize(global,&n);CHKERRQ(ierr); n = n/dof; for (j=0; j<dof; j++) { for (i=0; i<n; i++) { alocal[j+dof*i] = PetscSinScalar(2*PETSC_PI*(j+1)*x[i]); } } ierr = VecRestoreArray(global,&alocal);CHKERRQ(ierr); ierr = VecRestoreArray(coors,&x);CHKERRQ(ierr); ierr = VecDestroy(coords);CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); /* Send ghost points to local vectors */ ierr = DAGlobalToLocalBegin(da,global,INSERT_VALUES,locala);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da,global,INSERT_VALUES,locala);CHKERRQ(ierr); /* Free memory */ ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); ierr = VecDestroy(global);CHKERRQ(ierr); ierr = VecDestroy(local);CHKERRQ(ierr); ierr = VecDestroy(locala);CHKERRQ(ierr); ierr = DADestroy(da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
/* FormFunction - Evaluates nonlinear function, F(x). Input Parameters: . snes - the SNES context . x - input vector . ctx - optional user-defined context, as set by SNESSetFunction() Output Parameter: . f - function vector Note: The user-defined context can contain any application-specific data needed for the function evaluation. */ PetscErrorCode FormFunction(SNES snes,Vec x,Vec f,void *ctx) { ApplicationCtx *user = (ApplicationCtx*) ctx; DA da = user->da; PetscScalar *xx,*ff,*FF,d; PetscErrorCode ierr; PetscInt i,M,xs,xm; Vec xlocal; PetscFunctionBegin; ierr = DAGetLocalVector(da,&xlocal);CHKERRQ(ierr); /* Scatter ghost points to local vector, using the 2-step process DAGlobalToLocalBegin(), DAGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ ierr = DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal);CHKERRQ(ierr); /* Get pointers to vector data. - The vector xlocal includes ghost point; the vectors x and f do NOT include ghost points. - Using DAVecGetArray() allows accessing the values using global ordering */ ierr = DAVecGetArray(da,xlocal,&xx);CHKERRQ(ierr); ierr = DAVecGetArray(da,f,&ff);CHKERRQ(ierr); ierr = DAVecGetArray(da,user->F,&FF);CHKERRQ(ierr); /* Get local grid boundaries (for 1-dimensional DA): xs, xm - starting grid index, width of local grid (no ghost points) */ ierr = DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DAGetInfo(da,PETSC_NULL,&M,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL, PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); /* Set function values for boundary points; define local interior grid point range: xsi - starting interior grid index xei - ending interior grid index */ if (xs == 0) { /* left boundary */ ff[0] = xx[0]; xs++;xm--; } if (xs+xm == M) { /* right boundary */ ff[xs+xm-1] = xx[xs+xm-1] - 1.0; xm--; } /* Compute function over locally owned part of the grid (interior points only) */ d = 1.0/(user->h*user->h); for (i=xs; i<xs+xm; i++) { ff[i] = d*(xx[i-1] - 2.0*xx[i] + xx[i+1]) + xx[i]*xx[i] - FF[i]; } /* Restore vectors */ ierr = DAVecRestoreArray(da,xlocal,&xx);CHKERRQ(ierr); ierr = DAVecRestoreArray(da,f,&ff);CHKERRQ(ierr); ierr = DAVecRestoreArray(da,user->F,&FF);CHKERRQ(ierr); ierr = DARestoreLocalVector(da,&xlocal);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { DMMG *dmmg_comp; /* multilevel grid structure */ AppCtx user; /* user-defined work context */ PetscInt mx,my,its,max_its,i; PetscErrorCode ierr; MPI_Comm comm; SNES snes; DA da1,da2; DMComposite pack; DMMG *dmmg1,*dmmg2; PetscTruth SolveSubPhysics=PETSC_FALSE,GaussSeidel=PETSC_TRUE,Jacobi=PETSC_FALSE; Vec X1,X1_local,X2,X2_local; PetscViewer viewer; PetscInitialize(&argc,&argv,(char *)0,help); comm = PETSC_COMM_WORLD; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create user context, set problem data, create vector data structures. Also, compute the initial guess. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Setup Physics 1: - Lap(U) - Grad_y(Omega) = 0 - Lap(V) + Grad_x(Omega) = 0 - Lap(Omega) + Div([U*Omega,V*Omega]) - GR*Grad_x(T) = 0 where T is given by the given x.temp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,3,1,0,0,&da1);CHKERRQ(ierr); ierr = DASetFieldName(da1,0,"x-velocity");CHKERRQ(ierr); ierr = DASetFieldName(da1,1,"y-velocity");CHKERRQ(ierr); ierr = DASetFieldName(da1,2,"Omega");CHKERRQ(ierr); /* Create the solver object and attach the grid/physics info */ ierr = DMMGCreate(comm,1,&user,&dmmg1);CHKERRQ(ierr); ierr = DMMGSetDM(dmmg1,(DM)da1);CHKERRQ(ierr); ierr = DMMGSetISColoringType(dmmg1,IS_COLORING_GLOBAL);CHKERRQ(ierr); ierr = DMMGSetInitialGuess(dmmg1,FormInitialGuess1);CHKERRQ(ierr); ierr = DMMGSetSNES(dmmg1,FormFunction1,0);CHKERRQ(ierr); ierr = DMMGSetFromOptions(dmmg1);CHKERRQ(ierr); /* Set problem parameters (velocity of lid, prandtl, and grashof numbers) */ ierr = DAGetInfo(da1,PETSC_NULL,&mx,&my,0,0,0,0,0,0,0,0);CHKERRQ(ierr); user.lidvelocity = 1.0/(mx*my); user.prandtl = 1.0; user.grashof = 1000.0; ierr = PetscOptionsGetReal(PETSC_NULL,"-lidvelocity",&user.lidvelocity,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-prandtl",&user.prandtl,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-grashof",&user.grashof,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-solvesubphysics",&SolveSubPhysics);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-Jacobi",&Jacobi);CHKERRQ(ierr); if (Jacobi) GaussSeidel=PETSC_FALSE; ierr = PetscPrintf(comm,"grashof: %g, ",user.grashof);CHKERRQ(ierr); if (GaussSeidel){ ierr = PetscPrintf(comm,"use Block Gauss-Seidel\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(comm,"use Block Jacobi\n");CHKERRQ(ierr); } ierr = PetscPrintf(comm,"===========================================\n");CHKERRQ(ierr); /* Solve the nonlinear system 1 */ if (SolveSubPhysics){ ierr = DMMGSolve(dmmg1);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg1); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Physics 1: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Setup Physics 2: - Lap(T) + PR*Div([U*T,V*T]) = 0 where U and V are given by the given x.u and x.v - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da2);CHKERRQ(ierr); ierr = DASetFieldName(da2,0,"temperature");CHKERRQ(ierr); /* Create the solver object and attach the grid/physics info */ ierr = DMMGCreate(comm,1,&user,&dmmg2);CHKERRQ(ierr); ierr = DMMGSetDM(dmmg2,(DM)da2);CHKERRQ(ierr); ierr = DMMGSetISColoringType(dmmg2,IS_COLORING_GLOBAL);CHKERRQ(ierr); ierr = DMMGSetInitialGuess(dmmg2,FormInitialGuess2);CHKERRQ(ierr); ierr = DMMGSetSNES(dmmg2,FormFunction2,0);CHKERRQ(ierr); ierr = DMMGSetFromOptions(dmmg2);CHKERRQ(ierr); /* Solve the nonlinear system 2 */ if (SolveSubPhysics){ ierr = DMMGSolve(dmmg2);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg2); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Physics 2: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve system 1 and 2 iteratively - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DACreateLocalVector(da1,&X1_local);CHKERRQ(ierr); ierr = DACreateLocalVector(da2,&X2_local);CHKERRQ(ierr); /* Only 1 snes iteration is allowed for each subphysics */ /* snes = DMMGGetSNES(dmmg1); ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1,PETSC_DEFAULT);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg2); ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1,PETSC_DEFAULT);CHKERRQ(ierr); */ max_its = 5; ierr = PetscOptionsGetInt(PETSC_NULL,"-mp_max_it",&max_its,PETSC_NULL);CHKERRQ(ierr); user.nsolve = 0; for (i=0; i<max_its; i++){ ierr = PetscPrintf(comm,"\nIterative nsolve %D ...\n", user.nsolve);CHKERRQ(ierr); if (!GaussSeidel){ /* get the ghosted X1_local for Physics 2 */ X1 = DMMGGetx(dmmg1); //Jacobian if (i){ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);} ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAVecGetArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr); } ierr = DMMGSolve(dmmg1);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg1); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); if (GaussSeidel){ /* get the ghosted X1_local for Physics 2 */ X1 = DMMGGetx(dmmg1); if (i){ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);} ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAVecGetArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr); } ierr = PetscPrintf(comm," Iterative physics 1: Number of Newton iterations = %D\n", its);CHKERRQ(ierr); user.nsolve++; ierr = DMMGSolve(dmmg2);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg2); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); /* get the ghosted X2_local for Physics 1 */ X2 = DMMGGetx(dmmg2); if (i){ierr = DAVecRestoreArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr);} ierr = DAGlobalToLocalBegin(da2,X2,INSERT_VALUES,X2_local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da2,X2,INSERT_VALUES,X2_local);CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr); ierr = PetscPrintf(comm," Iterative physics 2: Number of Newton iterations = %D\n", its);CHKERRQ(ierr); //user.nsolve++; } ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the DMComposite object to manage the two grids/physics. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscPrintf(comm," \n\n DMComposite iteration......\n");CHKERRQ(ierr); ierr = DMCompositeCreate(comm,&pack);CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,(DM)da1);CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,(DM)da2);CHKERRQ(ierr); /* Create the solver object and attach the grid/physics info */ ierr = DMMGCreate(comm,1,&user,&dmmg_comp);CHKERRQ(ierr); ierr = DMMGSetDM(dmmg_comp,(DM)pack);CHKERRQ(ierr); ierr = DMMGSetISColoringType(dmmg_comp,IS_COLORING_GLOBAL);CHKERRQ(ierr); ierr = DMMGSetInitialGuess(dmmg_comp,FormInitialGuessComp);CHKERRQ(ierr); ierr = DMMGSetSNES(dmmg_comp,FormFunctionComp,0);CHKERRQ(ierr); ierr = DMMGSetFromOptions(dmmg_comp);CHKERRQ(ierr); /* Solve the nonlinear system */ /* ierr = DMMGSolve(dmmg_comp);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg_comp); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Composite Physics: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr);*/ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free spaces - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCompositeDestroy(pack);CHKERRQ(ierr); ierr = DADestroy(da1);CHKERRQ(ierr); ierr = DADestroy(da2);CHKERRQ(ierr); ierr = DMMGDestroy(dmmg_comp);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(comm,"log.py",&viewer);CHKERRQ(ierr); /* -log_summary */ ierr = PetscLogPrintSummaryToPy(comm,viewer);CHKERRQ(ierr); /* -snes_view */ //snes = DMMGGetSNES(dmmg1);CHKERRQ(ierr); ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); ierr = DMMGDestroy(dmmg1);CHKERRQ(ierr); ierr = DMMGDestroy(dmmg2);CHKERRQ(ierr); ierr = VecDestroy(X1_local);CHKERRQ(ierr); ierr = VecDestroy(X2_local);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
static int TaoDA2dLoopADFunctionGradient(TAO_APPLICATION tao, DA da, Vec X, double *f, Vec G, void * ctx) { TaoDA2D4DOFADICFGCtx *myapp = (TaoDA2D4DOFADICFGCtx*) ctx; MPI_Comm comm; Vec localX, localG; int info, i, j, coor[2]; int xs, xm, mx, xe, ys, ym, ye, my; PetscScalar zero=0.0, floc = 0.0; DERIV_TYPE adF,*adX=myapp->adX; Field **x,**g; info = DAGetLocalVector(da, &localX); CHKERRQ(info); info = DAGetLocalVector(da, &localG); CHKERRQ(info); info = VecSet(G, zero); CHKERRQ(info); info = VecSet(localG, zero); CHKERRQ(info); info = DAGetInfo(da,PETSC_NULL,&mx,&my,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL, PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(info); info = DAGlobalToLocalBegin(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAGlobalToLocalEnd(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info); info = DAVecGetArray(da, localG, (void**)&g); CHKERRQ(info); info = DAGetCorners(da, &xs, &ys, PETSC_NULL, &xm, &ym, PETSC_NULL); CHKERRQ(info); xe = xs + xm; ye = ys + ym; for (j = ys; j < ye; j++) { for (i = xs; i < xe; i++) { DERIV_val(adX[0]) = x[j][i].x; DERIV_val(adX[1]) = x[j][i].y; DERIV_val(adX[2]) = x[j][i].vpotx; DERIV_val(adX[3]) = x[j][i].vpoty; DERIV_val(adX[4]) = x[j][i+1].x; DERIV_val(adX[5]) = x[j][i+1].y; DERIV_val(adX[6]) = x[j][i+1].vpotx; DERIV_val(adX[7]) = x[j][i+1].vpoty; DERIV_val(adX[8]) = x[j+1][i].x; DERIV_val(adX[9]) = x[j+1][i].y; DERIV_val(adX[10]) = x[j+1][i].vpotx; DERIV_val(adX[11]) = x[j+1][i].vpoty; DERIV_val(adX[12]) = x[j+1][i+1].x; DERIV_val(adX[13]) = x[j+1][i+1].y; DERIV_val(adX[14]) = x[j+1][i+1].vpotx; DERIV_val(adX[15]) = x[j+1][i+1].vpoty; coor[0] = i; coor[1] = j; info = myapp->computeadicfunctiongradient(coor,adX,&adF,myapp->elementfgctx); CHKERRQ(info); floc += DERIV_val(adF); g[j][i].x += DERIV_grad(adF)[0]; g[j][i].y += DERIV_grad(adF)[1]; g[j][i].vpotx += DERIV_grad(adF)[2]; g[j][i].vpoty += DERIV_grad(adF)[3]; g[j][i+1].x += DERIV_grad(adF)[4]; g[j][i+1].y += DERIV_grad(adF)[5]; g[j][i+1].vpotx += DERIV_grad(adF)[6]; g[j][i+1].vpoty += DERIV_grad(adF)[7]; g[j+1][i].x += DERIV_grad(adF)[8]; g[j+1][i].y += DERIV_grad(adF)[9]; g[j+1][i].vpotx += DERIV_grad(adF)[10]; g[j+1][i].vpoty += DERIV_grad(adF)[11]; g[j+1][i+1].x += DERIV_grad(adF)[12]; g[j+1][i+1].y += DERIV_grad(adF)[13]; g[j+1][i+1].vpotx += DERIV_grad(adF)[14]; g[j+1][i+1].vpoty += DERIV_grad(adF)[15]; } } info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info); info = DAVecRestoreArray(da, localG, (void**)&g); CHKERRQ(info); info = DALocalToGlobalBegin(da, localG, G); CHKERRQ(info); info = DARestoreLocalVector(da, &localX); CHKERRQ(info); info = DARestoreLocalVector(da, &localG); CHKERRQ(info); info = DALocalToGlobalEnd(da, localG, G); CHKERRQ(info); PetscLogFlops((ye-ys)*(xe-xs)*(myapp->elementfgflops + 33)); PetscObjectGetComm((PetscObject)da,&comm); CHKERRQ(info); info = MPI_Allreduce(&floc, f, 1, MPI_DOUBLE, MPI_SUM, comm); CHKERRQ(info); PetscFunctionReturn(0); } /* TaoDA2dLoopADFunctionGradient */
int FormFunctionGradient(TAO_APPLICATION taoapp, Vec X, double *fcn,Vec G,void *ptr) { AppCtx* user=(AppCtx*)ptr; int info; PetscInt i,j,k,kk; PetscInt col[5],row,nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym; PetscReal one=1.0, two=2.0, six=6.0,pi=4.0*atan(1.0); PetscReal hx,hy,hxhy,hxhx,hyhy; PetscReal xi,v[5]; PetscReal ecc=user->ecc, trule1,trule2,trule3,trule4,trule5,trule6; PetscReal vmiddle, vup, vdown, vleft, vright; PetscReal tt,f1,f2; PetscReal *x,*g,zero=0.0; Vec localX; nx=user->nx; ny=user->ny; hx=two*pi/(nx+1.0); hy=two*user->b/(ny+1.0); hxhy=hx*hy; hxhx=one/(hx*hx); hyhy=one/(hy*hy); info = DAGetLocalVector(user->da,&localX);CHKERRQ(info); info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = VecSet(G, zero); CHKERRQ(info); /* Get local grid boundaries */ info = DAGetCorners(user->da,&xs,&ys,TAO_NULL,&xm,&ym,TAO_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,TAO_NULL,&gxm,&gym,TAO_NULL); CHKERRQ(info); info = VecGetArray(localX,&x); CHKERRQ(info); info = VecGetArray(G,&g); CHKERRQ(info); for (i=xs; i< xs+xm; i++){ xi=(i+1)*hx; trule1=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi,ecc) ) / six; /* L(i,j) */ trule2=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi,ecc) ) / six; /* U(i,j) */ trule3=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi+hx,ecc) ) / six; /* U(i+1,j) */ trule4=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi-hx,ecc) ) / six; /* L(i-1,j) */ trule5=trule1; /* L(i,j-1) */ trule6=trule2; /* U(i,j+1) */ vdown=-(trule5+trule2)*hyhy; vleft=-hxhx*(trule2+trule4); vright= -hxhx*(trule1+trule3); vup=-hyhy*(trule1+trule6); vmiddle=(hxhx)*(trule1+trule2+trule3+trule4)+hyhy*(trule1+trule2+trule5+trule6); for (j=ys; j<ys+ym; j++){ row=(j-gys)*gxm + (i-gxs); v[0]=0; v[1]=0; v[2]=0; v[3]=0; v[4]=0; k=0; if (j>gys){ v[k]=vdown; col[k]=row - gxm; k++; } if (i>gxs){ v[k]= vleft; col[k]=row - 1; k++; } v[k]= vmiddle; col[k]=row; k++; if (i+1 < gxs+gxm){ v[k]= vright; col[k]=row+1; k++; } if (j+1 <gys+gym){ v[k]= vup; col[k] = row+gxm; k++; } tt=0; for (kk=0;kk<k;kk++){ tt+=v[kk]*x[col[kk]]; } row=(j-ys)*xm + (i-xs); g[row]=tt; } } info = VecRestoreArray(localX,&x); CHKERRQ(info); info = VecRestoreArray(G,&g); CHKERRQ(info); info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info); info = VecDot(X,G,&f1); CHKERRQ(info); info = VecDot(user->B,X,&f2); CHKERRQ(info); info = VecAXPY(G, one, user->B); CHKERRQ(info); *fcn = f1/2.0 + f2; info = PetscLogFlops((91 + 10*ym) * xm); CHKERRQ(info); return 0; }
int Smoothing(Vec *x, Vec *y, PetscScalar *cacheScalar, PetscInt *cacheInt , VecScatter *ctx,PetscInt n,DA myDA, PetscInt Istart, PetscInt Iend){ PetscScalar C0,C1,C2; PetscErrorCode ierr; PetscInt localsizex; PetscInt n2,i, j, k; Vec lvecx,lvecy; PetscScalar **lvecptx,**lvecpty; Vec bcvec; IS isbc; //VecScatter ctx; PetscScalar *bcpt1,*bcpt2,*bcpt3,*bcpt4; localsizex = Iend-Istart; C0 = 1.0/8; C1 = 1*1.0/4; C2 = 1*3.0/16; n2 = (PetscInt)(n*0.5); DACreateLocalVector(myDA,&lvecx); DACreateLocalVector(myDA,&lvecy); DAGlobalToLocalBegin(myDA,*x,INSERT_VALUES,lvecx); DAGlobalToLocalEnd(myDA,*x,INSERT_VALUES,lvecx); VecGetArray2d(lvecx,localsizex+4,n2+4,0,0,&lvecptx); VecGetArray2d(lvecy,localsizex+4,n2+4,0,0,&lvecpty); // X direction smoothing for(j=0;j<n2+4;j++){ for(i=2;i<localsizex+2;i++){ lvecpty[i][j] = C0*lvecptx[i][j] +C1*lvecptx[i-1][j] +C1*lvecptx[i+1][j] +C2*lvecptx[i-2][j]+C2*lvecptx[i+2][j]; } } VecCreateSeqWithArray(MPI_COMM_SELF,localsizex*4,cacheScalar,&bcvec); VecScatterBegin(*x,bcvec,INSERT_VALUES,SCATTER_FORWARD,*ctx); VecScatterEnd(*x,bcvec,INSERT_VALUES,SCATTER_FORWARD,*ctx); bcpt1 = cacheScalar; bcpt2 = cacheScalar+localsizex; bcpt3 = cacheScalar+localsizex*2; bcpt4 = cacheScalar+localsizex*3; k= 0; for(i=2;i<localsizex+2;i++){ lvecpty[i][0]= *(bcpt3+k); lvecpty[i][1]= *(bcpt4+k); lvecpty[i][n2+3]= *(bcpt2+k); lvecpty[i][n2+2]= *(bcpt1+k); k++; } // Y direction smoothing for(j=2;j<n2+2;j++){ for(i=2;i<localsizex+2;i++){ lvecptx[i][j] = C0*lvecpty[i][j] +C1*lvecpty[i][j-1] +C1*lvecpty[i][j+1] +C2*lvecpty[i][j-2] +C2*lvecpty[i][j+2]; } } VecRestoreArray2d(lvecy,localsizex+4,n2+4,0,0,&lvecpty); VecRestoreArray2d(lvecx,localsizex+4,n2+4,0,0,&lvecptx); DALocalToGlobal(myDA,lvecx,INSERT_VALUES,*x); VecDestroy(bcvec); VecDestroy(lvecx); VecDestroy(lvecy); return 0; }
/* FormJacobian - Evaluates Jacobian matrix. Input Parameters: . ot - the OT context . x - input vector . ptr - optional user-defined context, as set by OTSetJacobian() Output Parameters: . A - Jacobian matrix . B - optionally different preconditioning matrix . flag - flag indicating matrix structure Notes: Due to grid point reordering with DAs, we must always work with the local grid points, and then transform them to the new global numbering with the "ltog" mapping (via DAGetGlobalIndices()). We cannot work directly with the global numbers for the original uniprocessor grid! Two methods are available for imposing this transformation when setting matrix entries: (A) MatSetValuesLocal(), using the local ordering (including ghost points!) - Use DAGetGlobalIndices() to extract the local-to-global map - Associate this map with the matrix by calling MatSetLocalToGlobalMapping() once - Set matrix entries using the local ordering by calling MatSetValuesLocal() (B) MatSetValues(), using the global ordering - Use DAGetGlobalIndices() to extract the local-to-global map - Then apply this map explicitly yourself - Set matrix entries using the global ordering by calling MatSetValues() Option (A) seems cleaner/easier in many cases, and is the procedure used in this example. */ int FormJacobian(TAO_SOLVER ot,Vec X,Mat *JJ,void *ptr) { AppCtx *user = (AppCtx *) ptr; /* user-defined application context */ Mat jac=*JJ; Vec localX=user->localX; // local vector int info, i, j, row, mx, my, col[5]; int xs, ys, xm, ym, gxs, gys, gxm, gym; PetscScalar two = 2.0, one = 1.0, lambda, v[5], hx, hy, hxdhy, hydhx, sc, *x; mx = user->mx; my = user->my; lambda = user->param; hx = one/(double)(mx-1); hy = one/(double)(my-1); sc = hx*hy; hxdhy = hx/hy; hydhx = hy/hx; /* Scatter ghost points to local vector, using the 2-step process DAGlobalToLocalBegin(), DAGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ // info = DAGetLocalVector(user->da,&(user->localX)); CHKERRQ(info); info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); /* Get pointer to vector data */ info = VecGetArray(localX,&x); CHKERRQ(info); /* Get local grid boundaries */ info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info); /* Compute entries for the locally owned part of the Jacobian. - Currently, all PETSc parallel matrix formats are partitioned by contiguous chunks of rows across the processors. - Each processor needs to insert only elements that it owns locally (but any non-local elements will be sent to the appropriate processor during matrix assembly). - Here, we set all entries for a particular row at once. - We can set matrix entries either using either MatSetValuesLocal() or MatSetValues(), as discussed above. */ for (j=ys; j<ys+ym; j++) { row = (j - gys)*gxm + xs - gxs - 1; for (i=xs; i<xs+xm; i++) { row++; /* boundary points */ if (i == 0 || j == 0 || i == mx-1 || j == my-1 ) { info = MatSetValuesLocal(jac,1,&row,1,&row,&one,INSERT_VALUES); CHKERRQ(info); continue; } /* interior grid points */ v[0] = -hxdhy; col[0] = row - gxm; v[1] = -hydhx; col[1] = row - 1; v[2] = two*(hydhx + hxdhy) - sc*lambda*exp(x[row]); col[2] = row; v[3] = -hydhx; col[3] = row + 1; v[4] = -hxdhy; col[4] = row + gxm; info = MatSetValuesLocal(jac,1,&row,5,col,v,INSERT_VALUES); CHKERRQ(info); } } /* Assemble matrix, using the 2-step process: MatAssemblyBegin(), MatAssemblyEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ info = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = VecRestoreArray(localX,&x); CHKERRQ(info); info = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY); CHKERRQ(info); /* Set flag to indicate that the Jacobian matrix retains an identical nonzero structure throughout all nonlinear iterations (although the values of the entries change). Thus, we can save some work in setting up the preconditioner (e.g., no need to redo symbolic factorization for ILU/ICC preconditioners). - If the nonzero structure of the matrix is different during successive linear solves, then the flag DIFFERENT_NONZERO_PATTERN must be used instead. If you are unsure whether the matrix structure has changed or not, use the flag DIFFERENT_NONZERO_PATTERN. - Caution: If you specify SAME_NONZERO_PATTERN, PETSc believes your assertion and does not check the structure of the matrix. If you erroneously claim that the structure is the same when it actually is not, the new preconditioner will not function correctly. Thus, use this optimization feature with caution! */ /* Tell the matrix we will never add a new nonzero location to the matrix. If we do it will generate an error. */ info = MatSetOption(jac,MAT_NEW_NONZERO_LOCATION_ERR);CHKERRQ(info); return 0; }
static PetscErrorCode BodFunctionLocal(DALocalInfo *info, Node *Hu, Node *f, AppCtx *user) { PetscErrorCode ierr; PetscReal rg = user->rho * user->g, dx = user->dx; PetscScalar *M, *Bstag, *beta, duH, ul, u, ur, dHdx, Fl, Fr, Tl, Tr; PetscInt i, Mx = info->mx; Vec locBstag; PetscFunctionBegin; /* we need stencil width on Bstag (but not for M, beta) */ ierr = DAGetLocalVector(user->scalarda,&locBstag);CHKERRQ(ierr); /* do NOT destroy it */ ierr = DAGlobalToLocalBegin(user->scalarda,user->Bstag,INSERT_VALUES,locBstag); CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(user->scalarda,user->Bstag,INSERT_VALUES,locBstag); CHKERRQ(ierr); ierr = DAVecGetArray(user->scalarda,locBstag,&Bstag);CHKERRQ(ierr); ierr = DAVecGetArray(user->scalarda,user->M,&M);CHKERRQ(ierr); ierr = DAVecGetArray(user->scalarda,user->beta,&beta);CHKERRQ(ierr); for (i = info->xs; i < info->xs + info->xm; i++) { /* MASS CONT */ if (i == 0) { /* residual at left-most point is Dirichlet cond. */ f[0].H = Hu[0].H - user->H0; } else { /* centered difference IS UNSTABLE: duH = Hu[i+1].u * Hu[i+1].H - ( (i == 1) ? 0.0 : Hu[i-1].u * Hu[i-1].H ); duH *= 0.5; */ if (user->upwind1) { /* 1st-order upwind; leftward difference because u > 0 (because dH/dx < 0) */ duH = Hu[i].u * Hu[i].H - ( (i == 1) ? 0.0 : Hu[i-1].u * Hu[i-1].H ); } else { /* 2nd-order upwind; see Beam-Warming discussion in R. LeVeque, "Finite Volume ..." */ if (i == 1) { /* use PDE M - (uH)_x = 0 to get quadratic poly, then diff that */ duH = - dx * M[0] + 2.0 * Hu[1].u * Hu[1].H; } else { duH = 3.0 * Hu[i].u * Hu[i].H - 4.0 * Hu[i-1].u * Hu[i-1].H; /* if i == 2 then u=0 so uH = 0 */ if (i >= 3) duH += Hu[i-2].u * Hu[i-2].H; duH *= 0.5; } } f[i].H = dx * M[i] - duH; } /* SSA */ if (i == 0) { /* residual at left-most point is Dirichlet cond. */ f[0].u = Hu[0].u - 0.0; } else { /* residual: SSA eqn */ /* consecutive values of u */ ul = (i == 1) ? 0.0 : Hu[i-1].u; u = Hu[i].u; ur = (i == Mx-1) ? -1.1e30 : Hu[i+1].u; /* surface slope */ if (i == 1) { dHdx = (Hu[i+1].H - user->H0) / (2.0 * dx); } else if (i == Mx-1) { /* nearly 2nd-order global convergence seems to occur even with this: dHdx = (Hu[i].H - Hu[i-1].H) / dx; */ dHdx = (3.0*Hu[i].H - 4.0*Hu[i-1].H + Hu[i-2].H) / (2.0 * dx); } else { /* generic case */ dHdx = (Hu[i+1].H - Hu[i-1].H) / (2.0 * dx); } /* vertically-integrated longitudinal stress */ Fl = GetFSR(dx,user->epsilon,user->n, ul,u); if (i == Mx-1) { Tl = 2.0 * (Hu[i-1].H + Hu[i].H) * Bstag[i-1] * Fl; Tr = (1.0 - user->rho / user->rhow) * user->rho * user->g * Hu[i].H * Hu[i].H; /* exact value: Tr = 2.0 * user->Txc; */ } else { Fr = GetFSR(dx,user->epsilon,user->n, u,ur); Tl = (Hu[i-1].H + Hu[i].H) * Bstag[i-1] * Fl; Tr = (Hu[i].H + Hu[i+1].H) * Bstag[i] * Fr; } f[i].u = (Tr - Tl) - dx * beta[i] * u - dx * rg * Hu[i].H * dHdx; /* SSA */ } } ierr = DAVecRestoreArray(user->scalarda,locBstag,&Bstag);CHKERRQ(ierr); ierr = DAVecRestoreArray(user->scalarda,user->M,&M);CHKERRQ(ierr); ierr = DAVecRestoreArray(user->scalarda,user->beta,&beta);CHKERRQ(ierr); ierr = DARestoreLocalVector(user->scalarda,&locBstag);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* WholeMSurfFunctionGradient - Evaluates function and gradient over the whole grid Input: daapplication - TAO application object da - distributed array X - the current point, at which the function and gradient are evaluated ptr - user-defined application context Output: f - value of the objective funtion at X G - gradient at X */ static int WholeMSurfFunctionGradient(TAO_APPLICATION daapplication, DA da, Vec X, double *f, Vec G, void *ptr) { AppCtx *user = (AppCtx*)ptr; Vec localX, localG; PetscInt i, j; int info; PetscInt xs, xm, gxs, gxm, xe, ys, ym, gys, gym, ye; double **x, **g; double floc = 0.0; PetscScalar zero = 0.0; double hx, hy, area; double dvdx, dvdy, flow, fup; double areadivf; hx = user->hx; hy = user->hy; area = user->area; info = DAGetLocalVector(da, &localX); CHKERRQ(info); info = DAGetLocalVector(da, &localG); CHKERRQ(info); info = VecSet(G, zero); CHKERRQ(info); info = VecSet(localG, zero); CHKERRQ(info); info = DAGlobalToLocalBegin(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAGlobalToLocalEnd(da, X, INSERT_VALUES, localX); CHKERRQ(info); info = DAVecGetArray(da, localX, (void**)&x); CHKERRQ(info); info = DAVecGetArray(da, localG, (void**)&g); CHKERRQ(info); info = DAGetCorners(da, &xs, &ys, TAO_NULL, &xm, &ym, TAO_NULL); CHKERRQ(info); info = DAGetGhostCorners(da, &gxs, &gys, TAO_NULL, &gxm, &gym, TAO_NULL); CHKERRQ(info); xe = gxs + gxm - 1; ye = gys + gym - 1; for (j = ys; j < ye; j++) { for (i = xs; i < xe; i++) { /* lower triangle contribution */ dvdx = (x[j][i] - x[j][i+1]) / hx; dvdy = (x[j][i] - x[j+1][i]) / hy; flow = sqrt( 1 + dvdx * dvdx + dvdy * dvdy ); areadivf = area / flow; g[j][i] += (dvdx / hx + dvdy / hy) * areadivf; g[j][i+1] += (-dvdx / hx) * areadivf; g[j+1][i] += (-dvdy / hy) * areadivf; /* upper triangle contribution */ dvdx = (x[j+1][i+1] - x[j+1][i]) / hx; dvdy = (x[j+1][i+1] - x[j][i+1]) / hy; fup = sqrt( 1 + dvdx * dvdx + dvdy * dvdy ); areadivf = area / fup; g[j][i+1] += (-dvdy / hy) * areadivf; g[j+1][i] += (-dvdx / hx) * areadivf; g[j+1][i+1] += (dvdx / hx + dvdy / hy) * areadivf; floc += area * (flow + fup); } } info = MPI_Allreduce(&floc, f, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); CHKERRQ(info); info = DAVecRestoreArray(da, localX, (void**)&x); CHKERRQ(info); info = DAVecRestoreArray(da, localG, (void**)&g); CHKERRQ(info); info = DALocalToGlobalBegin(da, localG, G); CHKERRQ(info); info = DALocalToGlobalEnd(da, localG, G); CHKERRQ(info); info = DARestoreLocalVector(da, &localX); CHKERRQ(info); info = DARestoreLocalVector(da, &localG); CHKERRQ(info); info = PetscLogFlops((xe-xs) * (ye-ys) * 42); CHKERRQ(info); return 0; } /* WholeMSurfFunctionGradient */