Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 : /*
11 : LME routines related to options that can be set via the command-line
12 : or procedurally
13 : */
14 :
15 : #include <slepc/private/lmeimpl.h> /*I "slepclme.h" I*/
16 : #include <petscdraw.h>
17 :
18 : /*@C
19 : LMEMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type
20 : indicated by the user.
21 :
22 : Collective
23 :
24 : Input Parameters:
25 : + lme - the linear matrix equation context
26 : . opt - the command line option for this monitor
27 : . name - the monitor type one is seeking
28 : - ctx - an optional user context for the monitor, or NULL
29 :
30 : Level: developer
31 :
32 : .seealso: LMEMonitorSet()
33 : @*/
34 8 : PetscErrorCode LMEMonitorSetFromOptions(LME lme,const char opt[],const char name[],void *ctx)
35 : {
36 8 : PetscErrorCode (*mfunc)(LME,PetscInt,PetscReal,void*);
37 8 : PetscErrorCode (*cfunc)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);
38 8 : PetscErrorCode (*dfunc)(PetscViewerAndFormat**);
39 8 : PetscViewerAndFormat *vf;
40 8 : PetscViewer viewer;
41 8 : PetscViewerFormat format;
42 8 : PetscViewerType vtype;
43 8 : char key[PETSC_MAX_PATH_LEN];
44 8 : PetscBool flg;
45 :
46 8 : PetscFunctionBegin;
47 8 : PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)lme),((PetscObject)lme)->options,((PetscObject)lme)->prefix,opt,&viewer,&format,&flg));
48 8 : if (!flg) PetscFunctionReturn(PETSC_SUCCESS);
49 :
50 2 : PetscCall(PetscViewerGetType(viewer,&vtype));
51 2 : PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
52 2 : PetscCall(PetscFunctionListFind(LMEMonitorList,key,&mfunc));
53 2 : PetscCheck(mfunc,PetscObjectComm((PetscObject)lme),PETSC_ERR_SUP,"Specified viewer and format not supported");
54 2 : PetscCall(PetscFunctionListFind(LMEMonitorCreateList,key,&cfunc));
55 2 : PetscCall(PetscFunctionListFind(LMEMonitorDestroyList,key,&dfunc));
56 2 : if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
57 2 : if (!dfunc) dfunc = PetscViewerAndFormatDestroy;
58 :
59 2 : PetscCall((*cfunc)(viewer,format,ctx,&vf));
60 2 : PetscCall(PetscOptionsRestoreViewer(&viewer));
61 2 : PetscCall(LMEMonitorSet(lme,mfunc,vf,(PetscErrorCode(*)(void **))dfunc));
62 2 : PetscFunctionReturn(PETSC_SUCCESS);
63 : }
64 :
65 : /*@
66 : LMESetFromOptions - Sets LME options from the options database.
67 : This routine must be called before LMESetUp() if the user is to be
68 : allowed to set the solver type.
69 :
70 : Collective
71 :
72 : Input Parameters:
73 : . lme - the linear matrix equation solver context
74 :
75 : Notes:
76 : To see all options, run your program with the -help option.
77 :
78 : Level: beginner
79 :
80 : .seealso: LMESetOptionsPrefix()
81 : @*/
82 8 : PetscErrorCode LMESetFromOptions(LME lme)
83 : {
84 8 : char type[256];
85 8 : PetscBool set,flg,flg1,flg2;
86 8 : PetscReal r;
87 8 : PetscInt i;
88 :
89 8 : PetscFunctionBegin;
90 8 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
91 8 : PetscCall(LMERegisterAll());
92 24 : PetscObjectOptionsBegin((PetscObject)lme);
93 8 : PetscCall(PetscOptionsFList("-lme_type","Linear matrix equation","LMESetType",LMEList,(char*)(((PetscObject)lme)->type_name?((PetscObject)lme)->type_name:LMEKRYLOV),type,sizeof(type),&flg));
94 8 : if (flg) PetscCall(LMESetType(lme,type));
95 8 : else if (!((PetscObject)lme)->type_name) PetscCall(LMESetType(lme,LMEKRYLOV));
96 :
97 8 : PetscCall(PetscOptionsBoolGroupBegin("-lme_lyapunov","Continuous-time Lyapunov equation","LMESetProblemType",&flg));
98 8 : if (flg) PetscCall(LMESetProblemType(lme,LME_LYAPUNOV));
99 8 : PetscCall(PetscOptionsBoolGroup("-lme_sylvester","Continuous-time Sylvester equation","LMESetProblemType",&flg));
100 8 : if (flg) PetscCall(LMESetProblemType(lme,LME_SYLVESTER));
101 8 : PetscCall(PetscOptionsBoolGroup("-lme_gen_lyapunov","Generalized Lyapunov equation","LMESetProblemType",&flg));
102 8 : if (flg) PetscCall(LMESetProblemType(lme,LME_GEN_LYAPUNOV));
103 8 : PetscCall(PetscOptionsBoolGroup("-lme_gen_sylvester","Generalized Sylvester equation","LMESetProblemType",&flg));
104 8 : if (flg) PetscCall(LMESetProblemType(lme,LME_GEN_SYLVESTER));
105 8 : PetscCall(PetscOptionsBoolGroup("-lme_dt_lyapunov","Discrete-time Lyapunov equation","LMESetProblemType",&flg));
106 8 : if (flg) PetscCall(LMESetProblemType(lme,LME_DT_LYAPUNOV));
107 8 : PetscCall(PetscOptionsBoolGroupEnd("-lme_stein","Stein equation","LMESetProblemType",&flg));
108 8 : if (flg) PetscCall(LMESetProblemType(lme,LME_STEIN));
109 :
110 8 : i = lme->max_it;
111 8 : PetscCall(PetscOptionsInt("-lme_max_it","Maximum number of iterations","LMESetTolerances",lme->max_it,&i,&flg1));
112 8 : if (!flg1) i = PETSC_DEFAULT;
113 8 : r = lme->tol;
114 14 : PetscCall(PetscOptionsReal("-lme_tol","Tolerance","LMESetTolerances",SlepcDefaultTol(lme->tol),&r,&flg2));
115 8 : if (flg1 || flg2) PetscCall(LMESetTolerances(lme,r,i));
116 :
117 8 : PetscCall(PetscOptionsInt("-lme_ncv","Number of basis vectors","LMESetDimensions",lme->ncv,&i,&flg));
118 8 : if (flg) PetscCall(LMESetDimensions(lme,i));
119 :
120 8 : PetscCall(PetscOptionsBool("-lme_error_if_not_converged","Generate error if solver does not converge","LMESetErrorIfNotConverged",lme->errorifnotconverged,&lme->errorifnotconverged,NULL));
121 :
122 : /* -----------------------------------------------------------------------*/
123 : /*
124 : Cancels all monitors hardwired into code before call to LMESetFromOptions()
125 : */
126 8 : PetscCall(PetscOptionsBool("-lme_monitor_cancel","Remove any hardwired monitor routines","LMEMonitorCancel",PETSC_FALSE,&flg,&set));
127 8 : if (set && flg) PetscCall(LMEMonitorCancel(lme));
128 8 : PetscCall(LMEMonitorSetFromOptions(lme,"-lme_monitor","error_estimate",NULL));
129 :
130 : /* -----------------------------------------------------------------------*/
131 8 : PetscCall(PetscOptionsName("-lme_view","Print detailed information on solver used","LMEView",&set));
132 :
133 8 : PetscTryTypeMethod(lme,setfromoptions,PetscOptionsObject);
134 8 : PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)lme,PetscOptionsObject));
135 8 : PetscOptionsEnd();
136 :
137 8 : if (!lme->V) PetscCall(LMEGetBV(lme,&lme->V));
138 8 : PetscCall(BVSetFromOptions(lme->V));
139 8 : PetscFunctionReturn(PETSC_SUCCESS);
140 : }
141 :
142 : /*@
143 : LMESetProblemType - Specifies the type of matrix equation to be solved.
144 :
145 : Logically Collective
146 :
147 : Input Parameters:
148 : + lme - the linear matrix equation solver context
149 : - type - a known type of matrix equation
150 :
151 : Options Database Keys:
152 : + -lme_lyapunov - continuous-time Lyapunov equation A*X+X*A'=-C
153 : . -lme_sylvester - continuous-time Sylvester equation A*X+X*B=C
154 : . -lme_gen_lyapunov - generalized Lyapunov equation A*X*D'+D*X*A'=-C
155 : . -lme_gen_sylvester - generalized Sylvester equation A*X*E+D*X*B=C
156 : . -lme_dt_lyapunov - discrete-time Lyapunov equation A*X*A'-X=-C
157 : - -lme_stein - Stein equation A*X*E+X=C
158 :
159 : Notes:
160 : The coefficient matrices A, B, D, E must be provided via LMESetCoefficients(),
161 : but some of them are optional depending on the matrix equation.
162 :
163 : .vb
164 : equation A B D E
165 : ----------------- --- --- --- ---
166 : LME_LYAPUNOV A*X+X*A'=-C yes (A-t) - -
167 : LME_SYLVESTER A*X+X*B=C yes yes - -
168 : LME_GEN_LYAPUNOV A*X*D'+D*X*A'=-C yes (A-t) yes (D-t)
169 : LME_GEN_SYLVESTER A*X*E+D*X*B=C yes yes yes yes
170 : LME_DT_LYAPUNOV A*X*A'-X=-C yes - - (A-t)
171 : LME_STEIN A*X*E+X=C yes - - yes
172 : .ve
173 :
174 : In the above table, the notation (A-t) means that this matrix need
175 : not be passed, but the user may choose to pass an explicit transpose
176 : of matrix A (for improved efficiency).
177 :
178 : Also note that some of the equation types impose restrictions on the
179 : properties of the coefficient matrices and possibly on the right-hand
180 : side C.
181 :
182 : Level: beginner
183 :
184 : .seealso: LMESetCoefficients(), LMESetType(), LMEGetProblemType(), LMEProblemType
185 : @*/
186 11 : PetscErrorCode LMESetProblemType(LME lme,LMEProblemType type)
187 : {
188 11 : PetscFunctionBegin;
189 11 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
190 44 : PetscValidLogicalCollectiveEnum(lme,type,2);
191 11 : if (type == lme->problem_type) PetscFunctionReturn(PETSC_SUCCESS);
192 6 : switch (type) {
193 : case LME_LYAPUNOV:
194 : case LME_SYLVESTER:
195 : case LME_GEN_LYAPUNOV:
196 : case LME_GEN_SYLVESTER:
197 : case LME_DT_LYAPUNOV:
198 : case LME_STEIN:
199 6 : break;
200 0 : default:
201 0 : SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_WRONG,"Unknown matrix equation type");
202 : }
203 6 : lme->problem_type = type;
204 6 : lme->setupcalled = PETSC_FALSE;
205 6 : PetscFunctionReturn(PETSC_SUCCESS);
206 : }
207 :
208 : /*@
209 : LMEGetProblemType - Gets the matrix equation type from the LME object.
210 :
211 : Not Collective
212 :
213 : Input Parameter:
214 : . lme - the linear matrix equation solver context
215 :
216 : Output Parameter:
217 : . type - name of LME problem type
218 :
219 : Level: intermediate
220 :
221 : .seealso: LMESetProblemType(), LMEProblemType
222 : @*/
223 6 : PetscErrorCode LMEGetProblemType(LME lme,LMEProblemType *type)
224 : {
225 6 : PetscFunctionBegin;
226 6 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
227 6 : PetscAssertPointer(type,2);
228 6 : *type = lme->problem_type;
229 6 : PetscFunctionReturn(PETSC_SUCCESS);
230 : }
231 :
232 : /*@C
233 : LMEGetTolerances - Gets the tolerance and maximum iteration count used
234 : by the LME convergence tests.
235 :
236 : Not Collective
237 :
238 : Input Parameter:
239 : . lme - the linear matrix equation solver context
240 :
241 : Output Parameters:
242 : + tol - the convergence tolerance
243 : - maxits - maximum number of iterations
244 :
245 : Notes:
246 : The user can specify NULL for any parameter that is not needed.
247 :
248 : Level: intermediate
249 :
250 : .seealso: LMESetTolerances()
251 : @*/
252 5 : PetscErrorCode LMEGetTolerances(LME lme,PetscReal *tol,PetscInt *maxits)
253 : {
254 5 : PetscFunctionBegin;
255 5 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
256 5 : if (tol) *tol = lme->tol;
257 5 : if (maxits) *maxits = lme->max_it;
258 5 : PetscFunctionReturn(PETSC_SUCCESS);
259 : }
260 :
261 : /*@
262 : LMESetTolerances - Sets the tolerance and maximum iteration count used
263 : by the LME convergence tests.
264 :
265 : Logically Collective
266 :
267 : Input Parameters:
268 : + lme - the linear matrix equation solver context
269 : . tol - the convergence tolerance
270 : - maxits - maximum number of iterations to use
271 :
272 : Options Database Keys:
273 : + -lme_tol <tol> - Sets the convergence tolerance
274 : - -lme_max_it <maxits> - Sets the maximum number of iterations allowed
275 :
276 : Notes:
277 : Use PETSC_DEFAULT for either argument to assign a reasonably good value.
278 :
279 : Level: intermediate
280 :
281 : .seealso: LMEGetTolerances()
282 : @*/
283 5 : PetscErrorCode LMESetTolerances(LME lme,PetscReal tol,PetscInt maxits)
284 : {
285 5 : PetscFunctionBegin;
286 5 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
287 20 : PetscValidLogicalCollectiveReal(lme,tol,2);
288 20 : PetscValidLogicalCollectiveInt(lme,maxits,3);
289 5 : if (tol == (PetscReal)PETSC_DEFAULT) {
290 3 : lme->tol = PETSC_DEFAULT;
291 3 : lme->setupcalled = 0;
292 : } else {
293 2 : PetscCheck(tol>0.0,PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
294 2 : lme->tol = tol;
295 : }
296 5 : if (maxits == PETSC_DEFAULT || maxits == PETSC_DECIDE) {
297 2 : lme->max_it = PETSC_DEFAULT;
298 2 : lme->setupcalled = 0;
299 : } else {
300 3 : PetscCheck(maxits>0,PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
301 3 : lme->max_it = maxits;
302 : }
303 5 : PetscFunctionReturn(PETSC_SUCCESS);
304 : }
305 :
306 : /*@
307 : LMEGetDimensions - Gets the dimension of the subspace used by the solver.
308 :
309 : Not Collective
310 :
311 : Input Parameter:
312 : . lme - the linear matrix equation solver context
313 :
314 : Output Parameter:
315 : . ncv - the maximum dimension of the subspace to be used by the solver
316 :
317 : Level: intermediate
318 :
319 : .seealso: LMESetDimensions()
320 : @*/
321 5 : PetscErrorCode LMEGetDimensions(LME lme,PetscInt *ncv)
322 : {
323 5 : PetscFunctionBegin;
324 5 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
325 5 : PetscAssertPointer(ncv,2);
326 5 : *ncv = lme->ncv;
327 5 : PetscFunctionReturn(PETSC_SUCCESS);
328 : }
329 :
330 : /*@
331 : LMESetDimensions - Sets the dimension of the subspace to be used by the solver.
332 :
333 : Logically Collective
334 :
335 : Input Parameters:
336 : + lme - the linear matrix equation solver context
337 : - ncv - the maximum dimension of the subspace to be used by the solver
338 :
339 : Options Database Keys:
340 : . -lme_ncv <ncv> - Sets the dimension of the subspace
341 :
342 : Notes:
343 : Use PETSC_DEFAULT for ncv to assign a reasonably good value, which is
344 : dependent on the solution method.
345 :
346 : Level: intermediate
347 :
348 : .seealso: LMEGetDimensions()
349 : @*/
350 3 : PetscErrorCode LMESetDimensions(LME lme,PetscInt ncv)
351 : {
352 3 : PetscFunctionBegin;
353 3 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
354 12 : PetscValidLogicalCollectiveInt(lme,ncv,2);
355 3 : if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
356 0 : lme->ncv = PETSC_DEFAULT;
357 : } else {
358 3 : PetscCheck(ncv>0,PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
359 3 : lme->ncv = ncv;
360 : }
361 3 : lme->setupcalled = 0;
362 3 : PetscFunctionReturn(PETSC_SUCCESS);
363 : }
364 :
365 : /*@
366 : LMESetErrorIfNotConverged - Causes LMESolve() to generate an error if the
367 : solver has not converged.
368 :
369 : Logically Collective
370 :
371 : Input Parameters:
372 : + lme - the linear matrix equation solver context
373 : - flg - PETSC_TRUE indicates you want the error generated
374 :
375 : Options Database Keys:
376 : . -lme_error_if_not_converged - this takes an optional truth value (0/1/no/yes/true/false)
377 :
378 : Level: intermediate
379 :
380 : Note:
381 : Normally SLEPc continues if the solver fails to converge, you can call
382 : LMEGetConvergedReason() after a LMESolve() to determine if it has converged.
383 :
384 : .seealso: LMEGetErrorIfNotConverged()
385 : @*/
386 6 : PetscErrorCode LMESetErrorIfNotConverged(LME lme,PetscBool flg)
387 : {
388 6 : PetscFunctionBegin;
389 6 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
390 24 : PetscValidLogicalCollectiveBool(lme,flg,2);
391 6 : lme->errorifnotconverged = flg;
392 6 : PetscFunctionReturn(PETSC_SUCCESS);
393 : }
394 :
395 : /*@
396 : LMEGetErrorIfNotConverged - Return a flag indicating whether LMESolve() will
397 : generate an error if the solver does not converge.
398 :
399 : Not Collective
400 :
401 : Input Parameter:
402 : . lme - the linear matrix equation solver context
403 :
404 : Output Parameter:
405 : . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
406 :
407 : Level: intermediate
408 :
409 : .seealso: LMESetErrorIfNotConverged()
410 : @*/
411 3 : PetscErrorCode LMEGetErrorIfNotConverged(LME lme,PetscBool *flag)
412 : {
413 3 : PetscFunctionBegin;
414 3 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
415 3 : PetscAssertPointer(flag,2);
416 3 : *flag = lme->errorifnotconverged;
417 3 : PetscFunctionReturn(PETSC_SUCCESS);
418 : }
419 :
420 : /*@C
421 : LMESetOptionsPrefix - Sets the prefix used for searching for all
422 : LME options in the database.
423 :
424 : Logically Collective
425 :
426 : Input Parameters:
427 : + lme - the linear matrix equation solver context
428 : - prefix - the prefix string to prepend to all LME option requests
429 :
430 : Notes:
431 : A hyphen (-) must NOT be given at the beginning of the prefix name.
432 : The first character of all runtime options is AUTOMATICALLY the
433 : hyphen.
434 :
435 : For example, to distinguish between the runtime options for two
436 : different LME contexts, one could call
437 : .vb
438 : LMESetOptionsPrefix(lme1,"fun1_")
439 : LMESetOptionsPrefix(lme2,"fun2_")
440 : .ve
441 :
442 : Level: advanced
443 :
444 : .seealso: LMEAppendOptionsPrefix(), LMEGetOptionsPrefix()
445 : @*/
446 4 : PetscErrorCode LMESetOptionsPrefix(LME lme,const char *prefix)
447 : {
448 4 : PetscFunctionBegin;
449 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
450 4 : if (!lme->V) PetscCall(LMEGetBV(lme,&lme->V));
451 4 : PetscCall(BVSetOptionsPrefix(lme->V,prefix));
452 4 : PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lme,prefix));
453 4 : PetscFunctionReturn(PETSC_SUCCESS);
454 : }
455 :
456 : /*@C
457 : LMEAppendOptionsPrefix - Appends to the prefix used for searching for all
458 : LME options in the database.
459 :
460 : Logically Collective
461 :
462 : Input Parameters:
463 : + lme - the linear matrix equation solver context
464 : - prefix - the prefix string to prepend to all LME option requests
465 :
466 : Notes:
467 : A hyphen (-) must NOT be given at the beginning of the prefix name.
468 : The first character of all runtime options is AUTOMATICALLY the hyphen.
469 :
470 : Level: advanced
471 :
472 : .seealso: LMESetOptionsPrefix(), LMEGetOptionsPrefix()
473 : @*/
474 4 : PetscErrorCode LMEAppendOptionsPrefix(LME lme,const char *prefix)
475 : {
476 4 : PetscFunctionBegin;
477 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
478 4 : if (!lme->V) PetscCall(LMEGetBV(lme,&lme->V));
479 4 : PetscCall(BVAppendOptionsPrefix(lme->V,prefix));
480 4 : PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)lme,prefix));
481 4 : PetscFunctionReturn(PETSC_SUCCESS);
482 : }
483 :
484 : /*@C
485 : LMEGetOptionsPrefix - Gets the prefix used for searching for all
486 : LME options in the database.
487 :
488 : Not Collective
489 :
490 : Input Parameters:
491 : . lme - the linear matrix equation solver context
492 :
493 : Output Parameters:
494 : . prefix - pointer to the prefix string used is returned
495 :
496 : Note:
497 : On the Fortran side, the user should pass in a string 'prefix' of
498 : sufficient length to hold the prefix.
499 :
500 : Level: advanced
501 :
502 : .seealso: LMESetOptionsPrefix(), LMEAppendOptionsPrefix()
503 : @*/
504 1 : PetscErrorCode LMEGetOptionsPrefix(LME lme,const char *prefix[])
505 : {
506 1 : PetscFunctionBegin;
507 1 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
508 1 : PetscAssertPointer(prefix,2);
509 1 : PetscCall(PetscObjectGetOptionsPrefix((PetscObject)lme,prefix));
510 1 : PetscFunctionReturn(PETSC_SUCCESS);
511 : }
|