1 
2 /*
3     Code for setting KSP options from the options database.
4 */
5 
6 #include <petsc/private/kspimpl.h>  /*I "petscksp.h" I*/
7 #include <petscdraw.h>
8 
KSPSetupMonitor_Private(KSP ksp,PetscViewer viewer,PetscViewerFormat format,PetscErrorCode (* monitor)(KSP,PetscInt,PetscReal,void *),PetscBool useMonitor)9 static PetscErrorCode KSPSetupMonitor_Private(KSP ksp, PetscViewer viewer, PetscViewerFormat format, PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,void*), PetscBool useMonitor)
10 {
11   PetscErrorCode ierr;
12 
13   PetscFunctionBegin;
14   if (useMonitor) {
15     PetscViewerAndFormat *vf;
16 
17     ierr = PetscViewerAndFormatCreate(viewer, format, &vf);CHKERRQ(ierr);
18     ierr = PetscObjectDereference((PetscObject) viewer);CHKERRQ(ierr);
19     ierr = KSPMonitorSet(ksp, monitor, vf, (PetscErrorCode (*)(void**)) PetscViewerAndFormatDestroy);CHKERRQ(ierr);
20   }
21   PetscFunctionReturn(0);
22 }
23 
24 /*@C
25    KSPSetOptionsPrefix - Sets the prefix used for searching for all
26    KSP options in the database.
27 
28    Logically Collective on ksp
29 
30    Input Parameters:
31 +  ksp - the Krylov context
32 -  prefix - the prefix string to prepend to all KSP option requests
33 
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.
38 
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
45 
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
51 
52    Level: advanced
53 
54 .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
55 @*/
KSPSetOptionsPrefix(KSP ksp,const char prefix[])56 PetscErrorCode  KSPSetOptionsPrefix(KSP ksp,const char prefix[])
57 {
58   PetscErrorCode ierr;
59 
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
62   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
63   ierr = PCSetOptionsPrefix(ksp->pc,prefix);CHKERRQ(ierr);
64   ierr = PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);CHKERRQ(ierr);
65   PetscFunctionReturn(0);
66 }
67 
68 /*@C
69    KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
70    KSP options in the database.
71 
72    Logically Collective on ksp
73 
74    Input Parameters:
75 +  ksp - the Krylov context
76 -  prefix - the prefix string to prepend to all KSP option requests
77 
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.
81 
82    Level: advanced
83 
84 .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
85 @*/
KSPAppendOptionsPrefix(KSP ksp,const char prefix[])86 PetscErrorCode  KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
87 {
88   PetscErrorCode ierr;
89 
90   PetscFunctionBegin;
91   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
92   if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
93   ierr = PCAppendOptionsPrefix(ksp->pc,prefix);CHKERRQ(ierr);
94   ierr = PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);CHKERRQ(ierr);
95   PetscFunctionReturn(0);
96 }
97 
98 /*@
99    KSPSetUseFischerGuess - Use the Paul Fischer algorithm
100 
101    Logically Collective on ksp
102 
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
107 
108     Options Database:
109 .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
110 
111    Level: advanced
112 
113 .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
114 @*/
KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)115 PetscErrorCode  KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
116 {
117   KSPGuess       guess;
118   PetscErrorCode ierr;
119 
120   PetscFunctionBegin;
121   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
122   PetscValidLogicalCollectiveInt(ksp,model,2);
123   PetscValidLogicalCollectiveInt(ksp,size,3);
124   ierr = KSPGetGuess(ksp,&guess);CHKERRQ(ierr);
125   ierr = KSPGuessSetType(guess,KSPGUESSFISCHER);CHKERRQ(ierr);
126   ierr = KSPGuessFischerSetModel(guess,model,size);CHKERRQ(ierr);
127   PetscFunctionReturn(0);
128 }
129 
130 /*@
131    KSPSetGuess - Set the initial guess object
132 
133    Logically Collective on ksp
134 
135    Input Parameters:
136 +  ksp - the Krylov context
137 -  guess - the object created with KSPGuessCreate()
138 
139    Level: advanced
140 
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()).
144 
145           This increases the reference count of the guess object, you must destroy the object with KSPGuessDestroy()
146           before the end of the program.
147 
148 .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPGetGuess()
149 @*/
KSPSetGuess(KSP ksp,KSPGuess guess)150 PetscErrorCode  KSPSetGuess(KSP ksp,KSPGuess guess)
151 {
152   PetscErrorCode ierr;
153 
154   PetscFunctionBegin;
155   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
156   PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,2);
157   ierr = PetscObjectReference((PetscObject)guess);CHKERRQ(ierr);
158   ierr = KSPGuessDestroy(&ksp->guess);CHKERRQ(ierr);
159   ksp->guess = guess;
160   ksp->guess->ksp = ksp;
161   PetscFunctionReturn(0);
162 }
163 
164 /*@
165    KSPGetGuess - Gets the initial guess generator for the KSP.
166 
167    Not Collective
168 
169    Input Parameters:
170 .  ksp - the Krylov context
171 
172    Output Parameters:
173 .   guess - the object
174 
175    Level: developer
176 
177 .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess()
178 @*/
KSPGetGuess(KSP ksp,KSPGuess * guess)179 PetscErrorCode  KSPGetGuess(KSP ksp,KSPGuess *guess)
180 {
181   PetscErrorCode ierr;
182 
183   PetscFunctionBegin;
184   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
185   PetscValidPointer(guess,2);
186   if (!ksp->guess) {
187     const char* prefix;
188 
189     ierr = KSPGuessCreate(PetscObjectComm((PetscObject)ksp),&ksp->guess);CHKERRQ(ierr);
190     ierr = PetscObjectGetOptionsPrefix((PetscObject)ksp,&prefix);CHKERRQ(ierr);
191     if (prefix) {
192       ierr = PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);CHKERRQ(ierr);
193     }
194     ksp->guess->ksp = ksp;
195   }
196   *guess = ksp->guess;
197   PetscFunctionReturn(0);
198 }
199 
200 /*@C
201    KSPGetOptionsPrefix - Gets the prefix used for searching for all
202    KSP options in the database.
203 
204    Not Collective
205 
206    Input Parameters:
207 .  ksp - the Krylov context
208 
209    Output Parameters:
210 .  prefix - pointer to the prefix string used is returned
211 
212    Notes:
213     On the fortran side, the user should pass in a string 'prefix' of
214    sufficient length to hold the prefix.
215 
216    Level: advanced
217 
218 .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
219 @*/
KSPGetOptionsPrefix(KSP ksp,const char * prefix[])220 PetscErrorCode  KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
221 {
222   PetscErrorCode ierr;
223 
224   PetscFunctionBegin;
225   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
226   ierr = PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);CHKERRQ(ierr);
227   PetscFunctionReturn(0);
228 }
229 
230 /*@C
231    KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
232 
233    Collective on ksp
234 
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
241 
242    Level: developer
243 
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 @*/
KSPMonitorSetFromOptions(KSP ksp,const char name[],const char help[],const char manual[],PetscErrorCode (* monitor)(KSP,PetscInt,PetscReal,PetscViewerAndFormat *))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;
258 
259   PetscFunctionBegin;
260   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)ksp),((PetscObject)ksp)->options,((PetscObject)ksp)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
261   ierr = KSPSetupMonitor_Private(ksp, viewer, format, (PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*)) monitor, flg);CHKERRQ(ierr);
262   PetscFunctionReturn(0);
263 }
264 
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.
269 
270    Collective on ksp
271 
272    Input Parameters:
273 .  ksp - the Krylov space context
274 
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
306 
307    Notes:
308    To see all options, run your program with the -help option
309    or consult Users-Manual: ch_ksp
310 
311    Level: beginner
312 
313 .seealso: KSPSetOptionsPrefix(), KSPResetFromOptions(), KSPSetUseFischerGuess()
314 
315 @*/
KSPSetFromOptions(KSP ksp)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;
326   PetscErrorCode ierr;
327 
328   PetscFunctionBegin;
329   PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
330   ierr = PetscObjectGetComm((PetscObject) ksp, &comm);CHKERRQ(ierr);
331   ierr = PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);CHKERRQ(ierr);
332   if (!ksp->skippcsetfromoptions) {
333     if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
334     ierr = PCSetFromOptions(ksp->pc);CHKERRQ(ierr);
335   }
336 
337   ierr = KSPRegisterAll();CHKERRQ(ierr);
338   ierr = PetscObjectOptionsBegin((PetscObject)ksp);CHKERRQ(ierr);
339   ierr = PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);CHKERRQ(ierr);
340   if (flg) {
341     ierr = KSPSetType(ksp,type);CHKERRQ(ierr);
342   }
343   /*
344     Set the type if it was never set.
345   */
346   if (!((PetscObject)ksp)->type_name) {
347     ierr = KSPSetType(ksp,KSPGMRES);CHKERRQ(ierr);
348   }
349 
350   ierr = KSPResetViewers(ksp);CHKERRQ(ierr);
351 
352   ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);CHKERRQ(ierr);
353   if (flg) {
354     ierr = KSPGetReusePreconditioner(ksp,&reuse);CHKERRQ(ierr);
355     ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr);
356     ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr);
357     ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr);
358     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer, &ksp->format,&ksp->view);CHKERRQ(ierr);
359     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason",&ksp->viewerReason,&ksp->formatReason,&ksp->viewReason);CHKERRQ(ierr);
360     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);CHKERRQ(ierr);
361     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);CHKERRQ(ierr);
362     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);CHKERRQ(ierr);
363     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);CHKERRQ(ierr);
364     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);CHKERRQ(ierr);
365     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);CHKERRQ(ierr);
366     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);CHKERRQ(ierr);
367     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);CHKERRQ(ierr);
368 
369     ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr);
370     ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr);
371     if (flg) {
372       ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr);
373     }
374     ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr);
375     ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr);
376     if (flg) {
377       ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr);
378     }
379     goto skipoptions;
380   }
381 
382   ierr = PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);CHKERRQ(ierr);
383   ierr = PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);CHKERRQ(ierr);
384   ierr = PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);CHKERRQ(ierr);
385   ierr = PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);CHKERRQ(ierr);
386 
387   ierr = PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);CHKERRQ(ierr);
388   if (set && flag) {ierr = KSPConvergedDefaultSetUIRNorm(ksp);CHKERRQ(ierr);}
389   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);
390   if (set && flag) {ierr = KSPConvergedDefaultSetUMIRNorm(ksp);CHKERRQ(ierr);}
391   ierr = PetscOptionsBool("-ksp_converged_maxits","Declare convergence if the maximum number of iterations is reached","KSPConvergedDefaultSetConvergedMaxits",PETSC_FALSE,&flag,&set);CHKERRQ(ierr);
392   if (set) {ierr = KSPConvergedDefaultSetConvergedMaxits(ksp,flag);CHKERRQ(ierr);}
393   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);
394   if (flg) {
395     ierr = KSPSetInitialGuessNonzero(ksp,flag);CHKERRQ(ierr);
396   }
397   ierr = KSPGetReusePreconditioner(ksp,&reuse);CHKERRQ(ierr);
398   ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr);
399   ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr);
400 
401   ierr = PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);CHKERRQ(ierr);
402   ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr);
403   ierr = PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);CHKERRQ(ierr);
404   if (flg) {
405     ierr = KSPGetGuess(ksp,&ksp->guess);CHKERRQ(ierr);
406     ierr = KSPGuessSetType(ksp->guess,guesstype);CHKERRQ(ierr);
407     ierr = KSPGuessSetFromOptions(ksp->guess);CHKERRQ(ierr);
408   } else { /* old option for KSP */
409     nmax = 2;
410     ierr = PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);CHKERRQ(ierr);
411     if (flag) {
412       if (nmax != 2) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
413       ierr = KSPSetUseFischerGuess(ksp,model[0],model[1]);CHKERRQ(ierr);
414     }
415   }
416 
417   ierr = PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);CHKERRQ(ierr);
418   if (flg) {
419     switch (indx) {
420     case 0:
421       ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr);
422       ierr = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr);
423       break;
424     case 1:
425       ierr = KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr);
426       break;
427     case 2:
428       ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr);
429       ierr = KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr);
430       break;
431     }
432   }
433 
434   ierr = KSPSetUpNorms_Private(ksp,PETSC_FALSE,&normtype,NULL);CHKERRQ(ierr);
435   ierr = PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);CHKERRQ(ierr);
436   if (flg) { ierr = KSPSetNormType(ksp,normtype);CHKERRQ(ierr); }
437 
438   ierr = PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);CHKERRQ(ierr);
439 
440   ierr = PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);CHKERRQ(ierr);
441   if (flg) {
442     ierr = KSPSetLagNorm(ksp,flag);CHKERRQ(ierr);
443   }
444 
445   ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr);
446   ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr);
447   if (flg) {
448     ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr);
449   }
450   ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr);
451   ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr);
452   if (flg) {
453     ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr);
454   }
455 
456   ierr = PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
457   if (set && flg) {
458     MatNullSpace nsp;
459     Mat          Amat = NULL;
460 
461     ierr = MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);CHKERRQ(ierr);
462     if (ksp->pc) { ierr = PCGetOperators(ksp->pc,&Amat,NULL);CHKERRQ(ierr); }
463     if (Amat) {
464       ierr = MatSetNullSpace(Amat,nsp);CHKERRQ(ierr);
465       ierr = MatNullSpaceDestroy(&nsp);CHKERRQ(ierr);
466     } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided");
467   }
468 
469   ierr = PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
470   /* -----------------------------------------------------------------------*/
471   /*
472     Cancels all monitors hardwired into code before call to KSPSetFromOptions()
473   */
474   if (set && flg) {
475     ierr = KSPMonitorCancel(ksp);CHKERRQ(ierr);
476   }
477   ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);CHKERRQ(ierr);
478   ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);CHKERRQ(ierr);
479   ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unpreconditioned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);CHKERRQ(ierr);
480   ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);CHKERRQ(ierr);
481   ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);CHKERRQ(ierr);
482   ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);CHKERRQ(ierr);
483   ierr = KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);CHKERRQ(ierr);
484   ierr = PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);CHKERRQ(ierr);
485   if (flg) {
486     ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr);
487   }
488   flg = PETSC_FALSE;
489   if (ksp->pc) {
490     ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);CHKERRQ(ierr);
491     if (!flg) ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flg);CHKERRQ(ierr);
492     if (!flg) ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCDEFLATION,&flg);CHKERRQ(ierr);
493   }
494 
495   if (flg) {
496     /* A hack for using dynamic tolerance in preconditioner */
497     ierr = PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr);
498     if (flg) {
499       KSPDynTolCtx *scale;
500       ierr        = PetscMalloc1(1,&scale);CHKERRQ(ierr);
501       scale->bnrm = -1.0;
502       scale->coef = 1.0;
503       ierr        = PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);CHKERRQ(ierr);
504       ierr        = KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);CHKERRQ(ierr);
505     }
506   }
507 
508   /*
509    Calls Python function
510   */
511   ierr = PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr);
512   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ksp,monfilename);CHKERRQ(ierr);}
513   /*
514     Graphically plots preconditioned residual norm
515   */
516   ierr = PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
517   if (set && flg) {
518     PetscDrawLG ctx;
519 
520     ierr = KSPMonitorLGResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
521     ierr = KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr);
522   }
523   /*
524     Graphically plots preconditioned and true residual norm
525   */
526   ierr = PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
527   if (set && flg) {
528     PetscDrawLG ctx;
529 
530     ierr = KSPMonitorLGTrueResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
531     ierr = KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr);
532   }
533   /*
534     Graphically plots preconditioned residual norm and range of residual element values
535   */
536   ierr = PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
537   if (set && flg) {
538     PetscViewer ctx;
539 
540     ierr = PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
541     ierr = KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
542   }
543   /* TODO Do these show up in help? */
544   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer,&ksp->format,&ksp->view);CHKERRQ(ierr);
545   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pre",&ksp->viewerPre,&ksp->formatPre,&ksp->viewPre);CHKERRQ(ierr);
546   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason",&ksp->viewerReason,&ksp->formatReason,&ksp->viewReason);CHKERRQ(ierr);
547   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);CHKERRQ(ierr);
548   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);CHKERRQ(ierr);
549   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);CHKERRQ(ierr);
550   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);CHKERRQ(ierr);
551   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);CHKERRQ(ierr);
552   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);CHKERRQ(ierr);
553   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);CHKERRQ(ierr);
554   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues_explicit",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);CHKERRQ(ierr);
555   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);CHKERRQ(ierr);
556   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);CHKERRQ(ierr);
557   ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);CHKERRQ(ierr);
558 
559   /* Deprecated options */
560   if (!ksp->viewEV) {
561     ierr = PetscOptionsDeprecated("-ksp_compute_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues");CHKERRQ(ierr);
562     ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);CHKERRQ(ierr);
563   }
564   if (!ksp->viewEV) {
565     ierr = PetscOptionsDeprecated("-ksp_plot_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues draw");CHKERRQ(ierr);
566     ierr = PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);CHKERRQ(ierr);
567     if (ksp->viewEV) {
568       ksp->formatEV = PETSC_VIEWER_DEFAULT;
569       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
570       ierr = PetscObjectReference((PetscObject) ksp->viewerEV);CHKERRQ(ierr);
571     }
572   }
573   if (!ksp->viewEV) {
574     ierr = PetscOptionsDeprecated("-ksp_plot_eigencontours",NULL,"3.9","Use -ksp_view_eigenvalues draw::draw_contour");CHKERRQ(ierr);
575     ierr = PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);CHKERRQ(ierr);
576     if (ksp->viewEV) {
577       ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
578       ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
579       ierr = PetscObjectReference((PetscObject) ksp->viewerEV);CHKERRQ(ierr);
580     }
581   }
582   if (!ksp->viewEVExp) {
583     ierr = PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit");CHKERRQ(ierr);
584     ierr = PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues_explicitly",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);CHKERRQ(ierr);
585   }
586   if (!ksp->viewEVExp) {
587     ierr = PetscOptionsDeprecated("-ksp_plot_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit draw");CHKERRQ(ierr);
588     ierr = PetscOptionsName("-ksp_plot_eigenvalues_explicitly","[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]","KSPView",&ksp->viewEVExp);CHKERRQ(ierr);
589     if (ksp->viewEVExp) {
590       ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
591       ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
592       ierr = PetscObjectReference((PetscObject) ksp->viewerEVExp);CHKERRQ(ierr);
593     }
594   }
595   if (!ksp->viewSV) {
596     ierr = PetscOptionsDeprecated("-ksp_compute_singularvalues",NULL,"3.9","Use -ksp_view_singularvalues");CHKERRQ(ierr);
597     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_compute_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);CHKERRQ(ierr);
598   }
599   if (!ksp->viewFinalRes) {
600     ierr = PetscOptionsDeprecated("-ksp_final_residual",NULL,"3.9","Use -ksp_view_final_residual");CHKERRQ(ierr);
601     ierr = PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);CHKERRQ(ierr);
602   }
603 
604 #if defined(PETSC_HAVE_SAWS)
605   /*
606     Publish convergence information using AMS
607   */
608   ierr = PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
609   if (set && flg) {
610     void *ctx;
611     ierr = KSPMonitorSAWsCreate(ksp,&ctx);CHKERRQ(ierr);
612     ierr = KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);CHKERRQ(ierr);
613     ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr);
614   }
615 #endif
616 
617   /* -----------------------------------------------------------------------*/
618   ierr = KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);CHKERRQ(ierr);
619   ierr = PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
620   if (flg) {ierr = KSPSetPCSide(ksp,pcside);CHKERRQ(ierr);}
621 
622   if (ksp->viewSV || ksp->viewEV) {
623     ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr);
624   }
625 
626 #if defined(PETSC_HAVE_SAWS)
627   {
628   PetscBool set;
629   flg  = PETSC_FALSE;
630   ierr = PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);CHKERRQ(ierr);
631   if (set) {
632     ierr = PetscObjectSAWsSetBlock((PetscObject)ksp,flg);CHKERRQ(ierr);
633   }
634   }
635 #endif
636 
637   nmax = PETSC_DECIDE;
638   ierr = PetscOptionsInt("-ksp_matsolve_block_size", "Maximum number of columns treated simultaneously", "KSPMatSolve", nmax, &nmax, &flg);CHKERRQ(ierr);
639   if (flg) {
640     ierr = KSPSetMatSolveBlockSize(ksp, nmax);CHKERRQ(ierr);
641   }
642 
643   if (ksp->ops->setfromoptions) {
644     ierr = (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);CHKERRQ(ierr);
645   }
646   skipoptions:
647   /* process any options handlers added with PetscObjectAddOptionsHandler() */
648   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);CHKERRQ(ierr);
649   ierr = PetscOptionsEnd();CHKERRQ(ierr);
650   ksp->setfromoptionscalled++;
651   PetscFunctionReturn(0);
652 }
653 
654 /*@
655    KSPResetFromOptions - Sets various KSP parameters from user options ONLY if the KSP was previously set from options
656 
657    Collective on ksp
658 
659    Input Parameter:
660 .  ksp - the KSP context
661 
662    Level: beginner
663 
664 .seealso: KSPSetFromOptions(), KSPSetOptionsPrefix()
665 @*/
KSPResetFromOptions(KSP ksp)666 PetscErrorCode KSPResetFromOptions(KSP ksp)
667 {
668   PetscErrorCode ierr;
669 
670   PetscFunctionBegin;
671   if (ksp->setfromoptionscalled) {ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);}
672   PetscFunctionReturn(0);
673 }
674