Actual source code: iguess.c

      1: #include <petsc/private/kspimpl.h>

      3: PetscFunctionList KSPGuessList = NULL;
      4: static PetscBool KSPGuessRegisterAllCalled;

      6: /*
      7:   KSPGuessRegister -  Adds a method for initial guess computation in Krylov subspace solver package.

      9:    Not Collective

     11:    Input Parameters:
     12: +  name_solver - name of a new user-defined solver
     13: -  routine_create - routine to create method context

     15:    Notes:
     16:    KSPGuessRegister() may be called multiple times to add several user-defined solvers.

     18:    Sample usage:
     19: .vb
     20:    KSPGuessRegister("my_initial_guess",MyInitialGuessCreate);
     21: .ve

     23:    Then, it can be chosen with the procedural interface via
     24: $     KSPSetGuessType(ksp,"my_initial_guess")
     25:    or at runtime via the option
     26: $     -ksp_guess_type my_initial_guess

     28:    Level: advanced

     30: .seealso: KSPGuess, KSPGuessRegisterAll()

     32: @*/
     33: PetscErrorCode  KSPGuessRegister(const char sname[],PetscErrorCode (*function)(KSPGuess))
     34: {

     38:   KSPInitializePackage();
     39:   PetscFunctionListAdd(&KSPGuessList,sname,function);
     40:   return(0);
     41: }

     43: /*
     44:   KSPGuessRegisterAll - Registers all KSPGuess implementations in the KSP package.

     46:   Not Collective

     48:   Level: advanced

     50: .seealso: KSPRegisterAll(),  KSPInitializePackage()
     51: */
     52: PetscErrorCode KSPGuessRegisterAll(void)
     53: {

     57:   if (KSPGuessRegisterAllCalled) return(0);
     58:   KSPGuessRegisterAllCalled = PETSC_TRUE;
     59:   KSPGuessRegister(KSPGUESSFISCHER,KSPGuessCreate_Fischer);
     60:   KSPGuessRegister(KSPGUESSPOD,KSPGuessCreate_POD);
     61:   return(0);
     62: }

     64: /*@
     65:     KSPGuessSetFromOptions - Sets the options for a KSPGuess from the options database

     67:     Collective on guess

     69:     Input Parameter:
     70: .    guess - KSPGuess object

     72:    Level: intermediate

     74: .seealso: KSPGuess, KSPGetGuess(), KSPSetGuessType(), KSPGuessType
     75: @*/
     76: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
     77: {

     82:   if (guess->ops->setfromoptions) { (*guess->ops->setfromoptions)(guess); }
     83:   return(0);
     84: }

     86: /*@
     87:    KSPGuessDestroy - Destroys KSPGuess context.

     89:    Collective on kspGuess

     91:    Input Parameter:
     92: .  guess - initial guess object

     94:    Level: beginner

     96: .seealso: KSPGuessCreate(), KSPGuess, KSPGuessType
     97: @*/
     98: PetscErrorCode  KSPGuessDestroy(KSPGuess *guess)
     99: {

    103:   if (!*guess) return(0);
    105:   if (--((PetscObject)(*guess))->refct > 0) {*guess = NULL; return(0);}
    106:   if ((*guess)->ops->destroy) { (*(*guess)->ops->destroy)(*guess); }
    107:   MatDestroy(&(*guess)->A);
    108:   PetscHeaderDestroy(guess);
    109:   return(0);
    110: }

    112: /*@C
    113:    KSPGuessView - View the KSPGuess object

    115:    Logically Collective on guess

    117:    Input Parameters:
    118: +  guess  - the initial guess object for the Krylov method
    119: -  viewer - the viewer object

    121:    Notes:

    123:   Level: intermediate

    125: .seealso: KSP, KSPGuess, KSPGuessType, KSPGuessRegister(), KSPGuessCreate(), PetscViewer
    126: @*/
    127: PetscErrorCode  KSPGuessView(KSPGuess guess, PetscViewer view)
    128: {
    130:   PetscBool      ascii;

    134:   if (!view) {
    135:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess),&view);
    136:   }
    139:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&ascii);
    140:   if (ascii) {
    141:     PetscObjectPrintClassNamePrefixType((PetscObject)guess,view);
    142:     if (guess->ops->view) {
    143:       PetscViewerASCIIPushTab(view);
    144:       (*guess->ops->view)(guess,view);
    145:       PetscViewerASCIIPopTab(view);
    146:     }
    147:   }
    148:   return(0);
    149: }

    151: /*@
    152:    KSPGuessCreate - Creates the default KSPGuess context.

    154:    Collective

    156:    Input Parameter:
    157: .  comm - MPI communicator

    159:    Output Parameter:
    160: .  guess - location to put the KSPGuess context

    162:    Notes:
    163:    The default KSPGuess type is XXX

    165:    Level: beginner

    167: .seealso: KSPSolve(), KSPGuessDestroy(), KSPGuess, KSPGuessType, KSP
    168: @*/
    169: PetscErrorCode  KSPGuessCreate(MPI_Comm comm,KSPGuess *guess)
    170: {
    171:   KSPGuess       tguess;

    176:   *guess = NULL;
    177:   KSPInitializePackage();
    178:   PetscHeaderCreate(tguess,KSPGUESS_CLASSID,"KSPGuess","Initial guess for Krylov Method","KSPGuess",comm,KSPGuessDestroy,KSPGuessView);
    179:   tguess->omatstate = -1;
    180:   *guess = tguess;
    181:   return(0);
    182: }

    184: /*@C
    185:    KSPGuessSetType - Sets the type of a KSPGuess

    187:    Logically Collective on guess

    189:    Input Parameters:
    190: +  guess - the initial guess object for the Krylov method
    191: -  type  - a known KSPGuess method

    193:    Options Database Key:
    194: .  -ksp_guess_type  <method> - Sets the method; use -help for a list
    195:     of available methods

    197:    Notes:

    199:   Level: intermediate

    201: .seealso: KSP, KSPGuess, KSPGuessType, KSPGuessRegister(), KSPGuessCreate()

    203: @*/
    204: PetscErrorCode  KSPGuessSetType(KSPGuess guess, KSPGuessType type)
    205: {
    206:   PetscErrorCode ierr,(*r)(KSPGuess);
    207:   PetscBool      match;

    213:   PetscObjectTypeCompare((PetscObject)guess,type,&match);
    214:   if (match) return(0);

    216:    PetscFunctionListFind(KSPGuessList,type,&r);
    217:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)guess),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSPGuess type %s",type);
    218:   if (guess->ops->destroy) {
    219:     (*guess->ops->destroy)(guess);
    220:     guess->ops->destroy = NULL;
    221:   }
    222:   PetscMemzero(guess->ops,sizeof(struct _KSPGuessOps));
    223:   PetscObjectChangeTypeName((PetscObject)guess,type);
    224:   (*r)(guess);
    225:   return(0);
    226: }

    228: /*@C
    229:    KSPGuessGetType - Gets the KSPGuess type as a string from the KSPGuess object.

    231:    Not Collective

    233:    Input Parameter:
    234: .  guess - the initial guess context

    236:    Output Parameter:
    237: .  name - name of KSPGuess method

    239:    Level: intermediate

    241: .seealso: KSPGuessSetType()
    242: @*/
    243: PetscErrorCode  KSPGuessGetType(KSPGuess guess,KSPGuessType *type)
    244: {
    248:   *type = ((PetscObject)guess)->type_name;
    249:   return(0);
    250: }

    252: /*@
    253:     KSPGuessUpdate - Updates the guess object with the current solution and rhs vector

    255:    Collective on guess

    257:    Input Parameter:
    258: +  guess - the initial guess context
    259: .  rhs   - the corresponding rhs
    260: -  sol   - the computed solution

    262:    Level: intermediate

    264: .seealso: KSPGuessCreate(), KSPGuess
    265: @*/
    266: PetscErrorCode  KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
    267: {

    274:   if (guess->ops->update) { (*guess->ops->update)(guess,rhs,sol); }
    275:   return(0);
    276: }

    278: /*@
    279:     KSPGuessFormGuess - Form the initial guess

    281:    Collective on guess

    283:    Input Parameter:
    284: +  guess - the initial guess context
    285: .  rhs   - the current rhs vector
    286: -  sol   - the initial guess vector

    288:    Level: intermediate

    290: .seealso: KSPGuessCreate(), KSPGuess
    291: @*/
    292: PetscErrorCode  KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
    293: {

    300:   if (guess->ops->formguess) { (*guess->ops->formguess)(guess,rhs,sol); }
    301:   return(0);
    302: }

    304: /*@
    305:     KSPGuessSetUp - Setup the initial guess object

    307:    Collective on guess

    309:    Input Parameter:
    310: -  guess - the initial guess context

    312:    Level: intermediate

    314: .seealso: KSPGuessCreate(), KSPGuess
    315: @*/
    316: PetscErrorCode  KSPGuessSetUp(KSPGuess guess)
    317: {
    318:   PetscErrorCode   ierr;
    319:   PetscObjectState matstate;
    320:   PetscInt         oM = 0, oN = 0, M, N;
    321:   Mat              omat = NULL;
    322:   PC               pc;
    323:   PetscBool        reuse;

    327:   if (guess->A) {
    328:     omat = guess->A;
    329:     MatGetSize(guess->A,&oM,&oN);
    330:   }
    331:   KSPGetOperators(guess->ksp,&guess->A,NULL);
    332:   KSPGetPC(guess->ksp,&pc);
    333:   PCGetReusePreconditioner(pc,&reuse);
    334:   PetscObjectReference((PetscObject)guess->A);
    335:   MatGetSize(guess->A,&M,&N);
    336:   PetscObjectStateGet((PetscObject)guess->A,&matstate);
    337:   if (M != oM || N != oN) {
    338:     PetscInfo4(guess,"Resetting KSPGuess since matrix sizes have changed (%D != %D, %D != %D)\n",oM,M,oN,N);
    339:   } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
    340:     PetscInfo1(guess,"Resetting KSPGuess since %s has changed\n",omat != guess->A ? "matrix" : "matrix state");
    341:     if (guess->ops->reset) { (*guess->ops->reset)(guess); }
    342:   } else if (reuse) {
    343:     PetscInfo(guess,"Not resettting KSPGuess since reuse preconditioner has been specified\n");
    344:   } else {
    345:     PetscInfo(guess,"KSPGuess status unchanged\n");
    346:   }
    347:   if (guess->ops->setup) { (*guess->ops->setup)(guess); }
    348:   guess->omatstate = matstate;
    349:   MatDestroy(&omat);
    350:   return(0);
    351: }