Actual source code: mfnbasic.c

slepc-3.7.2 2016-07-19
Report Typos and Errors
  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 MFN

103:    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 MFN

141:    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(), MFN
187: @*/
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 MFN

230:    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: MFNType
253: @*/
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 MFN

349:    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 MFN

374:    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 MFN

406:    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 MFN

473:    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: }