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: 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: /*@C
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 <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
71: . -ksp_guess_view <viewer> - view the `KSPGuess` object
72: . -ksp_guess_fischer_model <a,b> - set details for the Fischer models
73: . -ksp_guess_fischer_monitor - monitor the Fischer models
74: . -ksp_guess_fischer_tol <tol> - set the tolerance for the Fischer models
75: . -ksp_guess_pod_size <size> - Number of snapshots
76: . -ksp_guess_pod_monitor true - monitor the pod initial guess processing
77: . -ksp_guess_pod_tol <tol> - Tolerance to retain eigenvectors
78: - -ksp_guess_pod_Ainner true - Use the operator as inner product (must be SPD)
80: Level: developer
82: .seealso: [](ch_ksp), `KSPGuess`, `KSPGetGuess()`, `KSPGuessSetType()`, `KSPGuessType`
83: @*/
84: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
85: {
86: PetscFunctionBegin;
88: PetscTryTypeMethod(guess, setfromoptions);
89: PetscFunctionReturn(PETSC_SUCCESS);
90: }
92: /*@
93: KSPGuessSetTolerance - Sets the relative tolerance used in either eigenvalue (POD) or singular value (Fischer type 3) calculations.
95: Collective
97: Input Parameters:
98: + guess - `KSPGuess` object
99: - tol - the tolerance
101: Options Database Key:
102: + -ksp_guess_fischer_tol <tol> - set the tolerance for the Fischer models
103: - -ksp_guess_pod_tol <tol> - set the tolerance for the Pod models
105: Level: developer
107: Note:
108: Ignored by the first and second Fischer guess types
110: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessType`, `KSPGuessSetFromOptions()`
111: @*/
112: PetscErrorCode KSPGuessSetTolerance(KSPGuess guess, PetscReal tol)
113: {
114: PetscFunctionBegin;
116: PetscTryTypeMethod(guess, settolerance, tol);
117: PetscFunctionReturn(PETSC_SUCCESS);
118: }
120: /*@
121: KSPGuessDestroy - Destroys `KSPGuess` context.
123: Collective
125: Input Parameter:
126: . guess - initial guess object
128: Level: developer
130: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`, `KSPGuessType`
131: @*/
132: PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
133: {
134: PetscFunctionBegin;
135: if (!*guess) PetscFunctionReturn(PETSC_SUCCESS);
137: if (--((PetscObject)*guess)->refct > 0) {
138: *guess = NULL;
139: PetscFunctionReturn(PETSC_SUCCESS);
140: }
141: PetscTryTypeMethod(*guess, destroy);
142: PetscCall(MatDestroy(&(*guess)->A));
143: PetscCall(PetscHeaderDestroy(guess));
144: PetscFunctionReturn(PETSC_SUCCESS);
145: }
147: /*@C
148: KSPGuessView - View the `KSPGuess` object
150: Logically Collective
152: Input Parameters:
153: + guess - the initial guess object for the Krylov method
154: - view - the viewer object
156: Options Database Key:
157: . -ksp_guess_view viewer - view the `KSPGuess` object
159: Level: developer
161: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `PetscViewer`
162: @*/
163: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
164: {
165: PetscBool ascii;
167: PetscFunctionBegin;
169: if (!view) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess), &view));
171: PetscCheckSameComm(guess, 1, view, 2);
172: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &ascii));
173: if (ascii) {
174: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)guess, view));
175: PetscCall(PetscViewerASCIIPushTab(view));
176: PetscTryTypeMethod(guess, view, view);
177: PetscCall(PetscViewerASCIIPopTab(view));
178: }
179: PetscFunctionReturn(PETSC_SUCCESS);
180: }
182: /*@
183: KSPGuessCreate - Creates a `KSPGuess` context.
185: Collective
187: Input Parameter:
188: . comm - MPI communicator
190: Output Parameter:
191: . guess - location to put the `KSPGuess` context
193: Options Database Keys:
194: + -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
195: . -ksp_guess_view <viewer> - view the `KSPGuess` object
196: . -ksp_guess_fischer_model <a,b> - set details for the Fischer models
197: . -ksp_guess_fischer_monitor - monitor the fischer models
198: . -ksp_guess_fischer_tol <tol> - set the tolerance for the Fischer models
199: . -ksp_guess_pod_size <size> - Number of snapshots
200: . -ksp_guess_pod_monitor true - monitor the pod initial guess processing
201: . -ksp_guess_pod_tol <tol> - Tolerance to retain eigenvectors
202: - -ksp_guess_pod_Ainner true - Use the operator as inner product (must be SPD)
204: Level: developer
206: Note:
207: These are generally created automatically by using the option `-ksp_guess_type type` and controlled from the options database
209: There are two families of methods `KSPGUESSFISCHER`, developed by Paul Fischer and `KSPGUESSPOD`
211: .seealso: [](ch_ksp), `KSPSolve()`, `KSPGuessDestroy()`, `KSPGuess`, `KSPGuessType`, `KSP`
212: @*/
213: PetscErrorCode KSPGuessCreate(MPI_Comm comm, KSPGuess *guess)
214: {
215: KSPGuess tguess;
217: PetscFunctionBegin;
218: PetscAssertPointer(guess, 2);
219: *guess = NULL;
220: PetscCall(KSPInitializePackage());
221: PetscCall(PetscHeaderCreate(tguess, KSPGUESS_CLASSID, "KSPGuess", "Initial guess for Krylov Method", "KSPGuess", comm, KSPGuessDestroy, KSPGuessView));
222: tguess->omatstate = -1;
223: *guess = tguess;
224: PetscFunctionReturn(PETSC_SUCCESS);
225: }
227: /*@C
228: KSPGuessSetType - Sets the type of a `KSPGuess`
230: Logically Collective
232: Input Parameters:
233: + guess - the initial guess object for the Krylov method
234: - type - a known `KSPGuessType`
236: Options Database Key:
237: . -ksp_guess_type <method> - Turns on generation of initial guesses and sets the method; use -help for a list of available methods
239: Level: developer
241: .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`
242: @*/
243: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
244: {
245: PetscBool match;
246: PetscErrorCode (*r)(KSPGuess);
248: PetscFunctionBegin;
250: PetscAssertPointer(type, 2);
252: PetscCall(PetscObjectTypeCompare((PetscObject)guess, type, &match));
253: if (match) PetscFunctionReturn(PETSC_SUCCESS);
255: PetscCall(PetscFunctionListFind(KSPGuessList, type, &r));
256: PetscCheck(r, PetscObjectComm((PetscObject)guess), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested KSPGuess type %s", type);
257: PetscTryTypeMethod(guess, destroy);
258: guess->ops->destroy = NULL;
260: PetscCall(PetscMemzero(guess->ops, sizeof(struct _KSPGuessOps)));
261: PetscCall(PetscObjectChangeTypeName((PetscObject)guess, type));
262: PetscCall((*r)(guess));
263: PetscFunctionReturn(PETSC_SUCCESS);
264: }
266: /*@C
267: KSPGuessGetType - Gets the `KSPGuessType` as a string from the `KSPGuess` object.
269: Not Collective
271: Input Parameter:
272: . guess - the initial guess context
274: Output Parameter:
275: . type - type of `KSPGuess` method
277: Level: developer
279: .seealso: [](ch_ksp), `KSPGuess`, `KSPGuessSetType()`
280: @*/
281: PetscErrorCode KSPGuessGetType(KSPGuess guess, KSPGuessType *type)
282: {
283: PetscFunctionBegin;
285: PetscAssertPointer(type, 2);
286: *type = ((PetscObject)guess)->type_name;
287: PetscFunctionReturn(PETSC_SUCCESS);
288: }
290: /*@
291: KSPGuessUpdate - Updates the guess object with the current solution and rhs vector
293: Collective
295: Input Parameters:
296: + guess - the initial guess context
297: . rhs - the corresponding rhs
298: - sol - the computed solution
300: Level: developer
302: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
303: @*/
304: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
305: {
306: PetscFunctionBegin;
310: PetscTryTypeMethod(guess, update, rhs, sol);
311: PetscFunctionReturn(PETSC_SUCCESS);
312: }
314: /*@
315: KSPGuessFormGuess - Form the initial guess
317: Collective
319: Input Parameters:
320: + guess - the initial guess context
321: . rhs - the current right-hand side vector
322: - sol - the initial guess vector
324: Level: developer
326: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
327: @*/
328: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
329: {
330: PetscFunctionBegin;
334: PetscTryTypeMethod(guess, formguess, rhs, sol);
335: PetscFunctionReturn(PETSC_SUCCESS);
336: }
338: /*@
339: KSPGuessSetUp - Setup the initial guess object
341: Collective
343: Input Parameter:
344: . guess - the initial guess context
346: Level: developer
348: .seealso: [](ch_ksp), `KSPGuessCreate()`, `KSPGuess`
349: @*/
350: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
351: {
352: PetscObjectState matstate;
353: PetscInt oM = 0, oN = 0, M, N;
354: Mat omat = NULL;
355: PC pc;
356: PetscBool reuse;
358: PetscFunctionBegin;
360: if (guess->A) {
361: omat = guess->A;
362: PetscCall(MatGetSize(guess->A, &oM, &oN));
363: }
364: PetscCall(KSPGetOperators(guess->ksp, &guess->A, NULL));
365: PetscCall(KSPGetPC(guess->ksp, &pc));
366: PetscCall(PCGetReusePreconditioner(pc, &reuse));
367: PetscCall(PetscObjectReference((PetscObject)guess->A));
368: PetscCall(MatGetSize(guess->A, &M, &N));
369: PetscCall(PetscObjectStateGet((PetscObject)guess->A, &matstate));
370: if (M != oM || N != oN) {
371: PetscCall(PetscInfo(guess, "Resetting KSPGuess since matrix sizes have changed (%" PetscInt_FMT " != %" PetscInt_FMT ", %" PetscInt_FMT " != %" PetscInt_FMT ")\n", oM, M, oN, N));
372: } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
373: PetscCall(PetscInfo(guess, "Resetting KSPGuess since %s has changed\n", omat != guess->A ? "matrix" : "matrix state"));
374: PetscTryTypeMethod(guess, reset);
375: } else if (reuse) {
376: PetscCall(PetscInfo(guess, "Not resettting KSPGuess since reuse preconditioner has been specified\n"));
377: } else {
378: PetscCall(PetscInfo(guess, "KSPGuess status unchanged\n"));
379: }
380: PetscTryTypeMethod(guess, setup);
381: guess->omatstate = matstate;
382: PetscCall(MatDestroy(&omat));
383: PetscFunctionReturn(PETSC_SUCCESS);
384: }