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: [](chapter_ksp), `KSPGuess`, `KSPGuessRegisterAll()`
31: @*/
32: PetscErrorCode KSPGuessRegister(const char sname[], PetscErrorCode (*function)(KSPGuess))
33: {
34: KSPInitializePackage();
35: PetscFunctionListAdd(&KSPGuessList, sname, function);
36: return 0;
37: }
39: /*@C
40: KSPGuessRegisterAll - Registers all `KSPGuess` implementations in the `KSP` package.
42: Not Collective
44: Level: developer
46: .seealso: [](chapter_ksp), `KSPGuess`, `KSPRegisterAll()`, `KSPInitializePackage()`
47: @*/
48: PetscErrorCode KSPGuessRegisterAll(void)
49: {
50: if (KSPGuessRegisterAllCalled) return 0;
51: KSPGuessRegisterAllCalled = PETSC_TRUE;
52: KSPGuessRegister(KSPGUESSFISCHER, KSPGuessCreate_Fischer);
53: KSPGuessRegister(KSPGUESSPOD, KSPGuessCreate_POD);
54: return 0;
55: }
57: /*@
58: KSPGuessSetFromOptions - Sets the options for a `KSPGuess` from the options database
60: Collective
62: Input Parameter:
63: . guess - `KSPGuess` object
65: Level: developer
67: .seealso: [](chapter_ksp), `KSPGuess`, `KSPGetGuess()`, `KSPSetGuessType()`, `KSPGuessType`
68: @*/
69: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
70: {
72: PetscTryTypeMethod(guess, setfromoptions);
73: return 0;
74: }
76: /*@
77: KSPGuessSetTolerance - Sets the relative tolerance used in either eigenvalue (POD) or singular value (Fischer type 3) calculations.
78: Ignored by the first and second Fischer types.
80: Collective
82: Input Parameter:
83: . guess - `KSPGuess` object
85: Level: developer
87: .seealso: [](chapter_ksp), `KSPGuess`, `KSPGuessType`, `KSPGuessSetFromOptions()`
88: @*/
89: PetscErrorCode KSPGuessSetTolerance(KSPGuess guess, PetscReal tol)
90: {
92: PetscTryTypeMethod(guess, settolerance, tol);
93: return 0;
94: }
96: /*@
97: KSPGuessDestroy - Destroys `KSPGuess` context.
99: Collective
101: Input Parameter:
102: . guess - initial guess object
104: Level: developer
106: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`, `KSPGuessType`
107: @*/
108: PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
109: {
110: if (!*guess) return 0;
112: if (--((PetscObject)(*guess))->refct > 0) {
113: *guess = NULL;
114: return 0;
115: }
116: PetscTryTypeMethod((*guess), destroy);
117: MatDestroy(&(*guess)->A);
118: PetscHeaderDestroy(guess);
119: return 0;
120: }
122: /*@C
123: KSPGuessView - View the `KSPGuess` object
125: Logically Collective
127: Input Parameters:
128: + guess - the initial guess object for the Krylov method
129: - viewer - the viewer object
131: Level: developer
133: .seealso: [](chapter_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`, `PetscViewer`
134: @*/
135: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
136: {
137: PetscBool ascii;
140: if (!view) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess), &view);
143: PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &ascii);
144: if (ascii) {
145: PetscObjectPrintClassNamePrefixType((PetscObject)guess, view);
146: PetscViewerASCIIPushTab(view);
147: PetscTryTypeMethod(guess, view, view);
148: PetscViewerASCIIPopTab(view);
149: }
150: return 0;
151: }
153: /*@
154: KSPGuessCreate - Creates the default `KSPGuess` context.
156: Collective
158: Input Parameter:
159: . comm - MPI communicator
161: Output Parameter:
162: . guess - location to put the `KSPGuess` context
164: Level: developer
166: .seealso: [](chapter_ksp), `KSPSolve()`, `KSPGuessDestroy()`, `KSPGuess`, `KSPGuessType`, `KSP`
167: @*/
168: PetscErrorCode KSPGuessCreate(MPI_Comm comm, KSPGuess *guess)
169: {
170: KSPGuess tguess;
173: *guess = NULL;
174: KSPInitializePackage();
175: PetscHeaderCreate(tguess, KSPGUESS_CLASSID, "KSPGuess", "Initial guess for Krylov Method", "KSPGuess", comm, KSPGuessDestroy, KSPGuessView);
176: tguess->omatstate = -1;
177: *guess = tguess;
178: return 0;
179: }
181: /*@C
182: KSPGuessSetType - Sets the type of a `KSPGuess`
184: Logically Collective
186: Input Parameters:
187: + guess - the initial guess object for the Krylov method
188: - type - a known `KSPGuessType`
190: Options Database Key:
191: . -ksp_guess_type <method> - Sets the method; use -help for a list of available methods
193: Level: developer
195: .seealso: [](chapter_ksp), `KSP`, `KSPGuess`, `KSPGuessType`, `KSPGuessRegister()`, `KSPGuessCreate()`
196: @*/
197: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
198: {
199: PetscBool match;
200: PetscErrorCode (*r)(KSPGuess);
205: PetscObjectTypeCompare((PetscObject)guess, type, &match);
206: if (match) return 0;
208: PetscFunctionListFind(KSPGuessList, type, &r);
210: PetscTryTypeMethod(guess, destroy);
211: guess->ops->destroy = NULL;
213: PetscMemzero(guess->ops, sizeof(struct _KSPGuessOps));
214: PetscObjectChangeTypeName((PetscObject)guess, type);
215: (*r)(guess);
216: return 0;
217: }
219: /*@C
220: KSPGuessGetType - Gets the `KSPGuessType` as a string from the `KSPGuess` object.
222: Not Collective
224: Input Parameter:
225: . guess - the initial guess context
227: Output Parameter:
228: . name - type of `KSPGuess` method
230: Level: developer
232: .seealso: [](chapter_ksp), `KSPGuess`, `KSPGuessSetType()`
233: @*/
234: PetscErrorCode KSPGuessGetType(KSPGuess guess, KSPGuessType *type)
235: {
238: *type = ((PetscObject)guess)->type_name;
239: return 0;
240: }
242: /*@
243: KSPGuessUpdate - Updates the guess object with the current solution and rhs vector
245: Collective
247: Input Parameters:
248: + guess - the initial guess context
249: . rhs - the corresponding rhs
250: - sol - the computed solution
252: Level: developer
254: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`
255: @*/
256: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
257: {
261: PetscTryTypeMethod(guess, update, rhs, sol);
262: return 0;
263: }
265: /*@
266: KSPGuessFormGuess - Form the initial guess
268: Collective
270: Input Parameters:
271: + guess - the initial guess context
272: . rhs - the current rhs vector
273: - sol - the initial guess vector
275: Level: developer
277: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`
278: @*/
279: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
280: {
284: PetscTryTypeMethod(guess, formguess, rhs, sol);
285: return 0;
286: }
288: /*@
289: KSPGuessSetUp - Setup the initial guess object
291: Collective
293: Input Parameter:
294: - guess - the initial guess context
296: Level: developer
298: .seealso: [](chapter_ksp), `KSPGuessCreate()`, `KSPGuess`
299: @*/
300: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
301: {
302: PetscObjectState matstate;
303: PetscInt oM = 0, oN = 0, M, N;
304: Mat omat = NULL;
305: PC pc;
306: PetscBool reuse;
309: if (guess->A) {
310: omat = guess->A;
311: MatGetSize(guess->A, &oM, &oN);
312: }
313: KSPGetOperators(guess->ksp, &guess->A, NULL);
314: KSPGetPC(guess->ksp, &pc);
315: PCGetReusePreconditioner(pc, &reuse);
316: PetscObjectReference((PetscObject)guess->A);
317: MatGetSize(guess->A, &M, &N);
318: PetscObjectStateGet((PetscObject)guess->A, &matstate);
319: if (M != oM || N != oN) {
320: PetscInfo(guess, "Resetting KSPGuess since matrix sizes have changed (%" PetscInt_FMT " != %" PetscInt_FMT ", %" PetscInt_FMT " != %" PetscInt_FMT ")\n", oM, M, oN, N);
321: } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
322: PetscInfo(guess, "Resetting KSPGuess since %s has changed\n", omat != guess->A ? "matrix" : "matrix state");
323: PetscTryTypeMethod(guess, reset);
324: } else if (reuse) {
325: PetscInfo(guess, "Not resettting KSPGuess since reuse preconditioner has been specified\n");
326: } else {
327: PetscInfo(guess, "KSPGuess status unchanged\n");
328: }
329: PetscTryTypeMethod(guess, setup);
330: guess->omatstate = matstate;
331: MatDestroy(&omat);
332: return 0;
333: }