Actual source code: fasgalerkin.c
1: #include <../src/snes/impls/fas/fasimpls.h>
3: /*@
4: SNESFASGetGalerkin - Gets if the coarse problems are formed by projection to the fine problem
6: Not Collective but the result would be the same on all MPI processes
8: Input Parameter:
9: . snes - the `SNESFAS` nonlinear solver context
11: Output Parameter:
12: . flg - `PETSC_TRUE` if the coarse problem is formed by projection
14: Level: advanced
16: .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASSetLevels()`, `SNESFASSetGalerkin()`
17: @*/
18: PetscErrorCode SNESFASGetGalerkin(SNES snes, PetscBool *flg)
19: {
20: SNES_FAS *fas;
22: PetscFunctionBegin;
24: fas = (SNES_FAS *)snes->data;
25: *flg = fas->galerkin;
26: PetscFunctionReturn(PETSC_SUCCESS);
27: }
29: /*@
30: SNESFASSetGalerkin - Sets coarse problems as formed by projection to the fine problem
32: Logically Collective
34: Input Parameters:
35: + snes - the `SNESFAS` nonlinear solver context
36: - flg - `PETSC_TRUE` to use the projection process
38: Level: advanced
40: .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASSetLevels()`, `SNESFASGetGalerkin()`
41: @*/
42: PetscErrorCode SNESFASSetGalerkin(SNES snes, PetscBool flg)
43: {
44: SNES_FAS *fas;
46: PetscFunctionBegin;
48: fas = (SNES_FAS *)snes->data;
49: fas->galerkin = flg;
50: if (fas->next) PetscCall(SNESFASSetGalerkin(fas->next, flg));
51: PetscFunctionReturn(PETSC_SUCCESS);
52: }
54: /*@C
55: SNESFASGalerkinFunctionDefault - Computes the Galerkin FAS function
57: Collective
59: Input Parameters:
60: + snes - the `SNESFAS` nonlinear solver context
61: . X - input vector
62: - ctx - the application context
64: Output Parameter:
65: . F - output vector
67: Level: developer
69: Note:
70: The Galerkin FAS function evaluation is defined as
72: $$
73: F^l(x^l) = I^l_0 F^0(P^0_l x^l)
74: $$
76: .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASGetGalerkin()`, `SNESFASSetGalerkin()`
77: @*/
78: PetscErrorCode SNESFASGalerkinFunctionDefault(SNES snes, Vec X, Vec F, void *ctx)
79: {
80: SNES fassnes;
81: SNES_FAS *fas;
82: SNES_FAS *prevfas;
83: SNES prevsnes;
84: Vec b_temp;
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: }