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); }
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; }
/* 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 */
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 */
void PETSC_STDCALL dagetlocalvector_(DM dm,Vec* g, int *__ierr ){ *__ierr = DAGetLocalVector( (DM)PetscToPointer((dm) ),g); }
/* 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; }
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; }
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); }
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 */
/* 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); }