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: }