1: /*
2: The basic MFN routines, Create, View, etc. are here.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2016, Universitat Politecnica de Valencia, Spain
8: This file is part of SLEPc.
10: SLEPc is free software: you can redistribute it and/or modify it under the
11: terms of version 3 of the GNU Lesser General Public License as published by
12: the Free Software Foundation.
14: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
15: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17: more details.
19: You should have received a copy of the GNU Lesser General Public License
20: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22: */
24: #include <slepc/private/mfnimpl.h> /*I "slepcmfn.h" I*/
26: PetscFunctionList MFNList = 0;
27: PetscBool MFNRegisterAllCalled = PETSC_FALSE;
28: PetscClassId MFN_CLASSID = 0;
29: PetscLogEvent MFN_SetUp = 0,MFN_Solve = 0;
33: /*@C
34: MFNView - Prints the MFN data structure.
36: Collective on MFN 38: Input Parameters:
39: + mfn - the matrix function solver context
40: - viewer - optional visualization context
42: Options Database Key:
43: . -mfn_view - Calls MFNView() at end of MFNSolve()
45: Note:
46: The available visualization contexts include
47: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
48: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
49: output where only the first processor opens
50: the file. All other processors send their
51: data to the first processor to print.
53: The user can open an alternative visualization context with
54: PetscViewerASCIIOpen() - output to a specified file.
56: Level: beginner
58: .seealso: PetscViewerASCIIOpen()
59: @*/
60: PetscErrorCode MFNView(MFN mfn,PetscViewer viewer) 61: {
63: PetscBool isascii;
67: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)mfn));
71: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
72: if (isascii) {
73: PetscObjectPrintClassNamePrefixType((PetscObject)mfn,viewer);
74: if (mfn->ops->view) {
75: PetscViewerASCIIPushTab(viewer);
76: (*mfn->ops->view)(mfn,viewer);
77: PetscViewerASCIIPopTab(viewer);
78: }
79: PetscViewerASCIIPrintf(viewer," number of column vectors (ncv): %D\n",mfn->ncv);
80: PetscViewerASCIIPrintf(viewer," maximum number of iterations: %D\n",mfn->max_it);
81: PetscViewerASCIIPrintf(viewer," tolerance: %g\n",(double)mfn->tol);
82: } else {
83: if (mfn->ops->view) {
84: (*mfn->ops->view)(mfn,viewer);
85: }
86: }
87: PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
88: if (!mfn->V) { MFNGetFN(mfn,&mfn->fn); }
89: FNView(mfn->fn,viewer);
90: if (!mfn->V) { MFNGetBV(mfn,&mfn->V); }
91: BVView(mfn->V,viewer);
92: PetscViewerPopFormat(viewer);
93: return(0);
94: }
98: /*@C
99: MFNReasonView - Displays the reason an MFN solve converged or diverged.
101: Collective on MFN103: Parameter:
104: + mfn - the matrix function context
105: - viewer - the viewer to display the reason
107: Options Database Keys:
108: . -mfn_converged_reason - print reason for convergence, and number of iterations
110: Level: intermediate
112: .seealso: MFNSetTolerances(), MFNGetIterationNumber()
113: @*/
114: PetscErrorCode MFNReasonView(MFN mfn,PetscViewer viewer)115: {
117: PetscBool isAscii;
120: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
121: if (isAscii) {
122: PetscViewerASCIIAddTab(viewer,((PetscObject)mfn)->tablevel);
123: if (mfn->reason > 0) {
124: PetscViewerASCIIPrintf(viewer,"%s Matrix function solve converged due to %s; iterations %D\n",((PetscObject)mfn)->prefix?((PetscObject)mfn)->prefix:"",MFNConvergedReasons[mfn->reason],mfn->its);
125: } else {
126: PetscViewerASCIIPrintf(viewer,"%s Matrix function solve did not converge due to %s; iterations %D\n",((PetscObject)mfn)->prefix?((PetscObject)mfn)->prefix:"",MFNConvergedReasons[mfn->reason],mfn->its);
127: }
128: PetscViewerASCIISubtractTab(viewer,((PetscObject)mfn)->tablevel);
129: }
130: return(0);
131: }
135: /*@
136: MFNReasonViewFromOptions - Processes command line options to determine if/how
137: the MFN converged reason is to be viewed.
139: Collective on MFN141: Input Parameters:
142: . mfn - the matrix function context
144: Level: developer
145: @*/
146: PetscErrorCode MFNReasonViewFromOptions(MFN mfn)147: {
148: PetscErrorCode ierr;
149: PetscViewer viewer;
150: PetscBool flg;
151: static PetscBool incall = PETSC_FALSE;
152: PetscViewerFormat format;
155: if (incall) return(0);
156: incall = PETSC_TRUE;
157: PetscOptionsGetViewer(PetscObjectComm((PetscObject)mfn),((PetscObject)mfn)->prefix,"-mfn_converged_reason",&viewer,&format,&flg);
158: if (flg) {
159: PetscViewerPushFormat(viewer,format);
160: MFNReasonView(mfn,viewer);
161: PetscViewerPopFormat(viewer);
162: PetscViewerDestroy(&viewer);
163: }
164: incall = PETSC_FALSE;
165: return(0);
166: }
170: /*@
171: MFNCreate - Creates the default MFN context.
173: Collective on MPI_Comm
175: Input Parameter:
176: . comm - MPI communicator
178: Output Parameter:
179: . mfn - location to put the MFN context
181: Note:
182: The default MFN type is MFNKRYLOV
184: Level: beginner
186: .seealso: MFNSetUp(), MFNSolve(), MFNDestroy(), MFN187: @*/
188: PetscErrorCode MFNCreate(MPI_Comm comm,MFN *outmfn)189: {
191: MFN mfn;
195: *outmfn = 0;
196: MFNInitializePackage();
197: SlepcHeaderCreate(mfn,MFN_CLASSID,"MFN","Matrix Function","MFN",comm,MFNDestroy,MFNView);
199: mfn->A = NULL;
200: mfn->fn = NULL;
201: mfn->max_it = 0;
202: mfn->ncv = 0;
203: mfn->tol = PETSC_DEFAULT;
204: mfn->errorifnotconverged = PETSC_FALSE;
206: mfn->numbermonitors = 0;
208: mfn->V = NULL;
209: mfn->nwork = 0;
210: mfn->work = NULL;
211: mfn->data = NULL;
213: mfn->its = 0;
214: mfn->nv = 0;
215: mfn->errest = 0;
216: mfn->setupcalled = 0;
217: mfn->reason = MFN_CONVERGED_ITERATING;
219: *outmfn = mfn;
220: return(0);
221: }
225: /*@C
226: MFNSetType - Selects the particular solver to be used in the MFN object.
228: Logically Collective on MFN230: Input Parameters:
231: + mfn - the matrix function context
232: - type - a known method
234: Options Database Key:
235: . -mfn_type <method> - Sets the method; use -help for a list
236: of available methods
238: Notes:
239: See "slepc/include/slepcmfn.h" for available methods. The default
240: is MFNKRYLOV
242: Normally, it is best to use the MFNSetFromOptions() command and
243: then set the MFN type from the options database rather than by using
244: this routine. Using the options database provides the user with
245: maximum flexibility in evaluating the different available methods.
246: The MFNSetType() routine is provided for those situations where it
247: is necessary to set the iterative solver independently of the command
248: line or options database.
250: Level: intermediate
252: .seealso: MFNType253: @*/
254: PetscErrorCode MFNSetType(MFN mfn,MFNType type)255: {
256: PetscErrorCode ierr,(*r)(MFN);
257: PetscBool match;
263: PetscObjectTypeCompare((PetscObject)mfn,type,&match);
264: if (match) return(0);
266: PetscFunctionListFind(MFNList,type,&r);
267: if (!r) SETERRQ1(PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown MFN type given: %s",type);
269: if (mfn->ops->destroy) { (*mfn->ops->destroy)(mfn); }
270: PetscMemzero(mfn->ops,sizeof(struct _MFNOps));
272: mfn->setupcalled = 0;
273: PetscObjectChangeTypeName((PetscObject)mfn,type);
274: (*r)(mfn);
275: return(0);
276: }
280: /*@C
281: MFNGetType - Gets the MFN type as a string from the MFN object.
283: Not Collective
285: Input Parameter:
286: . mfn - the matrix function context
288: Output Parameter:
289: . name - name of MFN method
291: Level: intermediate
293: .seealso: MFNSetType()
294: @*/
295: PetscErrorCode MFNGetType(MFN mfn,MFNType *type)296: {
300: *type = ((PetscObject)mfn)->type_name;
301: return(0);
302: }
306: /*@C
307: MFNRegister - Adds a method to the matrix function solver package.
309: Not Collective
311: Input Parameters:
312: + name - name of a new user-defined solver
313: - function - routine to create the solver context
315: Notes:
316: MFNRegister() may be called multiple times to add several user-defined solvers.
318: Sample usage:
319: .vb
320: MFNRegister("my_solver",MySolverCreate);
321: .ve
323: Then, your solver can be chosen with the procedural interface via
324: $ MFNSetType(mfn,"my_solver")
325: or at runtime via the option
326: $ -mfn_type my_solver
328: Level: advanced
330: .seealso: MFNRegisterAll()
331: @*/
332: PetscErrorCode MFNRegister(const char *name,PetscErrorCode (*function)(MFN))333: {
337: PetscFunctionListAdd(&MFNList,name,function);
338: return(0);
339: }
343: /*@
344: MFNReset - Resets the MFN context to the setupcalled=0 state and removes any
345: allocated objects.
347: Collective on MFN349: Input Parameter:
350: . mfn - matrix function context obtained from MFNCreate()
352: Level: advanced
354: .seealso: MFNDestroy()
355: @*/
356: PetscErrorCode MFNReset(MFN mfn)357: {
362: if (mfn->ops->reset) { (mfn->ops->reset)(mfn); }
363: mfn->setupcalled = 0;
364: return(0);
365: }
369: /*@
370: MFNDestroy - Destroys the MFN context.
372: Collective on MFN374: Input Parameter:
375: . mfn - matrix function context obtained from MFNCreate()
377: Level: beginner
379: .seealso: MFNCreate(), MFNSetUp(), MFNSolve()
380: @*/
381: PetscErrorCode MFNDestroy(MFN *mfn)382: {
386: if (!*mfn) return(0);
388: if (--((PetscObject)(*mfn))->refct > 0) { *mfn = 0; return(0); }
389: MFNReset(*mfn);
390: if ((*mfn)->ops->destroy) { (*(*mfn)->ops->destroy)(*mfn); }
391: MatDestroy(&(*mfn)->A);
392: BVDestroy(&(*mfn)->V);
393: FNDestroy(&(*mfn)->fn);
394: MFNMonitorCancel(*mfn);
395: PetscHeaderDestroy(mfn);
396: return(0);
397: }
401: /*@
402: MFNSetBV - Associates a basis vectors object to the matrix function solver.
404: Collective on MFN406: Input Parameters:
407: + mfn - matrix function context obtained from MFNCreate()
408: - bv - the basis vectors object
410: Note:
411: Use MFNGetBV() to retrieve the basis vectors context (for example,
412: to free it at the end of the computations).
414: Level: advanced
416: .seealso: MFNGetBV()
417: @*/
418: PetscErrorCode MFNSetBV(MFN mfn,BV bv)419: {
426: PetscObjectReference((PetscObject)bv);
427: BVDestroy(&mfn->V);
428: mfn->V = bv;
429: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->V);
430: return(0);
431: }
435: /*@
436: MFNGetBV - Obtain the basis vectors object associated to the matrix
437: function solver.
439: Not Collective
441: Input Parameters:
442: . mfn - matrix function context obtained from MFNCreate()
444: Output Parameter:
445: . bv - basis vectors context
447: Level: advanced
449: .seealso: MFNSetBV()
450: @*/
451: PetscErrorCode MFNGetBV(MFN mfn,BV *bv)452: {
458: if (!mfn->V) {
459: BVCreate(PetscObjectComm((PetscObject)mfn),&mfn->V);
460: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->V);
461: }
462: *bv = mfn->V;
463: return(0);
464: }
468: /*@
469: MFNSetFN - Specifies the function to be computed.
471: Collective on MFN473: Input Parameters:
474: + mfn - matrix function context obtained from MFNCreate()
475: - fn - the math function object
477: Note:
478: Use MFNGetFN() to retrieve the math function context (for example,
479: to free it at the end of the computations).
481: Level: beginner
483: .seealso: MFNGetFN()
484: @*/
485: PetscErrorCode MFNSetFN(MFN mfn,FN fn)486: {
493: PetscObjectReference((PetscObject)fn);
494: FNDestroy(&mfn->fn);
495: mfn->fn = fn;
496: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->fn);
497: return(0);
498: }
502: /*@
503: MFNGetFN - Obtain the math function object associated to the MFN object.
505: Not Collective
507: Input Parameters:
508: . mfn - matrix function context obtained from MFNCreate()
510: Output Parameter:
511: . fn - math function context
513: Level: beginner
515: .seealso: MFNSetFN()
516: @*/
517: PetscErrorCode MFNGetFN(MFN mfn,FN *fn)518: {
524: if (!mfn->fn) {
525: FNCreate(PetscObjectComm((PetscObject)mfn),&mfn->fn);
526: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->fn);
527: }
528: *fn = mfn->fn;
529: return(0);
530: }