Actual source code: iguess.c
1: #include <petsc/private/kspimpl.h>
3: PetscFunctionList KSPGuessList = NULL;
4: static PetscBool KSPGuessRegisterAllCalled;
6: /*@
7: KSPGuessRegister - Registers a method for initial guess computation in Krylov subspace solver package.
9: Not Collective, No Fortran Support
11: Input Parameters:
12: + sname - name of a new user-defined solver
13: - function - routine to create method context
15: Example Usage:
16: .vb
17: KSPGuessRegister("my_initial_guess", MyInitialGuessCreate);
18: .ve
20: Then, it can be chosen with the procedural interface via
21: .vb
22: KSPGetGuess(ksp, &guess);
23: KSPGuessSetType(guess, "my_initial_guess");
24: .ve
25: or at runtime via the option `-ksp_guess_type my_initial_guess`
27: Level: developer
29: Note:
30: `KSPGuessRegister()` may be called multiple times to add several user-defined solvers.
32: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessRegisterAll()`
33: @*/
34: PetscErrorCode KSPGuessRegister(const char sname[], PetscErrorCode (*function)(KSPGuess))
35: {
36: PetscFunctionBegin;
37: PetscCall(KSPInitializePackage());
38: PetscCall(PetscFunctionListAdd(&KSPGuessList, sname, function));
39: PetscFunctionReturn(PETSC_SUCCESS);
40: }
42: /*@
43: KSPGuessRegisterAll - Registers all `KSPGuess` implementations in the `KSP` package.
45: Not Collective
47: Level: developer
49: .seealso: [](ch_ksp), `KSPGuess`, `KSPRegisterAll()`, `KSPInitializePackage()`
50: @*/
51: PetscErrorCode KSPGuessRegisterAll(void)
52: {
53: PetscFunctionBegin;
54: if (KSPGuessRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
55: KSPGuessRegisterAllCalled = PETSC_TRUE;
56: PetscCall(KSPGuessRegister(KSPGUESSFISCHER, KSPGuessCreate_Fischer));
57: PetscCall(KSPGuessRegister(KSPGUESSPOD, KSPGuessCreate_POD));
58: PetscFunctionReturn(PETSC_SUCCESS);
59: }
61: /*@
62: KSPGuessSetFromOptions - Sets the options for a `KSPGuess` from the options database
64: Collective
66: Input Parameter:
67: . guess - `KSPGuess` object
69: Options Database Keys:
70: + -ksp_guess_type (fischer|pod) - turns on generation of initial guesses and sets the method; see `KSPGuessType`
71: . -ksp_guess_fischer_model model,size - set details for the Fischer models
72: . -ksp_guess_fischer_monitor (true|false) - monitor the Fischer models
73: . -ksp_guess_fischer_tol tol - set the tolerance for the Fischer models
74: . -ksp_guess_pod_size size - number of POD snapshots
75: . -ksp_guess_pod_monitor (true|false) - monitor the POD initial guess processing
76: . -ksp_guess_pod_tol tol - tolerance to retain eigenvectors
77: - -ksp_guess_pod_Ainner (true|false) - use the operator as the inner product (must be SPD)
79: Level: developer
81: .seealso: [](ch_ksp), `KSPGuess`, `KSPGetGuess()`, `KSPGuessSetType()`, `KSPGuessType`
82: @*/
83: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
84: {
85: PetscFunctionBegin;
87: PetscTryTypeMethod(guess, setfromoptions);
88: PetscFunctionReturn(PETSC_SUCCESS);
89: }
91: /*@
92: KSPGuessSetTolerance - Sets the relative tolerance used in either eigenvalue (POD) or singular value (Fischer type 3) calculations.
94: Collective
96: Input Parameters:
97: + guess - `KSPGuess` object
98: - tol - the tolerance
100: Options Database Keys:
101: + -ksp_guess_fischer_tol tol - set the tolerance for the Fischer models
102: - -ksp_guess_pod_tol tol - set the tolerance for the POD models
104: Level: developer
106: Note:
107: Ignored by the first and second Fischer guess types
109: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessType`, `KSPGuessSetFromOptions()`
110: @*/
111: PetscErrorCode KSPGuessSetTolerance(KSPGuess guess, PetscReal tol)
112: {
113: PetscFunctionBegin;
115: PetscTryTypeMethod(guess, settolerance, tol);
116: PetscFunctionReturn(PETSC_SUCCESS);
117: }
119: /*@
120: KSPGuessDestroy - Destroys `KSPGuess` context.
122: Collective
124: Input Parameter:
125: . guess - initial guess object
127: Level: developer
129: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`, `KSPGuessType`
130: @*/
131: PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
132: {
133: PetscFunctionBegin;
134: if (!*guess) PetscFunctionReturn(PETSC_SUCCESS);
136: if (--((PetscObject)*guess)->refct > 0) {
137: *guess = NULL;
138: PetscFunctionReturn(PETSC_SUCCESS);
139: }
140: PetscTryTypeMethod(*guess, destroy);
141: PetscCall(MatDestroy(&(*guess)->A));
142: PetscCall(PetscHeaderDestroy(guess));
143: PetscFunctionReturn(PETSC_SUCCESS);
144: }
146: /*@
147: KSPGuessView - View the `KSPGuess` object
149: Logically Collective
151: Input Parameters:
152: + guess - the initial guess object for the Krylov method
153: - view - the viewer object
155: Level: developer
157: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `PetscViewer`
158: @*/
159: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
160: {
161: PetscBool ascii;
163: PetscFunctionBegin;
165: if (!view) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess), &view));
167: PetscCheckSameComm(guess, 1, view, 2);
168: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &ascii));
169: if (ascii) {
170: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)guess, view));
171: PetscCall(PetscViewerASCIIPushTab(view));
172: PetscTryTypeMethod(guess, view, view);
173: PetscCall(PetscViewerASCIIPopTab(view));
174: }
175: PetscFunctionReturn(PETSC_SUCCESS);
176: }
178: /*@
179: KSPGuessCreate - Creates a `KSPGuess` context.
181: Collective
183: Input Parameter:
184: . comm - MPI communicator
186: Output Parameter:
187: . guess - location to put the `KSPGuess` context
189: Level: developer
191: Notes:
192: These are generally created automatically by using the option `-ksp_guess_type (fischer|pod)` and controlled from the options database.
193: See `KSPGuessSetFromOptions()` for the `KSPGuess` options database keys
195: There are two families of methods `KSPGUESSFISCHER`, developed by Paul Fischer and `KSPGUESSPOD`
197: .seealso: [](ch_ksp), `KSPSolve()`, `KSPGuessDestroy()`, `KSPGuess`, `KSPGuessType`, `KSP`
198: @*/
199: PetscErrorCode KSPGuessCreate(MPI_Comm comm, KSPGuess *guess)
200: {
201: KSPGuess tguess;
203: PetscFunctionBegin;
204: PetscAssertPointer(guess, 2);
205: PetscCall(KSPInitializePackage());
207: PetscCall(PetscHeaderCreate(tguess, KSPGUESS_CLASSID, "KSPGuess", "Initial guess for Krylov Method", "KSPGuess", comm, KSPGuessDestroy, KSPGuessView));
208: PetscCall(MatStateInvalidate(tguess->omatstate));
209: *guess = tguess;
210: PetscFunctionReturn(PETSC_SUCCESS);
211: }
213: /*@
214: KSPGuessSetType - Sets the type of a `KSPGuess`. Each `KSPGuessType` provides a different algorithm for computing the initial guess.
216: Logically Collective
218: Input Parameters:
219: + guess - the initial guess object for the Krylov method
220: - type - a known `KSPGuessType`
222: Options Database Key:
223: . -ksp_guess_type (fischer|pod) - Turns on generation of initial guesses and sets the method; see `KSPGuessType`
225: Level: developer
227: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `KSPGUESSFISCHER`, `KSPGUESSPOD`
228: @*/
229: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
230: {
231: PetscBool match;
232: PetscErrorCode (*r)(KSPGuess);
234: PetscFunctionBegin;
236: PetscAssertPointer(type, 2);
238: PetscCall(PetscObjectTypeCompare((PetscObject)guess, type, &match));
239: if (match) PetscFunctionReturn(PETSC_SUCCESS);
241: PetscCall(PetscFunctionListFind(KSPGuessList, type, &r));
242: PetscCheck(r, PetscObjectComm((PetscObject)guess), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested KSPGuess type %s", type);
243: PetscTryTypeMethod(guess, destroy);
244: guess->ops->destroy = NULL;
246: PetscCall(PetscMemzero(guess->ops, sizeof(struct _KSPGuessOps)));
247: PetscCall(PetscObjectChangeTypeName((PetscObject)guess, type));
248: PetscCall((*r)(guess));
249: PetscFunctionReturn(PETSC_SUCCESS);
250: }
252: /*@
253: KSPGuessGetType - Gets the `KSPGuessType` as a string from the `KSPGuess` object.
255: Not Collective
257: Input Parameter:
258: . guess - the initial guess context
260: Output Parameter:
261: . type - type of `KSPGuess` method
263: Level: developer
265: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessSetType()`
266: @*/
267: PetscErrorCode KSPGuessGetType(KSPGuess guess, KSPGuessType *type)
268: {
269: PetscFunctionBegin;
271: PetscAssertPointer(type, 2);
272: *type = ((PetscObject)guess)->type_name;
273: PetscFunctionReturn(PETSC_SUCCESS);
274: }
276: /*@
277: KSPGuessUpdate - Updates the guess object with the current solution and rhs vector
279: Collective
281: Input Parameters:
282: + guess - the initial guess context
283: . rhs - the corresponding rhs
284: - sol - the computed solution
286: Level: developer
288: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
289: @*/
290: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
291: {
292: PetscFunctionBegin;
296: PetscTryTypeMethod(guess, update, rhs, sol);
297: PetscFunctionReturn(PETSC_SUCCESS);
298: }
300: /*@
301: KSPGuessFormGuess - Form the initial guess
303: Collective
305: Input Parameters:
306: + guess - the initial guess context
307: . rhs - the current right-hand side vector
308: - sol - the initial guess vector
310: Level: developer
312: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
313: @*/
314: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
315: {
316: PetscFunctionBegin;
320: PetscTryTypeMethod(guess, formguess, rhs, sol);
321: PetscFunctionReturn(PETSC_SUCCESS);
322: }
324: /*@
325: KSPGuessSetUp - Setup the initial guess object
327: Collective
329: Input Parameter:
330: . guess - the initial guess context
332: Level: developer
334: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
335: @*/
336: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
337: {
338: PetscInt oM = 0, oN = 0, M, N;
339: Mat omat = NULL;
340: PC pc;
341: PetscBool reuse, same;
342: MatState matstate;
344: PetscFunctionBegin;
346: if (guess->A) {
347: omat = guess->A;
348: PetscCall(MatGetSize(guess->A, &oM, &oN));
349: }
350: PetscCall(KSPGetOperators(guess->ksp, &guess->A, NULL));
351: PetscCall(KSPGetPC(guess->ksp, &pc));
352: PetscCall(PCGetReusePreconditioner(pc, &reuse));
353: PetscCall(PetscObjectReference((PetscObject)guess->A));
354: PetscCall(MatGetSize(guess->A, &M, &N));
355: PetscCall(MatGetState(guess->A, &matstate));
356: PetscCall(MatStateCompare(matstate, guess->omatstate, &same));
357: if (M != oM || N != oN) {
358: PetscCall(PetscInfo(guess, "Resetting KSPGuess since matrix sizes have changed (%" PetscInt_FMT " != %" PetscInt_FMT ", %" PetscInt_FMT " != %" PetscInt_FMT ")\n", oM, M, oN, N));
359: } else if (!reuse && !same) {
360: PetscCall(PetscInfo(guess, "Resetting KSPGuess since %s has changed\n", matstate.id != guess->omatstate.id ? "matrix" : "matrix state"));
361: PetscTryTypeMethod(guess, reset);
362: } else if (reuse) {
363: PetscCall(PetscInfo(guess, "Not resettting KSPGuess since reuse preconditioner has been specified\n"));
364: } else {
365: PetscCall(PetscInfo(guess, "KSPGuess status unchanged\n"));
366: }
367: PetscTryTypeMethod(guess, setup);
368: guess->omatstate = matstate;
369: PetscCall(MatDestroy(&omat));
370: PetscFunctionReturn(PETSC_SUCCESS);
371: }