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: .vb
22: KSPSetGuessType(ksp, "my_initial_guess")
23: .ve
24: or at runtime via the option `-ksp_guess_type my_initial_guess`
26: Level: developer
28: Note:
29: `KSPGuessRegister()` may be called multiple times to add several user-defined solvers.
31: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessRegisterAll()`
32: @*/
33: PetscErrorCode KSPGuessRegister(const char sname[], PetscErrorCode (*function)(KSPGuess))
34: {
35: PetscFunctionBegin;
36: PetscCall(KSPInitializePackage());
37: PetscCall(PetscFunctionListAdd(&KSPGuessList, sname, function));
38: PetscFunctionReturn(PETSC_SUCCESS);
39: }
41: /*@C
42: KSPGuessRegisterAll - Registers all `KSPGuess` implementations in the `KSP` package.
44: Not Collective
46: Level: developer
48: .seealso: [](ch_ksp), `KSPGuess`, `KSPRegisterAll()`, `KSPInitializePackage()`
49: @*/
50: PetscErrorCode KSPGuessRegisterAll(void)
51: {
52: PetscFunctionBegin;
53: if (KSPGuessRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
54: KSPGuessRegisterAllCalled = PETSC_TRUE;
55: PetscCall(KSPGuessRegister(KSPGUESSFISCHER, KSPGuessCreate_Fischer));
56: PetscCall(KSPGuessRegister(KSPGUESSPOD, KSPGuessCreate_POD));
57: PetscFunctionReturn(PETSC_SUCCESS);
58: }
60: /*@
61: KSPGuessSetFromOptions - Sets the options for a `KSPGuess` from the options database
63: Collective
65: Input Parameter:
66: . guess - `KSPGuess` object
68: Options Database Keys:
69: + -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
70: . -ksp_guess_view <viewer> - view the `KSPGuess` object
71: . -ksp_guess_fischer_model <a,b> - set details for the Fischer models
72: . -ksp_guess_fischer_monitor - 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 snapshots
75: . -ksp_guess_pod_monitor true - monitor the pod initial guess processing
76: . -ksp_guess_pod_tol <tol> - Tolerance to retain eigenvectors
77: - -ksp_guess_pod_Ainner true - Use the operator as inner product (must be SPD)
79: Level: developer
81: .seealso: [](ch_ksp), `KSPGuess`, `KSPGetGuess()`, `KSPSetGuessType()`, `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 Key:
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: /*@C
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: Options Database Key:
156: . -ksp_guess_view viewer - view the `KSPGuess` object
158: Level: developer
160: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `PetscViewer`
161: @*/
162: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
163: {
164: PetscBool ascii;
166: PetscFunctionBegin;
168: if (!view) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess), &view));
170: PetscCheckSameComm(guess, 1, view, 2);
171: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &ascii));
172: if (ascii) {
173: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)guess, view));
174: PetscCall(PetscViewerASCIIPushTab(view));
175: PetscTryTypeMethod(guess, view, view);
176: PetscCall(PetscViewerASCIIPopTab(view));
177: }
178: PetscFunctionReturn(PETSC_SUCCESS);
179: }
181: /*@
182: KSPGuessCreate - Creates a `KSPGuess` context.
184: Collective
186: Input Parameter:
187: . comm - MPI communicator
189: Output Parameter:
190: . guess - location to put the `KSPGuess` context
192: Options Database Keys:
193: + -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
194: . -ksp_guess_view <viewer> - view the `KSPGuess` object
195: . -ksp_guess_fischer_model <a,b> - set details for the Fischer models
196: . -ksp_guess_fischer_monitor - monitor the fischer models
197: . -ksp_guess_fischer_tol <tol> - set the tolerance for the Fischer models
198: . -ksp_guess_pod_size <size> - Number of snapshots
199: . -ksp_guess_pod_monitor true - monitor the pod initial guess processing
200: . -ksp_guess_pod_tol <tol> - Tolerance to retain eigenvectors
201: - -ksp_guess_pod_Ainner true - Use the operator as inner product (must be SPD)
203: Level: developer
205: Note:
206: These are generally created automatically by using the option `-ksp_guess_type type` and controlled from the options database
208: There are two families of methods `KSPGUESSFISCHER`, developed by Paul Fischer and `KSPGUESSPOD`
210: .seealso: [](ch_ksp), `KSPSolve()`, `KSPGuessDestroy()`, `KSPGuess`, `KSPGuessType`, `KSP`
211: @*/
212: PetscErrorCode KSPGuessCreate(MPI_Comm comm, KSPGuess *guess)
213: {
214: KSPGuess tguess;
216: PetscFunctionBegin;
217: PetscAssertPointer(guess, 2);
218: *guess = NULL;
219: PetscCall(KSPInitializePackage());
220: PetscCall(PetscHeaderCreate(tguess, KSPGUESS_CLASSID, "KSPGuess", "Initial guess for Krylov Method", "KSPGuess", comm, KSPGuessDestroy, KSPGuessView));
221: tguess->omatstate = -1;
222: *guess = tguess;
223: PetscFunctionReturn(PETSC_SUCCESS);
224: }
226: /*@C
227: KSPGuessSetType - Sets the type of a `KSPGuess`
229: Logically Collective
231: Input Parameters:
232: + guess - the initial guess object for the Krylov method
233: - type - a known `KSPGuessType`
235: Options Database Key:
236: . -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
238: Level: developer
240: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`
241: @*/
242: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
243: {
244: PetscBool match;
245: PetscErrorCode (*r)(KSPGuess);
247: PetscFunctionBegin;
249: PetscAssertPointer(type, 2);
251: PetscCall(PetscObjectTypeCompare((PetscObject)guess, type, &match));
252: if (match) PetscFunctionReturn(PETSC_SUCCESS);
254: PetscCall(PetscFunctionListFind(KSPGuessList, type, &r));
255: PetscCheck(r, PetscObjectComm((PetscObject)guess), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested KSPGuess type %s", type);
256: PetscTryTypeMethod(guess, destroy);
257: guess->ops->destroy = NULL;
259: PetscCall(PetscMemzero(guess->ops, sizeof(struct _KSPGuessOps)));
260: PetscCall(PetscObjectChangeTypeName((PetscObject)guess, type));
261: PetscCall((*r)(guess));
262: PetscFunctionReturn(PETSC_SUCCESS);
263: }
265: /*@C
266: KSPGuessGetType - Gets the `KSPGuessType` as a string from the `KSPGuess` object.
268: Not Collective
270: Input Parameter:
271: . guess - the initial guess context
273: Output Parameter:
274: . type - type of `KSPGuess` method
276: Level: developer
278: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessSetType()`
279: @*/
280: PetscErrorCode KSPGuessGetType(KSPGuess guess, KSPGuessType *type)
281: {
282: PetscFunctionBegin;
284: PetscAssertPointer(type, 2);
285: *type = ((PetscObject)guess)->type_name;
286: PetscFunctionReturn(PETSC_SUCCESS);
287: }
289: /*@
290: KSPGuessUpdate - Updates the guess object with the current solution and rhs vector
292: Collective
294: Input Parameters:
295: + guess - the initial guess context
296: . rhs - the corresponding rhs
297: - sol - the computed solution
299: Level: developer
301: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
302: @*/
303: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
304: {
305: PetscFunctionBegin;
309: PetscTryTypeMethod(guess, update, rhs, sol);
310: PetscFunctionReturn(PETSC_SUCCESS);
311: }
313: /*@
314: KSPGuessFormGuess - Form the initial guess
316: Collective
318: Input Parameters:
319: + guess - the initial guess context
320: . rhs - the current right hand side vector
321: - sol - the initial guess vector
323: Level: developer
325: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
326: @*/
327: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
328: {
329: PetscFunctionBegin;
333: PetscTryTypeMethod(guess, formguess, rhs, sol);
334: PetscFunctionReturn(PETSC_SUCCESS);
335: }
337: /*@
338: KSPGuessSetUp - Setup the initial guess object
340: Collective
342: Input Parameter:
343: . guess - the initial guess context
345: Level: developer
347: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
348: @*/
349: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
350: {
351: PetscObjectState matstate;
352: PetscInt oM = 0, oN = 0, M, N;
353: Mat omat = NULL;
354: PC pc;
355: PetscBool reuse;
357: PetscFunctionBegin;
359: if (guess->A) {
360: omat = guess->A;
361: PetscCall(MatGetSize(guess->A, &oM, &oN));
362: }
363: PetscCall(KSPGetOperators(guess->ksp, &guess->A, NULL));
364: PetscCall(KSPGetPC(guess->ksp, &pc));
365: PetscCall(PCGetReusePreconditioner(pc, &reuse));
366: PetscCall(PetscObjectReference((PetscObject)guess->A));
367: PetscCall(MatGetSize(guess->A, &M, &N));
368: PetscCall(PetscObjectStateGet((PetscObject)guess->A, &matstate));
369: if (M != oM || N != oN) {
370: PetscCall(PetscInfo(guess, "Resetting KSPGuess since matrix sizes have changed (%" PetscInt_FMT " != %" PetscInt_FMT ", %" PetscInt_FMT " != %" PetscInt_FMT ")\n", oM, M, oN, N));
371: } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
372: PetscCall(PetscInfo(guess, "Resetting KSPGuess since %s has changed\n", omat != guess->A ? "matrix" : "matrix state"));
373: PetscTryTypeMethod(guess, reset);
374: } else if (reuse) {
375: PetscCall(PetscInfo(guess, "Not resettting KSPGuess since reuse preconditioner has been specified\n"));
376: } else {
377: PetscCall(PetscInfo(guess, "KSPGuess status unchanged\n"));
378: }
379: PetscTryTypeMethod(guess, setup);
380: guess->omatstate = matstate;
381: PetscCall(MatDestroy(&omat));
382: PetscFunctionReturn(PETSC_SUCCESS);
383: }