1 #include <petsc/private/kspimpl.h> /*I "petscksp.h" I*/
2
3 PetscFunctionList KSPGuessList = NULL;
4 static PetscBool KSPGuessRegisterAllCalled;
5
6 /*
7 KSPGuessRegister - Adds a method for initial guess computation in Krylov subspace solver package.
8
9 Not Collective
10
11 Input Parameters:
12 + name_solver - name of a new user-defined solver
13 - routine_create - routine to create method context
14
15 Notes:
16 KSPGuessRegister() may be called multiple times to add several user-defined solvers.
17
18 Sample usage:
19 .vb
20 KSPGuessRegister("my_initial_guess",MyInitialGuessCreate);
21 .ve
22
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
27
28 Level: advanced
29
30 .seealso: KSPGuess, KSPGuessRegisterAll()
31
32 @*/
KSPGuessRegister(const char sname[],PetscErrorCode (* function)(KSPGuess))33 PetscErrorCode KSPGuessRegister(const char sname[],PetscErrorCode (*function)(KSPGuess))
34 {
35 PetscErrorCode ierr;
36
37 PetscFunctionBegin;
38 ierr = KSPInitializePackage();CHKERRQ(ierr);
39 ierr = PetscFunctionListAdd(&KSPGuessList,sname,function);CHKERRQ(ierr);
40 PetscFunctionReturn(0);
41 }
42
43 /*
44 KSPGuessRegisterAll - Registers all KSPGuess implementations in the KSP package.
45
46 Not Collective
47
48 Level: advanced
49
50 .seealso: KSPRegisterAll(), KSPInitializePackage()
51 */
KSPGuessRegisterAll(void)52 PetscErrorCode KSPGuessRegisterAll(void)
53 {
54 PetscErrorCode ierr;
55
56 PetscFunctionBegin;
57 if (KSPGuessRegisterAllCalled) PetscFunctionReturn(0);
58 KSPGuessRegisterAllCalled = PETSC_TRUE;
59 ierr = KSPGuessRegister(KSPGUESSFISCHER,KSPGuessCreate_Fischer);CHKERRQ(ierr);
60 ierr = KSPGuessRegister(KSPGUESSPOD,KSPGuessCreate_POD);CHKERRQ(ierr);
61 PetscFunctionReturn(0);
62 }
63
64 /*@
65 KSPGuessSetFromOptions - Sets the options for a KSPGuess from the options database
66
67 Collective on guess
68
69 Input Parameter:
70 . guess - KSPGuess object
71
72 Level: intermediate
73
74 .seealso: KSPGuess, KSPGetGuess(), KSPSetGuessType(), KSPGuessType
75 @*/
KSPGuessSetFromOptions(KSPGuess guess)76 PetscErrorCode KSPGuessSetFromOptions(KSPGuess guess)
77 {
78 PetscErrorCode ierr;
79
80 PetscFunctionBegin;
81 PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,1);
82 if (guess->ops->setfromoptions) { ierr = (*guess->ops->setfromoptions)(guess);CHKERRQ(ierr); }
83 PetscFunctionReturn(0);
84 }
85
86 /*@
87 KSPGuessDestroy - Destroys KSPGuess context.
88
89 Collective on kspGuess
90
91 Input Parameter:
92 . guess - initial guess object
93
94 Level: beginner
95
96 .seealso: KSPGuessCreate(), KSPGuess, KSPGuessType
97 @*/
KSPGuessDestroy(KSPGuess * guess)98 PetscErrorCode KSPGuessDestroy(KSPGuess *guess)
99 {
100 PetscErrorCode ierr;
101
102 PetscFunctionBegin;
103 if (!*guess) PetscFunctionReturn(0);
104 PetscValidHeaderSpecific((*guess),KSPGUESS_CLASSID,1);
105 if (--((PetscObject)(*guess))->refct > 0) {*guess = NULL; PetscFunctionReturn(0);}
106 if ((*guess)->ops->destroy) { ierr = (*(*guess)->ops->destroy)(*guess);CHKERRQ(ierr); }
107 ierr = MatDestroy(&(*guess)->A);CHKERRQ(ierr);
108 ierr = PetscHeaderDestroy(guess);CHKERRQ(ierr);
109 PetscFunctionReturn(0);
110 }
111
112 /*@C
113 KSPGuessView - View the KSPGuess object
114
115 Logically Collective on guess
116
117 Input Parameters:
118 + guess - the initial guess object for the Krylov method
119 - viewer - the viewer object
120
121 Notes:
122
123 Level: intermediate
124
125 .seealso: KSP, KSPGuess, KSPGuessType, KSPGuessRegister(), KSPGuessCreate(), PetscViewer
126 @*/
KSPGuessView(KSPGuess guess,PetscViewer view)127 PetscErrorCode KSPGuessView(KSPGuess guess, PetscViewer view)
128 {
129 PetscErrorCode ierr;
130 PetscBool ascii;
131
132 PetscFunctionBegin;
133 PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,1);
134 if (!view) {
135 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)guess),&view);CHKERRQ(ierr);
136 }
137 PetscValidHeaderSpecific(view,PETSC_VIEWER_CLASSID,2);
138 PetscCheckSameComm(guess,1,view,2);
139 ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&ascii);CHKERRQ(ierr);
140 if (ascii) {
141 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)guess,view);CHKERRQ(ierr);
142 if (guess->ops->view) {
143 ierr = PetscViewerASCIIPushTab(view);CHKERRQ(ierr);
144 ierr = (*guess->ops->view)(guess,view);CHKERRQ(ierr);
145 ierr = PetscViewerASCIIPopTab(view);CHKERRQ(ierr);
146 }
147 }
148 PetscFunctionReturn(0);
149 }
150
151 /*@
152 KSPGuessCreate - Creates the default KSPGuess context.
153
154 Collective
155
156 Input Parameter:
157 . comm - MPI communicator
158
159 Output Parameter:
160 . guess - location to put the KSPGuess context
161
162 Notes:
163 The default KSPGuess type is XXX
164
165 Level: beginner
166
167 .seealso: KSPSolve(), KSPGuessDestroy(), KSPGuess, KSPGuessType, KSP
168 @*/
KSPGuessCreate(MPI_Comm comm,KSPGuess * guess)169 PetscErrorCode KSPGuessCreate(MPI_Comm comm,KSPGuess *guess)
170 {
171 KSPGuess tguess;
172 PetscErrorCode ierr;
173
174 PetscFunctionBegin;
175 PetscValidPointer(guess,2);
176 *guess = NULL;
177 ierr = KSPInitializePackage();CHKERRQ(ierr);
178 ierr = PetscHeaderCreate(tguess,KSPGUESS_CLASSID,"KSPGuess","Initial guess for Krylov Method","KSPGuess",comm,KSPGuessDestroy,KSPGuessView);CHKERRQ(ierr);
179 tguess->omatstate = -1;
180 *guess = tguess;
181 PetscFunctionReturn(0);
182 }
183
184 /*@C
185 KSPGuessSetType - Sets the type of a KSPGuess
186
187 Logically Collective on guess
188
189 Input Parameters:
190 + guess - the initial guess object for the Krylov method
191 - type - a known KSPGuess method
192
193 Options Database Key:
194 . -ksp_guess_type <method> - Sets the method; use -help for a list
195 of available methods
196
197 Notes:
198
199 Level: intermediate
200
201 .seealso: KSP, KSPGuess, KSPGuessType, KSPGuessRegister(), KSPGuessCreate()
202
203 @*/
KSPGuessSetType(KSPGuess guess,KSPGuessType type)204 PetscErrorCode KSPGuessSetType(KSPGuess guess, KSPGuessType type)
205 {
206 PetscErrorCode ierr,(*r)(KSPGuess);
207 PetscBool match;
208
209 PetscFunctionBegin;
210 PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,1);
211 PetscValidCharPointer(type,2);
212
213 ierr = PetscObjectTypeCompare((PetscObject)guess,type,&match);CHKERRQ(ierr);
214 if (match) PetscFunctionReturn(0);
215
216 ierr = PetscFunctionListFind(KSPGuessList,type,&r);CHKERRQ(ierr);
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 ierr = (*guess->ops->destroy)(guess);CHKERRQ(ierr);
220 guess->ops->destroy = NULL;
221 }
222 ierr = PetscMemzero(guess->ops,sizeof(struct _KSPGuessOps));CHKERRQ(ierr);
223 ierr = PetscObjectChangeTypeName((PetscObject)guess,type);CHKERRQ(ierr);
224 ierr = (*r)(guess);CHKERRQ(ierr);
225 PetscFunctionReturn(0);
226 }
227
228 /*@C
229 KSPGuessGetType - Gets the KSPGuess type as a string from the KSPGuess object.
230
231 Not Collective
232
233 Input Parameter:
234 . guess - the initial guess context
235
236 Output Parameter:
237 . name - name of KSPGuess method
238
239 Level: intermediate
240
241 .seealso: KSPGuessSetType()
242 @*/
KSPGuessGetType(KSPGuess guess,KSPGuessType * type)243 PetscErrorCode KSPGuessGetType(KSPGuess guess,KSPGuessType *type)
244 {
245 PetscFunctionBegin;
246 PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,1);
247 PetscValidPointer(type,2);
248 *type = ((PetscObject)guess)->type_name;
249 PetscFunctionReturn(0);
250 }
251
252 /*@
253 KSPGuessUpdate - Updates the guess object with the current solution and rhs vector
254
255 Collective on guess
256
257 Input Parameter:
258 + guess - the initial guess context
259 . rhs - the corresponding rhs
260 - sol - the computed solution
261
262 Level: intermediate
263
264 .seealso: KSPGuessCreate(), KSPGuess
265 @*/
KSPGuessUpdate(KSPGuess guess,Vec rhs,Vec sol)266 PetscErrorCode KSPGuessUpdate(KSPGuess guess, Vec rhs, Vec sol)
267 {
268 PetscErrorCode ierr;
269
270 PetscFunctionBegin;
271 PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,1);
272 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
273 PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
274 if (guess->ops->update) { ierr = (*guess->ops->update)(guess,rhs,sol);CHKERRQ(ierr); }
275 PetscFunctionReturn(0);
276 }
277
278 /*@
279 KSPGuessFormGuess - Form the initial guess
280
281 Collective on guess
282
283 Input Parameter:
284 + guess - the initial guess context
285 . rhs - the current rhs vector
286 - sol - the initial guess vector
287
288 Level: intermediate
289
290 .seealso: KSPGuessCreate(), KSPGuess
291 @*/
KSPGuessFormGuess(KSPGuess guess,Vec rhs,Vec sol)292 PetscErrorCode KSPGuessFormGuess(KSPGuess guess, Vec rhs, Vec sol)
293 {
294 PetscErrorCode ierr;
295
296 PetscFunctionBegin;
297 PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,1);
298 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2);
299 PetscValidHeaderSpecific(sol,VEC_CLASSID,3);
300 if (guess->ops->formguess) { ierr = (*guess->ops->formguess)(guess,rhs,sol);CHKERRQ(ierr); }
301 PetscFunctionReturn(0);
302 }
303
304 /*@
305 KSPGuessSetUp - Setup the initial guess object
306
307 Collective on guess
308
309 Input Parameter:
310 - guess - the initial guess context
311
312 Level: intermediate
313
314 .seealso: KSPGuessCreate(), KSPGuess
315 @*/
KSPGuessSetUp(KSPGuess guess)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;
324
325 PetscFunctionBegin;
326 PetscValidHeaderSpecific(guess,KSPGUESS_CLASSID,1);
327 if (guess->A) {
328 omat = guess->A;
329 ierr = MatGetSize(guess->A,&oM,&oN);CHKERRQ(ierr);
330 }
331 ierr = KSPGetOperators(guess->ksp,&guess->A,NULL);CHKERRQ(ierr);
332 ierr = KSPGetPC(guess->ksp,&pc);CHKERRQ(ierr);
333 ierr = PCGetReusePreconditioner(pc,&reuse);CHKERRQ(ierr);
334 ierr = PetscObjectReference((PetscObject)guess->A);CHKERRQ(ierr);
335 ierr = MatGetSize(guess->A,&M,&N);CHKERRQ(ierr);
336 ierr = PetscObjectStateGet((PetscObject)guess->A,&matstate);CHKERRQ(ierr);
337 if (M != oM || N != oN) {
338 ierr = PetscInfo4(guess,"Resetting KSPGuess since matrix sizes have changed (%D != %D, %D != %D)\n",oM,M,oN,N);CHKERRQ(ierr);
339 } else if (!reuse && (omat != guess->A || guess->omatstate != matstate)) {
340 ierr = PetscInfo1(guess,"Resetting KSPGuess since %s has changed\n",omat != guess->A ? "matrix" : "matrix state");CHKERRQ(ierr);
341 if (guess->ops->reset) { ierr = (*guess->ops->reset)(guess);CHKERRQ(ierr); }
342 } else if (reuse) {
343 ierr = PetscInfo(guess,"Not resettting KSPGuess since reuse preconditioner has been specified\n");CHKERRQ(ierr);
344 } else {
345 ierr = PetscInfo(guess,"KSPGuess status unchanged\n");CHKERRQ(ierr);
346 }
347 if (guess->ops->setup) { ierr = (*guess->ops->setup)(guess);CHKERRQ(ierr); }
348 guess->omatstate = matstate;
349 ierr = MatDestroy(&omat);CHKERRQ(ierr);
350 PetscFunctionReturn(0);
351 }
352