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: developer

 30: .seealso: [](chapter_ksp), `KSPGuess`, `KSPGuessRegisterAll()`
 31: @*/
 32: PetscErrorCode KSPGuessRegister(const char sname[], PetscErrorCode (*function)(KSPGuess))
 33: {
 34:   KSPInitializePackage();
 35:   PetscFunctionListAdd(&KSPGuessList, sname, function);
 36:   return 0;
 37: }

 39: /*@C
 40:   KSPGuessRegisterAll - Registers all `KSPGuess` implementations in the `KSP` package.

 42:   Not Collective

 44:   Level: developer

 46: .seealso: [](chapter_ksp), `KSPGuess`, `KSPRegisterAll()`, `KSPInitializePackage()`
 47: @*/
 48: PetscErrorCode KSPGuessRegisterAll(void)
 49: {
 50:   if (KSPGuessRegisterAllCalled) return 0;
 51:   KSPGuessRegisterAllCalled = PETSC_TRUE;
 52:   KSPGuessRegister(KSPGUESSFISCHER, KSPGuessCreate_Fischer);
 53:   KSPGuessRegister(KSPGUESSPOD, KSPGuessCreate_POD);
 54:   return 0;
 55: }

 57: /*@
 58:     KSPGuessSetFromOptions - Sets the options for a `KSPGuess` from the options database

 60:     Collective

 62:     Input Parameter:
 63: .    guess - `KSPGuess` object

 65:    Level: developer

 67: .seealso: [](chapter_ksp), `KSPGuess`, `KSPGetGuess()`, `KSPSetGuessType()`, `KSPGuessType`
 68: @*/
 69: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
 70: {
 72:   PetscTryTypeMethod(guess, setfromoptions);
 73:   return 0;
 74: }

 76: /*@
 77:     KSPGuessSetTolerance - Sets the relative tolerance used in either eigenvalue (POD) or singular value (Fischer type 3) calculations.
 78:     Ignored by the first and second Fischer types.

 80:     Collective

 82:     Input Parameter:
 83: .    guess - `KSPGuess` object

 85:    Level: developer

 87: .seealso: [](chapter_ksp), `KSPGuess`, `KSPGuessType`, `KSPGuessSetFromOptions()`
 88: @*/
 89: PetscErrorCode KSPGuessSetTolerance(KSPGuess guess, PetscReal tol)
 90: {
 92:   PetscTryTypeMethod(guess, settolerance, tol);
 93:   return 0;
 94: }

 96: /*@
 97:    KSPGuessDestroy - Destroys `KSPGuess` context.

 99:    Collective

101:    Input Parameter:
102: .  guess - initial guess object

104:    Level: developer

106: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`, `KSPGuessType`
107: @*/
108: PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
109: {
110:   if (!*guess) return 0;
112:   if (--((PetscObject)(*guess))->refct > 0) {
113:     *guess = NULL;
114:     return 0;
115:   }
116:   PetscTryTypeMethod((*guess), destroy);
117:   MatDestroy(&(*guess)->A);
118:   PetscHeaderDestroy(guess);
119:   return 0;
120: }

122: /*@C
123:    KSPGuessView - View the `KSPGuess` object

125:    Logically Collective

127:    Input Parameters:
128: +  guess  - the initial guess object for the Krylov method
129: -  viewer - the viewer object

131:   Level: developer

133: .seealso: [](chapter_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `PetscViewer`
134: @*/
135: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
136: {
137:   PetscBool ascii;

140:   if (!view) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess), &view);
143:   PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &ascii);
144:   if (ascii) {
145:     PetscObjectPrintClassNamePrefixType((PetscObject)guess, view);
146:     PetscViewerASCIIPushTab(view);
147:     PetscTryTypeMethod(guess, view, view);
148:     PetscViewerASCIIPopTab(view);
149:   }
150:   return 0;
151: }

