Actual source code: lmebasic.c
slepc-3.8.0 2017-10-20
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2017, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7: SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9: */
10: /*
11: Basic LME routines
12: */
14: #include <slepc/private/lmeimpl.h> /*I "slepclme.h" I*/
16: PetscFunctionList LMEList = 0;
17: PetscBool LMERegisterAllCalled = PETSC_FALSE;
18: PetscClassId LME_CLASSID = 0;
19: PetscLogEvent LME_SetUp = 0,LME_Solve = 0,LME_ComputeError = 0;
21: /*@C
22: LMEView - Prints the LME data structure.
24: Collective on LME
26: Input Parameters:
27: + lme - the linear matrix equation solver context
28: - viewer - optional visualization context
30: Options Database Key:
31: . -lme_view - Calls LMEView() at end of LMESolve()
33: Note:
34: The available visualization contexts include
35: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
36: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
37: output where only the first processor opens
38: the file. All other processors send their
39: data to the first processor to print.
41: The user can open an alternative visualization context with
42: PetscViewerASCIIOpen() - output to a specified file.
44: Level: beginner
46: .seealso: PetscViewerASCIIOpen()
47: @*/
48: PetscErrorCode LMEView(LME lme,PetscViewer viewer)
49: {
51: PetscBool isascii;
52: const char *eqname[] = {
53: "continuous-time Lyapunov",
54: "continuous-time Sylvester",
55: "generalized Lyapunov",
56: "generalized Sylvester",
57: "Stein",
58: "discrete-time Lyapunov"
59: };
63: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)lme));
67: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
68: if (isascii) {
69: PetscObjectPrintClassNamePrefixType((PetscObject)lme,viewer);
70: if (lme->ops->view) {
71: PetscViewerASCIIPushTab(viewer);
72: (*lme->ops->view)(lme,viewer);
73: PetscViewerASCIIPopTab(viewer);
74: }
75: PetscViewerASCIIPrintf(viewer," equation type: %s\n",eqname[lme->problem_type]);
76: PetscViewerASCIIPrintf(viewer," number of column vectors (ncv): %D\n",lme->ncv);
77: PetscViewerASCIIPrintf(viewer," maximum number of iterations: %D\n",lme->max_it);
78: PetscViewerASCIIPrintf(viewer," tolerance: %g\n",(double)lme->tol);
79: } else {
80: if (lme->ops->view) {
81: (*lme->ops->view)(lme,viewer);
82: }
83: }
84: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
85: if (!lme->V) { LMEGetBV(lme,&lme->V); }
86: BVView(lme->V,viewer);
87: PetscViewerPopFormat(viewer);
88: return(0);
89: }
91: /*@C
92: LMEReasonView - Displays the reason an LME solve converged or diverged.
94: Collective on LME
96: Parameter:
97: + lme - the linear matrix equation context
98: - viewer - the viewer to display the reason
100: Options Database Keys:
101: . -lme_converged_reason - print reason for convergence, and number of iterations
103: Level: intermediate
105: .seealso: LMESetTolerances(), LMEGetIterationNumber()
106: @*/
107: PetscErrorCode LMEReasonView(LME lme,PetscViewer viewer)
108: {
110: PetscBool isAscii;
113: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
114: if (isAscii) {
115: PetscViewerASCIIAddTab(viewer,((PetscObject)lme)->tablevel);
116: if (lme->reason > 0) {
117: PetscViewerASCIIPrintf(viewer,"%s Linear matrix equation solve converged due to %s; iterations %D\n",((PetscObject)lme)->prefix?((PetscObject)lme)->prefix:"",LMEConvergedReasons[lme->reason],lme->its);
118: } else {
119: PetscViewerASCIIPrintf(viewer,"%s Linear matrix equation solve did not converge due to %s; iterations %D\n",((PetscObject)lme)->prefix?((PetscObject)lme)->prefix:"",LMEConvergedReasons[lme->reason],lme->its);
120: }
121: PetscViewerASCIISubtractTab(viewer,((PetscObject)lme)->tablevel);
122: }
123: return(0);
124: }
126: /*@
127: LMEReasonViewFromOptions - Processes command line options to determine if/how
128: the LME converged reason is to be viewed.
130: Collective on LME
132: Input Parameters:
133: . lme - the linear matrix equation context
135: Level: developer
136: @*/
137: PetscErrorCode LMEReasonViewFromOptions(LME lme)
138: {
139: PetscErrorCode ierr;
140: PetscViewer viewer;
141: PetscBool flg;
142: static PetscBool incall = PETSC_FALSE;
143: PetscViewerFormat format;
146: if (incall) return(0);
147: incall = PETSC_TRUE;
148: PetscOptionsGetViewer(PetscObjectComm((PetscObject)lme),((PetscObject)lme)->prefix,"-lme_converged_reason",&viewer,&format,&flg);
149: if (flg) {
150: PetscViewerPushFormat(viewer,format);
151: LMEReasonView(lme,viewer);
152: PetscViewerPopFormat(viewer);
153: PetscViewerDestroy(&viewer);
154: }
155: incall = PETSC_FALSE;
156: return(0);
157: }
159: /*@
160: LMECreate - Creates the default LME context.
162: Collective on MPI_Comm
164: Input Parameter:
165: . comm - MPI communicator
167: Output Parameter:
168: . lme - location to put the LME context
170: Note:
171: The default LME type is LMEKRYLOV
173: Level: beginner
175: .seealso: LMESetUp(), LMESolve(), LMEDestroy(), LME
176: @*/
177: PetscErrorCode LMECreate(MPI_Comm comm,LME *outlme)
178: {
180: LME lme;
184: *outlme = 0;
185: LMEInitializePackage();
186: SlepcHeaderCreate(lme,LME_CLASSID,"LME","Linear Matrix Equation","LME",comm,LMEDestroy,LMEView);
188: lme->A = NULL;
189: lme->B = NULL;
190: lme->D = NULL;
191: lme->E = NULL;
192: lme->C = NULL;
193: lme->X = NULL;
194: lme->problem_type = LME_LYAPUNOV;
195: lme->max_it = 0;
196: lme->ncv = 0;
197: lme->tol = PETSC_DEFAULT;
198: lme->errorifnotconverged = PETSC_FALSE;
200: lme->numbermonitors = 0;
202: lme->V = NULL;
203: lme->nwork = 0;
204: lme->work = NULL;
205: lme->data = NULL;
207: lme->its = 0;
208: lme->errest = 0;
209: lme->setupcalled = 0;
210: lme->reason = LME_CONVERGED_ITERATING;
212: *outlme = lme;
213: return(0);
214: }
216: /*@C
217: LMESetType - Selects the particular solver to be used in the LME object.
219: Logically Collective on LME
221: Input Parameters:
222: + lme - the linear matrix equation context
223: - type - a known method
225: Options Database Key:
226: . -lme_type <method> - Sets the method; use -help for a list
227: of available methods
229: Notes:
230: See "slepc/include/slepclme.h" for available methods. The default
231: is LMEKRYLOV
233: Normally, it is best to use the LMESetFromOptions() command and
234: then set the LME type from the options database rather than by using
235: this routine. Using the options database provides the user with
236: maximum flexibility in evaluating the different available methods.
237: The LMESetType() routine is provided for those situations where it
238: is necessary to set the iterative solver independently of the command
239: line or options database.
241: Level: intermediate
243: .seealso: LMEType
244: @*/
245: PetscErrorCode LMESetType(LME lme,LMEType type)
246: {
247: PetscErrorCode ierr,(*r)(LME);
248: PetscBool match;
254: PetscObjectTypeCompare((PetscObject)lme,type,&match);
255: if (match) return(0);
257: PetscFunctionListFind(LMEList,type,&r);
258: if (!r) SETERRQ1(PetscObjectComm((PetscObject)lme),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown LME type given: %s",type);
260: if (lme->ops->destroy) { (*lme->ops->destroy)(lme); }
261: PetscMemzero(lme->ops,sizeof(struct _LMEOps));
263: lme->setupcalled = 0;
264: PetscObjectChangeTypeName((PetscObject)lme,type);
265: (*r)(lme);
266: return(0);
267: }
269: /*@C
270: LMEGetType - Gets the LME type as a string from the LME object.
272: Not Collective
274: Input Parameter:
275: . lme - the linear matrix equation context
277: Output Parameter:
278: . name - name of LME method
280: Level: intermediate
282: .seealso: LMESetType()
283: @*/
284: PetscErrorCode LMEGetType(LME lme,LMEType *type)
285: {
289: *type = ((PetscObject)lme)->type_name;
290: return(0);
291: }
293: /*@C
294: LMERegister - Adds a method to the linear matrix equation solver package.
296: Not Collective
298: Input Parameters:
299: + name - name of a new user-defined solver
300: - function - routine to create the solver context
302: Notes:
303: LMERegister() may be called multiple times to add several user-defined solvers.
305: Sample usage:
306: .vb
307: LMERegister("my_solver",MySolverCreate);
308: .ve
310: Then, your solver can be chosen with the procedural interface via
311: $ LMESetType(lme,"my_solver")
312: or at runtime via the option
313: $ -lme_type my_solver
315: Level: advanced
317: .seealso: LMERegisterAll()
318: @*/
319: PetscErrorCode LMERegister(const char *name,PetscErrorCode (*function)(LME))
320: {
324: PetscFunctionListAdd(&LMEList,name,function);
325: return(0);
326: }
328: /*@
329: LMEReset - Resets the LME context to the initial state (prior to setup)
330: and destroys any allocated Vecs and Mats.
332: Collective on LME
334: Input Parameter:
335: . lme - linear matrix equation context obtained from LMECreate()
337: Level: advanced
339: .seealso: LMEDestroy()
340: @*/
341: PetscErrorCode LMEReset(LME lme)
342: {
347: if (!lme) return(0);
348: if (lme->ops->reset) { (lme->ops->reset)(lme); }
349: MatDestroy(&lme->A);
350: MatDestroy(&lme->B);
351: MatDestroy(&lme->D);
352: MatDestroy(&lme->E);
353: MatDestroy(&lme->C);
354: MatDestroy(&lme->X);
355: BVDestroy(&lme->V);
356: VecDestroyVecs(lme->nwork,&lme->work);
357: lme->nwork = 0;
358: lme->setupcalled = 0;
359: return(0);
360: }
362: /*@
363: LMEDestroy - Destroys the LME context.
365: Collective on LME
367: Input Parameter:
368: . lme - linear matrix equation context obtained from LMECreate()
370: Level: beginner
372: .seealso: LMECreate(), LMESetUp(), LMESolve()
373: @*/
374: PetscErrorCode LMEDestroy(LME *lme)
375: {
379: if (!*lme) return(0);
381: if (--((PetscObject)(*lme))->refct > 0) { *lme = 0; return(0); }
382: LMEReset(*lme);
383: if ((*lme)->ops->destroy) { (*(*lme)->ops->destroy)(*lme); }
384: LMEMonitorCancel(*lme);
385: PetscHeaderDestroy(lme);
386: return(0);
387: }
389: /*@
390: LMESetBV - Associates a basis vectors object to the linear matrix equation solver.
392: Collective on LME
394: Input Parameters:
395: + lme - linear matrix equation context obtained from LMECreate()
396: - bv - the basis vectors object
398: Note:
399: Use LMEGetBV() to retrieve the basis vectors context (for example,
400: to free it at the end of the computations).
402: Level: advanced
404: .seealso: LMEGetBV()
405: @*/
406: PetscErrorCode LMESetBV(LME lme,BV bv)
407: {
414: PetscObjectReference((PetscObject)bv);
415: BVDestroy(&lme->V);
416: lme->V = bv;
417: PetscLogObjectParent((PetscObject)lme,(PetscObject)lme->V);
418: return(0);
419: }
421: /*@
422: LMEGetBV - Obtain the basis vectors object associated to the matrix
423: function solver.
425: Not Collective
427: Input Parameters:
428: . lme - linear matrix equation context obtained from LMECreate()
430: Output Parameter:
431: . bv - basis vectors context
433: Level: advanced
435: .seealso: LMESetBV()
436: @*/
437: PetscErrorCode LMEGetBV(LME lme,BV *bv)
438: {
444: if (!lme->V) {
445: BVCreate(PetscObjectComm((PetscObject)lme),&lme->V);
446: PetscLogObjectParent((PetscObject)lme,(PetscObject)lme->V);
447: }
448: *bv = lme->V;
449: return(0);
450: }