Actual source code: iguess.c

petsc-master 2020-06-03
Report Typos and Errors
  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: }