int main(int argc,char **argv) { SNES snes; PetscErrorCode ierr; PetscInt its,lits; PetscReal litspit; DM da; PetscInitialize(&argc,&argv,PETSC_NULL,help); /* Set the DMDA (grid structure) for the grids. */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-5,-5,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,PETSC_NULL);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,0,0);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetLinearSolveIterations(snes,&lits);CHKERRQ(ierr); litspit = ((PetscReal)lits)/((PetscReal)its); ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of SNES iterations = %D\n",its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of Linear iterations = %D\n",lits);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Average Linear its / SNES = %e\n",litspit);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; KSP ksp; Vec u, uexact; FishCtx user; DMDALocalInfo info; double errnorm; PetscInitialize(&argc,&argv,NULL,help); user.printevals = PETSC_FALSE; ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "f3_", "options for fish3", ""); CHKERRQ(ierr); ierr = PetscOptionsBool("-printevals","residual and Jacobian routines report grid", "fish3.c",user.printevals,&user.printevals,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd(); CHKERRQ(ierr); ierr = DMDACreate3d(COMM, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, 3,3,3,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE, 1,1, NULL,NULL,NULL,&(user.da)); CHKERRQ(ierr); ierr = DMSetFromOptions(user.da); CHKERRQ(ierr); ierr = DMSetUp(user.da); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(user.da,&info); CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.da,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&uexact);CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.b));CHKERRQ(ierr); ierr = formExactRHS(&info,uexact,user.b,&user); CHKERRQ(ierr); ierr = SNESCreate(COMM,&snes); CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da); CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES, (DMDASNESFunction)FormFunctionLocal,&user); CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da, (DMDASNESJacobian)FormJacobianLocal,&user); CHKERRQ(ierr); ierr = SNESGetKSP(snes,&ksp); CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPCG); CHKERRQ(ierr); ierr = SNESSetFromOptions(snes); CHKERRQ(ierr); ierr = VecSet(u,0.0); CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,u); CHKERRQ(ierr); ierr = VecAXPY(u,-1.0,uexact); CHKERRQ(ierr); // u <- u + (-1.0) uexact ierr = VecNorm(u,NORM_INFINITY,&errnorm); CHKERRQ(ierr); ierr = PetscPrintf(COMM,"on %d x %d x %d grid: error |u-uexact|_inf = %g\n", info.mx,info.my,info.mz,errnorm); CHKERRQ(ierr); VecDestroy(&u); VecDestroy(&uexact); VecDestroy(&(user.b)); SNESDestroy(&snes); DMDestroy(&(user.da)); PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; Vec u; DMDALocalInfo info; Ctx user; PetscInitialize(&argc,&argv,(char*)0,help); ierr = configureCtx(&user); CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, -3,-3, PETSC_DECIDE,PETSC_DECIDE, 1,1, NULL,NULL, &user.da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.da,-1.0,1.0,-1.0,1.0,0.0,1.0); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user); CHKERRQ(ierr); ierr = DMDAGetLocalInfo(user.da,&info); CHKERRQ(ierr); if ((info.mx < 2) || (info.my < 2)) { SETERRQ(PETSC_COMM_WORLD,1,"grid too coarse ... require (mx,my) > (2,2)"); } ierr = DMCreateGlobalVector(user.da,&u); CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)u,"u_vec");CHKERRQ(ierr); ierr = formInitial(&info,&user,u); CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES, (DMDASNESFunction)FormFunctionLocal,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da, (DMDASNESJacobian)FormJacobianLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,u); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "done on %d x %d x %d grid with eps=%g ...\n", info.mx,info.my,info.mz,user.eps); CHKERRQ(ierr); VecDestroy(&u); SNESDestroy(&snes); DMDestroy(&user.da); ierr = PetscFinalize(); CHKERRQ(ierr); return 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) { AppCtx user; /* user-defined work context */ PetscInt mx,my; PetscErrorCode ierr; MPI_Comm comm; DM da; Vec x; Mat J = NULL,Jmf = NULL; MatShellCtx matshellctx; PetscInt mlocal,nlocal; PC pc; KSP ksp; PetscBool errorinmatmult = PETSC_FALSE,errorinpcapply = PETSC_FALSE,errorinpcsetup = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return(1); PetscFunctionBeginUser; ierr = PetscOptionsGetBool(NULL,"-error_in_matmult",&errorinmatmult,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcapply",&errorinpcapply,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcsetup",&errorinpcsetup,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domain",&user.errorindomain,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domainmf",&user.errorindomainmf,NULL);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = SNESCreate(comm,&user.snes);CHKERRQ(ierr); /* Create distributed array object to manage parallel grid and vectors for principal unknowns (x) and governing residuals (f) */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,4,1,0,0,&da);CHKERRQ(ierr); ierr = SNESSetDM(user.snes,da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&mx,&my,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); /* Problem parameters (velocity of lid, prandtl, and grashof numbers) */ user.lidvelocity = 1.0/(mx*my); user.prandtl = 1.0; user.grashof = 1.0; ierr = PetscOptionsGetReal(NULL,"-lidvelocity",&user.lidvelocity,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-prandtl",&user.prandtl,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-grashof",&user.grashof,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-contours",&user.draw_contours);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"x_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"y_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"Omega");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"temperature");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create user context, set problem data, create vector data structures. Also, compute the initial guess. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); if (errorinmatmult) { ierr = MatCreateSNESMF(user.snes,&Jmf);CHKERRQ(ierr); ierr = MatSetFromOptions(Jmf);CHKERRQ(ierr); ierr = MatGetLocalSize(Jmf,&mlocal,&nlocal);CHKERRQ(ierr); matshellctx.Jmf = Jmf; ierr = MatCreateShell(PetscObjectComm((PetscObject)Jmf),mlocal,nlocal,PETSC_DECIDE,PETSC_DECIDE,&matshellctx,&J);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_MULT,(void (*)(void))MatMult_MyShell);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_ASSEMBLY_END,(void (*)(void))MatAssemblyEnd_MyShell);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr); } ierr = SNESSetFromOptions(user.snes);CHKERRQ(ierr); ierr = PetscPrintf(comm,"lid velocity = %g, prandtl # = %g, grashof # = %g\n",(double)user.lidvelocity,(double)user.prandtl,(double)user.grashof);CHKERRQ(ierr); if (errorinpcapply) { ierr = SNESGetKSP(user.snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetApply(pc,PCApply_MyShell);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(&user,da,x);CHKERRQ(ierr); if (errorinpcsetup) { ierr = SNESSetUp(user.snes);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,NULL,NULL,SNESComputeJacobian_MyShell,NULL);CHKERRQ(ierr); } ierr = SNESSolve(user.snes,NULL,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatDestroy(&Jmf);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESDestroy(&user.snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
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) { SNES snes; /* nonlinear solver */ AppCtx user; /* user-defined work context */ PetscInt its; /* iterations for convergence */ PetscErrorCode ierr; DM da; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize problem parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Surface Process Problem Options", "SNES");CHKERRQ(ierr); user.D = 1.0; ierr = PetscOptionsReal("-D", "The diffusion coefficient D", __FILE__, user.D, &user.D, NULL);CHKERRQ(ierr); user.K = 1.0; ierr = PetscOptionsReal("-K", "The advection coefficient K", __FILE__, user.K, &user.K, NULL);CHKERRQ(ierr); user.m = 1; ierr = PetscOptionsInt("-m", "The exponent for A", __FILE__, user.m, &user.m, NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,4,4,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = SNESSetDM(snes, da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set local function evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSolve(snes,0,0);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of SNES iterations = %D\n",its);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; Vec u, uexact; double err, uexnorm; DMDALocalInfo info; Ctx user; PetscInitialize(&argc,&argv,(char*)0,help); ierr = configureCtx(&user); CHKERRQ(ierr); //STARTDMDA ierr = DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_PERIODIC, DMDA_STENCIL_STAR, 3,3,3, PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE, 1, 1, NULL,NULL,NULL, &user.da); CHKERRQ(ierr); //ENDDMDA ierr = DMSetFromOptions(user.da); CHKERRQ(ierr); ierr = DMSetUp(user.da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.da,-1.0,1.0,-1.0,1.0,-1.0,1.0); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user); CHKERRQ(ierr); ierr = DMDAGetLocalInfo(user.da,&info); CHKERRQ(ierr); if ((info.mx < 2) || (info.my < 2) || (info.mz < 3)) { SETERRQ(PETSC_COMM_WORLD,1,"grid too coarse: require (mx,my,mz) > (2,2,3)"); } ierr = DMCreateGlobalVector(user.da,&uexact); CHKERRQ(ierr); ierr = VecDuplicate(uexact,&user.f); CHKERRQ(ierr); ierr = VecDuplicate(uexact,&user.g); CHKERRQ(ierr); ierr = formUexFG(&info,&user,uexact); CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes); CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da); CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES, (DMDASNESFunction)FormFunctionLocal,&user); CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da, (DMDASNESJacobian)FormJacobianLocal,&user); CHKERRQ(ierr); ierr = SNESSetFromOptions(snes); CHKERRQ(ierr); ierr = VecDuplicate(uexact,&u); CHKERRQ(ierr); ierr = VecCopy(user.g,u); CHKERRQ(ierr); // g has zeros except at bdry ierr = SNESSolve(snes,NULL,u); CHKERRQ(ierr); ierr = VecAXPY(u,-1.0,uexact); CHKERRQ(ierr); // u <- u + (-1.0) uxact ierr = VecNorm(u,NORM_2,&err); CHKERRQ(ierr); ierr = VecNorm(uexact,NORM_2,&uexnorm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "done on %d x %d x %d grid with eps=%g: error |u-uexact|_2/|uexact|_2 = %g\n", info.mx,info.my,info.mz,user.eps,err/uexnorm); CHKERRQ(ierr); VecDestroy(&u); VecDestroy(&uexact); VecDestroy(&user.f); VecDestroy(&user.g); SNESDestroy(&snes); DMDestroy(&user.da); 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) { AppCtx user; /* user-defined work context */ PetscInt mx,my,its; PetscErrorCode ierr; MPI_Comm comm; SNES snes; DM da; Vec x,X,b; PetscBool youngflg,poissonflg,muflg,lambdaflg,view=PETSC_FALSE,viewline=PETSC_FALSE; PetscReal poisson=0.2,young=4e4; char filename[PETSC_MAX_PATH_LEN] = "ex16.vts"; char filename_def[PETSC_MAX_PATH_LEN] = "ex16_def.vts"; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = FormElements();CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = SNESCreate(comm,&snes);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,11,2,2,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,3,1,NULL,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = SNESSetDM(snes,(DM)da);CHKERRQ(ierr); ierr = SNESSetNGS(snes,NonlinearGS,&user);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&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.loading = 0.0; user.arc = PETSC_PI/3.; user.mu = 4.0; user.lambda = 1.0; user.rad = 100.0; user.height = 3.; user.width = 1.; user.ploading = -5e3; ierr = PetscOptionsGetReal(NULL,NULL,"-arc",&user.arc,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-mu",&user.mu,&muflg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-lambda",&user.lambda,&lambdaflg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-rad",&user.rad,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-height",&user.height,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-width",&user.width,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-loading",&user.loading,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-ploading",&user.ploading,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-poisson",&poisson,&poissonflg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-young",&young,&youngflg);CHKERRQ(ierr); if ((youngflg || poissonflg) || !(muflg || lambdaflg)) { /* set the lame' parameters based upon the poisson ratio and young's modulus */ user.lambda = poisson*young / ((1. + poisson)*(1. - 2.*poisson)); user.mu = young/(2.*(1. + poisson)); } ierr = PetscOptionsGetBool(NULL,NULL,"-view",&view,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_line",&viewline,NULL);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"x_disp");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"y_disp");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"z_disp");CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(da,(DMDASNESJacobian)FormJacobianLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = FormCoordinates(da,&user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = InitialGuess(da,&user,x);CHKERRQ(ierr); ierr = FormRHS(da,&user,b);CHKERRQ(ierr); ierr = PetscPrintf(comm,"lambda: %f mu: %f\n",(double)user.lambda,(double)user.mu);CHKERRQ(ierr); /* show a cross-section of the initial state */ if (viewline) { ierr = DisplayLine(snes,x);CHKERRQ(ierr); } /* get the loaded configuration */ ierr = SNESSolve(snes,b,x);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Number of SNES iterations = %D\n", its);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); /* show a cross-section of the final state */ if (viewline) { ierr = DisplayLine(snes,X);CHKERRQ(ierr); } if (view) { PetscViewer viewer; Vec coords; ierr = PetscViewerVTKOpen(PETSC_COMM_WORLD,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = VecView(x,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coords);CHKERRQ(ierr); ierr = VecAXPY(coords,1.0,x);CHKERRQ(ierr); ierr = PetscViewerVTKOpen(PETSC_COMM_WORLD,filename_def,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = VecView(x,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
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; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; /* nonlinear solver */ Vec Hu; /* solution vector */ AppCtx user; /* user-defined work context */ ExactCtx exact; PetscInt its; /* snes reports iteration count */ SNESConvergedReason reason; /* snes reports convergence */ PetscReal tmp1, tmp2, tmp3, errnorms[2], scaleNode[2], descaleNode[2]; PetscInt i; char dumpfile[80],dxdocstr[80]; PetscBool eps_set = PETSC_FALSE, dump = PETSC_FALSE, exactinitial = PETSC_FALSE, snes_mf_set, snes_fd_set, dx_set; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &user.rank); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "MARINE solves for thickness and velocity in 1D, steady marine ice sheet\n" " [run with -help for info and options]\n");CHKERRQ(ierr); user.n = 3.0; /* Glen flow law exponent */ user.secpera = 31556926.0; user.rho = 910.0; /* kg m^-3 */ user.rhow = 1028.0; /* kg m^-3 */ user.omega = 1.0 - user.rho / user.rhow; user.g = 9.81; /* m s^-2 */ /* get parameters of exact solution */ ierr = params_exactBod(&tmp1, &(exact.L0), &(exact.xg), &tmp2, &tmp3, &(user.k)); CHKERRQ(ierr); ierr = exactBod(exact.xg,&(exact.Hg),&tmp2,&(exact.Mg)); CHKERRQ(ierr); ierr = exactBodBueler(exact.xg,&tmp1,&(exact.Bg)); CHKERRQ(ierr); user.zocean = user.rho * exact.Hg / user.rhow; /* see ../marineshoot.py: */ #define xa_default 0.2 #define xc_default 0.98 /* define interval [xa,xc] */ user.xa = xa_default * exact.L0; user.xc = xc_default * exact.L0; /* get Dirichlet boundary conditions, and mass balance on shelf */ ierr = exactBod(user.xa, &(user.Ha), &(user.ua), &tmp1); CHKERRQ(ierr); /* regularize using strain rate of 1/(length) per year */ user.epsilon = (1.0 / user.secpera) / (user.xc - user.xa); /*user.epsilon = 0.0;*/ user.Hscale = 1000.0; user.uscale = 100.0 / user.secpera; user.noscale = PETSC_FALSE; user.dx = 10000.0; /* default to coarse 10 km grid */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "","options to marine (steady marine ice sheet solver)","");CHKERRQ(ierr); { ierr = PetscOptionsBool("-snes_mf","","",PETSC_FALSE,&snes_mf_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-snes_fd","","",PETSC_FALSE,&snes_fd_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-noscale","","",PETSC_FALSE,&user.noscale,NULL);CHKERRQ(ierr); snprintf(dxdocstr,80,"target grid spacing (m) on interval of length %.0f m", user.xc-user.xa); ierr = PetscOptionsReal("-dx",dxdocstr,"",user.dx,&user.dx,&dx_set);CHKERRQ(ierr); ierr = PetscOptionsBool("-exactinit", "initialize using exact solution instead of default linear function","", PETSC_FALSE,&exactinitial,NULL);CHKERRQ(ierr); ierr = PetscOptionsString("-dump", "dump approx and exact solution into given file (as ascii matlab format)","", NULL,dumpfile,80,&dump);CHKERRQ(ierr); ierr = PetscOptionsReal("-epsilon","regularizing strain rate for stress computation (a-1)","", user.epsilon * user.secpera,&user.epsilon,&eps_set);CHKERRQ(ierr); if (eps_set) user.epsilon *= 1.0 / user.secpera; } ierr = PetscOptionsEnd();CHKERRQ(ierr); if (snes_fd_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " using approximate Jacobian; finite-differencing using coloring\n"); CHKERRQ(ierr); } else if (snes_mf_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " matrix free; no preconditioner\n"); CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, " true Jacobian\n"); CHKERRQ(ierr); } if (dx_set && (user.dx <= 0.0)) { PetscPrintf(PETSC_COMM_WORLD, "\n***ERROR: -dx value must be positive ... USAGE FOLLOWS ...\n\n%s",help); PetscEnd(); } user.N = (int)ceil( ((user.xc - user.xa) / user.dx) - 0.5 ); user.Mx = user.N + 2; user.dx = (user.xc - user.xa) / ((PetscReal)(user.N) + 0.5); /* recompute so dx * (N+1/2) = xc - xa */ if (dx_set && (user.dx < 1.0)) { PetscPrintf(PETSC_COMM_WORLD, "\n***WARNING: '-dx %.3f' meters is below one meter and creates grid of %d points\n" " ... probably uncomputable!\n\n", user.dx,user.Mx); } /* residual scaling coeffs; motivation at right */ user.rscHa = 1.0 / user.Hscale, /* Dirichlet cond for H */ user.rscua = 1.0 / user.uscale, /* Dirichlet cond for u */ user.rscuH = user.dx / (user.Hscale * user.uscale), /* flux derivative d(uH)/dx */ user.rscstress = 1.0 / (user.k * user.rho * user.g * user.Hscale * user.uscale), /* beta term in SSA */ user.rsccalv = 1.0 / (0.025 * user.rho * user.g * user.Hscale); /* 0.5 * omega * overburden */ /* Create machinery for parallel grid management (DMDA), nonlinear solver (SNES), and Vecs for fields (solution, RHS). Degrees of freedom = 2 (thickness and velocity at each point). */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,user.Mx,2,1,PETSC_NULL,&user.da); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user);CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,0,"ice thickness [non-dimensional]"); CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,1,"ice velocity [non-dimensional]"); CHKERRQ(ierr); ierr = DMSetFromOptions(user.da); CHKERRQ(ierr); ierr = DMDAGetInfo(user.da,PETSC_IGNORE,&user.Mx,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); ierr = DMDAGetCorners(user.da,&user.xs,PETSC_NULL,PETSC_NULL,&user.xm,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); /* another DMDA for scalar staggered parameters; one fewer point */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,user.Mx-1,1,1,PETSC_NULL,&user.stagda); CHKERRQ(ierr); /* establish geometry on grid; note xa = x_0 and xc = x_{N+1/2} */ ierr = DMDASetUniformCoordinates(user.da, user.xa, user.xc+0.5*user.dx, 0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.stagda,user.xa+0.5*user.dx,user.xc, 0.0,1.0,0.0,1.0);CHKERRQ(ierr); /* report on current grid */ ierr = PetscPrintf(PETSC_COMM_WORLD, " grid: Mx = N+2 = %D regular points, dx = %.3f m, xa = %.2f km, xc = %.2f km\n", user.Mx, user.dx, user.xa/1000.0, user.xc/1000.0);CHKERRQ(ierr); /* Extract/allocate global vectors from DMDAs and duplicate for remaining same types */ ierr = DMCreateGlobalVector(user.da,&Hu);CHKERRQ(ierr); ierr = VecSetBlockSize(Hu,2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)Hu,"Hu");CHKERRQ(ierr); ierr = VecDuplicate(Hu,&exact.Hu);CHKERRQ(ierr); /* inherits block size */ ierr = PetscObjectSetName((PetscObject)exact.Hu,"exactHu");CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.stagda,&user.Mstag);CHKERRQ(ierr); ierr = VecDuplicate(user.Mstag,&user.Bstag);CHKERRQ(ierr); /* set up snes */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES,(DMDASNESFunction)scshell,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da,(DMDASNESJacobian)JacobianMatrixLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* the exact thickness and exact ice velocity (user.uHexact) are known */ ierr = FillExactSoln(&exact, &user); CHKERRQ(ierr); /* the exact solution allows setting M(x), B(x) */ ierr = FillDistributedParams(&exact, &user);CHKERRQ(ierr); if (exactinitial) { ierr = PetscPrintf(PETSC_COMM_WORLD," using exact solution as initial guess\n"); CHKERRQ(ierr); /* the initial guess is the exact continuum solution */ ierr = VecCopy(exact.Hu,Hu); CHKERRQ(ierr); } else { /* the initial guess is a linear solution */ ierr = FillInitial(&user, &Hu); CHKERRQ(ierr); } /************ SOLVE NONLINEAR SYSTEM ************/ /* recall that RHS r is used internally by KSP, and is set by the SNES */ if (user.noscale) { user.Hscale = 1.0; user.uscale = 1.0; } scaleNode[0] = user.Hscale; scaleNode[1] = user.uscale; for (i = 0; i < 2; i++) descaleNode[i] = 1.0 / scaleNode[i]; ierr = VecStrideScaleAll(Hu,descaleNode); CHKERRQ(ierr); /* de-dimensionalize initial guess */ ierr = SNESSolve(snes,PETSC_NULL,Hu);CHKERRQ(ierr); ierr = VecStrideScaleAll(Hu,scaleNode); CHKERRQ(ierr); /* put back in "real" scale */ /* minimal report on solve */ ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " %s Number of Newton iterations = %D\n", SNESConvergedReasons[reason],its);CHKERRQ(ierr); if (dump) { ierr = PetscPrintf(PETSC_COMM_WORLD, "dumping results in ascii matlab format to file '%s' ...\n",dumpfile);CHKERRQ(ierr); PetscViewer viewer; ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,dumpfile,&viewer);CHKERRQ(ierr); ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); DM coord_da; Vec coord_x; ierr = DMGetCoordinateDM(user.da, &coord_da); CHKERRQ(ierr); ierr = DMGetCoordinates(user.da, &coord_x); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% START MATLAB\n"); CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)coord_x,"x");CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing coordinate vector x \n");CHKERRQ(ierr); ierr = VecView(coord_x,viewer); CHKERRQ(ierr); ierr = VecView(Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing combined result Hu\n");CHKERRQ(ierr); ierr = VecView(Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing combined exact result exactHu\n");CHKERRQ(ierr); ierr = VecView(exact.Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer, "%% defining plottable variables and plotting in Matlab\n" "Mx = %d; secpera = 31556926.0;\n" "H = Hu(1:2:2*Mx-1);\n" "u = Hu(2:2:2*Mx);\n" "exactH = exactHu(1:2:2*Mx-1);\n" "exactu = exactHu(2:2:2*Mx);\n" "figure, plot(x,H,x,exactH);\n" "legend('numerical','exact'), xlabel x, ylabel('H (m)')\n" "figure, plot(x,u*secpera,x,exactu*secpera);\n" "legend('numerical','exact'), xlabel x, ylabel('u (m/a)')\n" "figure, subplot(2,1,1), semilogy(x,abs(H-exactH));\n" "ylabel('H error (m)'), grid\n" "subplot(2,1,2), semilogy(x,abs(u-exactu)*secpera);\n" "xlabel x, ylabel('u error (m/a)'), grid\n", user.Mx); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% END MATLAB\n"); CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* evaluate error relative to exact solution */ ierr = VecAXPY(Hu,-1.0,exact.Hu); CHKERRQ(ierr); /* Hu = - Huexact + Hu */ ierr = VecStrideNormAll(Hu,NORM_INFINITY,errnorms); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "(dx,errHinf,erruinf) %.3f %.4e %.4e\n", user.dx,errnorms[0],errnorms[1]*user.secpera);CHKERRQ(ierr); ierr = VecDestroy(&Hu);CHKERRQ(ierr); ierr = VecDestroy(&(exact.Hu));CHKERRQ(ierr); ierr = VecDestroy(&(user.Mstag));CHKERRQ(ierr); ierr = VecDestroy(&(user.Bstag));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&(user.da));CHKERRQ(ierr); ierr = DMDestroy(&(user.stagda));CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { DM da; SNES snes; /* nonlinear solver */ AppCtx *user; /* user-defined work context */ PetscBag bag; PetscInt its; /* iterations for convergence */ PetscMPIInt size; SNESConvergedReason reason; PetscErrorCode ierr; PetscReal lambda_max = 6.81, lambda_min = 0.0, error; Vec x; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Example only works for one process."); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize problem parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscBagCreate(PETSC_COMM_WORLD, sizeof(AppCtx), &bag);CHKERRQ(ierr); ierr = PetscBagGetData(bag, (void**) &user);CHKERRQ(ierr); ierr = PetscBagSetName(bag, "params", "Parameters for SNES example 4");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &user->alpha, 1.0, "alpha", "Linear coefficient");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &user->lambda, 6.0, "lambda", "Nonlinear coefficient");CHKERRQ(ierr); ierr = PetscBagSetFromOptions(bag);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-alpha",&user->alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-lambda",&user->lambda,NULL);CHKERRQ(ierr); if (user->lambda > lambda_max || user->lambda < lambda_min) SETERRQ3(PETSC_COMM_SELF,1,"Lambda %g is out of range [%g, %g]", (double)user->lambda, (double)lambda_min, (double)lambda_max); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create multilevel DM data structure (SNES) to manage hierarchical solvers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,-3,-3,PETSC_DECIDE,PETSC_DECIDE,3,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetFieldName(da, 0, "ooblek");CHKERRQ(ierr); ierr = DMSetApplicationContext(da,user);CHKERRQ(ierr); ierr = SNESSetDM(snes, (DM) da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set the discretization functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 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); ierr = SNESSetComputeInitialGuess(snes, FormInitialGuess,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSolve(snes,NULL,NULL);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes, &reason);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of SNES iterations = %D, %s\n",its,SNESConvergedReasons[reason]);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESGetDM(snes,&da);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); ierr = L_2Error(da, x, &error, user);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"L_2 error in the solution: %g\n", (double)error);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscBagDestroy(&bag);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }