static PetscErrorCode SNESSetUp_Composite(SNES snes) { PetscErrorCode ierr; DM dm; SNES_Composite *jac = (SNES_Composite*)snes->data; SNES_CompositeLink next = jac->head; PetscInt n=0,i; Vec F; PetscFunctionBegin; ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); if (snes->ops->computevariablebounds) { /* SNESVI only ever calls computevariablebounds once, so calling it once here is justified */ if (!snes->xl) {ierr = VecDuplicate(snes->vec_sol,&snes->xl);CHKERRQ(ierr);} if (!snes->xu) {ierr = VecDuplicate(snes->vec_sol,&snes->xu);CHKERRQ(ierr);} ierr = (*snes->ops->computevariablebounds)(snes,snes->xl,snes->xu);CHKERRQ(ierr); } while (next) { n++; ierr = SNESSetDM(next->snes,dm);CHKERRQ(ierr); ierr = SNESSetApplicationContext(next->snes, snes->user);CHKERRQ(ierr); if (snes->xl && snes->xu) { if (snes->ops->computevariablebounds) { ierr = SNESVISetComputeVariableBounds(next->snes, snes->ops->computevariablebounds);CHKERRQ(ierr); } else { ierr = SNESVISetVariableBounds(next->snes,snes->xl,snes->xu);CHKERRQ(ierr); } } next = next->next; } jac->nsnes = n; ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr); if (jac->type == SNES_COMPOSITE_ADDITIVEOPTIMAL) { ierr = VecDuplicateVecs(F,jac->nsnes,&jac->Xes);CHKERRQ(ierr); ierr = PetscMalloc1(n,&jac->Fes);CHKERRQ(ierr); ierr = PetscMalloc1(n,&jac->fnorms);CHKERRQ(ierr); next = jac->head; i = 0; while (next) { ierr = SNESGetFunction(next->snes,&F,NULL,NULL);CHKERRQ(ierr); jac->Fes[i] = F; ierr = PetscObjectReference((PetscObject)F);CHKERRQ(ierr); next = next->next; i++; } /* allocate the subspace direct solve area */ jac->nrhs = 1; jac->lda = jac->nsnes; jac->ldb = jac->nsnes; jac->n = jac->nsnes; ierr = PetscMalloc1(jac->n*jac->n,&jac->h);CHKERRQ(ierr); ierr = PetscMalloc1(jac->n,&jac->beta);CHKERRQ(ierr); ierr = PetscMalloc1(jac->n,&jac->s);CHKERRQ(ierr); ierr = PetscMalloc1(jac->n,&jac->g);CHKERRQ(ierr); jac->lwork = 12*jac->n; #if PETSC_USE_COMPLEX ierr = PetscMalloc1(jac->lwork,&jac->rwork);CHKERRQ(ierr); #endif ierr = PetscMalloc1(jac->lwork,&jac->work);CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; DM da, da_after; SNES snes; Vec u_initial, u; PoissonCtx user; SNESConvergedReason reason; int snesits; double lflops,flops; DMDALocalInfo info; PetscInitialize(&argc,&argv,NULL,help); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"el_", "elasto-plastic torsion solver options",""); CHKERRQ(ierr); ierr = PetscOptionsReal("-C","f(x,y)=2C is source term", "elasto.c",C,&C,NULL); CHKERRQ(ierr); ierr = PetscOptionsEnd(); CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, 3,3, // override with -da_grid_x,_y PETSC_DECIDE,PETSC_DECIDE, // num of procs in each dim 1,1,NULL,NULL, // dof = 1 and stencil width = 1 &da);CHKERRQ(ierr); ierr = DMSetFromOptions(da); CHKERRQ(ierr); ierr = DMSetUp(da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,-1.0,-1.0);CHKERRQ(ierr); user.cx = 1.0; user.cy = 1.0; user.cz = 1.0; user.g_bdry = &zero; user.f_rhs = &f_fcn; user.addctx = NULL; ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = SNESSetApplicationContext(snes,&user);CHKERRQ(ierr); ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,&FormBounds);CHKERRQ(ierr); // reuse residual and jacobian from ch6/ ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES, (DMDASNESFunction)Poisson2DFunctionLocal,&user); CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(da, (DMDASNESJacobian)Poisson2DJacobianLocal,&user); CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); // initial iterate is zero ierr = DMCreateGlobalVector(da,&u_initial);CHKERRQ(ierr); ierr = VecSet(u_initial,0.0); CHKERRQ(ierr); /* solve; then get solution and DM after solution*/ ierr = SNESSolve(snes,NULL,u_initial);CHKERRQ(ierr); ierr = VecDestroy(&u_initial); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = SNESGetDM(snes,&da_after); CHKERRQ(ierr); ierr = SNESGetSolution(snes,&u); CHKERRQ(ierr); /* do not destroy u */ /* performance measures */ ierr = SNESGetConvergedReason(snes,&reason); CHKERRQ(ierr); if (reason <= 0) { ierr = PetscPrintf(PETSC_COMM_WORLD, "WARNING: SNES not converged ... use -snes_converged_reason to check\n"); CHKERRQ(ierr); } ierr = SNESGetIterationNumber(snes,&snesits); CHKERRQ(ierr); ierr = PetscGetFlops(&lflops); CHKERRQ(ierr); ierr = MPI_Allreduce(&lflops,&flops,1,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD); CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da_after,&info); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "done on %4d x %4d grid; total flops = %.3e; SNES iterations %d\n", info.mx,info.my,flops,snesits); CHKERRQ(ierr); SNESDestroy(&snes); return PetscFinalize(); }
int main(int argc,char **argv) { PetscErrorCode ierr; DM da; /* structured grid topology object */ TS ts; /* time-stepping object (contains snes) */ SNES snes; /* Newton solver object */ Vec X,residual; /* solution, residual */ Mat J; /* Jacobian matrix */ PetscInt Mx,My,fsteps,steps; ISColoring iscoloring; PetscReal tstart,tend,ftime,secperday=3600.0*24.0,Y0; PetscBool fdflg = PETSC_FALSE, mfileflg = PETSC_FALSE, optflg = PETSC_FALSE; char mfile[PETSC_MAX_PATH_LEN] = "out.m"; MatFDColoring matfdcoloring; PorousCtx user; /* user-defined work context */ PetscInitialize(&argc,&argv,(char *)0,help); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, // correct for zero Dirichlet DMDA_STENCIL_STAR, // nonlinear diffusion but diffusivity // depends on soln W not grad W -21,-21, // default to 20x20 grid but override with // -da_grid_x, -da_grid_y (or -da_refine) PETSC_DECIDE,PETSC_DECIDE, // num of procs in each dim 2, // dof = 2: node = (W,Y) // or node = (P,dPsqr) // or node = (ddxE,ddyN) 1, // s = 1 (stencil extends out one cell) PETSC_NULL,PETSC_NULL, // no specify proc decomposition &da);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); /* get Vecs and Mats for this grid */ ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&residual);CHKERRQ(ierr); ierr = VecDuplicate(X,&user.geom);CHKERRQ(ierr); ierr = DMGetMatrix(da,MATAIJ,&J);CHKERRQ(ierr); /* set up contexts */ tstart = 10.0 * secperday; /* 10 days in seconds */ tend = 30.0 * secperday; steps = 20; Y0 = 1.0; /* initial value of Y, for computing initial value of P; note Ymin = 0.1 is different */ user.da = da; ierr = DefaultContext(&user);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "","options to (W,P)-space better hydrology model alt","");CHKERRQ(ierr); { ierr = PetscOptionsReal("-alt_sigma","nonlinear power","", user.sigma,&user.sigma,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Ymin", "min capacity thickness (esp. in pressure computation)","", user.Ymin,&user.Ymin,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Wmin", "min water amount (esp. in pressure computation)","", user.Wmin,&user.Wmin,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Y0", "constant initial capacity thickness","", Y0,&Y0,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Cmelt", "additional coefficient for amount of melt","", user.Cmelt,&user.Cmelt,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Creep", "creep closure coefficient","", user.Creep,&user.Creep,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_L","half-width of square region in meters","", user.L,&user.L,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_tstart_days","start time in days","", tstart/secperday,&tstart,&optflg);CHKERRQ(ierr); if (optflg) { tstart *= secperday; } ierr = PetscOptionsReal("-alt_tend_days","end time in days","", tend/secperday,&tend,&optflg);CHKERRQ(ierr); if (optflg) { tend *= secperday; } ierr = PetscOptionsInt("-alt_steps","number of timesteps to take","", steps,&steps,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-alt_converge_check", "run silent and check for convergence", "",user.run_silent,&user.run_silent,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsString("-mfile", "name of Matlab file to write results","", mfile,mfile,PETSC_MAX_PATH_LEN,&mfileflg); CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* fix remaining parameters */ ierr = DerivedConstants(&user);CHKERRQ(ierr); ierr = VecStrideSet(user.geom,0,user.H0);CHKERRQ(ierr); /* H(x,y) = H0 */ ierr = VecStrideSet(user.geom,1,0.0);CHKERRQ(ierr); /* b(x,y) = 0 */ ierr = DMDASetUniformCoordinates(da, // square domain -user.L, user.L, -user.L, user.L, 0.0, 1.0);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); user.dx = 2.0 * user.L / (Mx-1); user.dy = 2.0 * user.L / (My-1); /* setup TS = timestepping object */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,residual,RHSFunction,&user);CHKERRQ(ierr); /* use coloring to compute rhs Jacobian efficiently */ ierr = PetscOptionsGetBool(PETSC_NULL,"-fd",&fdflg,PETSC_NULL);CHKERRQ(ierr); if (fdflg){ ierr = DMGetColoring(da,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode (*)(void))RHSFunction,&user);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,J,J,TSDefaultComputeJacobianColor, matfdcoloring);CHKERRQ(ierr); } else { /* default case */ ierr = TSSetRHSJacobian(ts,J,J,RHSJacobian,&user);CHKERRQ(ierr); } /* set initial state: W = barenblatt, P = pi (W/Y0)^sigma */ ierr = InitialState(da,&user,tstart,Y0,X);CHKERRQ(ierr); /* set up times for time-stepping */ ierr = TSSetInitialTimeStep(ts,tstart, (tend - tstart) / (PetscReal)steps);CHKERRQ(ierr); ierr = TSSetDuration(ts,steps,tend);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,PETSC_TRUE);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyTSMonitor,&user,PETSC_NULL);CHKERRQ(ierr); /* Set SNESVI type and supply upper and lower bounds. */ ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,FormPositivityBounds); CHKERRQ(ierr); /* ask user to finalize settings */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* report on setup */ if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "setup done: square side length = %.3f km\n" " grid Mx,My = %d,%d\n" " spacing dx,dy = %.3f,%.3f m\n" " times tstart:dt:tend = %.3f:%.3f:%.3f days\n", 2.0 * user.L / 1000.0, Mx, My, user.dx, user.dy, tstart / secperday, (tend-tstart)/(steps*secperday), tend / secperday); CHKERRQ(ierr); } if (mfileflg) { if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "writing initial W,P and geometry H,b to Matlab file %s ...\n", mfile);CHKERRQ(ierr); } ierr = print2vecmatlab(da,X,"W_init","P_init",mfile,PETSC_FALSE);CHKERRQ(ierr); ierr = print2vecmatlab(da,user.geom,"H","b",mfile,PETSC_TRUE);CHKERRQ(ierr); } /* run time-stepping with implicit steps */ ierr = TSSolve(ts,X,&ftime);CHKERRQ(ierr); /* make a report on run and final state */ ierr = TSGetTimeStepNumber(ts,&fsteps);CHKERRQ(ierr); if ((!user.run_silent) && (ftime != tend)) { ierr = PetscPrintf(PETSC_COMM_WORLD, "***WARNING3***: reported final time wrong: ftime(=%.12e) != tend(=%.12e) (days)\n", ftime / secperday, tend / secperday);CHKERRQ(ierr); } if ((!user.run_silent) && (fsteps != steps)) { ierr = PetscPrintf(PETSC_COMM_WORLD, "***WARNING4***: reported number of steps wrong: fsteps(=%D) != steps(=%D)\n", fsteps, steps);CHKERRQ(ierr); } if (mfileflg) { if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "writing final fields to %s ...\n",mfile);CHKERRQ(ierr); } ierr = print2vecmatlab(da,X,"W_final","P_final",mfile,PETSC_TRUE);CHKERRQ(ierr); ierr = printfigurematlab(da,2,"W_init","W_final",mfile,PETSC_TRUE);CHKERRQ(ierr); ierr = printfigurematlab(da,3,"P_init","P_final",mfile,PETSC_TRUE);CHKERRQ(ierr); } if (user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "%6d %6d %9.3f %.12e\n", Mx, My, (tend-tstart)/secperday, user.maxrnorm);CHKERRQ(ierr); } /* Free work space. */ ierr = MatDestroy(&J);CHKERRQ(ierr); if (fdflg) { ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); } ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&user.geom);CHKERRQ(ierr); ierr = VecDestroy(&residual);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); PetscFunctionReturn((PetscInt)(user.not_converged_warning)); }
int main(int argc,char **argv) { PetscErrorCode ierr; ObsCtx user; SNES snes; DM da; Vec u; /* solution */ DMDALocalInfo info; PetscReal error1,errorinf; PetscInitialize(&argc,&argv,(char*)0,help); ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, -11,-11, /* default to 10x10 grid */ PETSC_DECIDE,PETSC_DECIDE, /* number of processors in each dimension */ 1, /* dof = 1 */ 1, /* s = 1; stencil extends out one cell */ NULL,NULL, /* do not specify processor decomposition */ &da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.uexact));CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.psi));CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,-2.0,2.0,-2.0,2.0,0.0,1.0);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = FormPsiAndExactSoln(da);CHKERRQ(ierr); ierr = VecSet(u,0.0);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = SNESSetApplicationContext(snes,&user);CHKERRQ(ierr); ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,&FormBounds);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(da,(PetscErrorCode (*)(DMDALocalInfo*,void*,Mat,Mat,void*))FormJacobianLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* report on setup */ ierr = DMDAGetLocalInfo(da,&info); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"setup done: grid Mx,My = %D,%D with spacing dx,dy = %.4f,%.4f\n", info.mx,info.my,4.0/(PetscReal)(info.mx-1),4.0/(PetscReal)(info.my-1));CHKERRQ(ierr); /* solve nonlinear system */ ierr = SNESSolve(snes,NULL,u);CHKERRQ(ierr); /* compare to exact */ ierr = VecAXPY(u,-1.0,user.uexact);CHKERRQ(ierr); /* u <- u - uexact */ ierr = VecNorm(u,NORM_1,&error1);CHKERRQ(ierr); error1 /= (PetscReal)info.mx * (PetscReal)info.my; ierr = VecNorm(u,NORM_INFINITY,&errorinf);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"errors: av |u-uexact| = %.3e |u-uexact|_inf = %.3e\n",error1,errorinf);CHKERRQ(ierr); /* Free work space. */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&(user.psi));CHKERRQ(ierr); ierr = VecDestroy(&(user.uexact));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; Vec u, r; /* solution, residual vector */ PetscInt Mx,My,its; SNESConvergedReason reason; DM da; ObsCtx user; PetscReal dx,dy,error1,errorinf; PetscBool feasible = PETSC_FALSE,fdflg = PETSC_FALSE; PetscInitialize(&argc,&argv,(char *)0,help); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_STENCIL_STAR, /* nonlinear diffusion but diffusivity depends on soln W not grad W */ -11,-11, /* default to 10x10 grid but override with -da_grid_x, -da_grid_y (or -da_refine) */ PETSC_DECIDE,PETSC_DECIDE, /* num of procs in each dim */ 1, /* dof = 1 */ 1, /* s = 1 (stencil extends out one cell) */ PETSC_NULL,PETSC_NULL, /* no specify proc decomposition */ &da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&r);CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.uexact));CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.psi));CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","options to obstacle problem","");CHKERRQ(ierr); ierr = PetscOptionsBool("-fd","use coloring to compute Jacobian by finite differences",PETSC_NULL,fdflg,&fdflg,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-feasible","use feasible initial guess",PETSC_NULL,feasible,&feasible,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,-2.0,2.0,-2.0,2.0,0.0,1.0);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = FormPsiAndInitialGuess(da,u,feasible);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = SNESSetApplicationContext(snes,&user);CHKERRQ(ierr); ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,&FormBounds);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); if (!fdflg) { ierr = DMDASNESSetJacobianLocal(da,(PetscErrorCode (*)(DMDALocalInfo*,void*,Mat,Mat,MatStructure*,void*))FormJacobianLocal,&user);CHKERRQ(ierr); } ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* report on setup */ ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); dx = 4.0 / (PetscReal)(Mx-1); dy = 4.0 / (PetscReal)(My-1); ierr = PetscPrintf(PETSC_COMM_WORLD, "setup done: square side length = %.3f\n" " grid Mx,My = %D,%D\n" " spacing dx,dy = %.3f,%.3f\n", 4.0, Mx, My, (double)dx, (double)dy);CHKERRQ(ierr); /* solve nonlinear system */ ierr = SNESSolve(snes,PETSC_NULL,u);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"number of Newton iterations = %D; result = %s\n", its,SNESConvergedReasons[reason]);CHKERRQ(ierr); /* compare to exact */ ierr = VecWAXPY(r,-1.0,user.uexact,u);CHKERRQ(ierr); /* r = W - Wexact */ ierr = VecNorm(r,NORM_1,&error1);CHKERRQ(ierr); error1 /= (PetscReal)Mx * (PetscReal)My; ierr = VecNorm(r,NORM_INFINITY,&errorinf);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"errors: av |u-uexact| = %.3e\n |u-uexact|_inf = %.3e\n",error1,errorinf);CHKERRQ(ierr); /* Free work space. */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = VecDestroy(&(user.psi));CHKERRQ(ierr); ierr = VecDestroy(&(user.uexact));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; Vec u, r; /* solution, residual vector */ PetscInt its; SNESConvergedReason reason; DM da; ObsCtx user; PetscReal error1,errorinf; PetscBool feasible = PETSC_FALSE,fdflg = PETSC_FALSE; DMDALocalInfo info; PetscInitialize(&argc,&argv,NULL,help); //CREATE ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, 11,11, // override with -da_grid_x,_y or -da_refine PETSC_DECIDE,PETSC_DECIDE, // num of procs in each dim 1,1,NULL,NULL, // dof = 1 and stencil width = 1 &da);CHKERRQ(ierr); ierr = DMSetFromOptions(da); CHKERRQ(ierr); ierr = DMSetUp(da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,-2.0,2.0,-2.0,2.0,-1.0,-1.0);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(da,&info); CHKERRQ(ierr); user.dx = 4.0 / (PetscReal)(info.mx-1); user.dy = 4.0 / (PetscReal)(info.my-1); ierr = DMCreateGlobalVector(da,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&r);CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.g));CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.psi));CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","options to obstacle problem","");CHKERRQ(ierr); ierr = PetscOptionsBool("-fd","use coloring to compute Jacobian by finite differences", NULL,fdflg,&fdflg,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-feasible","use feasible initial guess", NULL,feasible,&feasible,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); //ENDCREATE //SETUPSNES ierr = FormPsiAndInitialGuess(da,u,feasible,&user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = SNESSetApplicationContext(snes,&user);CHKERRQ(ierr); ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,&FormBounds);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES, (PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal, &user);CHKERRQ(ierr); if (!fdflg) { ierr = DMDASNESSetJacobianLocal(da, (PetscErrorCode (*)(DMDALocalInfo*,void*,Mat,Mat,void*))FormJacobianLocal, &user);CHKERRQ(ierr); } ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); //ENDSETUPSNES /* report on setup */ ierr = PetscPrintf(PETSC_COMM_WORLD, "setup done: square side length = %.3f\n" " grid Mx,My = %D,%D\n" " spacing dx,dy = %.3f,%.3f\n", 4.0, info.mx, info.my, user.dx, user.dy);CHKERRQ(ierr); //SOLVE /* solve nonlinear system */ ierr = SNESSolve(snes,NULL,u);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"number of Newton iterations = %D; result = %s\n", its,SNESConvergedReasons[reason]);CHKERRQ(ierr); /* compare to exact */ ierr = VecWAXPY(r,-1.0,user.g,u);CHKERRQ(ierr); /* r = u - g = u - uexact */ ierr = VecNorm(r,NORM_1,&error1);CHKERRQ(ierr); error1 /= (PetscReal)info.mx * (PetscReal)info.my; ierr = VecNorm(r,NORM_INFINITY,&errorinf);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "errors: av |u-uexact| = %.3e\n" " |u-uexact|_inf = %.3e\n", (double)error1,(double)errorinf);CHKERRQ(ierr); //ENDSOLVE /* Free work space. */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = VecDestroy(&(user.psi));CHKERRQ(ierr); ierr = VecDestroy(&(user.g));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }