Actual source code: itcl.c
petsc-3.10.5 2019-03-28
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: .keywords: KSP, set, options, prefix, database

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

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

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

     74:    Logically Collective on KSP

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

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

     84:    Level: advanced

     86: .keywords: KSP, append, options, prefix, database

     88: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
     89: @*/
     90: PetscErrorCode  KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
     91: {

     96:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
     97:   PCAppendOptionsPrefix(ksp->pc,prefix);
     98:   PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
     99:   return(0);
    100: }

    102: /*@
    103:    KSPGetTabLevel - Gets the number of tabs that ASCII output used by ksp.

    105:    Not Collective

    107:    Input Parameter:
    108: .  ksp - a KSP object.

    110:    Output Parameter:
    111: .   tab - the number of tabs

    113:    Level: developer

    115:     Notes:
    116:     this is used in conjunction with KSPSetTabLevel() to manage the output from the KSP and its PC coherently.

    119: .seealso:  KSPSetTabLevel()

    121: @*/
    122: PetscErrorCode  KSPGetTabLevel(KSP ksp,PetscInt *tab)
    123: {

    128:   PetscObjectGetTabLevel((PetscObject)ksp, tab);
    129:   return(0);
    130: }

    132: /*@
    133:    KSPSetTabLevel - Sets the number of tabs that ASCII output for the ksp andn its pc will use.

    135:    Not Collective

    137:    Input Parameters:
    138: +  ksp - a KSP object
    139: -  tab - the number of tabs

    141:    Level: developer

    143:     Notes:
    144:     this is used to manage the output from KSP and PC objects that are imbedded in other objects,
    145:            for example, the KSP object inside a SNES object. By indenting each lower level further the heirarchy
    146:            of objects is very clear.  By setting the KSP object's tab level with KSPSetTabLevel() its PC object
    147:            automatically receives the same tab level, so that whatever objects the pc might create are tabbed
    148:            appropriately, too.

    150: .seealso:  KSPGetTabLevel()
    151: @*/
    152: PetscErrorCode  KSPSetTabLevel(KSP ksp, PetscInt tab)
    153: {

    158:   PetscObjectSetTabLevel((PetscObject)ksp, tab);
    159:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
    160:   /* Do we need a PCSetTabLevel()? */
    161:   PetscObjectSetTabLevel((PetscObject)ksp->pc, tab);
    162:   return(0);
    163: }

    165: /*@
    166:    KSPSetUseFischerGuess - Use the Paul Fischer algorithm

    168:    Logically Collective on KSP

    170:    Input Parameters:
    171: +  ksp - the Krylov context
    172: .  model - use model 1, model 2 or any other number to turn it off
    173: -  size - size of subspace used to generate initial guess

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

    178:    Level: advanced

    180: .keywords: KSP, set, options, prefix, database

    182: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
    183: @*/
    184: PetscErrorCode  KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
    185: {
    186:   KSPGuess       guess;

    193:   KSPGetGuess(ksp,&guess);
    194:   KSPGuessSetType(guess,KSPGUESSFISCHER);
    195:   KSPGuessFischerSetModel(guess,model,size);
    196:   return(0);
    197: }

    199: /*@
    200:    KSPSetGuess - Set the initial guess object

    202:    Logically Collective on KSP

    204:    Input Parameters:
    205: +  ksp - the Krylov context
    206: -  guess - the object created with KSPGuessCreate()

    208:    Level: advanced

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

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

    217: .keywords: KSP, set, options, prefix, database

    219: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPGetGuess()
    220: @*/
    221: PetscErrorCode  KSPSetGuess(KSP ksp,KSPGuess guess)
    222: {

    228:   PetscObjectReference((PetscObject)guess);
    229:   KSPGuessDestroy(&ksp->guess);
    230:   ksp->guess = guess;
    231:   ksp->guess->ksp = ksp;
    232:   return(0);
    233: }

    235: /*@
    236:    KSPGetGuess - Gets the initial guess generator for the KSP.

    238:    Not Collective

    240:    Input Parameters:
    241: .  ksp - the Krylov context

    243:    Output Parameters:
    244: .   guess - the object

    246:    Level: developer

    248: .keywords: KSP, set, options, prefix, database

    250: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess()
    251: @*/
    252: PetscErrorCode  KSPGetGuess(KSP ksp,KSPGuess *guess)
    253: {

    259:   if (!ksp->guess) {
    260:     const char* prefix;

    262:     KSPGuessCreate(PetscObjectComm((PetscObject)ksp),&ksp->guess);
    263:     PetscObjectGetOptionsPrefix((PetscObject)ksp,&prefix);
    264:     if (prefix) {
    265:       PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);
    266:     }
    267:     ksp->guess->ksp = ksp;
    268:   }
    269:   *guess = ksp->guess;
    270:   return(0);
    271: }

    273: /*@C
    274:    KSPGetOptionsPrefix - Gets the prefix used for searching for all
    275:    KSP options in the database.

    277:    Not Collective

    279:    Input Parameters:
    280: .  ksp - the Krylov context

    282:    Output Parameters:
    283: .  prefix - pointer to the prefix string used is returned

    285:    Notes:
    286:     On the fortran side, the user should pass in a string 'prefix' of
    287:    sufficient length to hold the prefix.

    289:    Level: advanced

    291: .keywords: KSP, set, options, prefix, database

    293: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
    294: @*/
    295: PetscErrorCode  KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
    296: {

    301:   PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
    302:   return(0);
    303: }

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

    308:    Collective on KSP

    310:    Input Parameters:
    311: +  ksp - KSP object you wish to monitor
    312: .  name - the monitor type one is seeking
    313: .  help - message indicating what monitoring is done
    314: .  manual - manual page for the monitor
    315: -  monitor - the monitor function, the context for this object is a PetscViewerAndFormat

    317:    Level: developer

    319: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
    320:           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
    321:           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
    322:           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
    323:           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
    324:           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
    325:           PetscOptionsFList(), PetscOptionsEList()
    326: @*/
    327: PetscErrorCode  KSPMonitorSetFromOptions(KSP ksp,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,PetscViewerAndFormat*))
    328: {
    329:   PetscErrorCode       ierr;
    330:   PetscBool            flg;
    331:   PetscViewer          viewer;
    332:   PetscViewerFormat    format;

    335:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)ksp),((PetscObject)ksp)->prefix,name,&viewer,&format,&flg);
    336:   KSPSetupMonitor_Private(ksp, viewer, format, (PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*)) monitor, flg);
    337:   return(0);
    338: }

    340: /*@
    341:    KSPSetFromOptions - Sets KSP options from the options database.
    342:    This routine must be called before KSPSetUp() if the user is to be
    343:    allowed to set the Krylov type.

    345:    Collective on KSP

    347:    Input Parameters:
    348: .  ksp - the Krylov space context

    350:    Options Database Keys:
    351: +   -ksp_max_it - maximum number of linear iterations
    352: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
    353:                 if residual norm decreases by this factor than convergence is declared
    354: .   -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
    355:                 norm is less than this then convergence is declared
    356: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
    357: .   -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm()
    358: .   -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm()
    359: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
    360:                        convergence test (say you always want to run with 5 iterations) to
    361:                        save on communication overhead
    362:                     preconditioned - default for left preconditioning
    363:                     unpreconditioned - see KSPSetNormType()
    364:                     natural - see KSPSetNormType()
    365: .   -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
    366:        works only for PCBCGS, PCIBCGS and and PCCG
    367: .   -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
    368:        the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
    369:        This will require 1 more iteration of the solver than usual.
    370: .   -ksp_guess_type - Type of initial guess generator for repeated linear solves
    371: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
    372: .   -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
    373: .   -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space
    374: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
    375: .   -ksp_monitor_cancel - cancel all previous convergene monitor routines set
    376: .   -ksp_monitor <optional filename> - print residual norm at each iteration
    377: .   -ksp_monitor_lg_residualnorm - plot residual norm at each iteration
    378: .   -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
    379: -   -ksp_monitor_singular_value - monitor extreme singular values at each iteration

    381:    Notes:
    382:    To see all options, run your program with the -help option
    383:    or consult Users-Manual: Chapter 4 KSP: Linear System Solvers

    385:    Level: beginner

    387: .keywords: KSP, set, from, options, database

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

    391: @*/
    392: PetscErrorCode  KSPSetFromOptions(KSP ksp)
    393: {
    394:   PetscInt       indx;
    395:   const char     *convtests[] = {"default","skip","lsqr"};
    396:   char           type[256], guesstype[256], monfilename[PETSC_MAX_PATH_LEN];
    397:   PetscBool      flg,flag,reuse,set;
    398:   PetscInt       model[2]={0,0},nmax;
    399:   KSPNormType    normtype;
    400:   PCSide         pcside;
    401:   void           *ctx;
    402:   MPI_Comm       comm;
    403:   const char    *prefix;

    408:   PetscObjectGetComm((PetscObject) ksp, &comm);
    409:   PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
    410:   if (!ksp->skippcsetfromoptions) {
    411:     if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
    412:     PCSetFromOptions(ksp->pc);
    413:   }

    415:   KSPRegisterAll();
    416:   PetscObjectOptionsBegin((PetscObject)ksp);
    417:   PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
    418:   if (flg) {
    419:     KSPSetType(ksp,type);
    420:   }
    421:   /*
    422:     Set the type if it was never set.
    423:   */
    424:   if (!((PetscObject)ksp)->type_name) {
    425:     KSPSetType(ksp,KSPGMRES);
    426:   }

    428:   PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);
    429:   if (flg) {
    430:     PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
    431:     goto skipoptions;
    432:   }

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

    439:   PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);
    440:   if (set && flag) {KSPConvergedDefaultSetUIRNorm(ksp);}
    441:   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);
    442:   if (set && flag) {KSPConvergedDefaultSetUMIRNorm(ksp);}
    443:   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);
    444:   if (flg) {
    445:     KSPSetInitialGuessNonzero(ksp,flag);
    446:   }
    447:   PCGetReusePreconditioner(ksp->pc,&reuse);
    448:   PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);
    449:   KSPSetReusePreconditioner(ksp,reuse);

    451:   PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
    452:   PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
    453:   PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);
    454:   if (flg) {
    455:     KSPGetGuess(ksp,&ksp->guess);
    456:     KSPGuessSetType(ksp->guess,guesstype);
    457:     KSPGuessSetFromOptions(ksp->guess);
    458:   } else { /* old option for KSP */
    459:     nmax = 2;
    460:     PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
    461:     if (flag) {
    462:       if (nmax != 2) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
    463:       KSPSetUseFischerGuess(ksp,model[0],model[1]);
    464:     }
    465:   }

    467:   PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);
    468:   if (flg) {
    469:     switch (indx) {
    470:     case 0:
    471:       KSPConvergedDefaultCreate(&ctx);
    472:       KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
    473:       break;
    474:     case 1: KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);    break;
    475:     case 2:
    476:       KSPConvergedDefaultCreate(&ctx);
    477:       KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);
    478:       break;
    479:     }
    480:   }

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

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

    488:   PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);
    489:   if (flg) {
    490:     KSPSetLagNorm(ksp,flag);
    491:   }

    493:   KSPGetDiagonalScale(ksp,&flag);
    494:   PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
    495:   if (flg) {
    496:     KSPSetDiagonalScale(ksp,flag);
    497:   }
    498:   KSPGetDiagonalScaleFix(ksp,&flag);
    499:   PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
    500:   if (flg) {
    501:     KSPSetDiagonalScaleFix(ksp,flag);
    502:   }

    504:   PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);
    505:   if (set && flg) {
    506:     MatNullSpace nsp;
    507:     Mat          Amat;

    509:     MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);
    510:     PCGetOperators(ksp->pc,&Amat,NULL);
    511:     if (Amat) {
    512:       MatSetNullSpace(Amat,nsp);
    513:       MatNullSpaceDestroy(&nsp);
    514:     } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided");
    515:   }

    517:   PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);
    518:   /* -----------------------------------------------------------------------*/
    519:   /*
    520:     Cancels all monitors hardwired into code before call to KSPSetFromOptions()
    521:   */
    522:   if (set && flg) {
    523:     KSPMonitorCancel(ksp);
    524:   }
    525:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);
    526:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);
    527:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unprecondiitoned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);
    528:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);
    529:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);
    530:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);
    531:   KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);
    532:   PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);
    533:   if (flg) {
    534:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
    535:   }
    536:   PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
    537:   PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);

    539:   if (flg || flag) {
    540:     /* A hack for using dynamic tolerance in preconditioner */
    541:     PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
    542:     if (flg) {
    543:       KSPDynTolCtx *scale;
    544:       PetscMalloc1(1,&scale);
    545:       scale->bnrm = -1.0;
    546:       scale->coef = 1.0;
    547:       PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);
    548:       KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
    549:     }
    550:   }

    553:   /*
    554:    Calls Python function
    555:   */
    556:   PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
    557:   if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
    558:   /*
    559:     Graphically plots preconditioned residual norm
    560:   */
    561:   PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    562:   if (set && flg) {
    563:     PetscDrawLG ctx;

    565:     KSPMonitorLGResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    566:     KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
    567:   }
    568:   /*
    569:     Graphically plots preconditioned and true residual norm
    570:   */
    571:   PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    572:   if (set && flg) {
    573:     PetscDrawLG ctx;

    575:     KSPMonitorLGTrueResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    576:     KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
    577:   }
    578:   /*
    579:     Graphically plots preconditioned residual norm and range of residual element values
    580:   */
    581:   PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    582:   if (set && flg) {
    583:     PetscViewer ctx;

    585:     PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
    586:     KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
    587:   }
    588:   /* TODO Do these show up in help? */
    589:   PetscOptionsGetViewer(comm, prefix, "-ksp_view",                        &ksp->viewer,         &ksp->format,         &ksp->view);
    590:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_pre",                    &ksp->viewerPre,      &ksp->formatPre,      &ksp->viewPre);
    591:   PetscOptionsGetViewer(comm, prefix, "-ksp_converged_reason",            &ksp->viewerReason,   &ksp->formatReason,   &ksp->viewReason);
    592:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_mat",                    &ksp->viewerMat,      &ksp->formatMat,      &ksp->viewMat);
    593:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_pmat",                   &ksp->viewerPMat,     &ksp->formatPMat,     &ksp->viewPMat);
    594:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_rhs",                    &ksp->viewerRhs,      &ksp->formatRhs,      &ksp->viewRhs);
    595:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_solution",               &ksp->viewerSol,      &ksp->formatSol,      &ksp->viewSol);
    596:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_mat_explicit",           &ksp->viewerMatExp,   &ksp->formatMatExp,   &ksp->viewMatExp);
    597:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_eigenvalues",            &ksp->viewerEV,       &ksp->formatEV,       &ksp->viewEV);
    598:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_singularvalues",         &ksp->viewerSV,       &ksp->formatSV,       &ksp->viewSV);
    599:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_eigenvalues_explicit",   &ksp->viewerEVExp,    &ksp->formatEVExp,    &ksp->viewEVExp);
    600:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_final_residual",         &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes);
    601:   PetscOptionsGetViewer(comm, prefix, "-ksp_view_preconditioned_operator_explicit", &ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp);

    603:   /* Deprecated options */
    604:   if (!ksp->viewEV)       {PetscOptionsGetViewer(comm, prefix, "-ksp_compute_eigenvalues",              &ksp->viewerEV,       &ksp->formatEV,       &ksp->viewEV);}
    605:   if (!ksp->viewEV)       {
    606:     PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);
    607:     if (ksp->viewEV) {
    608:       ksp->formatEV = PETSC_VIEWER_DEFAULT;
    609:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
    610:       PetscObjectReference((PetscObject) ksp->viewerEV);
    611:     }
    612:   }
    613:   if (!ksp->viewEV)       {
    614:     PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);
    615:     if (ksp->viewEV) {
    616:       ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
    617:       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
    618:       PetscObjectReference((PetscObject) ksp->viewerEV);
    619:     }
    620:   }
    621:   if (!ksp->viewEVExp)    {PetscOptionsGetViewer(comm, prefix, "-ksp_compute_eigenvalues_explicitly",   &ksp->viewerEVExp,    &ksp->formatEVExp,    &ksp->viewEVExp);}
    622:   if (!ksp->viewEVExp)    {
    623:     PetscOptionsName("-ksp_plot_eigenvalues_explicitly", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]", "KSPView", &ksp->viewEVExp);
    624:     if (ksp->viewEVExp) {
    625:       ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
    626:       ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
    627:       PetscObjectReference((PetscObject) ksp->viewerEVExp);
    628:     }
    629:   }
    630:   if (!ksp->viewSV)       {PetscOptionsGetViewer(comm, prefix, "-ksp_compute_singularvalues",           &ksp->viewerSV,       &ksp->formatSV,       &ksp->viewSV);}
    631:   if (!ksp->viewFinalRes) {PetscOptionsGetViewer(comm, prefix, "-ksp_final_residual",                   &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes);}

    633: #if defined(PETSC_HAVE_SAWS)
    634:   /*
    635:     Publish convergence information using AMS
    636:   */
    637:   PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);
    638:   if (set && flg) {
    639:     void *ctx;
    640:     KSPMonitorSAWsCreate(ksp,&ctx);
    641:     KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
    642:     KSPSetComputeSingularValues(ksp,PETSC_TRUE);
    643:   }
    644: #endif

    646:   /* -----------------------------------------------------------------------*/
    647:   KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);
    648:   PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
    649:   if (flg) {KSPSetPCSide(ksp,pcside);}

    651:   PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);
    652:   if (set) { KSPSetComputeSingularValues(ksp,flg); }
    653:   PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);
    654:   if (set) { KSPSetComputeSingularValues(ksp,flg); }
    655:   PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",PETSC_FALSE,&flg,&set);
    656:   if (set) { KSPSetComputeSingularValues(ksp,flg); }

    658: #if defined(PETSC_HAVE_SAWS)
    659:   {
    660:   PetscBool set;
    661:   flg  = PETSC_FALSE;
    662:   PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
    663:   if (set) {
    664:     PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
    665:   }
    666:   }
    667: #endif

    669:   if (ksp->ops->setfromoptions) {
    670:     (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);
    671:   }
    672:   skipoptions:
    673:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
    674:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);
    675:   PetscOptionsEnd();
    676:   ksp->setfromoptionscalled++;
    677:   return(0);
    678: }

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

    683:    Collective on KSP

    685:    Input Parameter:
    686: .  ksp - the KSP context

    688:    Level: beginner

    690: .keywords: KSP, linear, set, options, database

    692: .seealso: KSPSetFromOptions(), KSPSetOptionsPrefix()
    693: @*/
    694: PetscErrorCode KSPResetFromOptions(KSP ksp)
    695: {

    699:   if (ksp->setfromoptionscalled) {KSPSetFromOptions(ksp);}
    700:   return(0);
    701: }