Date: 2013-09-02T10:08:16+00:00

Actual source code: mfnbasic.c

      1: /*
      2:      The basic MFN routines, Create, View, etc. are here.

      4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      6:    Copyright (c) 2002-2013, 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;
     30: static PetscBool  MFNPackageInitialized = PETSC_FALSE;

     34: /*@C
     35:   MFNFinalizePackage - This function destroys everything in the SLEPc interface
     36:   to the MFN package. It is called from SlepcFinalize().

     38:   Level: developer

     40: .seealso: SlepcFinalize()
     41: @*/
     42: PetscErrorCode MFNFinalizePackage(void)
     43: {

     47:   PetscFunctionListDestroy(&MFNList);
     48:   MFNPackageInitialized = PETSC_FALSE;
     49:   MFNRegisterAllCalled  = PETSC_FALSE;
     50:   return(0);
     51: }

     55: /*@C
     56:   MFNInitializePackage - This function initializes everything in the MFN package.
     57:   It is called from PetscDLLibraryRegister() when using dynamic libraries, and
     58:   on the first call to MFNCreate() when using static libraries.

     60:   Level: developer

     62: .seealso: SlepcInitialize()
     63: @*/
     64: PetscErrorCode MFNInitializePackage(void)
     65: {
     66:   char           logList[256];
     67:   char           *className;
     68:   PetscBool      opt;

     72:   if (MFNPackageInitialized) return(0);
     73:   MFNPackageInitialized = PETSC_TRUE;
     74:   /* Register Classes */
     75:   PetscClassIdRegister("Matrix Function",&MFN_CLASSID);
     76:   /* Register Constructors */
     77:   MFNRegisterAll();
     78:   /* Register Events */
     79:   PetscLogEventRegister("MFNSetUp",MFN_CLASSID,&MFN_SetUp);
     80:   PetscLogEventRegister("MFNSolve",MFN_CLASSID,&MFN_Solve);
     81:   /* Process info exclusions */
     82:   PetscOptionsGetString(NULL,"-info_exclude",logList,256,&opt);
     83:   if (opt) {
     84:     PetscStrstr(logList,"mfn",&className);
     85:     if (className) {
     86:       PetscInfoDeactivateClass(MFN_CLASSID);
     87:     }
     88:   }
     89:   /* Process summary exclusions */
     90:   PetscOptionsGetString(NULL,"-log_summary_exclude",logList,256,&opt);
     91:   if (opt) {
     92:     PetscStrstr(logList,"mfn",&className);
     93:     if (className) {
     94:       PetscLogEventDeactivateClass(MFN_CLASSID);
     95:     }
     96:   }
     97:   PetscRegisterFinalize(MFNFinalizePackage);
     98:   return(0);
     99: }

    103: /*@C
    104:    MFNView - Prints the MFN data structure.

    106:    Collective on MFN

    108:    Input Parameters:
    109: +  mfn - the matrix function solver context
    110: -  viewer - optional visualization context

    112:    Options Database Key:
    113: .  -mfn_view -  Calls MFNView() at end of MFNSolve()

    115:    Note:
    116:    The available visualization contexts include
    117: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
    118: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
    119:          output where only the first processor opens
    120:          the file.  All other processors send their
    121:          data to the first processor to print.

    123:    The user can open an alternative visualization context with
    124:    PetscViewerASCIIOpen() - output to a specified file.

    126:    Level: beginner

    128: .seealso: PetscViewerASCIIOpen()
    129: @*/
    130: PetscErrorCode MFNView(MFN mfn,PetscViewer viewer)
    131: {
    133:   const char     *fun;
    134:   char           str[50];
    135:   PetscBool      isascii;

    139:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)mfn));

    143:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    144:   if (isascii) {
    145:     PetscObjectPrintClassNamePrefixType((PetscObject)mfn,viewer,"MFN Object");
    146:     if (mfn->ops->view) {
    147:       PetscViewerASCIIPushTab(viewer);
    148:       (*mfn->ops->view)(mfn,viewer);
    149:       PetscViewerASCIIPopTab(viewer);
    150:     }
    151:     if (mfn->function) {
    152:       switch (mfn->function) {
    153:         case SLEPC_FUNCTION_EXP: fun = "exponential"; break;
    154:         default: SETERRQ(PetscObjectComm((PetscObject)mfn),1,"Wrong value of mfn->function");
    155:       }
    156:     } else fun = "not yet set";
    157:     PetscViewerASCIIPrintf(viewer,"  function: %s\n",fun);
    158:     PetscViewerASCIIPrintf(viewer,"  number of column vectors (ncv): %D\n",mfn->ncv);
    159:     PetscViewerASCIIPrintf(viewer,"  maximum number of iterations: %D\n",mfn->max_it);
    160:     PetscViewerASCIIPrintf(viewer,"  tolerance: %G\n",mfn->tol);
    161:     SlepcSNPrintfScalar(str,50,mfn->sfactor,PETSC_FALSE);
    162:     PetscViewerASCIIPrintf(viewer,"  scaling factor: %s\n",str);
    163:   } else {
    164:     if (mfn->ops->view) {
    165:       (*mfn->ops->view)(mfn,viewer);
    166:     }
    167:   }
    168:   if (!mfn->ip) { MFNGetIP(mfn,&mfn->ip); }
    169:   IPView(mfn->ip,viewer);
    170:   if (!mfn->ds) { MFNGetDS(mfn,&mfn->ds); }
    171:   PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO);
    172:   DSView(mfn->ds,viewer);
    173:   PetscViewerPopFormat(viewer);
    174:   return(0);
    175: }

    179: /*@C
    180:    MFNCreate - Creates the default MFN context.

    182:    Collective on MPI_Comm

    184:    Input Parameter:
    185: .  comm - MPI communicator

    187:    Output Parameter:
    188: .  mfn - location to put the MFN context

    190:    Note:
    191:    The default MFN type is MFNKRYLOV

    193:    Level: beginner

    195: .seealso: MFNSetUp(), MFNSolve(), MFNDestroy(), MFN
    196: @*/
    197: PetscErrorCode MFNCreate(MPI_Comm comm,MFN *outmfn)
    198: {
    200:   MFN            mfn;

    204:   *outmfn = 0;
    205: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
    206:   MFNInitializePackage();
    207: #endif

    209:   SlepcHeaderCreate(mfn,_p_MFN,struct _MFNOps,MFN_CLASSID,"MFN","Matrix Function","MFN",comm,MFNDestroy,MFNView);

    211:   mfn->max_it          = 0;
    212:   mfn->ncv             = 0;
    213:   mfn->allocated_ncv   = 0;
    214:   mfn->tol             = PETSC_DEFAULT;
    215:   mfn->function        = (SlepcFunction)0;
    216:   mfn->sfactor         = 1.0;

    218:   mfn->A               = 0;
    219:   mfn->V               = 0;
    220:   mfn->t               = 0;
    221:   mfn->errest          = 0;
    222:   mfn->ip              = 0;
    223:   mfn->ds              = 0;
    224:   mfn->rand            = 0;
    225:   mfn->data            = 0;
    226:   mfn->its             = 0;

    228:   mfn->nwork           = 0;
    229:   mfn->work            = 0;
    230:   mfn->setupcalled     = 0;
    231:   mfn->reason          = MFN_CONVERGED_ITERATING;
    232:   mfn->numbermonitors  = 0;

    234:   PetscRandomCreate(comm,&mfn->rand);
    235:   PetscRandomSetSeed(mfn->rand,0x12345678);
    236:   PetscLogObjectParent(mfn,mfn->rand);
    237:   *outmfn = mfn;
    238:   return(0);
    239: }

    243: /*@C
    244:    MFNSetType - Selects the particular solver to be used in the MFN object.

    246:    Logically Collective on MFN

    248:    Input Parameters:
    249: +  mfn  - the matrix function context
    250: -  type - a known method

    252:    Options Database Key:
    253: .  -mfn_type <method> - Sets the method; use -help for a list
    254:     of available methods

    256:    Notes:
    257:    See "slepc/include/slepcmfn.h" for available methods. The default
    258:    is MFNKRYLOV

    260:    Normally, it is best to use the MFNSetFromOptions() command and
    261:    then set the MFN type from the options database rather than by using
    262:    this routine.  Using the options database provides the user with
    263:    maximum flexibility in evaluating the different available methods.
    264:    The MFNSetType() routine is provided for those situations where it
    265:    is necessary to set the iterative solver independently of the command
    266:    line or options database.

    268:    Level: intermediate

    270: .seealso: MFNType
    271: @*/
    272: PetscErrorCode MFNSetType(MFN mfn,MFNType type)
    273: {
    274:   PetscErrorCode ierr,(*r)(MFN);
    275:   PetscBool      match;

    281:   PetscObjectTypeCompare((PetscObject)mfn,type,&match);
    282:   if (match) return(0);

    284:   PetscFunctionListFind(MFNList,type,&r);
    285:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown MFN type given: %s",type);

    287:   if (mfn->ops->destroy) { (*mfn->ops->destroy)(mfn); }
    288:   PetscMemzero(mfn->ops,sizeof(struct _MFNOps));

    290:   mfn->setupcalled = 0;
    291:   PetscObjectChangeTypeName((PetscObject)mfn,type);
    292:   (*r)(mfn);
    293:   return(0);
    294: }

    298: /*@C
    299:    MFNGetType - Gets the MFN type as a string from the MFN object.

    301:    Not Collective

    303:    Input Parameter:
    304: .  mfn - the matrix function context

    306:    Output Parameter:
    307: .  name - name of MFN method

    309:    Level: intermediate

    311: .seealso: MFNSetType()
    312: @*/
    313: PetscErrorCode MFNGetType(MFN mfn,MFNType *type)
    314: {
    318:   *type = ((PetscObject)mfn)->type_name;
    319:   return(0);
    320: }

    324: /*@C
    325:    MFNRegister - Adds a method to the matrix function solver package.

    327:    Not Collective

    329:    Input Parameters:
    330: +  name - name of a new user-defined solver
    331: -  function - routine to create the solver context

    333:    Notes:
    334:    MFNRegister() may be called multiple times to add several user-defined solvers.

    336:    Sample usage:
    337: .vb
    338:    MFNRegister("my_solver",MySolverCreate);
    339: .ve

    341:    Then, your solver can be chosen with the procedural interface via
    342: $     MFNSetType(mfn,"my_solver")
    343:    or at runtime via the option
    344: $     -mfn_type my_solver

    346:    Level: advanced

    348: .seealso: MFNRegisterAll()
    349: @*/
    350: PetscErrorCode MFNRegister(const char *name,PetscErrorCode (*function)(MFN))
    351: {

    355:   PetscFunctionListAdd(&MFNList,name,function);
    356:   return(0);
    357: }

    361: /*@
    362:    MFNReset - Resets the MFN context to the setupcalled=0 state and removes any
    363:    allocated objects.

    365:    Collective on MFN

    367:    Input Parameter:
    368: .  mfn - matrix function context obtained from MFNCreate()

    370:    Level: advanced

    372: .seealso: MFNDestroy()
    373: @*/
    374: PetscErrorCode MFNReset(MFN mfn)
    375: {

    380:   if (mfn->ops->reset) { (mfn->ops->reset)(mfn); }
    381:   if (mfn->ip) { IPReset(mfn->ip); }
    382:   if (mfn->ds) { DSReset(mfn->ds); }
    383:   VecDestroy(&mfn->t);
    384:   mfn->setupcalled = 0;
    385:   return(0);
    386: }

    390: /*@C
    391:    MFNDestroy - Destroys the MFN context.

    393:    Collective on MFN

    395:    Input Parameter:
    396: .  mfn - matrix function context obtained from MFNCreate()

    398:    Level: beginner

    400: .seealso: MFNCreate(), MFNSetUp(), MFNSolve()
    401: @*/
    402: PetscErrorCode MFNDestroy(MFN *mfn)
    403: {

    407:   if (!*mfn) return(0);
    409:   if (--((PetscObject)(*mfn))->refct > 0) { *mfn = 0; return(0); }
    410:   MFNReset(*mfn);
    411:   if ((*mfn)->ops->destroy) { (*(*mfn)->ops->destroy)(*mfn); }
    412:   MatDestroy(&(*mfn)->A);
    413:   IPDestroy(&(*mfn)->ip);
    414:   DSDestroy(&(*mfn)->ds);
    415:   PetscRandomDestroy(&(*mfn)->rand);
    416:   MFNMonitorCancel(*mfn);
    417:   PetscHeaderDestroy(mfn);
    418:   return(0);
    419: }

    423: /*@
    424:    MFNSetIP - Associates an inner product object to the matrix function solver.

    426:    Collective on MFN

    428:    Input Parameters:
    429: +  mfn - matrix function context obtained from MFNCreate()
    430: -  ip  - the inner product object

    432:    Note:
    433:    Use MFNGetIP() to retrieve the inner product context (for example,
    434:    to free it at the end of the computations).

    436:    Level: advanced

    438: .seealso: MFNGetIP()
    439: @*/
    440: PetscErrorCode MFNSetIP(MFN mfn,IP ip)
    441: {

    448:   PetscObjectReference((PetscObject)ip);
    449:   IPDestroy(&mfn->ip);
    450:   mfn->ip = ip;
    451:   PetscLogObjectParent(mfn,mfn->ip);
    452:   return(0);
    453: }

    457: /*@C
    458:    MFNGetIP - Obtain the inner product object associated to the eigensolver object.

    460:    Not Collective

    462:    Input Parameters:
    463: .  mfn - matrix function context obtained from MFNCreate()

    465:    Output Parameter:
    466: .  ip - inner product context

    468:    Level: advanced

    470: .seealso: MFNSetIP()
    471: @*/
    472: PetscErrorCode MFNGetIP(MFN mfn,IP *ip)
    473: {

    479:   if (!mfn->ip) {
    480:     IPCreate(PetscObjectComm((PetscObject)mfn),&mfn->ip);
    481:     PetscLogObjectParent(mfn,mfn->ip);
    482:   }
    483:   *ip = mfn->ip;
    484:   return(0);
    485: }

    489: /*@
    490:    MFNSetDS - Associates a direct solver object to the matrix function solver.

    492:    Collective on MFN

    494:    Input Parameters:
    495: +  mfn - matrix function context obtained from MFNCreate()
    496: -  ds  - the direct solver object

    498:    Note:
    499:    Use MFNGetDS() to retrieve the direct solver context (for example,
    500:    to free it at the end of the computations).

    502:    Level: advanced

    504: .seealso: MFNGetDS()
    505: @*/
    506: PetscErrorCode MFNSetDS(MFN mfn,DS ds)
    507: {

    514:   PetscObjectReference((PetscObject)ds);
    515:   DSDestroy(&mfn->ds);
    516:   mfn->ds = ds;
    517:   PetscLogObjectParent(mfn,mfn->ds);
    518:   return(0);
    519: }

    523: /*@C
    524:    MFNGetDS - Obtain the direct solver object associated to the matrix function object.

    526:    Not Collective

    528:    Input Parameters:
    529: .  mfn - matrix function context obtained from MFNCreate()

    531:    Output Parameter:
    532: .  ds - direct solver context

    534:    Level: advanced

    536: .seealso: MFNSetDS()
    537: @*/
    538: PetscErrorCode MFNGetDS(MFN mfn,DS *ds)
    539: {

    545:   if (!mfn->ds) {
    546:     DSCreate(PetscObjectComm((PetscObject)mfn),&mfn->ds);
    547:     PetscLogObjectParent(mfn,mfn->ds);
    548:   }
    549:   *ds = mfn->ds;
    550:   return(0);
    551: }