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