xref: /petsc/src/snes/impls/fas/fasgalerkin.c (revision 2ff79c18c26c94ed8cb599682f680f231dca6444)
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 @*/
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 @*/
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 @*/
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;
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