1 #include <../src/snes/impls/fas/fasimpls.h> /*I "petscsnes.h" I*/
2
3 /*@
4 SNESFASGetGalerkin - Gets if the coarse problems are formed by projection to the fine problem
5
6 Not Collective but the result would be the same on all MPI processes
7
8 Input Parameter:
9 . snes - the `SNESFAS` nonlinear solver context
10
11 Output Parameter:
12 . flg - `PETSC_TRUE` if the coarse problem is formed by projection
13
14 Level: advanced
15
16 .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASSetLevels()`, `SNESFASSetGalerkin()`
17 @*/
SNESFASGetGalerkin(SNES snes,PetscBool * flg)18 PetscErrorCode SNESFASGetGalerkin(SNES snes, PetscBool *flg)
19 {
20 SNES_FAS *fas;
21
22 PetscFunctionBegin;
23 PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
24 fas = (SNES_FAS *)snes->data;
25 *flg = fas->galerkin;
26 PetscFunctionReturn(PETSC_SUCCESS);
27 }
28
29 /*@
30 SNESFASSetGalerkin - Sets coarse problems as formed by projection to the fine problem
31
32 Logically Collective
33
34 Input Parameters:
35 + snes - the `SNESFAS` nonlinear solver context
36 - flg - `PETSC_TRUE` to use the projection process
37
38 Level: advanced
39
40 .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASSetLevels()`, `SNESFASGetGalerkin()`
41 @*/
SNESFASSetGalerkin(SNES snes,PetscBool flg)42 PetscErrorCode SNESFASSetGalerkin(SNES snes, PetscBool flg)
43 {
44 SNES_FAS *fas;
45
46 PetscFunctionBegin;
47 PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
48 fas = (SNES_FAS *)snes->data;
49 fas->galerkin = flg;
50 if (fas->next) PetscCall(SNESFASSetGalerkin(fas->next, flg));
51 PetscFunctionReturn(PETSC_SUCCESS);
52 }
53
54 /*@C
55 SNESFASGalerkinFunctionDefault - Computes the Galerkin FAS function
56
57 Collective
58
59 Input Parameters:
60 + snes - the `SNESFAS` nonlinear solver context
61 . X - input vector
62 - ctx - the application context
63
64 Output Parameter:
65 . F - output vector
66
67 Level: developer
68
69 Note:
70 The Galerkin FAS function evaluation is defined as
71
72 $$
73 F^l(x^l) = I^l_0 F^0(P^0_l x^l)
74 $$
75
76 .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASGetGalerkin()`, `SNESFASSetGalerkin()`
77 @*/
SNESFASGalerkinFunctionDefault(SNES snes,Vec X,Vec F,PetscCtx ctx)78 PetscErrorCode SNESFASGalerkinFunctionDefault(SNES snes, Vec X, Vec F, PetscCtx ctx)
79 {
80 SNES fassnes;
81 SNES_FAS *fas;
82 SNES_FAS *prevfas;
83 SNES prevsnes;
84 Vec b_temp;
85
86 PetscFunctionBegin;
87 /* prolong to the fine level and evaluate there. */
88 fassnes = (SNES)ctx;
89 fas = (SNES_FAS *)fassnes->data;
90 prevsnes = fas->previous;
91 prevfas = (SNES_FAS *)prevsnes->data;
92 /* interpolate down the solution */
93 PetscCall(MatInterpolate(prevfas->interpolate, X, prevfas->Xg));
94 /* the RHS we care about is at the coarsest level */
95 b_temp = prevsnes->vec_rhs;
96 prevsnes->vec_rhs = NULL;
97 PetscCall(SNESComputeFunction(prevsnes, prevfas->Xg, prevfas->Fg));
98 prevsnes->vec_rhs = b_temp;
99 /* restrict up the function */
100 PetscCall(MatRestrict(prevfas->restrct, prevfas->Fg, F));
101 PetscFunctionReturn(PETSC_SUCCESS);
102 }
103