PetscErrorCode BSSCR_KSPSetConvergenceMinIts(KSP ksp, PetscInt n, KSP_BSSCR * bsscr) { BSSCR_KSPConverged_Ctx *ctx; PetscErrorCode ierr; PetscFunctionBegin; bsscr->min_it = n; /* set minimum its */ #if ( (PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR >= 5 ) ) ierr = Stg_PetscNew(BSSCR_KSPConverged_Ctx,&ctx);CHKERRQ(ierr); ierr = KSPConvergedDefaultCreate(&ctx->ctx);CHKERRQ(ierr); ctx->bsscr=bsscr; ierr = KSPSetConvergenceTest(ksp,BSSCR_KSPConverged,ctx,BSSCR_KSPConverged_Destroy);CHKERRQ(ierr); #endif #if ( (PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR <=4 ) ) ierr = Stg_PetscNew(BSSCR_KSPConverged_Ctx,&ctx);CHKERRQ(ierr); ierr = KSPDefaultConvergedCreate(&ctx->ctx);CHKERRQ(ierr); ctx->bsscr=bsscr; ierr = KSPSetConvergenceTest(ksp,BSSCR_KSPConverged,ctx,BSSCR_KSPConverged_Destroy);CHKERRQ(ierr); #endif #if ( PETSC_VERSION_MAJOR < 3) ierr = KSPSetConvergenceTest(ksp,BSSCR_KSPConverged,(void*)bsscr);CHKERRQ(ierr); #endif PetscFunctionReturn(0); }
/*! \brief try to solve the system with block jacobi pre-conditioner * * * */ void try_solve_complex_bj(Mat & A_, const Vec & b_, Vec & x_) { PETSC_SAFE_CALL(KSPSetTolerances(ksp,rtol,abstol,dtol,5)); PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); solve_complex(A_,b_,x_); }
void petscSetDefaults(FEProblem & problem) { // dig out Petsc solver NonlinearSystem & nl = problem.getNonlinearSystem(); PetscNonlinearSolver<Number> * petsc_solver = dynamic_cast<PetscNonlinearSolver<Number> *>(nl.sys().nonlinear_solver.get()); SNES snes = petsc_solver->snes(); KSP ksp; SNESGetKSP(snes, &ksp); PCSide pcside = getPetscPCSide(nl.getPCSide()); #if PETSC_VERSION_LESS_THAN(3,2,0) // PETSc 3.1.x- KSPSetPreconditionerSide(ksp, pcside); #else // PETSc 3.2.x+ KSPSetPCSide(ksp, pcside); #endif SNESSetMaxLinearSolveFailures(snes, 1000000); #if PETSC_VERSION_LESS_THAN(3,0,0) // PETSc 2.3.3- KSPSetConvergenceTest(ksp, petscConverged, &problem); SNESSetConvergenceTest(snes, petscNonlinearConverged, &problem); #else // PETSc 3.0.0+ // In 3.0.0, the context pointer must actually be used, and the // final argument to KSPSetConvergenceTest() is a pointer to a // routine for destroying said private data context. In this case, // we use the default context provided by PETSc in addition to // a few other tests. { PetscErrorCode ierr = KSPSetConvergenceTest(ksp, petscConverged, &problem, PETSC_NULL); CHKERRABORT(nl.comm().get(),ierr); ierr = SNESSetConvergenceTest(snes, petscNonlinearConverged, &problem, PETSC_NULL); CHKERRABORT(nl.comm().get(),ierr); } #endif }
PetscErrorCode BSSCR_KSPSetNormInfConvergenceTest(KSP ksp) { KSPPWConvergedCtx *ctx; PetscTruth monitor, flg; char *opt; const char *prefix; BSSCR_KSPPWConvergedCreate( (void**)&ctx ); KSPGetOptionsPrefix( ksp, &prefix ); #if(PETSC_VERSION_MAJOR == 3) KSPSetConvergenceTest( ksp, BSSCR_KSPNormInfConverged, ctx, BSSCR_KSPPWConvergedDestroy ); // 3.0.0 only #else KSPSetConvergenceTest( ksp, BSSCR_KSPNormInfConverged, ctx ); // 2.3.3 #endif PetscFunctionReturn(0); }
/*@ KSPCreate - Creates the default KSP context. Collective on MPI_Comm Input Parameter: . comm - MPI communicator Output Parameter: . ksp - location to put the KSP context Notes: The default KSP type is GMRES with a restart of 30, using modified Gram-Schmidt orthogonalization. Level: beginner .keywords: KSP, create, context .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSP @*/ PetscErrorCode KSPCreate(MPI_Comm comm,KSP *inksp) { KSP ksp; PetscErrorCode ierr; void *ctx; PetscFunctionBegin; PetscValidPointer(inksp,2); *inksp = 0; ierr = KSPInitializePackage();CHKERRQ(ierr); ierr = PetscHeaderCreate(ksp,KSP_CLASSID,"KSP","Krylov Method","KSP",comm,KSPDestroy,KSPView);CHKERRQ(ierr); ksp->max_it = 10000; ksp->pc_side = ksp->pc_side_set = PC_SIDE_DEFAULT; ksp->rtol = 1.e-5; #if defined(PETSC_USE_REAL_SINGLE) ksp->abstol = 1.e-25; #else ksp->abstol = 1.e-50; #endif ksp->divtol = 1.e4; ksp->chknorm = -1; ksp->normtype = ksp->normtype_set = KSP_NORM_DEFAULT; ksp->rnorm = 0.0; ksp->its = 0; ksp->guess_zero = PETSC_TRUE; ksp->calc_sings = PETSC_FALSE; ksp->res_hist = NULL; ksp->res_hist_alloc = NULL; ksp->res_hist_len = 0; ksp->res_hist_max = 0; ksp->res_hist_reset = PETSC_TRUE; ksp->numbermonitors = 0; ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); ksp->ops->buildsolution = KSPBuildSolutionDefault; ksp->ops->buildresidual = KSPBuildResidualDefault; ksp->vec_sol = 0; ksp->vec_rhs = 0; ksp->pc = 0; ksp->data = 0; ksp->nwork = 0; ksp->work = 0; ksp->reason = KSP_CONVERGED_ITERATING; ksp->setupstage = KSP_SETUP_NEW; ierr = KSPNormSupportTableReset_Private(ksp);CHKERRQ(ierr); *inksp = ksp; PetscFunctionReturn(0); }
/*@ KSPSetNormType - Sets the norm that is used for convergence testing. Logically Collective on KSP Input Parameter: + ksp - Krylov solver context - normtype - one of $ KSP_NORM_NONE - skips computing the norm, this should only be used if you are using $ the Krylov method as a smoother with a fixed small number of iterations. $ Implicitly sets KSPSkipConverged as KSP convergence test. $ Supported only by CG, Richardson, Bi-CG-stab, CR, and CGS methods. $ KSP_NORM_PRECONDITIONED - the default for left preconditioned solves, uses the l2 norm $ of the preconditioned residual $ KSP_NORM_UNPRECONDITIONED - uses the l2 norm of the true b - Ax residual, supported only by $ CG, CHEBYSHEV, and RICHARDSON, automatically true for right (see KSPSetPCSide()) $ preconditioning.. $ KSP_NORM_NATURAL - supported by KSPCG, KSPCR, KSPCGNE, KSPCGS Options Database Key: . -ksp_norm_type <none,preconditioned,unpreconditioned,natural> Notes: Currently only works with the CG, Richardson, Bi-CG-stab, CR, and CGS methods. Level: advanced .keywords: KSP, create, context, norms .seealso: KSPSetUp(), KSPSolve(), KSPDestroy(), KSPSkipConverged(), KSPSetCheckNormIteration() @*/ PetscErrorCode KSPSetNormType(KSP ksp,KSPNormType normtype) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscValidLogicalCollectiveEnum(ksp,normtype,2); ksp->normtype = normtype; if (normtype == KSP_NORM_NONE) { ierr = KSPSetConvergenceTest(ksp,KSPSkipConverged,0,0);CHKERRQ(ierr); ierr = PetscInfo(ksp,"Warning: setting KSPNormType to skip computing the norm\n\ KSP convergence test is implicitly set to KSPSkipConverged\n");CHKERRQ(ierr); }
/*! \brief Try to solve the system using all the Krylov solver with simple preconditioners * * * */ void try_solve_ASM(Mat & A_, const Vec & b_, Vec & x_) { PETSC_SAFE_CALL(KSPSetTolerances(ksp,rtol,abstol,dtol,5)); for (size_t i = 0 ; i < solvs.size() ; i++) { setSolver(solvs.get(i).c_str()); // Disable convergence check PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); // solve_simple(A_,b_,x_); solve_ASM(A_,b_,x_); } }
/*@ PCMGGetSmootherUp - Gets the KSP context to be used as smoother after coarse grid correction (post-smoother). Not Collective, KSP returned is parallel if PC is Input Parameters: + pc - the multigrid context - l - the level (0 is coarsest) to supply Ouput Parameters: . ksp - the smoother Level: advanced Notes: calling this will result in a different pre and post smoother so you may need to set options on the pre smoother also .keywords: MG, multigrid, get, smoother, up, post-smoother, level .seealso: PCMGGetSmootherUp(), PCMGGetSmootherDown() @*/ PetscErrorCode PCMGGetSmootherUp(PC pc,PetscInt l,KSP *ksp) { PC_MG *mg = (PC_MG*)pc->data; PC_MG_Levels **mglevels = mg->levels; PetscErrorCode ierr; const char *prefix; MPI_Comm comm; PetscFunctionBegin; PetscValidHeaderSpecific(pc,PC_CLASSID,1); /* This is called only if user wants a different pre-smoother from post. Thus we check if a different one has already been allocated, if not we allocate it. */ if (!l) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"There is no such thing as a up smoother on the coarse grid"); if (mglevels[l]->smoothu == mglevels[l]->smoothd) { KSPType ksptype; PCType pctype; PC ipc; PetscReal rtol,abstol,dtol; PetscInt maxits; KSPNormType normtype; ierr = PetscObjectGetComm((PetscObject)mglevels[l]->smoothd,&comm);CHKERRQ(ierr); ierr = KSPGetOptionsPrefix(mglevels[l]->smoothd,&prefix);CHKERRQ(ierr); ierr = KSPGetTolerances(mglevels[l]->smoothd,&rtol,&abstol,&dtol,&maxits);CHKERRQ(ierr); ierr = KSPGetType(mglevels[l]->smoothd,&ksptype);CHKERRQ(ierr); ierr = KSPGetNormType(mglevels[l]->smoothd,&normtype);CHKERRQ(ierr); ierr = KSPGetPC(mglevels[l]->smoothd,&ipc);CHKERRQ(ierr); ierr = PCGetType(ipc,&pctype);CHKERRQ(ierr); ierr = KSPCreate(comm,&mglevels[l]->smoothu);CHKERRQ(ierr); ierr = KSPSetErrorIfNotConverged(mglevels[l]->smoothu,pc->erroriffailure);CHKERRQ(ierr); ierr = PetscObjectIncrementTabLevel((PetscObject)mglevels[l]->smoothu,(PetscObject)pc,mglevels[0]->levels-l);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(mglevels[l]->smoothu,prefix);CHKERRQ(ierr); ierr = KSPSetTolerances(mglevels[l]->smoothu,rtol,abstol,dtol,maxits);CHKERRQ(ierr); ierr = KSPSetType(mglevels[l]->smoothu,ksptype);CHKERRQ(ierr); ierr = KSPSetNormType(mglevels[l]->smoothu,normtype);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(mglevels[l]->smoothu,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); ierr = KSPGetPC(mglevels[l]->smoothu,&ipc);CHKERRQ(ierr); ierr = PCSetType(ipc,pctype);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)mglevels[l]->smoothu);CHKERRQ(ierr); ierr = PetscObjectComposedDataSetInt((PetscObject) mglevels[l]->smoothu, PetscMGLevelId, mglevels[l]->level);CHKERRQ(ierr); } if (ksp) *ksp = mglevels[l]->smoothu; PetscFunctionReturn(0); }
static PetscErrorCode KSPChebyshevSetEstimateEigenvalues_Chebyshev(KSP ksp,PetscReal a,PetscReal b,PetscReal c,PetscReal d) { KSP_Chebyshev *cheb = (KSP_Chebyshev*)ksp->data; PetscErrorCode ierr; PetscFunctionBegin; if (a != 0.0 || b != 0.0 || c != 0.0 || d != 0.0) { if (!cheb->kspest) { /* should this block of code be moved to KSPSetUp_Chebyshev()? */ PetscBool nonzero; ierr = KSPCreate(PetscObjectComm((PetscObject)ksp),&cheb->kspest);CHKERRQ(ierr); ierr = PetscObjectIncrementTabLevel((PetscObject)cheb->kspest,(PetscObject)ksp,1);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(cheb->kspest,((PetscObject)ksp)->prefix);CHKERRQ(ierr); ierr = KSPAppendOptionsPrefix(cheb->kspest,"est_");CHKERRQ(ierr); ierr = KSPGetPC(cheb->kspest,&cheb->pcnone);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)cheb->pcnone);CHKERRQ(ierr); ierr = PCSetType(cheb->pcnone,PCNONE);CHKERRQ(ierr); ierr = KSPSetPC(cheb->kspest,ksp->pc);CHKERRQ(ierr); ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero(cheb->kspest,nonzero);CHKERRQ(ierr); ierr = KSPSetComputeEigenvalues(cheb->kspest,PETSC_TRUE);CHKERRQ(ierr); /* Estimate with a fixed number of iterations */ ierr = KSPSetConvergenceTest(cheb->kspest,KSPConvergedSkip,0,0);CHKERRQ(ierr); ierr = KSPSetNormType(cheb->kspest,KSP_NORM_NONE);CHKERRQ(ierr); ierr = KSPSetTolerances(cheb->kspest,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,cheb->eststeps);CHKERRQ(ierr); } if (a >= 0) cheb->tform[0] = a; if (b >= 0) cheb->tform[1] = b; if (c >= 0) cheb->tform[2] = c; if (d >= 0) cheb->tform[3] = d; cheb->estimate_current = PETSC_FALSE; } else { ierr = KSPDestroy(&cheb->kspest);CHKERRQ(ierr); ierr = PCDestroy(&cheb->pcnone);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/* SNESSolve_NEWTONTR - Implements Newton's Method with a very simple trust region approach for solving systems of nonlinear equations. */ static PetscErrorCode SNESSolve_NEWTONTR(SNES snes) { SNES_NEWTONTR *neP = (SNES_NEWTONTR*)snes->data; Vec X,F,Y,G,Ytmp; PetscErrorCode ierr; PetscInt maxits,i,lits; PetscReal rho,fnorm,gnorm,gpnorm,xnorm=0,delta,nrm,ynorm,norm1; PetscScalar cnorm; KSP ksp; SNESConvergedReason reason = SNES_CONVERGED_ITERATING; PetscBool conv = PETSC_FALSE,breakout = PETSC_FALSE; PetscFunctionBegin; if (snes->xl || snes->xu || snes->ops->computevariablebounds) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE, "SNES solver %s does not support bounds", ((PetscObject)snes)->type_name); maxits = snes->max_its; /* maximum number of iterations */ X = snes->vec_sol; /* solution vector */ F = snes->vec_func; /* residual vector */ Y = snes->work[0]; /* work vectors */ G = snes->work[1]; Ytmp = snes->work[2]; ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); snes->iter = 0; ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); if (!snes->vec_func_init_set) { ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); /* F(X) */ } else snes->vec_func_init_set = PETSC_FALSE; ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); /* fnorm <- || F || */ SNESCheckFunctionNorm(snes,fnorm); ierr = VecNorm(X,NORM_2,&xnorm);CHKERRQ(ierr); /* fnorm <- || F || */ ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); snes->norm = fnorm; ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); delta = xnorm ? neP->delta0*xnorm : neP->delta0; neP->delta = delta; ierr = SNESLogConvergenceHistory(snes,fnorm,0);CHKERRQ(ierr); ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr); /* test convergence */ ierr = (*snes->ops->converged)(snes,snes->iter,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); if (snes->reason) PetscFunctionReturn(0); /* Set the stopping criteria to use the More' trick. */ ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_tr_ksp_regular_convergence_test",&conv,NULL);CHKERRQ(ierr); if (!conv) { SNES_TR_KSPConverged_Ctx *ctx; ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = PetscNew(&ctx);CHKERRQ(ierr); ctx->snes = snes; ierr = KSPConvergedDefaultCreate(&ctx->ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,SNESTR_KSPConverged_Private,ctx,SNESTR_KSPConverged_Destroy);CHKERRQ(ierr); ierr = PetscInfo(snes,"Using Krylov convergence test SNESTR_KSPConverged_Private\n");CHKERRQ(ierr); } for (i=0; i<maxits; i++) { /* Call general purpose update function */ if (snes->ops->update) { ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr); } /* Solve J Y = F, where J is Jacobian matrix */ ierr = SNESComputeJacobian(snes,X,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); SNESCheckJacobianDomainerror(snes); ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr); ierr = KSPSolve(snes->ksp,F,Ytmp);CHKERRQ(ierr); ierr = KSPGetIterationNumber(snes->ksp,&lits);CHKERRQ(ierr); snes->linear_its += lits; ierr = PetscInfo2(snes,"iter=%D, linear solve iterations=%D\n",snes->iter,lits);CHKERRQ(ierr); ierr = VecNorm(Ytmp,NORM_2,&nrm);CHKERRQ(ierr); norm1 = nrm; while (1) { ierr = VecCopy(Ytmp,Y);CHKERRQ(ierr); nrm = norm1; /* Scale Y if need be and predict new value of F norm */ if (nrm >= delta) { nrm = delta/nrm; gpnorm = (1.0 - nrm)*fnorm; cnorm = nrm; ierr = PetscInfo1(snes,"Scaling direction by %g\n",(double)nrm);CHKERRQ(ierr); ierr = VecScale(Y,cnorm);CHKERRQ(ierr); nrm = gpnorm; ynorm = delta; } else { gpnorm = 0.0; ierr = PetscInfo(snes,"Direction is in Trust Region\n");CHKERRQ(ierr); ynorm = nrm; } ierr = VecAYPX(Y,-1.0,X);CHKERRQ(ierr); /* Y <- X - Y */ ierr = VecCopy(X,snes->vec_sol_update);CHKERRQ(ierr); ierr = SNESComputeFunction(snes,Y,G);CHKERRQ(ierr); /* F(X) */ ierr = VecNorm(G,NORM_2,&gnorm);CHKERRQ(ierr); /* gnorm <- || g || */ if (fnorm == gpnorm) rho = 0.0; else rho = (fnorm*fnorm - gnorm*gnorm)/(fnorm*fnorm - gpnorm*gpnorm); /* Update size of trust region */ if (rho < neP->mu) delta *= neP->delta1; else if (rho < neP->eta) delta *= neP->delta2; else delta *= neP->delta3; ierr = PetscInfo3(snes,"fnorm=%g, gnorm=%g, ynorm=%g\n",(double)fnorm,(double)gnorm,(double)ynorm);CHKERRQ(ierr); ierr = PetscInfo3(snes,"gpred=%g, rho=%g, delta=%g\n",(double)gpnorm,(double)rho,(double)delta);CHKERRQ(ierr); neP->delta = delta; if (rho > neP->sigma) break; ierr = PetscInfo(snes,"Trying again in smaller region\n");CHKERRQ(ierr); /* check to see if progress is hopeless */ neP->itflag = PETSC_FALSE; ierr = SNESTR_Converged_Private(snes,snes->iter,xnorm,ynorm,fnorm,&reason,snes->cnvP);CHKERRQ(ierr); if (!reason) { ierr = (*snes->ops->converged)(snes,snes->iter,xnorm,ynorm,fnorm,&reason,snes->cnvP);CHKERRQ(ierr); } if (reason) { /* We're not progressing, so return with the current iterate */ ierr = SNESMonitor(snes,i+1,fnorm);CHKERRQ(ierr); breakout = PETSC_TRUE; break; } snes->numFailures++; } if (!breakout) { /* Update function and solution vectors */ fnorm = gnorm; ierr = VecCopy(G,F);CHKERRQ(ierr); ierr = VecCopy(Y,X);CHKERRQ(ierr); /* Monitor convergence */ ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); snes->iter = i+1; snes->norm = fnorm; snes->xnorm = xnorm; snes->ynorm = ynorm; ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); ierr = SNESLogConvergenceHistory(snes,snes->norm,lits);CHKERRQ(ierr); ierr = SNESMonitor(snes,snes->iter,snes->norm);CHKERRQ(ierr); /* Test for convergence, xnorm = || X || */ neP->itflag = PETSC_TRUE; if (snes->ops->converged != SNESConvergedSkip) { ierr = VecNorm(X,NORM_2,&xnorm);CHKERRQ(ierr); } ierr = (*snes->ops->converged)(snes,snes->iter,xnorm,ynorm,fnorm,&reason,snes->cnvP);CHKERRQ(ierr); if (reason) break; } else break; } if (i == maxits) { ierr = PetscInfo1(snes,"Maximum number of iterations has been reached: %D\n",maxits);CHKERRQ(ierr); if (!reason) reason = SNES_DIVERGED_MAX_IT; } ierr = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr); snes->reason = reason; ierr = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*! \brief solve simple use a Krylov solver + Simple selected Parallel Pre-conditioner * */ void solve_Krylov_simple(Mat & A_, const Vec & b_, Vec & x_) { PETSC_SAFE_CALL(KSPSetType(ksp,s_type)); // We set the size of x according to the Matrix A PetscInt row; PetscInt col; PetscInt row_loc; PetscInt col_loc; PETSC_SAFE_CALL(MatGetSize(A_,&row,&col)); PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc)); PC pc; // We set the Matrix operators PETSC_SAFE_CALL(KSPSetOperators(ksp,A_,A_)); // We set the pre-conditioner PETSC_SAFE_CALL(KSPGetPC(ksp,&pc)); // PETSC_SAFE_CALL(PCSetType(pc,PCJACOBI)); PETSC_SAFE_CALL(PCSetType(pc,PCHYPRE)); // PCGAMGSetNSmooths(pc,0); PCFactorSetShiftType(pc, MAT_SHIFT_NONZERO); PCFactorSetShiftAmount(pc, PETSC_DECIDE); PCHYPRESetType(pc, "boomeramg"); MatSetBlockSize(A_,4); PetscOptionsSetValue("-pc_hypre_boomeramg_print_statistics","2"); PetscOptionsSetValue("-pc_hypre_boomeramg_max_iter","1000"); PetscOptionsSetValue("-pc_hypre_boomeramg_nodal_coarsen","true"); PetscOptionsSetValue("-pc_hypre_boomeramg_relax_type_all","SOR/Jacobi"); PetscOptionsSetValue("-pc_hypre_boomeramg_coarsen_type","Falgout"); PetscOptionsSetValue("-pc_hypre_boomeramg_cycle_type","W"); PetscOptionsSetValue("-pc_hypre_boomeramg_max_levels","10"); KSPSetFromOptions(ksp); // if we are on on best solve set-up a monitor function if (try_solve == true) { // for bench-mark we are interested in non-preconditioned norm PETSC_SAFE_CALL(KSPMonitorSet(ksp,monitor,&vres,NULL)); // Disable convergence check PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); } // Solve the system PETSC_SAFE_CALL(KSPSolve(ksp,b_,x_)); auto & v_cl = create_vcluster(); // if (try_solve == true) // { // calculate error statistic about the solution solError err = statSolutionError(A_,b_,x_); if (v_cl.getProcessUnitID() == 0) { std::cout << "Method: " << s_type << " " << " pre-conditoner: " << PCJACOBI << " iterations: " << err.its << std::endl; std::cout << "Norm of error: " << err.err_norm << " Norm infinity: " << err.err_inf << std::endl; } // } }
static PetscErrorCode SNESSolve_TR(SNES snes) { SNES_TR *neP = (SNES_TR*)snes->data; Vec X,F,Y,G,Ytmp; PetscErrorCode ierr; PetscInt maxits,i,lits; MatStructure flg = DIFFERENT_NONZERO_PATTERN; PetscReal rho,fnorm,gnorm,gpnorm,xnorm=0,delta,nrm,ynorm,norm1; PetscScalar cnorm; KSP ksp; SNESConvergedReason reason = SNES_CONVERGED_ITERATING; PetscBool conv = PETSC_FALSE,breakout = PETSC_FALSE; PetscBool domainerror; PetscFunctionBegin; maxits = snes->max_its; /* maximum number of iterations */ X = snes->vec_sol; /* solution vector */ F = snes->vec_func; /* residual vector */ Y = snes->work[0]; /* work vectors */ G = snes->work[1]; Ytmp = snes->work[2]; ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); snes->iter = 0; ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); if (!snes->vec_func_init_set) { ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr); /* F(X) */ ierr = SNESGetFunctionDomainError(snes, &domainerror);CHKERRQ(ierr); if (domainerror) { snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; PetscFunctionReturn(0); } } else { snes->vec_func_init_set = PETSC_FALSE; } if (!snes->norm_init_set) { ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr); /* fnorm <- || F || */ if (PetscIsInfOrNanReal(fnorm)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"User provided compute function generated a Not-a-Number"); } else { fnorm = snes->norm_init; snes->norm_init_set = PETSC_FALSE; } ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); snes->norm = fnorm; ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); delta = neP->delta0*fnorm; neP->delta = delta; SNESLogConvHistory(snes,fnorm,0); ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr); /* set parameter for default relative tolerance convergence test */ snes->ttol = fnorm*snes->rtol; /* test convergence */ ierr = (*snes->ops->converged)(snes,snes->iter,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr); if (snes->reason) PetscFunctionReturn(0); /* Set the stopping criteria to use the More' trick. */ ierr = PetscOptionsGetBool(PETSC_NULL,"-snes_tr_ksp_regular_convergence_test",&conv,PETSC_NULL);CHKERRQ(ierr); if (!conv) { SNES_TR_KSPConverged_Ctx *ctx; ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = PetscNew(SNES_TR_KSPConverged_Ctx,&ctx);CHKERRQ(ierr); ctx->snes = snes; ierr = KSPDefaultConvergedCreate(&ctx->ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,SNES_TR_KSPConverged_Private,ctx,SNES_TR_KSPConverged_Destroy);CHKERRQ(ierr); ierr = PetscInfo(snes,"Using Krylov convergence test SNES_TR_KSPConverged_Private\n");CHKERRQ(ierr); } for (i=0; i<maxits; i++) { /* Call general purpose update function */ if (snes->ops->update) { ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr); } /* Solve J Y = F, where J is Jacobian matrix */ ierr = SNESComputeJacobian(snes,X,&snes->jacobian,&snes->jacobian_pre,&flg);CHKERRQ(ierr); ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,flg);CHKERRQ(ierr); ierr = SNES_KSPSolve(snes,snes->ksp,F,Ytmp);CHKERRQ(ierr); ierr = KSPGetIterationNumber(snes->ksp,&lits);CHKERRQ(ierr); snes->linear_its += lits; ierr = PetscInfo2(snes,"iter=%D, linear solve iterations=%D\n",snes->iter,lits);CHKERRQ(ierr); ierr = VecNorm(Ytmp,NORM_2,&nrm);CHKERRQ(ierr); norm1 = nrm; while(1) { ierr = VecCopy(Ytmp,Y);CHKERRQ(ierr); nrm = norm1; /* Scale Y if need be and predict new value of F norm */ if (nrm >= delta) { nrm = delta/nrm; gpnorm = (1.0 - nrm)*fnorm; cnorm = nrm; ierr = PetscInfo1(snes,"Scaling direction by %G\n",nrm);CHKERRQ(ierr); ierr = VecScale(Y,cnorm);CHKERRQ(ierr); nrm = gpnorm; ynorm = delta; } else { gpnorm = 0.0; ierr = PetscInfo(snes,"Direction is in Trust Region\n");CHKERRQ(ierr); ynorm = nrm; } ierr = VecAYPX(Y,-1.0,X);CHKERRQ(ierr); /* Y <- X - Y */ ierr = VecCopy(X,snes->vec_sol_update);CHKERRQ(ierr); ierr = SNESComputeFunction(snes,Y,G);CHKERRQ(ierr); /* F(X) */ ierr = VecNorm(G,NORM_2,&gnorm);CHKERRQ(ierr); /* gnorm <- || g || */ if (fnorm == gpnorm) rho = 0.0; else rho = (fnorm*fnorm - gnorm*gnorm)/(fnorm*fnorm - gpnorm*gpnorm); /* Update size of trust region */ if (rho < neP->mu) delta *= neP->delta1; else if (rho < neP->eta) delta *= neP->delta2; else delta *= neP->delta3; ierr = PetscInfo3(snes,"fnorm=%G, gnorm=%G, ynorm=%G\n",fnorm,gnorm,ynorm);CHKERRQ(ierr); ierr = PetscInfo3(snes,"gpred=%G, rho=%G, delta=%G\n",gpnorm,rho,delta);CHKERRQ(ierr); neP->delta = delta; if (rho > neP->sigma) break; ierr = PetscInfo(snes,"Trying again in smaller region\n");CHKERRQ(ierr); /* check to see if progress is hopeless */ neP->itflag = PETSC_FALSE; ierr = SNES_TR_Converged_Private(snes,snes->iter,xnorm,ynorm,fnorm,&reason,snes->cnvP);CHKERRQ(ierr); if (!reason) { ierr = (*snes->ops->converged)(snes,snes->iter,xnorm,ynorm,fnorm,&reason,snes->cnvP);CHKERRQ(ierr); } if (reason) { /* We're not progressing, so return with the current iterate */ ierr = SNESMonitor(snes,i+1,fnorm);CHKERRQ(ierr); breakout = PETSC_TRUE; break; } snes->numFailures++; } if (!breakout) { /* Update function and solution vectors */ fnorm = gnorm; ierr = VecCopy(G,F);CHKERRQ(ierr); ierr = VecCopy(Y,X);CHKERRQ(ierr); /* Monitor convergence */ ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); snes->iter = i+1; snes->norm = fnorm; ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); SNESLogConvHistory(snes,snes->norm,lits); ierr = SNESMonitor(snes,snes->iter,snes->norm);CHKERRQ(ierr); /* Test for convergence, xnorm = || X || */ neP->itflag = PETSC_TRUE; if (snes->ops->converged != SNESSkipConverged) { ierr = VecNorm(X,NORM_2,&xnorm);CHKERRQ(ierr); } ierr = (*snes->ops->converged)(snes,snes->iter,xnorm,ynorm,fnorm,&reason,snes->cnvP);CHKERRQ(ierr); if (reason) break; } else { break; } } if (i == maxits) { ierr = PetscInfo1(snes,"Maximum number of iterations has been reached: %D\n",maxits);CHKERRQ(ierr); if (!reason) reason = SNES_DIVERGED_MAX_IT; } ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); snes->reason = reason; ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "KSPCreate_SpecEst" /*MC KSPSPECEST - Estimate the spectrum on the first KSPSolve, then use cheaper smoother for subsequent solves. Options Database Keys: + -ksp_specest_minfactor <0.9> - Multiplier on the minimum eigen/singular value . -ksp_specest_maxfactor <1.1> - Multiplier on the maximum eigen/singular value . -ksp_specest_richfactor <1> - Multiplier on the richimum eigen/singular value . -specest_ksp_type <type> - KSP used to estimate the spectrum (usually CG or GMRES) . -speccheap_ksp_type <type> - KSP used as a cheap smoother once the spectrum has been estimated (usually Chebyshev or Richardson) - see KSPSolve() for more Notes: This KSP estimates the extremal singular values on the first pass, then uses them to configure a smoother that uses fewer dot products. It is intended for use on the levels of multigrid, especially at high process counts, where dot products are very expensive. The same PC is used for both the estimator and the cheap smoother, it is only set up once. There are no options keys for -specest_pc_ or speccheap_pc_ since it is the same object as -pc_. Level: intermediate .seealso: KSPCreate(), KSPSetType(), KSPType (for list of available types), KSP, KSPGMRES, KSPCG, KSPCHEBYSHEV, KSPRICHARDSON M*/ PetscErrorCode KSPCreate_SpecEst(KSP ksp) { KSP_SpecEst *spec; PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPSetSupportedNorm(ksp,KSP_NORM_PRECONDITIONED,PC_LEFT,2);CHKERRQ(ierr); ierr = KSPSetSupportedNorm(ksp,KSP_NORM_PRECONDITIONED,PC_RIGHT,1);CHKERRQ(ierr); ierr = KSPSetSupportedNorm(ksp,KSP_NORM_UNPRECONDITIONED,PC_LEFT,1);CHKERRQ(ierr); ierr = KSPSetSupportedNorm(ksp,KSP_NORM_UNPRECONDITIONED,PC_RIGHT,1);CHKERRQ(ierr); ierr = PetscNewLog(ksp,KSP_SpecEst,&spec);CHKERRQ(ierr); ksp->data = (void*)spec; ksp->ops->setup = KSPSetUp_SpecEst; ksp->ops->solve = KSPSolve_SpecEst; ksp->ops->destroy = KSPDestroy_SpecEst; ksp->ops->buildsolution = KSPDefaultBuildSolution; ksp->ops->buildresidual = KSPDefaultBuildResidual; ksp->ops->setfromoptions = KSPSetFromOptions_SpecEst; ksp->ops->view = KSPView_SpecEst; spec->minfactor = 0.9; spec->maxfactor = 1.1; spec->richfactor = 1.0; ierr = KSPCreate(((PetscObject)ksp)->comm,&spec->kspest);CHKERRQ(ierr); ierr = KSPCreate(((PetscObject)ksp)->comm,&spec->kspcheap);CHKERRQ(ierr); /* Hold an empty PC */ ierr = KSPGetPC(spec->kspest,&spec->pcnone);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)spec->pcnone);CHKERRQ(ierr); ierr = PCSetType(spec->pcnone,PCNONE);CHKERRQ(ierr); ierr = KSPSetPC(spec->kspcheap,spec->pcnone);CHKERRQ(ierr); ierr = KSPSetTolerances(spec->kspest,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,5);CHKERRQ(ierr); /* Make the "cheap" preconditioner cheap by default */ ierr = KSPSetConvergenceTest(spec->kspcheap,KSPSkipConverged,0,0);CHKERRQ(ierr); ierr = KSPSetNormType(spec->kspcheap,KSP_NORM_NONE);CHKERRQ(ierr); ierr = KSPSetTolerances(spec->kspcheap,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,5);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ KSPSetFromOptions - Sets KSP options from the options database. This routine must be called before KSPSetUp() if the user is to be allowed to set the Krylov type. Collective on KSP Input Parameters: . ksp - the Krylov space context Options Database Keys: + -ksp_max_it - maximum number of linear iterations . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e. if residual norm decreases by this factor than convergence is declared . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual norm is less than this then convergence is declared . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm() . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm() . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using convergence test (say you always want to run with 5 iterations) to save on communication overhead preconditioned - default for left preconditioning unpreconditioned - see KSPSetNormType() natural - see KSPSetNormType() . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration) works only for PCBCGS, PCIBCGS and and PCCG . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations. This will require 1 more iteration of the solver than usual. . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space . -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side . -ksp_monitor_cancel - cancel all previous convergene monitor routines set . -ksp_monitor <optional filename> - print residual norm at each iteration . -ksp_monitor_lg_residualnorm - plot residual norm at each iteration . -ksp_monitor_solution - plot solution at each iteration - -ksp_monitor_singular_value - monitor extremem singular values at each iteration Notes: To see all options, run your program with the -help option or consult Users-Manual: ch_ksp Level: beginner .keywords: KSP, set, from, options, database .seealso: KSPSetUseFischerGuess() @*/ PetscErrorCode KSPSetFromOptions(KSP ksp) { PetscErrorCode ierr; PetscInt indx; const char *convtests[] = {"default","skip"}; char type[256], monfilename[PETSC_MAX_PATH_LEN]; PetscViewer monviewer; PetscBool flg,flag,reuse; PetscInt model[2]={0,0},nmax; KSPNormType normtype; PCSide pcside; void *ctx; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} ierr = PCSetFromOptions(ksp->pc);CHKERRQ(ierr); if (!KSPRegisterAllCalled) {ierr = KSPRegisterAll();CHKERRQ(ierr);} ierr = PetscObjectOptionsBegin((PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetType(ksp,type);CHKERRQ(ierr); } /* Set the type if it was never set. */ if (!((PetscObject)ksp)->type_name) { ierr = KSPSetType(ksp,KSPGMRES);CHKERRQ(ierr); } ierr = PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);CHKERRQ(ierr); flag = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",flag,&flag,NULL);CHKERRQ(ierr); if (flag) {ierr = KSPConvergedDefaultSetUIRNorm(ksp);CHKERRQ(ierr);} flag = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPConvergedDefaultSetUMIRNorm",flag,&flag,NULL);CHKERRQ(ierr); if (flag) {ierr = KSPConvergedDefaultSetUMIRNorm(ksp);CHKERRQ(ierr);} ierr = KSPGetInitialGuessNonzero(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetInitialGuessNonzero(ksp,flag);CHKERRQ(ierr); } ierr = PCGetReusePreconditioner(ksp->pc,&reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr); ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr); nmax = 2; ierr = PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);CHKERRQ(ierr); if (flag) { if (nmax != 2) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments"); ierr = KSPSetUseFischerGuess(ksp,model[0],model[1]);CHKERRQ(ierr); } ierr = PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); if (flg) { switch (indx) { case 0: ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); break; case 1: ierr = KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; } } ierr = KSPSetUpNorms_Private(ksp,&normtype,&pcside);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetNormType(ksp,normtype);CHKERRQ(ierr); } ierr = PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);CHKERRQ(ierr); flag = ksp->lagnorm; ierr = PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetLagNorm(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { MatNullSpace nsp; ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)ksp),PETSC_TRUE,0,0,&nsp);CHKERRQ(ierr); ierr = KSPSetNullSpace(ksp,nsp);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nsp);CHKERRQ(ierr); } /* option is actually checked in KSPSetUp(), just here so goes into help message */ if (ksp->nullsp) { ierr = PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);CHKERRQ(ierr); } /* Prints reason for convergence or divergence of each linear solve */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",flg,&flg,NULL);CHKERRQ(ierr); if (flg) ksp->printreason = PETSC_TRUE; flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",flg,&flg,NULL);CHKERRQ(ierr); /* -----------------------------------------------------------------------*/ /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */ if (flg) { ierr = KSPMonitorCancel(ksp);CHKERRQ(ierr); } /* Prints preconditioned residual norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints preconditioned residual norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor_range","Monitor percent of residual entries more than 10 percent of max","KSPMonitorRange","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorRange,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);CHKERRQ(ierr); if (flg || flag) { /* A hack for using dynamic tolerance in preconditioner */ ierr = PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { KSPDynTolCtx *scale = NULL; PetscReal defaultv = 1.0; ierr = PetscMalloc1(1,&scale);CHKERRQ(ierr); scale->bnrm = -1.0; scale->coef = defaultv; ierr = PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",defaultv,&(scale->coef),&flg);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);CHKERRQ(ierr); } } /* Plots the vector solution */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_solution","Monitor solution graphically","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPMonitorSet(ksp,KSPMonitorSolution,NULL,NULL);CHKERRQ(ierr); } /* Prints preconditioned and true residual norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor_true_residual","Monitor true residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorTrueResidualNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints with max norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor_max","Monitor true residual max norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorTrueResidualMaxNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints extreme eigenvalue estimates at each iteration */ ierr = PetscOptionsString("-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorSingularValue,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints preconditioned residual norm with fewer digits */ ierr = PetscOptionsString("-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Calls Python function */ ierr = PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ksp,monfilename);CHKERRQ(ierr);} /* Graphically plots preconditioned residual norm */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { PetscDrawLG ctx; ierr = KSPMonitorLGResidualNormCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))KSPMonitorLGResidualNormDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned and true residual norm */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { PetscDrawLG ctx; ierr = KSPMonitorLGTrueResidualNormCreate(PetscObjectComm((PetscObject)ksp),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))KSPMonitorLGTrueResidualNormDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned residual norm and range of residual element values */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { PetscViewer ctx; ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)ksp),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } #if defined(PETSC_HAVE_SAWS) /* Publish convergence information using AMS */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { void *ctx; ierr = KSPMonitorSAWsCreate(ksp,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } #endif /* -----------------------------------------------------------------------*/ ierr = KSPSetUpNorms_Private(ksp,&normtype,&pcside);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); if (flg) {ierr = KSPSetPCSide(ksp,pcside);CHKERRQ(ierr);} flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } #if defined(PETSC_HAVE_SAWS) { PetscBool set; flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);CHKERRQ(ierr); if (set) { ierr = PetscObjectSAWsSetBlock((PetscObject)ksp,flg);CHKERRQ(ierr); } } #endif if (ksp->ops->setfromoptions) { ierr = (*ksp->ops->setfromoptions)(ksp);CHKERRQ(ierr); } /* process any options handlers added with PetscObjectAddOptionsHandler() */ ierr = PetscObjectProcessOptionsHandlers((PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); PetscFunctionReturn(0); }
void solve_ASM(Mat & A_, const Vec & b_, Vec & x_) { PETSC_SAFE_CALL(KSPSetType(ksp,s_type)); // We set the size of x according to the Matrix A PetscInt row; PetscInt col; PetscInt row_loc; PetscInt col_loc; PETSC_SAFE_CALL(MatGetSize(A_,&row,&col)); PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc)); PC pc; // We set the Matrix operators PETSC_SAFE_CALL(KSPSetOperators(ksp,A_,A_)); // We set the pre-conditioner PETSC_SAFE_CALL(KSPGetPC(ksp,&pc)); PETSC_SAFE_CALL(PCSetType(pc,PCASM)); //////////////// ///////////////////// // PCASMSetLocalSubdomains(pc); PCASMSetOverlap(pc,5); KSP *subksp; /* array of KSP contexts for local subblocks */ PetscInt nlocal,first; /* number of local subblocks, first local subblock */ PC subpc; /* PC context for subblock */ PetscBool isasm; /* Set runtime options */ // KSPSetFromOptions(ksp); /* Flag an error if PCTYPE is changed from the runtime options */ // PetscObjectTypeCompare((PetscObject)pc,PCASM,&isasm); // if (!isasm) SETERRQ(PETSC_COMM_WORLD,1,"Cannot Change the PCTYPE when manually changing the subdomain solver settings"); /* Call KSPSetUp() to set the block Jacobi data structures (including creation of an internal KSP context for each block). Note: KSPSetUp() MUST be called before PCASMGetSubKSP(). */ KSPSetUp(ksp); /* Extract the array of KSP contexts for the local blocks */ PCASMGetSubKSP(pc,&nlocal,&first,&subksp); /* Loop over the local blocks, setting various KSP options for each block. */ for (size_t i = 0 ; i < nlocal ; i++) { KSPGetPC(subksp[i],&subpc); // PCFactorSetFill(subpc,30); PCFactorSetLevels(subpc,5); PCSetType(subpc,PCILU); KSPSetType(subksp[i],KSPRICHARDSON); KSPSetTolerances(subksp[i],1.e-3,0.1,PETSC_DEFAULT,PETSC_DEFAULT); } // if we are on on best solve set-up a monitor function if (try_solve == true) { // for bench-mark we are interested in non-preconditioned norm PETSC_SAFE_CALL(KSPMonitorSet(ksp,monitor,&vres,NULL)); // Disable convergence check PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); } // KSPGMRESSetRestart(ksp,100); // Solve the system PETSC_SAFE_CALL(KSPSolve(ksp,b_,x_)); KSPConvergedReason reason; KSPGetConvergedReason(ksp,&reason); std::cout << "Reason: " << reason << std::endl; auto & v_cl = create_vcluster(); // if (try_solve == true) // { // calculate error statistic about the solution solError err = statSolutionError(A_,b_,x_); if (v_cl.getProcessUnitID() == 0) { std::cout << "Method: " << s_type << " " << " pre-conditoner: " << PCJACOBI << " iterations: " << err.its << std::endl; std::cout << "Norm of error: " << err.err_norm << " Norm infinity: " << err.err_inf << std::endl; } // } }
/*@C PCMGSetLevels - Sets the number of levels to use with MG. Must be called before any other MG routine. Logically Collective on PC Input Parameters: + pc - the preconditioner context . levels - the number of levels - comms - optional communicators for each level; this is to allow solving the coarser problems on smaller sets of processors. Use NULL_OBJECT for default in Fortran Level: intermediate Notes: If the number of levels is one then the multigrid uses the -mg_levels prefix for setting the level options rather than the -mg_coarse prefix. .keywords: MG, set, levels, multigrid .seealso: PCMGSetType(), PCMGGetLevels() @*/ PetscErrorCode PCMGSetLevels(PC pc,PetscInt levels,MPI_Comm *comms) { PetscErrorCode ierr; PC_MG *mg = (PC_MG*)pc->data; MPI_Comm comm; PC_MG_Levels **mglevels = mg->levels; PCMGType mgtype = mg->am; PetscInt mgctype = (PetscInt) PC_MG_CYCLE_V; PetscInt i; PetscMPIInt size; const char *prefix; PC ipc; PetscInt n; PetscFunctionBegin; PetscValidHeaderSpecific(pc,PC_CLASSID,1); PetscValidLogicalCollectiveInt(pc,levels,2); ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); if (mg->nlevels == levels) PetscFunctionReturn(0); if (mglevels) { mgctype = mglevels[0]->cycles; /* changing the number of levels so free up the previous stuff */ ierr = PCReset_MG(pc);CHKERRQ(ierr); n = mglevels[0]->levels; for (i=0; i<n; i++) { if (mglevels[i]->smoothd != mglevels[i]->smoothu) { ierr = KSPDestroy(&mglevels[i]->smoothd);CHKERRQ(ierr); } ierr = KSPDestroy(&mglevels[i]->smoothu);CHKERRQ(ierr); ierr = PetscFree(mglevels[i]);CHKERRQ(ierr); } ierr = PetscFree(mg->levels);CHKERRQ(ierr); } mg->nlevels = levels; ierr = PetscMalloc1(levels,&mglevels);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)pc,levels*(sizeof(PC_MG*)));CHKERRQ(ierr); ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); mg->stageApply = 0; for (i=0; i<levels; i++) { ierr = PetscNewLog(pc,&mglevels[i]);CHKERRQ(ierr); mglevels[i]->level = i; mglevels[i]->levels = levels; mglevels[i]->cycles = mgctype; mg->default_smoothu = 2; mg->default_smoothd = 2; mglevels[i]->eventsmoothsetup = 0; mglevels[i]->eventsmoothsolve = 0; mglevels[i]->eventresidual = 0; mglevels[i]->eventinterprestrict = 0; if (comms) comm = comms[i]; ierr = KSPCreate(comm,&mglevels[i]->smoothd);CHKERRQ(ierr); ierr = KSPSetErrorIfNotConverged(mglevels[i]->smoothd,pc->erroriffailure);CHKERRQ(ierr); ierr = PetscObjectIncrementTabLevel((PetscObject)mglevels[i]->smoothd,(PetscObject)pc,levels-i);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(mglevels[i]->smoothd,prefix);CHKERRQ(ierr); ierr = PetscObjectComposedDataSetInt((PetscObject) mglevels[i]->smoothd, PetscMGLevelId, mglevels[i]->level);CHKERRQ(ierr); if (i || levels == 1) { char tprefix[128]; ierr = KSPSetType(mglevels[i]->smoothd,KSPCHEBYSHEV);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(mglevels[i]->smoothd,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); ierr = KSPSetNormType(mglevels[i]->smoothd,KSP_NORM_NONE);CHKERRQ(ierr); ierr = KSPGetPC(mglevels[i]->smoothd,&ipc);CHKERRQ(ierr); ierr = PCSetType(ipc,PCSOR);CHKERRQ(ierr); ierr = KSPSetTolerances(mglevels[i]->smoothd,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT, mg->default_smoothd);CHKERRQ(ierr); sprintf(tprefix,"mg_levels_%d_",(int)i); ierr = KSPAppendOptionsPrefix(mglevels[i]->smoothd,tprefix);CHKERRQ(ierr); } else { ierr = KSPAppendOptionsPrefix(mglevels[0]->smoothd,"mg_coarse_");CHKERRQ(ierr); /* coarse solve is (redundant) LU by default; set shifttype NONZERO to avoid annoying zero-pivot in LU preconditioner */ ierr = KSPSetType(mglevels[0]->smoothd,KSPPREONLY);CHKERRQ(ierr); ierr = KSPGetPC(mglevels[0]->smoothd,&ipc);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); if (size > 1) { ierr = PCSetType(ipc,PCREDUNDANT);CHKERRQ(ierr); } else { ierr = PCSetType(ipc,PCLU);CHKERRQ(ierr); } ierr = PCFactorSetShiftType(ipc,MAT_SHIFT_INBLOCKS);CHKERRQ(ierr); } ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)mglevels[i]->smoothd);CHKERRQ(ierr); mglevels[i]->smoothu = mglevels[i]->smoothd; mg->rtol = 0.0; mg->abstol = 0.0; mg->dtol = 0.0; mg->ttol = 0.0; mg->cyclesperpcapply = 1; } mg->levels = mglevels; ierr = PCMGSetType(pc,mgtype);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ KSPSetFromOptions - Sets KSP options from the options database. This routine must be called before KSPSetUp() if the user is to be allowed to set the Krylov type. Collective on KSP Input Parameters: . ksp - the Krylov space context Options Database Keys: + -ksp_max_it - maximum number of linear iterations . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e. if residual norm decreases by this factor than convergence is declared . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual norm is less than this then convergence is declared . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm() . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm() . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using convergence test (say you always want to run with 5 iterations) to save on communication overhead preconditioned - default for left preconditioning unpreconditioned - see KSPSetNormType() natural - see KSPSetNormType() . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration) works only for PCBCGS, PCIBCGS and and PCCG . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations. This will require 1 more iteration of the solver than usual. . -ksp_guess_type - Type of initial guess generator for repeated linear solves . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space . -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side . -ksp_monitor_cancel - cancel all previous convergene monitor routines set . -ksp_monitor <optional filename> - print residual norm at each iteration . -ksp_monitor_lg_residualnorm - plot residual norm at each iteration . -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration - -ksp_monitor_singular_value - monitor extreme singular values at each iteration Notes: To see all options, run your program with the -help option or consult Users-Manual: ch_ksp Level: beginner .keywords: KSP, set, from, options, database .seealso: KSPSetOptionsPrefix(), KSPResetFromOptions(), KSPSetUseFischerGuess() @*/ PetscErrorCode KSPSetFromOptions(KSP ksp) { PetscInt indx; const char *convtests[] = {"default","skip","lsqr"}; char type[256], guesstype[256], monfilename[PETSC_MAX_PATH_LEN]; PetscBool flg,flag,reuse,set; PetscInt model[2]={0,0},nmax; KSPNormType normtype; PCSide pcside; void *ctx; MPI_Comm comm; const char *prefix; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); ierr = PetscObjectGetComm((PetscObject) ksp, &comm);CHKERRQ(ierr); ierr = PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);CHKERRQ(ierr); if (!ksp->skippcsetfromoptions) { if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} ierr = PCSetFromOptions(ksp->pc);CHKERRQ(ierr); } ierr = KSPRegisterAll();CHKERRQ(ierr); ierr = PetscObjectOptionsBegin((PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetType(ksp,type);CHKERRQ(ierr); } /* Set the type if it was never set. */ if (!((PetscObject)ksp)->type_name) { ierr = KSPSetType(ksp,KSPGMRES);CHKERRQ(ierr); } ierr = KSPResetViewers(ksp);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);CHKERRQ(ierr); if (flg) { ierr = PCGetReusePreconditioner(ksp->pc,&reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr); ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view", &ksp->viewer, &ksp->format, &ksp->view);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason", &ksp->viewerReason, &ksp->formatReason, &ksp->viewReason);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual", &ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale);CHKERRQ(ierr); ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr); } goto skipoptions; } ierr = PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);CHKERRQ(ierr); if (set && flag) {ierr = KSPConvergedDefaultSetUIRNorm(ksp);CHKERRQ(ierr);} ierr = PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPConvergedDefaultSetUMIRNorm",PETSC_FALSE,&flag,&set);CHKERRQ(ierr); if (set && flag) {ierr = KSPConvergedDefaultSetUMIRNorm(ksp);CHKERRQ(ierr);} ierr = PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",ksp->guess_zero ? PETSC_FALSE : PETSC_TRUE,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetInitialGuessNonzero(ksp,flag);CHKERRQ(ierr); } ierr = PCGetReusePreconditioner(ksp->pc,&reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr); ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr); ierr = PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPGetGuess(ksp,&ksp->guess);CHKERRQ(ierr); ierr = KSPGuessSetType(ksp->guess,guesstype);CHKERRQ(ierr); ierr = KSPGuessSetFromOptions(ksp->guess);CHKERRQ(ierr); } else { /* old option for KSP */ nmax = 2; ierr = PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);CHKERRQ(ierr); if (flag) { if (nmax != 2) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments"); ierr = KSPSetUseFischerGuess(ksp,model[0],model[1]);CHKERRQ(ierr); } } ierr = PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);CHKERRQ(ierr); if (flg) { switch (indx) { case 0: ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); break; case 1: ierr = KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; case 2: ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); break; } } ierr = KSPSetUpNorms_Private(ksp,PETSC_FALSE,&normtype,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetNormType(ksp,normtype);CHKERRQ(ierr); } ierr = PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetLagNorm(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr); } ierr = PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { MatNullSpace nsp; Mat Amat; ierr = MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);CHKERRQ(ierr); ierr = PCGetOperators(ksp->pc,&Amat,NULL);CHKERRQ(ierr); if (Amat) { ierr = MatSetNullSpace(Amat,nsp);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nsp);CHKERRQ(ierr); } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided"); } ierr = PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); /* -----------------------------------------------------------------------*/ /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */ if (set && flg) { ierr = KSPMonitorCancel(ksp);CHKERRQ(ierr); } ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unprecondiitoned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);CHKERRQ(ierr); ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);CHKERRQ(ierr); if (flg || flag) { /* A hack for using dynamic tolerance in preconditioner */ ierr = PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { KSPDynTolCtx *scale; ierr = PetscMalloc1(1,&scale);CHKERRQ(ierr); scale->bnrm = -1.0; scale->coef = 1.0; ierr = PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);CHKERRQ(ierr); } } /* Calls Python function */ ierr = PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ksp,monfilename);CHKERRQ(ierr);} /* Graphically plots preconditioned residual norm */ ierr = PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { PetscDrawLG ctx; ierr = KSPMonitorLGResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned and true residual norm */ ierr = PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { PetscDrawLG ctx; ierr = KSPMonitorLGTrueResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned residual norm and range of residual element values */ ierr = PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { PetscViewer ctx; ierr = PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* TODO Do these show up in help? */ ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view", &ksp->viewer, &ksp->format, &ksp->view);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pre", &ksp->viewerPre, &ksp->formatPre, &ksp->viewPre);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason", &ksp->viewerReason, &ksp->formatReason, &ksp->viewReason);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues_explicit", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual", &ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp);CHKERRQ(ierr); ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale);CHKERRQ(ierr); /* Deprecated options */ if (!ksp->viewEV) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV);CHKERRQ(ierr);} if (!ksp->viewEV) { ierr = PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);CHKERRQ(ierr); if (ksp->viewEV) { ksp->formatEV = PETSC_VIEWER_DEFAULT; ksp->viewerEV = PETSC_VIEWER_DRAW_(comm); ierr = PetscObjectReference((PetscObject) ksp->viewerEV);CHKERRQ(ierr); } } if (!ksp->viewEV) { ierr = PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);CHKERRQ(ierr); if (ksp->viewEV) { ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR; ksp->viewerEV = PETSC_VIEWER_DRAW_(comm); ierr = PetscObjectReference((PetscObject) ksp->viewerEV);CHKERRQ(ierr); } } if (!ksp->viewEVExp) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues_explicitly", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp);CHKERRQ(ierr);} if (!ksp->viewEVExp) { ierr = PetscOptionsName("-ksp_plot_eigenvalues_explicitly", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]", "KSPView", &ksp->viewEVExp);CHKERRQ(ierr); if (ksp->viewEVExp) { ksp->formatEVExp = PETSC_VIEWER_DEFAULT; ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm); ierr = PetscObjectReference((PetscObject) ksp->viewerEVExp);CHKERRQ(ierr); } } if (!ksp->viewSV) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV);CHKERRQ(ierr);} if (!ksp->viewFinalRes) {ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes);CHKERRQ(ierr);} #if defined(PETSC_HAVE_SAWS) /* Publish convergence information using AMS */ ierr = PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set && flg) { void *ctx; ierr = KSPMonitorSAWsCreate(ksp,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } #endif /* -----------------------------------------------------------------------*/ ierr = KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); if (flg) {ierr = KSPSetPCSide(ksp,pcside);CHKERRQ(ierr);} ierr = PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);CHKERRQ(ierr); if (set) { ierr = KSPSetComputeSingularValues(ksp,flg);CHKERRQ(ierr); } ierr = PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);CHKERRQ(ierr); if (set) { ierr = KSPSetComputeSingularValues(ksp,flg);CHKERRQ(ierr); } ierr = PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",PETSC_FALSE,&flg,&set);CHKERRQ(ierr); if (set) { ierr = KSPSetComputeSingularValues(ksp,flg);CHKERRQ(ierr); } #if defined(PETSC_HAVE_SAWS) { PetscBool set; flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);CHKERRQ(ierr); if (set) { ierr = PetscObjectSAWsSetBlock((PetscObject)ksp,flg);CHKERRQ(ierr); } } #endif if (ksp->ops->setfromoptions) { ierr = (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);CHKERRQ(ierr); } skipoptions: /* process any options handlers added with PetscObjectAddOptionsHandler() */ ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ksp->setfromoptionscalled++; PetscFunctionReturn(0); }