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: [](ch_ksp), `KSPGuess`, `KSPGuessRegisterAll()`
 31: @*/
 32: PetscErrorCode KSPGuessRegister(const char sname[], PetscErrorCode (*function)(KSPGuess))
 33: {
 34:   PetscFunctionBegin;
 35:   PetscCall(KSPInitializePackage());
 36:   PetscCall(PetscFunctionListAdd(&KSPGuessList, sname, function));
 37:   PetscFunctionReturn(PETSC_SUCCESS);
 38: }

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

 43:   Not Collective

 45:   Level: developer

 47: .seealso: [](ch_ksp), `KSPGuess`, `KSPRegisterAll()`, `KSPInitializePackage()`
 48: @*/
 49: PetscErrorCode KSPGuessRegisterAll(void)
 50: {
 51:   PetscFunctionBegin;
 52:   if (KSPGuessRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
 53:   KSPGuessRegisterAllCalled = PETSC_TRUE;
 54:   PetscCall(KSPGuessRegister(KSPGUESSFISCHER, KSPGuessCreate_Fischer));
 55:   PetscCall(KSPGuessRegister(KSPGUESSPOD, KSPGuessCreate_POD));
 56:   PetscFunctionReturn(PETSC_SUCCESS);
 57: }

 59: /*@
 60:     KSPGuessSetFromOptions - Sets the options for a `KSPGuess` from the options database

 62:     Collective

 64:     Input Parameter:
 65: .    guess - `KSPGuess` object

 67:    Level: developer

 69: .seealso: [](ch_ksp), `KSPGuess`, `KSPGetGuess()`, `KSPSetGuessType()`, `KSPGuessType`
 70: @*/
 71: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
 72: {
 73:   PetscFunctionBegin;
 75:   PetscTryTypeMethod(guess, setfromoptions);
 76:   PetscFunctionReturn(PETSC_SUCCESS);
 77: }

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

 83:     Collective

 85:     Input Parameter:
 86: .    guess - `KSPGuess` object

 88:    Level: developer

 90: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessType`, `KSPGuessSetFromOptions()`
 91: @*/
 92: PetscErrorCode KSPGuessSetTolerance(KSPGuess guess, PetscReal tol)
 93: {
 94:   PetscFunctionBegin;
 96:   PetscTryTypeMethod(guess, settolerance, tol);
 97:   PetscFunctionReturn(PETSC_SUCCESS);
 98: }

100: /*@
101:    KSPGuessDestroy - Destroys `KSPGuess` context.

103:    Collective

105:    Input Parameter:
106: .  guess - initial guess object

108:    Level: developer

110: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`, `KSPGuessType`
111: @*/
112: PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
113: {
114:   PetscFunctionBegin;
115:   if (!*guess) PetscFunctionReturn(PETSC_SUCCESS);
117:   if (--((PetscObject)(*guess))->refct > 0) {
118:     *guess = NULL;
119:     PetscFunctionReturn(PETSC_SUCCESS);
120:   }
121:   PetscTryTypeMethod((*guess), destroy);
122:   PetscCall(MatDestroy(&(*guess)->A));
123:   PetscCall(PetscHeaderDestroy(guess));
124:   PetscFunctionReturn(PETSC_SUCCESS);
125: }

127: /*@C
128:    KSPGuessView - View the `KSPGuess` object

130:    Logically Collective

132:    Input Parameters:
133: +  guess  - the initial guess object for the Krylov method
134: -  viewer - the viewer object

136:   Level: developer

138: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `PetscViewer`
139: @*/
140: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
141: {
142:   PetscBool ascii;

144:   PetscFunctionBegin;
146:   if (!view) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess), &view));
148:   PetscCheckSameComm(guess, 1, view, 2);
149:   PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &ascii));
150:   if (ascii) {
151:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)guess, view));
152:     PetscCall(PetscViewerASCIIPushTab(view));
153:     PetscTryTypeMethod(guess, view, view);
154:     PetscCall(PetscViewerASCIIPopTab(view));
155:   }
156:   PetscFunctionReturn(PETSC_SUCCESS);
157: }

159: /*@
160:    KSPGuessCreate - Creates the default `KSPGuess` context.

162:    Collective

164:    Input Parameter:
165: .  comm - MPI communicator

167:    Output Parameter:
168: .  guess - location to put the `KSPGuess` context

170:    Level: developer

172: .seealso: [](ch_ksp), `KSPSolve()`, `KSPGuessDestroy()`, `KSPGuess`, `KSPGuessType`, `KSP`
173: @*/
174: PetscErrorCode KSPGuessCreate(MPI_Comm comm, KSPGuess *guess)
175: {
176:   KSPGuess tguess;

178:   PetscFunctionBegin;
180:   *guess = NULL;
181:   PetscCall(KSPInitializePackage());
182:   PetscCall(PetscHeaderCreate(tguess, KSPGUESS_CLASSID, "KSPGuess", "Initial guess for Krylov Method", "KSPGuess", comm, KSPGuessDestroy, KSPGuessView));
183:   tguess->omatstate = -1;
184:   *guess            = tguess;
185:   PetscFunctionReturn(PETSC_SUCCESS);
186: }

