xref: /petsc/src/snes/impls/fas/fasgalerkin.c (revision 6a4a1270853b5b1995c94de98f44d28bec57470a)
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 ranks
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: `SNESFAS`, `SNESFASSetLevels()`, `SNESFASSetGalerkin()`
17 @*/
18 PetscErrorCode SNESFASGetGalerkin(SNES snes, PetscBool *flg) {
19   SNES_FAS *fas;
20 
21   PetscFunctionBegin;
22   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
23   fas  = (SNES_FAS *)snes->data;
24   *flg = fas->galerkin;
25   PetscFunctionReturn(0);
26 }
27 
28 /*@
29    SNESFASSetGalerkin - Sets coarse problems as formed by projection to the fine problem
30 
31    Collective on snes
32 
33    Input Parameters:
34 +  snes - the `SNESFAS` nonlinear solver context
35 -  flg - `PETSC_TRUE` to use the projection process
36 
37    Level: advanced
38 
39 .seealso: `SNESFAS`, `SNESFASSetLevels()`, `SNESFASGetGalerkin()`
40 @*/
41 PetscErrorCode SNESFASSetGalerkin(SNES snes, PetscBool flg) {
42   SNES_FAS *fas;
43 
44   PetscFunctionBegin;
45   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
46   fas           = (SNES_FAS *)snes->data;
47   fas->galerkin = flg;
48   if (fas->next) PetscCall(SNESFASSetGalerkin(fas->next, flg));
49   PetscFunctionReturn(0);
50 }
51 
52 /*@C
53    SNESFASGalerkinFunctionDefault - Computes the Galerkin FAS function
54 
55    Collective on snes
56 
57    Input Parameters:
58 +  snes - the `SNESFAS` nonlinear solver context
59 .  X - input vector
60 -  ctx - the application context
61 
62    Output Parameter:
63 .  F - output vector
64 
65    Note:
66    The Galerkin FAS function evalutation is defined as
67 $  F^l(x^l) = I^l_0 F^0(P^0_l x^l)
68 
69    Level: developer
70 
71 .seealso: `SNESFAS`, `SNESFASGetGalerkin()`, `SNESFASSetGalerkin()`
72 @*/
73 PetscErrorCode SNESFASGalerkinFunctionDefault(SNES snes, Vec X, Vec F, void *ctx) {
74   SNES      fassnes;
75   SNES_FAS *fas;
76   SNES_FAS *prevfas;
77   SNES      prevsnes;
78   Vec       b_temp;
79 
80   PetscFunctionBegin;
81   /* prolong to the fine level and evaluate there. */
82   fassnes  = (SNES)ctx;
83   fas      = (SNES_FAS *)fassnes->data;
84   prevsnes = fas->previous;
85   prevfas  = (SNES_FAS *)prevsnes->data;
86   /* interpolate down the solution */
87   PetscCall(MatInterpolate(prevfas->interpolate, X, prevfas->Xg));
88   /* the RHS we care about is at the coarsest level */
89   b_temp            = prevsnes->vec_rhs;
90   prevsnes->vec_rhs = NULL;
91   PetscCall(SNESComputeFunction(prevsnes, prevfas->Xg, prevfas->Fg));
92   prevsnes->vec_rhs = b_temp;
93   /* restrict up the function */
94   PetscCall(MatRestrict(prevfas->restrct, prevfas->Fg, F));
95   PetscFunctionReturn(0);
96 }
97