Date: 2021-03-03T22:27:20+00:00

Actual source code: itcl.c
petsc-3.14.5 2021-03-03
Report Typos and Errors

      2: /*
      3:     Code for setting KSP options from the options database.
      4: */

      6: #include <petsc/private/kspimpl.h>
      7: #include <petscdraw.h>

      9: static PetscErrorCode KSPSetupMonitor_Private(KSP ksp, PetscViewer viewer, PetscViewerFormat format, PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,void*), PetscBool useMonitor)
     10: {

     14:   if (useMonitor) {
     15:     PetscViewerAndFormat *vf;

     17:     PetscViewerAndFormatCreate(viewer, format, &vf);
     18:     PetscObjectDereference((PetscObject) viewer);
     19:     KSPMonitorSet(ksp, monitor, vf, (PetscErrorCode (*)(void**)) PetscViewerAndFormatDestroy);
     20:   }
     21:   return(0);
     22: }

     24: /*@C
     25:    KSPSetOptionsPrefix - Sets the prefix used for searching for all
     26:    KSP options in the database.

     28:    Logically Collective on ksp

     30:    Input Parameters:
     31: +  ksp - the Krylov context
     32: -  prefix - the prefix string to prepend to all KSP option requests

     34:    Notes:
     35:    A hyphen (-) must NOT be given at the beginning of the prefix name.
     36:    The first character of all runtime options is AUTOMATICALLY the
     37:    hyphen.

     39:    For example, to distinguish between the runtime options for two
     40:    different KSP contexts, one could call
     41: .vb
     42:       KSPSetOptionsPrefix(ksp1,"sys1_")
     43:       KSPSetOptionsPrefix(ksp2,"sys2_")
     44: .ve

     46:    This would enable use of different options for each system, such as
     47: .vb
     48:       -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
     49:       -sys2_ksp_type bcgs  -sys2_ksp_rtol 1.e-4
     50: .ve

     52:    Level: advanced

     54: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
     55: @*/
     56: PetscErrorCode  KSPSetOptionsPrefix(KSP ksp,const char prefix[])
     57: {

     62:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
     63:   PCSetOptionsPrefix(ksp->pc,prefix);
     64:   PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
     65:   return(0);
     66: }

     68: /*@C
     69:    KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
     70:    KSP options in the database.

     72:    Logically Collective on ksp

     74:    Input Parameters:
     75: +  ksp - the Krylov context
     76: -  prefix - the prefix string to prepend to all KSP option requests

     78:    Notes:
     79:    A hyphen (-) must NOT be given at the beginning of the prefix name.
     80:    The first character of all runtime options is AUTOMATICALLY the hyphen.

     82:    Level: advanced

     84: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
     85: @*/
     86: PetscErrorCode  KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
     87: {

     92:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
     93:   PCAppendOptionsPrefix(ksp->pc,prefix);
     94:   PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
     95:   return(0);
     96: }

     98: /*@
     99:    KSPSetUseFischerGuess - Use the Paul Fischer algorithm

    101:    Logically Collective on ksp

    103:    Input Parameters:
    104: +  ksp - the Krylov context
    105: .  model - use model 1, model 2 or any other number to turn it off
    106: -  size - size of subspace used to generate initial guess

    108:     Options Database:
    109: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves

    111:    Level: advanced

    113: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
    114: @*/
    115: PetscErrorCode  KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
    116: {
    117:   KSPGuess       guess;

    124:   KSPGetGuess(ksp,&guess);
    125:   KSPGuessSetType(guess,KSPGUESSFISCHER);
    126:   KSPGuessFischerSetModel(guess,model,size);
    127:   return(0);
    128: }

    130: /*@
    131:    KSPSetGuess - Set the initial guess object

    133:    Logically Collective on ksp

    135:    Input Parameters:
    136: +  ksp - the Krylov context
    137: -  guess - the object created with KSPGuessCreate()

    139:    Level: advanced

    141:    Notes:
    142:     this allows a single KSP to be used with several different initial guess generators (likely for different linear
    143:           solvers, see KSPSetPC()).

    145:           This increases the reference count of the guess object, you must destroy the object with KSPGuessDestroy()
    146:           before the end of the program.

    148: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPGetGuess()
    149: @*/
    150: PetscErrorCode  KSPSetGuess(KSP ksp,KSPGuess guess)
    151: {

    157:   PetscObjectReference((PetscObject)guess);
    158:   KSPGuessDestroy(&ksp->guess);
    159:   ksp->guess = guess;
    160:   ksp->guess->ksp = ksp;
    161:   return(0);
    162: }

    164: /*@
    165:    KSPGetGuess - Gets the initial guess generator for the KSP.

    167:    Not Collective

    169:    Input Parameters:
    170: .  ksp - the Krylov context

    172:    Output Parameters:
    173: .   guess - the object

    175:    Level: developer

    177: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess()
    178: @*/
    179: PetscErrorCode  KSPGetGuess(KSP ksp,KSPGuess *guess)
    180: {

    186:   if (!ksp->guess) {
    187:     const char* prefix;

    189:     KSPGuessCreate(PetscObjectComm((PetscObject)ksp),&ksp->guess);
    190:     PetscObjectGetOptionsPrefix((PetscObject)ksp,&prefix);
    191:     if (prefix) {
    192:       PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);
    193:     }
    194:     ksp->guess->ksp = ksp;
    195:   }
    196:   *guess = ksp->guess;
    197:   return(0);
    198: }

    200: /*@C
    201:    KSPGetOptionsPrefix - Gets the prefix used for searching for all
    202:    KSP options in the database.

    204:    Not Collective

    206:    Input Parameters:
    207: .  ksp - the Krylov context

    209:    Output Parameters:
    210: .  prefix - pointer to the prefix string used is returned

    212:    Notes:
    213:     On the fortran side, the user should pass in a string 'prefix' of
    214:    sufficient length to hold the prefix.

    216:    Level: advanced

    218: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
    219: @*/
    220: PetscErrorCode  KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
    221: {

    226:   PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
    227:   return(0);
    228: }

    230: /*@C
    231:    KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user

    233:    Collective on ksp

    235:    Input Parameters:
    236: +  ksp - KSP object you wish to monitor
    237: .  name - the monitor type one is seeking
    238: .  help - message indicating what monitoring is done
    239: .  manual - manual page for the monitor
    240: -  monitor - the monitor function, the context for this object is a PetscViewerAndFormat

    242:    Level: developer

    244: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    245:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    246:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    247:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    248:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    249:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    250:           PetscOptionsFList(), PetscOptionsEList()
    251: @*/
    252: PetscErrorCode  KSPMonitorSetFromOptions(KSP ksp,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,PetscViewerAndFormat*))
    253: {
    254:   PetscErrorCode       ierr;
    255:   PetscBool            flg;
    256:   PetscViewer          viewer;
    257:   PetscViewerFormat    format;

    260:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ksp),((PetscObject)ksp)->options,((PetscObject)ksp)->prefix,name,&viewer,&format,&flg);
    261:   KSPSetupMonitor_Private(ksp, viewer, format, (PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*)) monitor, flg);
    262:   return(0);
    263: }

    265: /*@
    266:    KSPSetFromOptions - Sets KSP options from the options database.
    267:    This routine must be called before KSPSetUp() if the user is to be
    268:    allowed to set the Krylov type.

    270:    Collective on ksp

    272:    Input Parameters:
    273: .  ksp - the Krylov space context

    275:    Options Database Keys:
    276: +   -ksp_max_it - maximum number of linear iterations
    277: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
    278:                 if residual norm decreases by this factor than convergence is declared
    279: .   -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
    280:                 norm is less than this then convergence is declared
    281: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
    282: .   -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm()
    283: .   -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm()
    284: .   -ksp_converged_maxits - see KSPConvergedDefaultSetConvergedMaxits()
    285: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
    286:                        convergence test (say you always want to run with 5 iterations) to
    287:                        save on communication overhead
    288:                     preconditioned - default for left preconditioning
    289:                     unpreconditioned - see KSPSetNormType()
    290:                     natural - see KSPSetNormType()
    291: .   -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
    292:        works only for PCBCGS, PCIBCGS and and PCCG
    293: .   -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
    294:        the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
    295:        This will require 1 more iteration of the solver than usual.
    296: .   -ksp_guess_type - Type of initial guess generator for repeated linear solves
    297: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
    298: .   -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
    299: .   -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space
    300: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
    301: .   -ksp_monitor_cancel - cancel all previous convergene monitor routines set
    302: .   -ksp_monitor <optional filename> - print residual norm at each iteration
    303: .   -ksp_monitor_lg_residualnorm - plot residual norm at each iteration
    304: .   -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
    305: -   -ksp_monitor_singular_value - monitor extreme singular values at each iteration

    307:    Notes:
    308:    To see all options, run your program with the -help option
    309:    or consult Users-Manual: ch_ksp

    311:    Level: beginner

    313: .seealso: KSPSetOptionsPrefix(), KSPResetFromOptions(), KSPSetUseFischerGuess()

    315: @*/
    316: PetscErrorCode  KSPSetFromOptions(KSP ksp)
    317: {
    318:   const char     *convtests[]={"default","skip","lsqr"},*prefix;
    319:   char           type[256],guesstype[256],monfilename[PETSC_MAX_PATH_LEN];
    320:   PetscBool      flg,flag,reuse,set;
    321:   PetscInt       indx,model[2]={0,0},nmax;
    322:   KSPNormType    normtype;
    323:   PCSide         pcside;
    324:   void           *ctx;
    325:   MPI_Comm       comm;

    330:   PetscObjectGetComm((PetscObject) ksp, &comm);
    331:   PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
    332:   if (!ksp->skippcsetfromoptions) {
    333:     if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
    334:     PCSetFromOptions(ksp->pc);
    335:   }

    337:   KSPRegisterAll();
    338:   PetscObjectOptionsBegin((PetscObject)ksp);
    339:   PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
    340:   if (flg) {
    341:     KSPSetType(ksp,type);
    342:   }
    343:   /*
    344:     Set the type if it was never set.
    345:   */
    346:   if (!((PetscObject)ksp)->type_name) {
    347:     KSPSetType(ksp,KSPGMRES);
    348:   }

    350:   KSPResetViewers(ksp);

    352:   PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);
    353:   if (flg) {
    354:     KSPGetReusePreconditioner(ksp,&reuse);
    355:     PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);
    356:     KSPSetReusePreconditioner(ksp,reuse);
    357:     PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
    358:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer, &ksp->format,&ksp->view);
    359:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason",&ksp->viewerReason,&ksp->formatReason,&ksp->viewReason);
    360:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);
    361:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);
    362:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);
    363:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);
    364:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);
    365:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
    366:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);
    367:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);

    369:     KSPGetDiagonalScale(ksp,&flag);
    370:     PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
    371:     if (flg) {
    372:       KSPSetDiagonalScale(ksp,flag);
    373:     }
    374:     KSPGetDiagonalScaleFix(ksp,&flag);
    375:     PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
    376:     if (flg) {
    377:       KSPSetDiagonalScaleFix(ksp,flag);
    378:     }
    379:     goto skipoptions;
    380:   }

    382:   PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);
    383:   PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);
    384:   PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);
    385:   PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);

    387:   PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);
    388:   if (set && flag) {KSPConvergedDefaultSetUIRNorm(ksp);}
    389:   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);
    390:   if (set && flag) {KSPConvergedDefaultSetUMIRNorm(ksp);}
    391:   PetscOptionsBool("-ksp_converged_maxits","Declare convergence if the maximum number of iterations is reached","KSPConvergedDefaultSetConvergedMaxits",PETSC_FALSE,&flag,&set);
    392:   if (set) {KSPConvergedDefaultSetConvergedMaxits(ksp,flag);}
    393:   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);
    394:   if (flg) {
    395:     KSPSetInitialGuessNonzero(ksp,flag);
    396:   }
    397:   KSPGetReusePreconditioner(ksp,&reuse);
    398:   PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);
    399:   KSPSetReusePreconditioner(ksp,reuse);

    401:   PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
    402:   PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
    403:   PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);
    404:   if (flg) {
    405:     KSPGetGuess(ksp,&ksp->guess);
    406:     KSPGuessSetType(ksp->guess,guesstype);
    407:     KSPGuessSetFromOptions(ksp->guess);
    408:   } else { /* old option for KSP */
    409:     nmax = 2;
    410:     PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
    411:     if (flag) {
    412:       if (nmax != 2) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
    413:       KSPSetUseFischerGuess(ksp,model[0],model[1]);
    414:     }
    415:   }

    417:   PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);
    418:   if (flg) {
    419:     switch (indx) {
    420:     case 0:
    421:       KSPConvergedDefaultCreate(&ctx);
    422:       KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
    423:       break;
    424:     case 1:
    425:       KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);
    426:       break;
    427:     case 2:
    428:       KSPConvergedDefaultCreate(&ctx);
    429:       KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);
    430:       break;
    431:     }
    432:   }

    434:   KSPSetUpNorms_Private(ksp,PETSC_FALSE,&normtype,NULL);
    435:   PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);
    436:   if (flg) { KSPSetNormType(ksp,normtype); }

    438:   PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);

    440:   PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);
    441:   if (flg) {
    442:     KSPSetLagNorm(ksp,flag);
    443:   }

    445:   KSPGetDiagonalScale(ksp,&flag);
    446:   PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
    447:   if (flg) {
    448:     KSPSetDiagonalScale(ksp,flag);
    449:   }
    450:   KSPGetDiagonalScaleFix(ksp,&flag);
    451:   PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
    452:   if (flg) {
    453:     KSPSetDiagonalScaleFix(ksp,flag);
    454:   }

    456:   PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);
    457:   if (set && flg) {
    458:     MatNullSpace nsp;
    459:     Mat          Amat = NULL;

    461:     MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);
    462:     if (ksp->pc) { PCGetOperators(ksp->pc,&Amat,NULL); }
    463:     if (Amat) {
    464:       MatSetNullSpace(Amat,nsp);
    465:       MatNullSpaceDestroy(&nsp);
    466:     } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided");
    467:   }

    469:   PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);
    470:   /* -----------------------------------------------------------------------*/
    471:   /*
    472:     Cancels all monitors hardwired into code before call to KSPSetFromOptions()
    473:   */
    474:   if (set && flg) {
    475:     KSPMonitorCancel(ksp);
    476:   }
    477:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);
    478:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);
    479:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unpreconditioned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);
    480:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);
    481:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);
    482:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);
    483:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);
    484:   PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);
    485:   if (flg) {
    486:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
    487:   }
    488:   flg = PETSC_FALSE;
    489:   if (ksp->pc) {
    490:     PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
    491:     if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flg);
    492:     if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCDEFLATION,&flg);
    493:   }

    495:   if (flg) {
    496:     /* A hack for using dynamic tolerance in preconditioner */
    497:     PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,sizeof(monfilename),&flg);
    498:     if (flg) {
    499:       KSPDynTolCtx *scale;
    500:       PetscMalloc1(1,&scale);
    501:       scale->bnrm = -1.0;
    502:       scale->coef = 1.0;
    503:       PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);
    504:       KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
    505:     }
    506:   }

    508:   /*
    509:    Calls Python function
    510:   */
    511:   PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);
    512:   if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
    513:   /*
    514:     Graphically plots preconditioned residual norm
    515:   */
    516:   PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    517:   if (set && flg) {
    518:     PetscDrawLG ctx;

    520:     KSPMonitorLGResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    521:     KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
    522:   }
    523:   /*
    524:     Graphically plots preconditioned and true residual norm
    525:   */
    526:   PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    527:   if (set && flg) {
    528:     PetscDrawLG ctx;

    530:     KSPMonitorLGTrueResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    531:     KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
    532:   }
    533:   /*
    534:     Graphically plots preconditioned residual norm and range of residual element values
    535:   */
    536:   PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    537:   if (set && flg) {
    538:     PetscViewer ctx;

    540:     PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    541:     KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    542:   }
    543:   /* TODO Do these show up in help? */
    544:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer,&ksp->format,&ksp->view);
    545:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pre",&ksp->viewerPre,&ksp->formatPre,&ksp->viewPre);
    546:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason",&ksp->viewerReason,&ksp->formatReason,&ksp->viewReason);
    547:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);
    548:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);
    549:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);
    550:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);
    551:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);
    552:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
    553:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
    554:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues_explicit",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
    555:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
    556:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);
    557:   PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);

    559:   /* Deprecated options */
    560:   if (!ksp->viewEV) {
    561:     PetscOptionsDeprecated("-ksp_compute_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues");
    562:     PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
    563:   }
    564:   if (!ksp->viewEV) {
    565:     PetscOptionsDeprecated("-ksp_plot_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues draw");
    566:     PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);
    567:     if (ksp->viewEV) {
    568:       ksp->formatEV = PETSC_VIEWER_DEFAULT;
    569:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
    570:       PetscObjectReference((PetscObject) ksp->viewerEV);
    571:     }
    572:   }
    573:   if (!ksp->viewEV) {
    574:     PetscOptionsDeprecated("-ksp_plot_eigencontours",NULL,"3.9","Use -ksp_view_eigenvalues draw::draw_contour");
    575:     PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);
    576:     if (ksp->viewEV) {
    577:       ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
    578:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
    579:       PetscObjectReference((PetscObject) ksp->viewerEV);
    580:     }
    581:   }
    582:   if (!ksp->viewEVExp) {
    583:     PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit");
    584:     PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues_explicitly",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
    585:   }
    586:   if (!ksp->viewEVExp) {
    587:     PetscOptionsDeprecated("-ksp_plot_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit draw");
    588:     PetscOptionsName("-ksp_plot_eigenvalues_explicitly","[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]","KSPView",&ksp->viewEVExp);
    589:     if (ksp->viewEVExp) {
    590:       ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
    591:       ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
    592:       PetscObjectReference((PetscObject) ksp->viewerEVExp);
    593:     }
    594:   }
    595:   if (!ksp->viewSV) {
    596:     PetscOptionsDeprecated("-ksp_compute_singularvalues",NULL,"3.9","Use -ksp_view_singularvalues");
    597:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_compute_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
    598:   }
    599:   if (!ksp->viewFinalRes) {
    600:     PetscOptionsDeprecated("-ksp_final_residual",NULL,"3.9","Use -ksp_view_final_residual");
    601:     PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
    602:   }

    604: #if defined(PETSC_HAVE_SAWS)
    605:   /*
    606:     Publish convergence information using AMS
    607:   */
    608:   PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    609:   if (set && flg) {
    610:     void *ctx;
    611:     KSPMonitorSAWsCreate(ksp,&ctx);
    612:     KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
    613:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
    614:   }
    615: #endif

    617:   /* -----------------------------------------------------------------------*/
    618:   KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);
    619:   PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
    620:   if (flg) {KSPSetPCSide(ksp,pcside);}

    622:   if (ksp->viewSV || ksp->viewEV) {
    623:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
    624:   }

    626: #if defined(PETSC_HAVE_SAWS)
    627:   {
    628:   PetscBool set;
    629:   flg  = PETSC_FALSE;
    630:   PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
    631:   if (set) {
    632:     PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
    633:   }
    634:   }
    635: #endif

    637:   nmax = PETSC_DECIDE;
    638:   PetscOptionsInt("-ksp_matsolve_block_size", "Maximum number of columns treated simultaneously", "KSPMatSolve", nmax, &nmax, &flg);
    639:   if (flg) {
    640:     KSPSetMatSolveBlockSize(ksp, nmax);
    641:   }

    643:   if (ksp->ops->setfromoptions) {
    644:     (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);
    645:   }
    646:   skipoptions:
    647:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    648:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);
    649:   PetscOptionsEnd();
    650:   ksp->setfromoptionscalled++;
    651:   return(0);
    652: }

    654: /*@
    655:    KSPResetFromOptions - Sets various KSP parameters from user options ONLY if the KSP was previously set from options

    657:    Collective on ksp

    659:    Input Parameter:
    660: .  ksp - the KSP context

    662:    Level: beginner

    664: .seealso: KSPSetFromOptions(), KSPSetOptionsPrefix()
    665: @*/
    666: PetscErrorCode KSPResetFromOptions(KSP ksp)
    667: {

    671:   if (ksp->setfromoptionscalled) {KSPSetFromOptions(ksp);}
    672:   return(0);
    673: }