153: /*@
154:    KSPGuessCreate - Creates the default `KSPGuess` context.

156:    Collective

158:    Input Parameter:
159: .  comm - MPI communicator

161:    Output Parameter:
162: .  guess - location to put the `KSPGuess` context

164:    Level: developer

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

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

181: /*@C
182:    KSPGuessSetType - Sets the type of a `KSPGuess`

184:    Logically Collective

186:    Input Parameters:
187: +  guess - the initial guess object for the Krylov method
188: -  type  - a known `KSPGuessType`

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

193:   Level: developer

195: .seealso: [](chapter_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`
196: @*/
197: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
198: {
199:   PetscBool match;
200:   PetscErrorCode (*r)(KSPGuess);


205:   PetscObjectTypeCompare((PetscObject)guess, type, &match);
206:   if (match) return 0;

208:   PetscFunctionListFind(KSPGuessList, type, &r);
210:   PetscTryTypeMethod(guess, destroy);
211:   guess->ops->destroy = NULL;

213:   PetscMemzero(guess->ops, sizeof(struct _KSPGuessOps));
214:   PetscObjectChangeTypeName((PetscObject)guess, type);
215:   (*r)(guess);
216:   return 0;
217: }

219: /*@C
220:    KSPGuessGetType - Gets the `KSPGuessType` as a string from the `KSPGuess` object.

222:    Not Collective

224:    Input Parameter:
225: .  guess - the initial guess context

227:    Output Parameter:
228: .  name - type of `KSPGuess` method

230:    Level: developer

232: .seealso: [](chapter_ksp), `KSPGuess`, `KSPGuessSetType()`
233: @*/
234: PetscErrorCode KSPGuessGetType(KSPGuess guess, KSPGuessType *type)
235: {
238:   *type = ((PetscObject)guess)->type_name;
239:   return 0;
240: }

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

245:    Collective

247:    Input Parameters:
248: +  guess - the initial guess context
249: .  rhs   - the corresponding rhs
250: -  sol   - the computed solution

252:    Level: developer

254: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`
255: @*/
256: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
257: {
261:   PetscTryTypeMethod(guess, update, rhs, sol);
262:   return 0;
263: }

265: /*@
266:     KSPGuessFormGuess - Form the initial guess

268:    Collective

270:    Input Parameters:
271: +  guess - the initial guess context
272: .  rhs   - the current rhs vector
273: -  sol   - the initial guess vector

275:    Level: developer

277: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`
278: @*/
279: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
280: {
284:   PetscTryTypeMethod(guess, formguess, rhs, sol);
285:   return 0;
286: }

288: /*@
289:     KSPGuessSetUp - Setup the initial guess object

291:    Collective

293:    Input Parameter:
294: -  guess - the initial guess context

296:    Level: developer

298: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`
299: @*/
300: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
301: {
302:   PetscObjectState matstate;
303:   PetscInt         oM = 0, oN = 0, M, N;
304:   Mat              omat = NULL;
305:   PC               pc;
306:   PetscBool        reuse;

309:   if (guess->A) {
310:     omat = guess->A;
311:     MatGetSize(guess->A, &oM, &oN);
312:   }
313:   KSPGetOperators(guess->ksp, &guess->A, NULL);
314:   KSPGetPC(guess->ksp, &pc);
315:   PCGetReusePreconditioner(pc, &reuse);
316:   PetscObjectReference((PetscObject)guess->A);
317:   MatGetSize(guess->A, &M, &N);
318:   PetscObjectStateGet((PetscObject)guess->A, &matstate);
319:   if (M != oM || N != oN) {
320:     PetscInfo(guess, "Resetting KSPGuess since matrix sizes have changed (%" PetscInt_FMT " != %" PetscInt_FMT ", %" PetscInt_FMT " != %" PetscInt_FMT ")\n", oM, M, oN, N);
321:   } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
322:     PetscInfo(guess, "Resetting KSPGuess since %s has changed\n", omat != guess->A ? "matrix" : "matrix state");
323:     PetscTryTypeMethod(guess, reset);
324:   } else if (reuse) {
325:     PetscInfo(guess, "Not resettting KSPGuess since reuse preconditioner has been specified\n");
326:   } else {
327:     PetscInfo(guess, "KSPGuess status unchanged\n");
328:   }
329:   PetscTryTypeMethod(guess, setup);
330:   guess->omatstate = matstate;
331:   MatDestroy(&omat);
332:   return 0;
333: }