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 7 : PetscErrorCode LMEMonitorSetFromOptions(LME lme,const char opt[],const char name[],void *ctx)
35 : {
36 7 : PetscErrorCode (*mfunc)(LME,PetscInt,PetscReal,void*);
37 7 : PetscErrorCode (*cfunc)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**);
38 7 : PetscErrorCode (*dfunc)(PetscViewerAndFormat**);
39 7 : PetscViewerAndFormat *vf;
40 7 : PetscViewer viewer;
41 7 : PetscViewerFormat format;
42 7 : PetscViewerType vtype;
43 7 : char key[PETSC_MAX_PATH_LEN];
44 7 : PetscBool flg;
45 :
46 7 : PetscFunctionBegin;
47 7 : PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)lme),((PetscObject)lme)->options,((PetscObject)lme)->prefix,opt,&viewer,&format,&flg));
48 7 : if (!flg) PetscFunctionReturn(PETSC_SUCCESS);
49 :
50 1 : PetscCall(PetscViewerGetType(viewer,&vtype));
51 1 : PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
52 1 : PetscCall(PetscFunctionListFind(LMEMonitorList,key,&mfunc));
53 1 : PetscCheck(mfunc,PetscObjectComm((PetscObject)lme),PETSC_ERR_SUP,"Specified viewer and format not supported");
54 1 : PetscCall(PetscFunctionListFind(LMEMonitorCreateList,key,&cfunc));
55 1 : PetscCall(PetscFunctionListFind(LMEMonitorDestroyList,key,&dfunc));
56 1 : if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
57 1 : if (!dfunc) dfunc = PetscViewerAndFormatDestroy;
58 :
59 1 : PetscCall((*cfunc)(viewer,format,ctx,&vf));
60 1 : PetscCall(PetscViewerDestroy(&viewer));
61 1 : PetscCall(LMEMonitorSet(lme,mfunc,vf,(PetscErrorCode(*)(void **))dfunc));
62 1 : 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 7 : PetscErrorCode LMESetFromOptions(LME lme)
83 : {
84 7 : char type[256];
85 7 : PetscBool set,flg,flg1,flg2;
86 7 : PetscReal r;
87 7 : PetscInt i;
88 :
89 7 : PetscFunctionBegin;
90 7 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
91 7 : PetscCall(LMERegisterAll());
92 21 : PetscObjectOptionsBegin((PetscObject)lme);
93 7 : PetscCall(PetscOptionsFList("-lme_type","Linear matrix equation","LMESetType",LMEList,(char*)(((PetscObject)lme)->type_name?((PetscObject)lme)->type_name:LMEKRYLOV),type,sizeof(type),&flg));
94 7 : if (flg) PetscCall(LMESetType(lme,type));
95 7 : else if (!((PetscObject)lme)->type_name) PetscCall(LMESetType(lme,LMEKRYLOV));
96 :
97 7 : PetscCall(PetscOptionsBoolGroupBegin("-lme_lyapunov","Continuous-time Lyapunov equation","LMESetProblemType",&flg));
98 7 : if (flg) PetscCall(LMESetProblemType(lme,LME_LYAPUNOV));
99 7 : PetscCall(PetscOptionsBoolGroup("-lme_sylvester","Continuous-time Sylvester equation","LMESetProblemType",&flg));
100 7 : if (flg) PetscCall(LMESetProblemType(lme,LME_SYLVESTER));
101 7 : PetscCall(PetscOptionsBoolGroup("-lme_gen_lyapunov","Generalized Lyapunov equation","LMESetProblemType",&flg));
102 7 : if (flg) PetscCall(LMESetProblemType(lme,LME_GEN_LYAPUNOV));
103 7 : PetscCall(PetscOptionsBoolGroup("-lme_gen_sylvester","Generalized Sylvester equation","LMESetProblemType",&flg));
104 7 : if (flg) PetscCall(LMESetProblemType(lme,LME_GEN_SYLVESTER));
105 7 : PetscCall(PetscOptionsBoolGroup("-lme_dt_lyapunov","Discrete-time Lyapunov equation","LMESetProblemType",&flg));
106 7 : if (flg) PetscCall(LMESetProblemType(lme,LME_DT_LYAPUNOV));
107 7 : PetscCall(PetscOptionsBoolGroupEnd("-lme_stein","Stein equation","LMESetProblemType",&flg));
108 7 : if (flg) PetscCall(LMESetProblemType(lme,LME_STEIN));
109 :
110 7 : i = lme->max_it;
111 7 : PetscCall(PetscOptionsInt("-lme_max_it","Maximum number of iterations","LMESetTolerances",lme->max_it,&i,&flg1));
112 7 : if (!flg1) i = PETSC_DETERMINE;
113 7 : r = lme->tol;
114 12 : PetscCall(PetscOptionsReal("-lme_tol","Tolerance","LMESetTolerances",SlepcDefaultTol(lme->tol),&r,&flg2));
115 7 : if (flg1 || flg2) PetscCall(LMESetTolerances(lme,r,i));
116 :
117 7 : PetscCall(PetscOptionsInt("-lme_ncv","Number of basis vectors","LMESetDimensions",lme->ncv,&i,&flg));
118 7 : if (flg) PetscCall(LMESetDimensions(lme,i));
119 :
120 7 : 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 7 : PetscCall(PetscOptionsBool("-lme_monitor_cancel","Remove any hardwired monitor routines","LMEMonitorCancel",PETSC_FALSE,&flg,&set));
127 7 : if (set && flg) PetscCall(LMEMonitorCancel(lme));
128 7 : PetscCall(LMEMonitorSetFromOptions(lme,"-lme_monitor","error_estimate",NULL));
129 :
130 : /* -----------------------------------------------------------------------*/
131 7 : PetscCall(PetscOptionsName("-lme_view","Print detailed information on solver used","LMEView",&set));
132 :
133 7 : PetscTryTypeMethod(lme,setfromoptions,PetscOptionsObject);
134 7 : PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)lme,PetscOptionsObject));
135 7 : PetscOptionsEnd();
136 :
137 7 : if (!lme->V) PetscCall(LMEGetBV(lme,&lme->V));
138 7 : PetscCall(BVSetFromOptions(lme->V));
139 7 : 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 9 : PetscErrorCode LMESetProblemType(LME lme,LMEProblemType type)
187 : {
188 9 : PetscFunctionBegin;
189 9 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
190 27 : PetscValidLogicalCollectiveEnum(lme,type,2);
191 9 : if (type == lme->problem_type) PetscFunctionReturn(PETSC_SUCCESS);
192 4 : 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 4 : break;
200 0 : default:
201 0 : SETERRQ(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_WRONG,"Unknown matrix equation type");
202 : }
203 4 : lme->problem_type = type;
204 4 : lme->setupcalled = PETSC_FALSE;
205 4 : 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 4 : PetscErrorCode LMEGetProblemType(LME lme,LMEProblemType *type)
224 : {
225 4 : PetscFunctionBegin;
226 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
227 4 : PetscAssertPointer(type,2);
228 4 : *type = lme->problem_type;
229 4 : PetscFunctionReturn(PETSC_SUCCESS);
230 : }
231 :
232 : /*@
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 4 : PetscErrorCode LMEGetTolerances(LME lme,PetscReal *tol,PetscInt *maxits)
253 : {
254 4 : PetscFunctionBegin;
255 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
256 4 : if (tol) *tol = lme->tol;
257 4 : if (maxits) *maxits = lme->max_it;
258 4 : 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_CURRENT to retain the current value of any of the parameters.
278 : Use PETSC_DETERMINE for either argument to assign a default value computed
279 : internally (may be different in each solver).
280 : For maxits use PETSC_UMLIMITED to indicate there is no upper bound on this value.
281 :
282 : Level: intermediate
283 :
284 : .seealso: LMEGetTolerances()
285 : @*/
286 4 : PetscErrorCode LMESetTolerances(LME lme,PetscReal tol,PetscInt maxits)
287 : {
288 4 : PetscFunctionBegin;
289 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
290 12 : PetscValidLogicalCollectiveReal(lme,tol,2);
291 12 : PetscValidLogicalCollectiveInt(lme,maxits,3);
292 4 : if (tol == (PetscReal)PETSC_DETERMINE) {
293 0 : lme->tol = PETSC_DETERMINE;
294 0 : lme->setupcalled = 0;
295 4 : } else if (tol != (PetscReal)PETSC_CURRENT) {
296 2 : PetscCheck(tol>0.0,PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of tol. Must be > 0");
297 2 : lme->tol = tol;
298 : }
299 4 : if (maxits == PETSC_DETERMINE) {
300 0 : lme->max_it = PETSC_DETERMINE;
301 0 : lme->setupcalled = 0;
302 4 : } else if (maxits == PETSC_UNLIMITED) {
303 0 : lme->max_it = PETSC_INT_MAX;
304 4 : } else if (maxits != PETSC_CURRENT) {
305 2 : PetscCheck(maxits>0,PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of maxits. Must be > 0");
306 2 : lme->max_it = maxits;
307 : }
308 4 : PetscFunctionReturn(PETSC_SUCCESS);
309 : }
310 :
311 : /*@
312 : LMEGetDimensions - Gets the dimension of the subspace used by the solver.
313 :
314 : Not Collective
315 :
316 : Input Parameter:
317 : . lme - the linear matrix equation solver context
318 :
319 : Output Parameter:
320 : . ncv - the maximum dimension of the subspace to be used by the solver
321 :
322 : Level: intermediate
323 :
324 : .seealso: LMESetDimensions()
325 : @*/
326 4 : PetscErrorCode LMEGetDimensions(LME lme,PetscInt *ncv)
327 : {
328 4 : PetscFunctionBegin;
329 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
330 4 : PetscAssertPointer(ncv,2);
331 4 : *ncv = lme->ncv;
332 4 : PetscFunctionReturn(PETSC_SUCCESS);
333 : }
334 :
335 : /*@
336 : LMESetDimensions - Sets the dimension of the subspace to be used by the solver.
337 :
338 : Logically Collective
339 :
340 : Input Parameters:
341 : + lme - the linear matrix equation solver context
342 : - ncv - the maximum dimension of the subspace to be used by the solver
343 :
344 : Options Database Keys:
345 : . -lme_ncv <ncv> - Sets the dimension of the subspace
346 :
347 : Notes:
348 : Use PETSC_DETERMINE for ncv to assign a reasonably good value, which is
349 : dependent on the solution method.
350 :
351 : Level: intermediate
352 :
353 : .seealso: LMEGetDimensions()
354 : @*/
355 2 : PetscErrorCode LMESetDimensions(LME lme,PetscInt ncv)
356 : {
357 2 : PetscFunctionBegin;
358 2 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
359 6 : PetscValidLogicalCollectiveInt(lme,ncv,2);
360 2 : if (ncv == PETSC_DECIDE || ncv == PETSC_DEFAULT) {
361 0 : lme->ncv = PETSC_DETERMINE;
362 : } else {
363 2 : PetscCheck(ncv>0,PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ncv. Must be > 0");
364 2 : lme->ncv = ncv;
365 : }
366 2 : lme->setupcalled = 0;
367 2 : PetscFunctionReturn(PETSC_SUCCESS);
368 : }
369 :
370 : /*@
371 : LMESetErrorIfNotConverged - Causes LMESolve() to generate an error if the
372 : solver has not converged.
373 :
374 : Logically Collective
375 :
376 : Input Parameters:
377 : + lme - the linear matrix equation solver context
378 : - flg - PETSC_TRUE indicates you want the error generated
379 :
380 : Options Database Keys:
381 : . -lme_error_if_not_converged - this takes an optional truth value (0/1/no/yes/true/false)
382 :
383 : Level: intermediate
384 :
385 : Note:
386 : Normally SLEPc continues if the solver fails to converge, you can call
387 : LMEGetConvergedReason() after a LMESolve() to determine if it has converged.
388 :
389 : .seealso: LMEGetErrorIfNotConverged()
390 : @*/
391 5 : PetscErrorCode LMESetErrorIfNotConverged(LME lme,PetscBool flg)
392 : {
393 5 : PetscFunctionBegin;
394 5 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
395 15 : PetscValidLogicalCollectiveBool(lme,flg,2);
396 5 : lme->errorifnotconverged = flg;
397 5 : PetscFunctionReturn(PETSC_SUCCESS);
398 : }
399 :
400 : /*@
401 : LMEGetErrorIfNotConverged - Return a flag indicating whether LMESolve() will
402 : generate an error if the solver does not converge.
403 :
404 : Not Collective
405 :
406 : Input Parameter:
407 : . lme - the linear matrix equation solver context
408 :
409 : Output Parameter:
410 : . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
411 :
412 : Level: intermediate
413 :
414 : .seealso: LMESetErrorIfNotConverged()
415 : @*/
416 2 : PetscErrorCode LMEGetErrorIfNotConverged(LME lme,PetscBool *flag)
417 : {
418 2 : PetscFunctionBegin;
419 2 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
420 2 : PetscAssertPointer(flag,2);
421 2 : *flag = lme->errorifnotconverged;
422 2 : PetscFunctionReturn(PETSC_SUCCESS);
423 : }
424 :
425 : /*@
426 : LMESetOptionsPrefix - Sets the prefix used for searching for all
427 : LME options in the database.
428 :
429 : Logically Collective
430 :
431 : Input Parameters:
432 : + lme - the linear matrix equation solver context
433 : - prefix - the prefix string to prepend to all LME option requests
434 :
435 : Notes:
436 : A hyphen (-) must NOT be given at the beginning of the prefix name.
437 : The first character of all runtime options is AUTOMATICALLY the
438 : hyphen.
439 :
440 : For example, to distinguish between the runtime options for two
441 : different LME contexts, one could call
442 : .vb
443 : LMESetOptionsPrefix(lme1,"fun1_")
444 : LMESetOptionsPrefix(lme2,"fun2_")
445 : .ve
446 :
447 : Level: advanced
448 :
449 : .seealso: LMEAppendOptionsPrefix(), LMEGetOptionsPrefix()
450 : @*/
451 4 : PetscErrorCode LMESetOptionsPrefix(LME lme,const char *prefix)
452 : {
453 4 : PetscFunctionBegin;
454 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
455 4 : if (!lme->V) PetscCall(LMEGetBV(lme,&lme->V));
456 4 : PetscCall(BVSetOptionsPrefix(lme->V,prefix));
457 4 : PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lme,prefix));
458 4 : PetscFunctionReturn(PETSC_SUCCESS);
459 : }
460 :
461 : /*@
462 : LMEAppendOptionsPrefix - Appends to the prefix used for searching for all
463 : LME options in the database.
464 :
465 : Logically Collective
466 :
467 : Input Parameters:
468 : + lme - the linear matrix equation solver context
469 : - prefix - the prefix string to prepend to all LME option requests
470 :
471 : Notes:
472 : A hyphen (-) must NOT be given at the beginning of the prefix name.
473 : The first character of all runtime options is AUTOMATICALLY the hyphen.
474 :
475 : Level: advanced
476 :
477 : .seealso: LMESetOptionsPrefix(), LMEGetOptionsPrefix()
478 : @*/
479 4 : PetscErrorCode LMEAppendOptionsPrefix(LME lme,const char *prefix)
480 : {
481 4 : PetscFunctionBegin;
482 4 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
483 4 : if (!lme->V) PetscCall(LMEGetBV(lme,&lme->V));
484 4 : PetscCall(BVAppendOptionsPrefix(lme->V,prefix));
485 4 : PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)lme,prefix));
486 4 : PetscFunctionReturn(PETSC_SUCCESS);
487 : }
488 :
489 : /*@
490 : LMEGetOptionsPrefix - Gets the prefix used for searching for all
491 : LME options in the database.
492 :
493 : Not Collective
494 :
495 : Input Parameters:
496 : . lme - the linear matrix equation solver context
497 :
498 : Output Parameters:
499 : . prefix - pointer to the prefix string used is returned
500 :
501 : Note:
502 : On the Fortran side, the user should pass in a string 'prefix' of
503 : sufficient length to hold the prefix.
504 :
505 : Level: advanced
506 :
507 : .seealso: LMESetOptionsPrefix(), LMEAppendOptionsPrefix()
508 : @*/
509 1 : PetscErrorCode LMEGetOptionsPrefix(LME lme,const char *prefix[])
510 : {
511 1 : PetscFunctionBegin;
512 1 : PetscValidHeaderSpecific(lme,LME_CLASSID,1);
513 1 : PetscAssertPointer(prefix,2);
514 1 : PetscCall(PetscObjectGetOptionsPrefix((PetscObject)lme,prefix));
515 1 : PetscFunctionReturn(PETSC_SUCCESS);
516 : }
|