1: /*
2: The basic MFN routines, Create, View, etc. are here.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2015, 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->sfactor = 1.0;
205: mfn->errorifnotconverged = PETSC_FALSE;
207: mfn->numbermonitors = 0;
209: mfn->V = NULL;
210: mfn->rand = NULL;
211: mfn->nwork = 0;
212: mfn->work = NULL;
213: mfn->data = NULL;
215: mfn->its = 0;
216: mfn->nv = 0;
217: mfn->errest = 0;
218: mfn->setupcalled = 0;
219: mfn->reason = MFN_CONVERGED_ITERATING;
221: PetscRandomCreate(comm,&mfn->rand);
222: PetscRandomSetSeed(mfn->rand,0x12345678);
223: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->rand);
224: *outmfn = mfn;
225: return(0);
226: }
230: /*@C
231: MFNSetType - Selects the particular solver to be used in the MFN object.
233: Logically Collective on MFN235: Input Parameters:
236: + mfn - the matrix function context
237: - type - a known method
239: Options Database Key:
240: . -mfn_type <method> - Sets the method; use -help for a list
241: of available methods
243: Notes:
244: See "slepc/include/slepcmfn.h" for available methods. The default
245: is MFNKRYLOV
247: Normally, it is best to use the MFNSetFromOptions() command and
248: then set the MFN type from the options database rather than by using
249: this routine. Using the options database provides the user with
250: maximum flexibility in evaluating the different available methods.
251: The MFNSetType() routine is provided for those situations where it
252: is necessary to set the iterative solver independently of the command
253: line or options database.
255: Level: intermediate
257: .seealso: MFNType258: @*/
259: PetscErrorCode MFNSetType(MFN mfn,MFNType type)260: {
261: PetscErrorCode ierr,(*r)(MFN);
262: PetscBool match;
268: PetscObjectTypeCompare((PetscObject)mfn,type,&match);
269: if (match) return(0);
271: PetscFunctionListFind(MFNList,type,&r);
272: if (!r) SETERRQ1(PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown MFN type given: %s",type);
274: if (mfn->ops->destroy) { (*mfn->ops->destroy)(mfn); }
275: PetscMemzero(mfn->ops,sizeof(struct _MFNOps));
277: mfn->setupcalled = 0;
278: PetscObjectChangeTypeName((PetscObject)mfn,type);
279: (*r)(mfn);
280: return(0);
281: }
285: /*@C
286: MFNGetType - Gets the MFN type as a string from the MFN object.
288: Not Collective
290: Input Parameter:
291: . mfn - the matrix function context
293: Output Parameter:
294: . name - name of MFN method
296: Level: intermediate
298: .seealso: MFNSetType()
299: @*/
300: PetscErrorCode MFNGetType(MFN mfn,MFNType *type)301: {
305: *type = ((PetscObject)mfn)->type_name;
306: return(0);
307: }
311: /*@C
312: MFNRegister - Adds a method to the matrix function solver package.
314: Not Collective
316: Input Parameters:
317: + name - name of a new user-defined solver
318: - function - routine to create the solver context
320: Notes:
321: MFNRegister() may be called multiple times to add several user-defined solvers.
323: Sample usage:
324: .vb
325: MFNRegister("my_solver",MySolverCreate);
326: .ve
328: Then, your solver can be chosen with the procedural interface via
329: $ MFNSetType(mfn,"my_solver")
330: or at runtime via the option
331: $ -mfn_type my_solver
333: Level: advanced
335: .seealso: MFNRegisterAll()
336: @*/
337: PetscErrorCode MFNRegister(const char *name,PetscErrorCode (*function)(MFN))338: {
342: PetscFunctionListAdd(&MFNList,name,function);
343: return(0);
344: }
348: /*@
349: MFNReset - Resets the MFN context to the setupcalled=0 state and removes any
350: allocated objects.
352: Collective on MFN354: Input Parameter:
355: . mfn - matrix function context obtained from MFNCreate()
357: Level: advanced
359: .seealso: MFNDestroy()
360: @*/
361: PetscErrorCode MFNReset(MFN mfn)362: {
367: if (mfn->ops->reset) { (mfn->ops->reset)(mfn); }
368: mfn->setupcalled = 0;
369: return(0);
370: }
374: /*@
375: MFNDestroy - Destroys the MFN context.
377: Collective on MFN379: Input Parameter:
380: . mfn - matrix function context obtained from MFNCreate()
382: Level: beginner
384: .seealso: MFNCreate(), MFNSetUp(), MFNSolve()
385: @*/
386: PetscErrorCode MFNDestroy(MFN *mfn)387: {
391: if (!*mfn) return(0);
393: if (--((PetscObject)(*mfn))->refct > 0) { *mfn = 0; return(0); }
394: MFNReset(*mfn);
395: if ((*mfn)->ops->destroy) { (*(*mfn)->ops->destroy)(*mfn); }
396: MatDestroy(&(*mfn)->A);
397: BVDestroy(&(*mfn)->V);
398: FNDestroy(&(*mfn)->fn);
399: PetscRandomDestroy(&(*mfn)->rand);
400: MFNMonitorCancel(*mfn);
401: PetscHeaderDestroy(mfn);
402: return(0);
403: }
407: /*@
408: MFNSetBV - Associates a basis vectors object to the matrix function solver.
410: Collective on MFN412: Input Parameters:
413: + mfn - matrix function context obtained from MFNCreate()
414: - bv - the basis vectors object
416: Note:
417: Use MFNGetBV() to retrieve the basis vectors context (for example,
418: to free it at the end of the computations).
420: Level: advanced
422: .seealso: MFNGetBV()
423: @*/
424: PetscErrorCode MFNSetBV(MFN mfn,BV bv)425: {
432: PetscObjectReference((PetscObject)bv);
433: BVDestroy(&mfn->V);
434: mfn->V = bv;
435: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->V);
436: return(0);
437: }
441: /*@
442: MFNGetBV - Obtain the basis vectors object associated to the matrix
443: function solver.
445: Not Collective
447: Input Parameters:
448: . mfn - matrix function context obtained from MFNCreate()
450: Output Parameter:
451: . bv - basis vectors context
453: Level: advanced
455: .seealso: MFNSetBV()
456: @*/
457: PetscErrorCode MFNGetBV(MFN mfn,BV *bv)458: {
464: if (!mfn->V) {
465: BVCreate(PetscObjectComm((PetscObject)mfn),&mfn->V);
466: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->V);
467: }
468: *bv = mfn->V;
469: return(0);
470: }
474: /*@
475: MFNSetFN - Specifies the function to be computed.
477: Collective on MFN479: Input Parameters:
480: + mfn - matrix function context obtained from MFNCreate()
481: - fn - the math function object
483: Note:
484: Use MFNGetFN() to retrieve the math function context (for example,
485: to free it at the end of the computations).
487: Level: beginner
489: .seealso: MFNGetFN()
490: @*/
491: PetscErrorCode MFNSetFN(MFN mfn,FN fn)492: {
499: PetscObjectReference((PetscObject)fn);
500: FNDestroy(&mfn->fn);
501: mfn->fn = fn;
502: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->fn);
503: return(0);
504: }
508: /*@
509: MFNGetFN - Obtain the math function object associated to the MFN object.
511: Not Collective
513: Input Parameters:
514: . mfn - matrix function context obtained from MFNCreate()
516: Output Parameter:
517: . fn - math function context
519: Level: intermediate
521: .seealso: MFNSetFN()
522: @*/
523: PetscErrorCode MFNGetFN(MFN mfn,FN *fn)524: {
530: if (!mfn->fn) {
531: FNCreate(PetscObjectComm((PetscObject)mfn),&mfn->fn);
532: PetscLogObjectParent((PetscObject)mfn,(PetscObject)mfn->fn);
533: }
534: *fn = mfn->fn;
535: return(0);
536: }