188: /*@C
189:    KSPGuessSetType - Sets the type of a `KSPGuess`

191:    Logically Collective

193:    Input Parameters:
194: +  guess - the initial guess object for the Krylov method
195: -  type  - a known `KSPGuessType`

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

200:   Level: developer

202: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`
203: @*/
204: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
205: {
206:   PetscBool match;
207:   PetscErrorCode (*r)(KSPGuess);

209:   PetscFunctionBegin;

213:   PetscCall(PetscObjectTypeCompare((PetscObject)guess, type, &match));
214:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

216:   PetscCall(PetscFunctionListFind(KSPGuessList, type, &r));
217:   PetscCheck(r, PetscObjectComm((PetscObject)guess), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested KSPGuess type %s", type);
218:   PetscTryTypeMethod(guess, destroy);
219:   guess->ops->destroy = NULL;

221:   PetscCall(PetscMemzero(guess->ops, sizeof(struct _KSPGuessOps)));
222:   PetscCall(PetscObjectChangeTypeName((PetscObject)guess, type));
223:   PetscCall((*r)(guess));
224:   PetscFunctionReturn(PETSC_SUCCESS);
225: }

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

230:    Not Collective

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

235:    Output Parameter:
236: .  name - type of `KSPGuess` method

238:    Level: developer

240: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessSetType()`
241: @*/
242: PetscErrorCode KSPGuessGetType(KSPGuess guess, KSPGuessType *type)
243: {
244:   PetscFunctionBegin;
247:   *type = ((PetscObject)guess)->type_name;
248:   PetscFunctionReturn(PETSC_SUCCESS);
249: }

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

254:    Collective

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

261:    Level: developer

263: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
264: @*/
265: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
266: {
267:   PetscFunctionBegin;
271:   PetscTryTypeMethod(guess, update, rhs, sol);
272:   PetscFunctionReturn(PETSC_SUCCESS);
273: }

275: /*@
276:     KSPGuessFormGuess - Form the initial guess

278:    Collective

280:    Input Parameters:
281: +  guess - the initial guess context
282: .  rhs   - the current rhs vector
283: -  sol   - the initial guess vector

285:    Level: developer

287: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
288: @*/
289: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
290: {
291:   PetscFunctionBegin;
295:   PetscTryTypeMethod(guess, formguess, rhs, sol);
296:   PetscFunctionReturn(PETSC_SUCCESS);
297: }

299: /*@
300:     KSPGuessSetUp - Setup the initial guess object

302:    Collective

304:    Input Parameter:
305: -  guess - the initial guess context

307:    Level: developer

309: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
310: @*/
311: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
312: {
313:   PetscObjectState matstate;
314:   PetscInt         oM = 0, oN = 0, M, N;
315:   Mat              omat = NULL;
316:   PC               pc;
317:   PetscBool        reuse;

319:   PetscFunctionBegin;
321:   if (guess->A) {
322:     omat = guess->A;
323:     PetscCall(MatGetSize(guess->A, &oM, &oN));
324:   }
325:   PetscCall(KSPGetOperators(guess->ksp, &guess->A, NULL));
326:   PetscCall(KSPGetPC(guess->ksp, &pc));
327:   PetscCall(PCGetReusePreconditioner(pc, &reuse));
328:   PetscCall(PetscObjectReference((PetscObject)guess->A));
329:   PetscCall(MatGetSize(guess->A, &M, &N));
330:   PetscCall(PetscObjectStateGet((PetscObject)guess->A, &matstate));
331:   if (M != oM || N != oN) {
332:     PetscCall(PetscInfo(guess, "Resetting KSPGuess since matrix sizes have changed (%" PetscInt_FMT " != %" PetscInt_FMT ", %" PetscInt_FMT " != %" PetscInt_FMT ")\n", oM, M, oN, N));
333:   } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
334:     PetscCall(PetscInfo(guess, "Resetting KSPGuess since %s has changed\n", omat != guess->A ? "matrix" : "matrix state"));
335:     PetscTryTypeMethod(guess, reset);
336:   } else if (reuse) {
337:     PetscCall(PetscInfo(guess, "Not resettting KSPGuess since reuse preconditioner has been specified\n"));
338:   } else {
339:     PetscCall(PetscInfo(guess, "KSPGuess status unchanged\n"));
340:   }
341:   PetscTryTypeMethod(guess, setup);
342:   guess->omatstate = matstate;
343:   PetscCall(MatDestroy(&omat));
344:   PetscFunctionReturn(PETSC_SUCCESS);
345: }