Pointer<SAMRAIVectorReal<NDIM, double> > PETScSNESJacobianJOWrapper::getBaseVector() const { Vec petsc_x; int ierr = SNESGetSolution(d_petsc_snes, &petsc_x); IBTK_CHKERRQ(ierr); return PETScSAMRAIVectorReal::getSAMRAIVector(petsc_x); } // getBaseVector
int main(int argc, char **argv) { DM dm; /* Problem specification */ SNES snes; /* Nonlinear solver */ Vec u; /* Solutions */ AppCtx user; /* User-defined work context */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); /* Primal system */ ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); ierr = SetupFE(dm, user.dim, user.simplex, "displacement", SetupPrimalProblem, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = VecSet(u, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "displacement");CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm, &user, &user, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = DMSNESCheckFromOptions(snes, u, NULL, NULL);CHKERRQ(ierr); ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-displacement_view");CHKERRQ(ierr); /* Cleanup */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
Pointer<SAMRAIVectorReal<NDIM, double> > PETScNewtonKrylovSolver::getSolutionVector() const { Vec petsc_x; int ierr = SNESGetSolution(d_petsc_snes, &petsc_x); IBTK_CHKERRQ(ierr); return PETScSAMRAIVectorReal::getSAMRAIVector(petsc_x); } // getSolutionVector
PetscErrorCode KSPMonitorSNESLGResidualNorm(KSP ksp,PetscInt n,PetscReal rnorm,PetscObject *objs) { SNES snes = (SNES) objs[0]; PetscDrawLG lg = (PetscDrawLG) objs[1]; PetscErrorCode ierr; PetscReal y[2]; Vec snes_solution,work1,work2; PetscFunctionBegin; if (rnorm > 0.0) y[0] = PetscLog10Real(rnorm); else y[0] = -15.0; ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr); ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr); ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr); ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr); ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr); ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr); ierr = VecNorm(work2,NORM_2,y+1);CHKERRQ(ierr); if (y[1] > 0.0) y[1] = PetscLog10Real(y[1]); else y[1] = -15.0; ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = PetscDrawLGAddPoint(lg,NULL,y);CHKERRQ(ierr); if (n < 20 || !(n % 5)) { ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx) { #if defined(PETSC_MISSING_LAPACK_GEEV) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values."); #elif defined(PETSC_HAVE_ESSL) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines"); #else Vec X; Mat J,dJ,dJdense; PetscErrorCode ierr; PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); PetscInt n,i; PetscBLASInt nb,lwork; PetscReal *eigr,*eigi; MatStructure flg = DIFFERENT_NONZERO_PATTERN; PetscScalar *work; PetscScalar *a; PetscFunctionBegin; if (it == 0) PetscFunctionReturn(0); /* create the difference between the current update and the current jacobian */ ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); ierr = SNESGetJacobian(snes,&J,NULL,&func,NULL);CHKERRQ(ierr); ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr); ierr = SNESComputeJacobian(snes,X,&dJ,&dJ,&flg);CHKERRQ(ierr); ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* compute the spectrum directly */ ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr); ierr = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr); ierr = PetscBLASIntCast(n,&nb);CHKERRQ(ierr); lwork = 3*nb; ierr = PetscMalloc(n*sizeof(PetscReal),&eigr);CHKERRQ(ierr); ierr = PetscMalloc(n*sizeof(PetscReal),&eigi);CHKERRQ(ierr); ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr); ierr = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr); #if !defined(PETSC_USE_COMPLEX) { PetscBLASInt lierr; ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); PetscStackCall("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr)); if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr); ierr = PetscFPTrapPop();CHKERRQ(ierr); } #else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex"); #endif PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr); for (i=0;i<n;i++) { PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,eigr[i],eigi[i]);CHKERRQ(ierr); } ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr); ierr = MatDestroy(&dJ);CHKERRQ(ierr); ierr = MatDestroy(&dJdense);CHKERRQ(ierr); ierr = PetscFree(eigr);CHKERRQ(ierr); ierr = PetscFree(eigi);CHKERRQ(ierr); ierr = PetscFree(work);CHKERRQ(ierr); PetscFunctionReturn(0); #endif }
/*@ SNESGetNPCFunction - Gets the function from a preconditioner after SNESSolve() has been called. Collective on SNES Input Parameters: . snes - the SNES context Output Parameter: . F - function vector . fnorm - the norm of F Level: developer .keywords: SNES, nonlinear, function .seealso: SNESGetNPC(),SNESSetNPC(),SNESComputeFunction(),SNESApplyNPC(),SNESSolve() @*/ PetscErrorCode SNESGetNPCFunction(SNES snes,Vec F,PetscReal *fnorm) { PetscErrorCode ierr; PCSide npcside; SNESFunctionType functype; SNESNormSchedule normschedule; Vec FPC,XPC; PetscFunctionBegin; if (snes->pc) { ierr = SNESGetNPCSide(snes->pc,&npcside);CHKERRQ(ierr); ierr = SNESGetFunctionType(snes->pc,&functype);CHKERRQ(ierr); ierr = SNESGetNormSchedule(snes->pc,&normschedule);CHKERRQ(ierr); /* check if the function is valid based upon how the inner solver is preconditioned */ if (normschedule != SNES_NORM_NONE && normschedule != SNES_NORM_INITIAL_ONLY && (npcside == PC_RIGHT || functype == SNES_FUNCTION_UNPRECONDITIONED)) { ierr = SNESGetFunction(snes->pc,&FPC,NULL,NULL);CHKERRQ(ierr); if (FPC) { if (fnorm) {ierr = SNESGetFunctionNorm(snes->pc,fnorm);CHKERRQ(ierr);} ierr = VecCopy(FPC,F);CHKERRQ(ierr); } else { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Preconditioner has no function"); } } else { ierr = SNESGetSolution(snes->pc,&XPC);CHKERRQ(ierr); if (XPC) { ierr = SNESComputeFunction(snes->pc,XPC,F);CHKERRQ(ierr); if (fnorm) {ierr = VecNorm(F,NORM_2,fnorm);CHKERRQ(ierr);} } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Preconditioner has no solution"); } } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No preconditioner set"); PetscFunctionReturn(0); }
/*@C KSPMonitorSNES - Print the residual norm of the nonlinear function at each iteration of the linear iterative solver. Collective on KSP Input Parameters: + ksp - iterative context . n - iteration number . rnorm - 2-norm (preconditioned) residual value (may be estimated). - dummy - unused monitor context Level: intermediate .keywords: KSP, default, monitor, residual .seealso: KSPMonitorSet(), KSPMonitorTrueResidualNorm(), KSPMonitorLGResidualNormCreate() @*/ PetscErrorCode KSPMonitorSNES(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy) { PetscErrorCode ierr; PetscViewer viewer; SNES snes = (SNES) dummy; Vec snes_solution,work1,work2; PetscReal snorm; PetscFunctionBegin; ierr = SNESGetSolution(snes,&snes_solution);CHKERRQ(ierr); ierr = VecDuplicate(snes_solution,&work1);CHKERRQ(ierr); ierr = VecDuplicate(snes_solution,&work2);CHKERRQ(ierr); ierr = KSPBuildSolution(ksp,work1,NULL);CHKERRQ(ierr); ierr = VecAYPX(work1,-1.0,snes_solution);CHKERRQ(ierr); ierr = SNESComputeFunction(snes,work1,work2);CHKERRQ(ierr); ierr = VecNorm(work2,NORM_2,&snorm);CHKERRQ(ierr); ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp),&viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); if (n == 0 && ((PetscObject)ksp)->prefix) { ierr = PetscViewerASCIIPrintf(viewer," Residual norms for %s solve.\n",((PetscObject)ksp)->prefix);CHKERRQ(ierr); } ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Residual norm %5.3e KSP Residual norm %5.3e \n",n,(double)snorm,(double)rnorm);CHKERRQ(ierr); ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)ksp)->tablevel);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Monitor - User-defined monitoring routine that views the current iterate with an x-window plot. Input Parameters: snes - the SNES context its - iteration number norm - 2-norm function value (may be estimated) ctx - optional user-defined context for private data for the monitor routine, as set by SNESMonitorSet() Note: See the manpage for PetscViewerDrawOpen() for useful runtime options, such as -nox to deactivate all x-window output. */ PetscErrorCode Monitor(SNES snes,PetscInt its,PetscReal fnorm,void *ctx) { PetscErrorCode ierr; MonitorCtx *monP = (MonitorCtx*) ctx; Vec x; ierr = PetscPrintf(PETSC_COMM_WORLD,"iter = %D, SNES Function norm %G\n",its,fnorm);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); ierr = VecView(x,monP->viewer);CHKERRQ(ierr); return 0; }
/*@C SNESMonitorSolution - Monitors progress of the SNES solvers by calling VecView() for the approximate solution at each iteration. Collective on SNES Input Parameters: + snes - the SNES context . its - iteration number . fgnorm - 2-norm of residual - dummy - a viewer Level: intermediate .keywords: SNES, nonlinear, vector, monitor, view .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() @*/ PetscErrorCode SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) { PetscErrorCode ierr; Vec x; PetscViewer viewer = (PetscViewer) dummy; PetscFunctionBegin; PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,4); ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); ierr = VecView(x,viewer);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* MatAssemblyEnd_SNESMF - Calls MatAssemblyEnd_MFFD() and then sets the base from the SNES context */ PetscErrorCode MatAssemblyEnd_SNESMF(Mat J,MatAssemblyType mt) { PetscErrorCode ierr; MatMFFD j = (MatMFFD)J->data; SNES snes = (SNES)j->funcctx; Vec u,f; PetscFunctionBegin; ierr = MatAssemblyEnd_MFFD(J,mt);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); ierr = SNESGetFunction(snes,&f,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = MatMFFDSetBase(J,u,f);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C SNESMonitorSolution - Monitors progress of the SNES solvers by calling VecView() for the approximate solution at each iteration. Collective on SNES Input Parameters: + snes - the SNES context . its - iteration number . fgnorm - 2-norm of residual - dummy - either a viewer or NULL Level: intermediate .keywords: SNES, nonlinear, vector, monitor, view .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() @*/ PetscErrorCode SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) { PetscErrorCode ierr; Vec x; PetscViewer viewer = (PetscViewer) dummy; PetscFunctionBegin; ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); if (!viewer) { MPI_Comm comm; ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); viewer = PETSC_VIEWER_DRAW_(comm); } ierr = VecView(x,viewer);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatAssemblyEnd_DAAD(Mat A,MatAssemblyType atype) { Mat_DAAD *a = (Mat_DAAD*)A->data; PetscErrorCode ierr; Vec u; PetscFunctionBegin; a->diagonalvalid = PETSC_FALSE; if (a->snes) { ierr = SNESGetSolution(a->snes,&u); CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(a->da,u,INSERT_VALUES,a->localu); CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(a->da,u,INSERT_VALUES,a->localu); CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode Monitor(SNES snes,PetscInt its,PetscReal rnorm,void *dummy) { UserCtx *user = (UserCtx*)dummy; PetscErrorCode ierr; Vec w,u,lambda,U,F; PetscFunctionBeginUser; ierr = SNESGetSolution(snes,&U);CHKERRQ(ierr); ierr = DMCompositeGetAccess(user->packer,U,&w,&u,&lambda);CHKERRQ(ierr); ierr = VecView(u,user->u_viewer);CHKERRQ(ierr); ierr = VecView(lambda,user->lambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(user->packer,U,&w,&u,&lambda);CHKERRQ(ierr); ierr = SNESGetFunction(snes,&F,0,0);CHKERRQ(ierr); ierr = DMCompositeGetAccess(user->packer,F,&w,&u,&lambda);CHKERRQ(ierr); ierr = VecView(u,user->fu_viewer);CHKERRQ(ierr); ierr = VecView(lambda,user->flambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(user->packer,F,&w,&u,&lambda);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode Monitor(SNES snes,PetscInt its,PetscReal rnorm,void *dummy) { UserCtx *user; PetscErrorCode ierr; PetscInt m,N; PetscScalar *w,*dw; Vec u_lambda,U,F,Uexact; DM packer; PetscReal norm; DM da; PetscFunctionBeginUser; ierr = SNESGetDM(snes,&packer);CHKERRQ(ierr); ierr = DMGetApplicationContext(packer,&user);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&U);CHKERRQ(ierr); ierr = DMCompositeGetAccess(packer,U,&w,&u_lambda);CHKERRQ(ierr); ierr = VecView(u_lambda,user->u_lambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(packer,U,&w,&u_lambda);CHKERRQ(ierr); ierr = SNESGetFunction(snes,&F,0,0);CHKERRQ(ierr); ierr = DMCompositeGetAccess(packer,F,&w,&u_lambda);CHKERRQ(ierr); /* ierr = VecView(u_lambda,user->fu_lambda_viewer); */ ierr = DMCompositeRestoreAccess(packer,U,&w,&u_lambda);CHKERRQ(ierr); ierr = DMCompositeGetEntries(packer,&m,&da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&N,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = VecDuplicate(U,&Uexact);CHKERRQ(ierr); ierr = ExactSolution(packer,Uexact);CHKERRQ(ierr); ierr = VecAXPY(Uexact,-1.0,U);CHKERRQ(ierr); ierr = DMCompositeGetAccess(packer,Uexact,&dw,&u_lambda);CHKERRQ(ierr); ierr = VecStrideNorm(u_lambda,0,NORM_2,&norm);CHKERRQ(ierr); norm = norm/PetscSqrtReal((PetscReal)N-1.); if (dw) ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %g Error at x = 0 %g\n",(double)norm,(double)PetscRealPart(dw[0]));CHKERRQ(ierr); ierr = VecView(u_lambda,user->fu_lambda_viewer);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(packer,Uexact,&dw,&u_lambda);CHKERRQ(ierr); ierr = VecDestroy(&Uexact);CHKERRQ(ierr); PetscFunctionReturn(0); }
// Function to hand to PETSc's SNES, // which monitors convergence at X PetscErrorCode __libmesh_petsc_diff_solver_monitor (SNES snes, PetscInt its, PetscReal fnorm, void *ctx) { PetscDiffSolver& solver = *(static_cast<PetscDiffSolver*> (ctx)); if (solver.verbose) libMesh::out << " PetscDiffSolver step " << its << ", |residual|_2 = " << fnorm << std::endl; if (solver.linear_solution_monitor.get()) { int ierr = 0; Vec petsc_delta_u; ierr = SNESGetSolutionUpdate(snes, &petsc_delta_u); CHKERRABORT(libMesh::COMM_WORLD, ierr); PetscVector<Number> delta_u(petsc_delta_u, solver.comm()); delta_u.close(); Vec petsc_u; ierr = SNESGetSolution(snes, &petsc_u); CHKERRABORT(libMesh::COMM_WORLD, ierr); PetscVector<Number> u(petsc_u, solver.comm()); u.close(); Vec petsc_res; ierr = SNESGetFunction(snes, &petsc_res, NULL, NULL); CHKERRABORT(libMesh::COMM_WORLD, ierr); PetscVector<Number> res(petsc_res, solver.comm()); res.close(); (*solver.linear_solution_monitor)( delta_u, delta_u.l2_norm(), u, u.l2_norm(), res, res.l2_norm(), its); } return 0; }
int main(int argc, char **argv) { DM dm; /* Problem specification */ SNES snes; /* Nonlinear solver */ Vec u; /* Solutions */ AppCtx user; /* User-defined work context */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); /* Primal system */ ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); ierr = SetupDiscretization(dm, "potential", SetupPrimalProblem, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = VecSet(u, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "potential");CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm, &user, &user, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-potential_view");CHKERRQ(ierr); if (user.spectral) { PetscInt planeDir[2] = {0, 1}; PetscReal planeCoord[2] = {0., 1.}; ierr = ComputeSpectral(dm, u, 2, planeDir, planeCoord, &user);CHKERRQ(ierr); } /* Adjoint system */ if (user.adjoint) { DM dmAdj; SNES snesAdj; Vec uAdj; ierr = SNESCreate(PETSC_COMM_WORLD, &snesAdj);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) snesAdj, "adjoint_");CHKERRQ(ierr); ierr = DMClone(dm, &dmAdj);CHKERRQ(ierr); ierr = SNESSetDM(snesAdj, dmAdj);CHKERRQ(ierr); ierr = SetupDiscretization(dmAdj, "adjoint", SetupAdjointProblem, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dmAdj, &uAdj);CHKERRQ(ierr); ierr = VecSet(uAdj, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) uAdj, "adjoint");CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dmAdj, &user, &user, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snesAdj);CHKERRQ(ierr); ierr = SNESSolve(snesAdj, NULL, uAdj);CHKERRQ(ierr); ierr = SNESGetSolution(snesAdj, &uAdj);CHKERRQ(ierr); ierr = VecViewFromOptions(uAdj, NULL, "-adjoint_view");CHKERRQ(ierr); /* Error representation */ { DM dmErr, dmErrAux, dms[2]; Vec errorEst, errorL2, uErr, uErrLoc, uAdjLoc, uAdjProj; IS *subis; PetscReal errorEstTot, errorL2Norm, errorL2Tot; PetscInt N, i; PetscErrorCode (*funcs[1])(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *) = {trig_u}; void (*identity[1])(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]) = {f0_identityaux_u}; void *ctxs[1] = {0}; ctxs[0] = &user; ierr = DMClone(dm, &dmErr);CHKERRQ(ierr); ierr = SetupDiscretization(dmErr, "error", SetupErrorProblem, &user);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErr, &errorEst);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErr, &errorL2);CHKERRQ(ierr); /* Compute auxiliary data (solution and projection of adjoint solution) */ ierr = DMGetLocalVector(dmAdj, &uAdjLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dmAdj, uAdj, INSERT_VALUES, uAdjLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dmAdj, uAdj, INSERT_VALUES, uAdjLoc);CHKERRQ(ierr); ierr = DMGetGlobalVector(dm, &uAdjProj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAdj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", (PetscObject) uAdjLoc);CHKERRQ(ierr); ierr = DMProjectField(dm, 0.0, u, identity, INSERT_VALUES, uAdjProj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", NULL);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", NULL);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmAdj, &uAdjLoc);CHKERRQ(ierr); /* Attach auxiliary data */ dms[0] = dm; dms[1] = dm; ierr = DMCreateSuperDM(dms, 2, &subis, &dmErrAux);CHKERRQ(ierr); if (0) { PetscSection sec; ierr = DMGetSection(dms[0], &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMGetSection(dms[1], &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMGetSection(dmErrAux, &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = DMViewFromOptions(dmErrAux, NULL, "-dm_err_view");CHKERRQ(ierr); ierr = ISViewFromOptions(subis[0], NULL, "-super_is_view");CHKERRQ(ierr); ierr = ISViewFromOptions(subis[1], NULL, "-super_is_view");CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErrAux, &uErr);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(uAdjProj, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(uErr, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecISCopy(uErr, subis[0], SCATTER_FORWARD, u);CHKERRQ(ierr); ierr = VecISCopy(uErr, subis[1], SCATTER_FORWARD, uAdjProj);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &uAdjProj);CHKERRQ(ierr); for (i = 0; i < 2; ++i) {ierr = ISDestroy(&subis[i]);CHKERRQ(ierr);} ierr = PetscFree(subis);CHKERRQ(ierr); ierr = DMGetLocalVector(dmErrAux, &uErrLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm, uErr, INSERT_VALUES, uErrLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm, uErr, INSERT_VALUES, uErrLoc);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErrAux, &uErr);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "dmAux", (PetscObject) dmErrAux);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "A", (PetscObject) uErrLoc);CHKERRQ(ierr); /* Compute cellwise error estimate */ ierr = VecSet(errorEst, 0.0);CHKERRQ(ierr); ierr = DMPlexComputeCellwiseIntegralFEM(dmAdj, uAdj, errorEst, &user);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "dmAux", NULL);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "A", NULL);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmErrAux, &uErrLoc);CHKERRQ(ierr); ierr = DMDestroy(&dmErrAux);CHKERRQ(ierr); /* Plot cellwise error vector */ ierr = VecViewFromOptions(errorEst, NULL, "-error_view");CHKERRQ(ierr); /* Compute ratio of estimate (sum over cells) with actual L_2 error */ ierr = DMComputeL2Diff(dm, 0.0, funcs, ctxs, u, &errorL2Norm);CHKERRQ(ierr); ierr = DMPlexComputeL2DiffVec(dm, 0.0, funcs, ctxs, u, errorL2);CHKERRQ(ierr); ierr = VecViewFromOptions(errorL2, NULL, "-l2_error_view");CHKERRQ(ierr); ierr = VecNorm(errorL2, NORM_INFINITY, &errorL2Tot);CHKERRQ(ierr); ierr = VecNorm(errorEst, NORM_INFINITY, &errorEstTot);CHKERRQ(ierr); ierr = VecGetSize(errorEst, &N);CHKERRQ(ierr); ierr = VecPointwiseDivide(errorEst, errorEst, errorL2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) errorEst, "Error ratio");CHKERRQ(ierr); ierr = VecViewFromOptions(errorEst, NULL, "-error_ratio_view");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "N: %D L2 error: %g Error Ratio: %g/%g = %g\n", N, (double) errorL2Norm, (double) errorEstTot, (double) PetscSqrtReal(errorL2Tot), (double) errorEstTot/PetscSqrtReal(errorL2Tot));CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErr, &errorEst);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErr, &errorL2);CHKERRQ(ierr); ierr = DMDestroy(&dmErr);CHKERRQ(ierr); } ierr = DMDestroy(&dmAdj);CHKERRQ(ierr); ierr = VecDestroy(&uAdj);CHKERRQ(ierr); ierr = SNESDestroy(&snesAdj);CHKERRQ(ierr); } /* Cleanup */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
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; }
/* SNESMatrixFreeMult2_Private - Default matrix-free form for Jacobian-vector product, y = F'(u)*a: y = (F(u + ha) - F(u)) /h, where F = nonlinear function, as set by SNESSetFunction() u = current iterate h = difference interval */ PetscErrorCode SNESMatrixFreeMult2_Private(Mat mat,Vec a,Vec y) { MFCtx_Private *ctx; SNES snes; PetscReal h,norm,sum,umin,noise; PetscScalar hs,dot; Vec w,U,F; PetscErrorCode ierr,(*eval_fct)(SNES,Vec,Vec); MPI_Comm comm; PetscInt iter; PetscFunctionBegin; /* We log matrix-free matrix-vector products separately, so that we can separate the performance monitoring from the cases that use conventional storage. We may eventually modify event logging to associate events with particular objects, hence alleviating the more general problem. */ ierr = PetscLogEventBegin(MATMFFD_Mult,a,y,0,0);CHKERRQ(ierr); ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); ierr = MatShellGetContext(mat,(void**)&ctx);CHKERRQ(ierr); snes = ctx->snes; w = ctx->w; umin = ctx->umin; ierr = SNESGetSolution(snes,&U);CHKERRQ(ierr); eval_fct = SNESComputeFunction; ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr); /* Determine a "good" step size, h */ if (ctx->need_h) { /* Use Jorge's method to compute h */ if (ctx->jorge) { ierr = SNESDiffParameterCompute_More(snes,ctx->data,U,a,&noise,&h);CHKERRQ(ierr); /* Use the Brown/Saad method to compute h */ } else { /* Compute error if desired */ ierr = SNESGetIterationNumber(snes,&iter);CHKERRQ(ierr); if ((ctx->need_err) || ((ctx->compute_err_freq) && (ctx->compute_err_iter != iter) && (!((iter-1)%ctx->compute_err_freq)))) { /* Use Jorge's method to compute noise */ ierr = SNESDiffParameterCompute_More(snes,ctx->data,U,a,&noise,&h);CHKERRQ(ierr); ctx->error_rel = PetscSqrtReal(noise); ierr = PetscInfo3(snes,"Using Jorge's noise: noise=%g, sqrt(noise)=%g, h_more=%g\n",(double)noise,(double)ctx->error_rel,(double)h);CHKERRQ(ierr); ctx->compute_err_iter = iter; ctx->need_err = PETSC_FALSE; } ierr = VecDotBegin(U,a,&dot);CHKERRQ(ierr); ierr = VecNormBegin(a,NORM_1,&sum);CHKERRQ(ierr); ierr = VecNormBegin(a,NORM_2,&norm);CHKERRQ(ierr); ierr = VecDotEnd(U,a,&dot);CHKERRQ(ierr); ierr = VecNormEnd(a,NORM_1,&sum);CHKERRQ(ierr); ierr = VecNormEnd(a,NORM_2,&norm);CHKERRQ(ierr); /* Safeguard for step sizes too small */ if (sum == 0.0) { dot = 1.0; norm = 1.0; } else if (PetscAbsScalar(dot) < umin*sum && PetscRealPart(dot) >= 0.0) dot = umin*sum; else if (PetscAbsScalar(dot) < 0.0 && PetscRealPart(dot) > -umin*sum) dot = -umin*sum; h = PetscRealPart(ctx->error_rel*dot/(norm*norm)); } } else h = ctx->h; if (!ctx->jorge || !ctx->need_h) {ierr = PetscInfo1(snes,"h = %g\n",(double)h);CHKERRQ(ierr);} /* Evaluate function at F(u + ha) */ hs = h; ierr = VecWAXPY(w,hs,a,U);CHKERRQ(ierr); ierr = eval_fct(snes,w,y);CHKERRQ(ierr); ierr = VecAXPY(y,-1.0,F);CHKERRQ(ierr); ierr = VecScale(y,1.0/hs);CHKERRQ(ierr); if (ctx->sp) {ierr = MatNullSpaceRemove(ctx->sp,y);CHKERRQ(ierr);} ierr = PetscLogEventEnd(MATMFFD_Mult,a,y,0,0);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) { 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); }