Actual source code: iguess.c
petsc-3.13.6 2020-09-29
1: #include <petsc/private/kspimpl.h>
3: PetscFunctionList KSPGuessList = 0;
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: advanced
30: .seealso: KSPGuess, KSPGuessRegisterAll()
32: @*/
33: PetscErrorCode KSPGuessRegister(const char sname[],PetscErrorCode (*function)(KSPGuess))
34: {
38: KSPInitializePackage();
39: PetscFunctionListAdd(&KSPGuessList,sname,function);
40: return(0);
41: }
43: /*
44: KSPGuessRegisterAll - Registers all KSPGuess implementations in the KSP package.
46: Not Collective
48: Level: advanced
50: .seealso: KSPRegisterAll(), KSPInitializePackage()
51: */
52: PetscErrorCode KSPGuessRegisterAll(void)
53: {
57: if (KSPGuessRegisterAllCalled) return(0);
58: KSPGuessRegisterAllCalled = PETSC_TRUE;
59: KSPGuessRegister(KSPGUESSFISCHER,KSPGuessCreate_Fischer);
60: KSPGuessRegister(KSPGUESSPOD,KSPGuessCreate_POD);
61: return(0);
62: }
64: /*@
65: KSPGuessSetFromOptions - Sets the options for a KSPGuess from the options database
67: Collective on guess
69: Input Parameter:
70: . guess - KSPGuess object
72: Level: intermediate
74: .seealso: KSPGuess, KSPGetGuess(), KSPSetGuessType(), KSPGuessType
75: @*/
76: PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
77: {
82: if (guess->ops->setfromoptions) { (*guess->ops->setfromoptions)(guess); }
83: return(0);
84: }
86: /*@
87: KSPGuessDestroy - Destroys KSPGuess context.
89: Collective on kspGuess
91: Input Parameter:
92: . guess - initial guess object
94: Level: beginner
96: .seealso: KSPGuessCreate(), KSPGuess, KSPGuessType
97: @*/
98: PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
99: {
103: if (!*guess) return(0);
105: if (--((PetscObject)(*guess))->refct > 0) {*guess = 0; return(0);}
106: if ((*guess)->ops->destroy) { (*(*guess)->ops->destroy)(*guess); }
107: MatDestroy(&(*guess)->A);
108: PetscHeaderDestroy(guess);
109: return(0);
110: }
112: /*@C
113: KSPGuessView - View the KSPGuess object
115: Logically Collective on guess
117: Input Parameters:
118: + guess - the initial guess object for the Krylov method
119: - viewer - the viewer object
121: Notes:
123: Level: intermediate
125: .seealso: KSP, KSPGuess, KSPGuessType, KSPGuessRegister(), KSPGuessCreate(), PetscViewer
126: @*/
127: PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
128: {
130: PetscBool ascii;
134: if (!view) {
135: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess),&view);
136: }
139: PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&ascii);
140: if (ascii) {
141: PetscObjectPrintClassNamePrefixType((PetscObject)guess,view);
142: if (guess->ops->view) {
143: PetscViewerASCIIPushTab(view);
144: (*guess->ops->view)(guess,view);
145: PetscViewerASCIIPopTab(view);
146: }
147: }
148: return(0);
149: }
151: /*@
152: KSPGuessCreate - Creates the default KSPGuess context.
154: Collective
156: Input Parameter:
157: . comm - MPI communicator
159: Output Parameter:
160: . guess - location to put the KSPGuess context
162: Notes:
163: The default KSPGuess type is XXX
165: Level: beginner
167: .seealso: KSPSolve(), KSPGuessDestroy(), KSPGuess, KSPGuessType, KSP
168: @*/
169: PetscErrorCode KSPGuessCreate(MPI_Comm comm,KSPGuess *guess)
170: {
171: KSPGuess tguess;
176: *guess = 0;
177: KSPInitializePackage();
178: PetscHeaderCreate(tguess,KSPGUESS_CLASSID,"KSPGuess","Initial guess for Krylov Method","KSPGuess",comm,KSPGuessDestroy,KSPGuessView);
179: tguess->omatstate = -1;
180: *guess = tguess;
181: return(0);
182: }
184: /*@C
185: KSPGuessSetType - Sets the type of a KSPGuess
187: Logically Collective on guess
189: Input Parameters:
190: + guess - the initial guess object for the Krylov method
191: - type - a known KSPGuess method
193: Options Database Key:
194: . -ksp_guess_type <method> - Sets the method; use -help for a list
195: of available methods
197: Notes:
199: Level: intermediate
201: .seealso: KSP, KSPGuess, KSPGuessType, KSPGuessRegister(), KSPGuessCreate()
203: @*/
204: PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
205: {
206: PetscErrorCode ierr,(*r)(KSPGuess);
207: PetscBool match;
213: PetscObjectTypeCompare((PetscObject)guess,type,&match);
214: if (match) return(0);
216: PetscFunctionListFind(KSPGuessList,type,&r);
217: if (!r) SETERRQ1(PetscObjectComm((PetscObject)guess),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested KSPGuess type %s",type);
218: if (guess->ops->destroy) {
219: (*guess->ops->destroy)(guess);
220: guess->ops->destroy = NULL;
221: }
222: PetscMemzero(guess->ops,sizeof(struct _KSPGuessOps));
223: PetscObjectChangeTypeName((PetscObject)guess,type);
224: (*r)(guess);
225: return(0);
226: }
228: /*@C
229: KSPGuessGetType - Gets the KSPGuess type as a string from the KSPGuess object.
231: Not Collective
233: Input Parameter:
234: . guess - the initial guess context
236: Output Parameter:
237: . name - name of KSPGuess method
239: Level: intermediate
241: .seealso: KSPGuessSetType()
242: @*/
243: PetscErrorCode KSPGuessGetType(KSPGuess guess,KSPGuessType *type)
244: {
248: *type = ((PetscObject)guess)->type_name;
249: return(0);
250: }
252: /*@
253: KSPGuessUpdate - Updates the guess object with the current solution and rhs vector
255: Collective on guess
257: Input Parameter:
258: + guess - the initial guess context
259: . rhs - the corresponding rhs
260: - sol - the computed solution
262: Level: intermediate
264: .seealso: KSPGuessCreate(), KSPGuess
265: @*/
266: PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
267: {
274: if (guess->ops->update) { (*guess->ops->update)(guess,rhs,sol); }
275: return(0);
276: }
278: /*@
279: KSPGuessFormGuess - Form the initial guess
281: Collective on guess
283: Input Parameter:
284: + guess - the initial guess context
285: . rhs - the current rhs vector
286: - sol - the initial guess vector
288: Level: intermediate
290: .seealso: KSPGuessCreate(), KSPGuess
291: @*/
292: PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
293: {
300: if (guess->ops->formguess) { (*guess->ops->formguess)(guess,rhs,sol); }
301: return(0);
302: }
304: /*@
305: KSPGuessSetUp - Setup the initial guess object
307: Collective on guess
309: Input Parameter:
310: - guess - the initial guess context
312: Level: intermediate
314: .seealso: KSPGuessCreate(), KSPGuess
315: @*/
316: PetscErrorCode KSPGuessSetUp(KSPGuess guess)
317: {
318: PetscErrorCode ierr;
319: PetscObjectState matstate;
320: PetscInt oM = 0, oN = 0, M, N;
321: Mat omat = NULL;
322: PC pc;
323: PetscBool reuse;
327: if (guess->A) {
328: omat = guess->A;
329: MatGetSize(guess->A,&oM,&oN);
330: }
331: KSPGetOperators(guess->ksp,&guess->A,NULL);
332: KSPGetPC(guess->ksp,&pc);
333: PCGetReusePreconditioner(pc,&reuse);
334: PetscObjectReference((PetscObject)guess->A);
335: MatGetSize(guess->A,&M,&N);
336: PetscObjectStateGet((PetscObject)guess->A,&matstate);
337: if (M != oM || N != oN) {
338: PetscInfo4(guess,"Resetting KSPGuess since matrix sizes have changed (%D != %D, %D != %D)\n",oM,M,oN,N);
339: } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
340: PetscInfo1(guess,"Resetting KSPGuess since %s has changed\n",omat != guess->A ? "matrix" : "matrix state");
341: if (guess->ops->reset) { (*guess->ops->reset)(guess); }
342: } else if (reuse) {
343: PetscInfo(guess,"Not resettting KSPGuess since reuse preconditioner has been specified\n");
344: } else {
345: PetscInfo(guess,"KSPGuess status unchanged\n");
346: }
347: if (guess->ops->setup) { (*guess->ops->setup)(guess); }
348: guess->omatstate = matstate;
349: MatDestroy(&omat);
350: return(0);
351: }