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