Actual source code: iguess.c
1: #include <petsc/private/kspimpl.h>
3: PetscFunctionList KSPGuessList = NULL;
4: static PetscBool KSPGuessRegisterAllCalled;
6: /*@C
7: KSPGuessRegister - Registers a method for initial guess computation in Krylov subspace solver package.
9: Not Collective
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: $ KSPSetGuessType(ksp, "my_initial_guess")
22: or at runtime via the option
23: $ -ksp_guess_type my_initial_guess
25: Level: developer
27: Note:
28: `KSPGuessRegister()` may be called multiple times to add several user-defined solvers.
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: Options Database Keys:
68: + -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
69: . -ksp_guess_view <viewer> - view the `KSPGuess` object
70: . -ksp_guess_fischer_model <a,b> - set details for the Fischer models
71: . -ksp_guess_fischer_monitor - monitor the Fischer models
72: . -ksp_guess_fischer_tol <tol> - set the tolerance for the Fischer models
73: . -ksp_guess_pod_size <size> - Number of snapshots
74: . -ksp_guess_pod_monitor true - monitor the pod initial guess processing
75: . -ksp_guess_pod_tol <tol> - Tolerance to retain eigenvectors
76: - -ksp_guess_pod_Ainner true - Use the operator as inner product (must be SPD)
78: Level: developer
80: .seealso: [](ch_ksp), `KSPGuess`, `KSPGetGuess()`, `KSPSetGuessType()`, `KSPGuessType`
81: @*/
82: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
83: {
84: PetscFunctionBegin;
86: PetscTryTypeMethod(guess, setfromoptions);
87: PetscFunctionReturn(PETSC_SUCCESS);
88: }
90: /*@
91: KSPGuessSetTolerance - Sets the relative tolerance used in either eigenvalue (POD) or singular value (Fischer type 3) calculations.
93: Collective
95: Input Parameters:
96: + guess - `KSPGuess` object
97: - tol - the tolerance
99: Options Database Key:
100: + -ksp_guess_fischer_tol <tol> - set the tolerance for the Fischer models
101: - -ksp_guess_pod_tol <tol> - set the tolerance for the Pod models
103: Level: developer
105: Note:
106: Ignored by the first and second Fischer guess types
108: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessType`, `KSPGuessSetFromOptions()`
109: @*/
110: PetscErrorCode KSPGuessSetTolerance(KSPGuess guess, PetscReal tol)
111: {
112: PetscFunctionBegin;
114: PetscTryTypeMethod(guess, settolerance, tol);
115: PetscFunctionReturn(PETSC_SUCCESS);
116: }
118: /*@
119: KSPGuessDestroy - Destroys `KSPGuess` context.
121: Collective
123: Input Parameter:
124: . guess - initial guess object
126: Level: developer
128: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`, `KSPGuessType`
129: @*/
130: PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
131: {
132: PetscFunctionBegin;
133: if (!*guess) PetscFunctionReturn(PETSC_SUCCESS);
135: if (--((PetscObject)(*guess))->refct > 0) {
136: *guess = NULL;
137: PetscFunctionReturn(PETSC_SUCCESS);
138: }
139: PetscTryTypeMethod((*guess), destroy);
140: PetscCall(MatDestroy(&(*guess)->A));
141: PetscCall(PetscHeaderDestroy(guess));
142: PetscFunctionReturn(PETSC_SUCCESS);
143: }
145: /*@C
146: KSPGuessView - View the `KSPGuess` object
148: Logically Collective
150: Input Parameters:
151: + guess - the initial guess object for the Krylov method
152: - view - the viewer object
154: Options Database Key:
155: . -ksp_guess_view viewer - view the `KSPGuess` object
157: Level: developer
159: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `PetscViewer`
160: @*/
161: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
162: {
163: PetscBool ascii;
165: PetscFunctionBegin;
167: if (!view) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess), &view));
169: PetscCheckSameComm(guess, 1, view, 2);
170: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &ascii));
171: if (ascii) {
172: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)guess, view));
173: PetscCall(PetscViewerASCIIPushTab(view));
174: PetscTryTypeMethod(guess, view, view);
175: PetscCall(PetscViewerASCIIPopTab(view));
176: }
177: PetscFunctionReturn(PETSC_SUCCESS);
178: }
180: /*@
181: KSPGuessCreate - Creates a `KSPGuess` context.
183: Collective
185: Input Parameter:
186: . comm - MPI communicator
188: Output Parameter:
189: . guess - location to put the `KSPGuess` context
191: Options Database Keys:
192: + -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
193: . -ksp_guess_view <viewer> - view the `KSPGuess` object
194: . -ksp_guess_fischer_model <a,b> - set details for the Fischer models
195: . -ksp_guess_fischer_monitor - monitor the fischer models
196: . -ksp_guess_fischer_tol <tol> - set the tolerance for the Fischer models
197: . -ksp_guess_pod_size <size> - Number of snapshots
198: . -ksp_guess_pod_monitor true - monitor the pod initial guess processing
199: . -ksp_guess_pod_tol <tol> - Tolerance to retain eigenvectors
200: - -ksp_guess_pod_Ainner true - Use the operator as inner product (must be SPD)
202: Level: developer
204: Note:
205: These are generally created automatically by using the option `-ksp_guess_type type` and controlled from the options database
207: There are two families of methods `KSPGUESSFISCHER`, developed by Paul Fischer and `KSPGUESSPOD`
209: .seealso: [](ch_ksp), `KSPSolve()`, `KSPGuessDestroy()`, `KSPGuess`, `KSPGuessType`, `KSP`
210: @*/
211: PetscErrorCode KSPGuessCreate(MPI_Comm comm, KSPGuess *guess)
212: {
213: KSPGuess tguess;
215: PetscFunctionBegin;
216: PetscAssertPointer(guess, 2);
217: *guess = NULL;
218: PetscCall(KSPInitializePackage());
219: PetscCall(PetscHeaderCreate(tguess, KSPGUESS_CLASSID, "KSPGuess", "Initial guess for Krylov Method", "KSPGuess", comm, KSPGuessDestroy, KSPGuessView));
220: tguess->omatstate = -1;
221: *guess = tguess;
222: PetscFunctionReturn(PETSC_SUCCESS);
223: }
225: /*@C
226: KSPGuessSetType - Sets the type of a `KSPGuess`
228: Logically Collective
230: Input Parameters:
231: + guess - the initial guess object for the Krylov method
232: - type - a known `KSPGuessType`
234: Options Database Key:
235: . -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
237: Level: developer
239: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`
240: @*/
241: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
242: {
243: PetscBool match;
244: PetscErrorCode (*r)(KSPGuess);
246: PetscFunctionBegin;
248: PetscAssertPointer(type, 2);
250: PetscCall(PetscObjectTypeCompare((PetscObject)guess, type, &match));
251: if (match) PetscFunctionReturn(PETSC_SUCCESS);
253: PetscCall(PetscFunctionListFind(KSPGuessList, type, &r));
254: PetscCheck(r, PetscObjectComm((PetscObject)guess), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested KSPGuess type %s", type);
255: PetscTryTypeMethod(guess, destroy);
256: guess->ops->destroy = NULL;
258: PetscCall(PetscMemzero(guess->ops, sizeof(struct _KSPGuessOps)));
259: PetscCall(PetscObjectChangeTypeName((PetscObject)guess, type));
260: PetscCall((*r)(guess));
261: PetscFunctionReturn(PETSC_SUCCESS);
262: }
264: /*@C
265: KSPGuessGetType - Gets the `KSPGuessType` as a string from the `KSPGuess` object.
267: Not Collective
269: Input Parameter:
270: . guess - the initial guess context
272: Output Parameter:
273: . type - type of `KSPGuess` method
275: Level: developer
277: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessSetType()`
278: @*/
279: PetscErrorCode KSPGuessGetType(KSPGuess guess, KSPGuessType *type)
280: {
281: PetscFunctionBegin;
283: PetscAssertPointer(type, 2);
284: *type = ((PetscObject)guess)->type_name;
285: PetscFunctionReturn(PETSC_SUCCESS);
286: }
288: /*@
289: KSPGuessUpdate - Updates the guess object with the current solution and rhs vector
291: Collective
293: Input Parameters:
294: + guess - the initial guess context
295: . rhs - the corresponding rhs
296: - sol - the computed solution
298: Level: developer
300: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
301: @*/
302: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
303: {
304: PetscFunctionBegin;
308: PetscTryTypeMethod(guess, update, rhs, sol);
309: PetscFunctionReturn(PETSC_SUCCESS);
310: }
312: /*@
313: KSPGuessFormGuess - Form the initial guess
315: Collective
317: Input Parameters:
318: + guess - the initial guess context
319: . rhs - the current right hand side vector
320: - sol - the initial guess vector
322: Level: developer
324: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
325: @*/
326: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
327: {
328: PetscFunctionBegin;
332: PetscTryTypeMethod(guess, formguess, rhs, sol);
333: PetscFunctionReturn(PETSC_SUCCESS);
334: }
336: /*@
337: KSPGuessSetUp - Setup the initial guess object
339: Collective
341: Input Parameter:
342: . guess - the initial guess context
344: Level: developer
346: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
347: @*/
348: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
349: {
350: PetscObjectState matstate;
351: PetscInt oM = 0, oN = 0, M, N;
352: Mat omat = NULL;
353: PC pc;
354: PetscBool reuse;
356: PetscFunctionBegin;
358: if (guess->A) {
359: omat = guess->A;
360: PetscCall(MatGetSize(guess->A, &oM, &oN));
361: }
362: PetscCall(KSPGetOperators(guess->ksp, &guess->A, NULL));
363: PetscCall(KSPGetPC(guess->ksp, &pc));
364: PetscCall(PCGetReusePreconditioner(pc, &reuse));
365: PetscCall(PetscObjectReference((PetscObject)guess->A));
366: PetscCall(MatGetSize(guess->A, &M, &N));
367: PetscCall(PetscObjectStateGet((PetscObject)guess->A, &matstate));
368: if (M != oM || N != oN) {
369: PetscCall(PetscInfo(guess, "Resetting KSPGuess since matrix sizes have changed (%" PetscInt_FMT " != %" PetscInt_FMT ", %" PetscInt_FMT " != %" PetscInt_FMT ")\n", oM, M, oN, N));
370: } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
371: PetscCall(PetscInfo(guess, "Resetting KSPGuess since %s has changed\n", omat != guess->A ? "matrix" : "matrix state"));
372: PetscTryTypeMethod(guess, reset);
373: } else if (reuse) {
374: PetscCall(PetscInfo(guess, "Not resettting KSPGuess since reuse preconditioner has been specified\n"));
375: } else {
376: PetscCall(PetscInfo(guess, "KSPGuess status unchanged\n"));
377: }
378: PetscTryTypeMethod(guess, setup);
379: guess->omatstate = matstate;
380: PetscCall(MatDestroy(&omat));
381: PetscFunctionReturn(PETSC_SUCCESS);
382: }