xref: /petsc/src/snes/impls/fas/fasgalerkin.c (revision f6dfbefd03961ab3be6f06be75c96cbf27a49667)
1a7b5fb5fSBarry Smith #include <../src/snes/impls/fas/fasimpls.h> /*I  "petscsnes.h"  I*/
2ab8d36c9SPeter Brune 
3ab8d36c9SPeter Brune /*@
4ab8d36c9SPeter Brune    SNESFASGetGalerkin - Gets if the coarse problems are formed by projection to the fine problem
5ab8d36c9SPeter Brune 
6*f6dfbefdSBarry Smith    Not collective but the result would be the same on all MPI ranks
7*f6dfbefdSBarry Smith 
8ab8d36c9SPeter Brune    Input Parameter:
9*f6dfbefdSBarry Smith .  snes - the `SNESFAS` nonlinear solver context
10ab8d36c9SPeter Brune 
11ab8d36c9SPeter Brune    Output parameter:
12*f6dfbefdSBarry Smith .  flg - `PETSC_TRUE` if the coarse problem is formed by projection
13ab8d36c9SPeter Brune 
14ab8d36c9SPeter Brune    Level: advanced
15ab8d36c9SPeter Brune 
16*f6dfbefdSBarry Smith .seealso: `SNESFAS`, `SNESFASSetLevels()`, `SNESFASSetGalerkin()`
17ab8d36c9SPeter Brune @*/
189371c9d4SSatish Balay PetscErrorCode SNESFASGetGalerkin(SNES snes, PetscBool *flg) {
19f833ba53SLisandro Dalcin   SNES_FAS *fas;
205fd66863SKarl Rupp 
21ab8d36c9SPeter Brune   PetscFunctionBegin;
22f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
23f833ba53SLisandro Dalcin   fas  = (SNES_FAS *)snes->data;
24ab8d36c9SPeter Brune   *flg = fas->galerkin;
25ab8d36c9SPeter Brune   PetscFunctionReturn(0);
26ab8d36c9SPeter Brune }
27ab8d36c9SPeter Brune 
28ab8d36c9SPeter Brune /*@
29ab8d36c9SPeter Brune    SNESFASSetGalerkin - Sets coarse problems as formed by projection to the fine problem
30ab8d36c9SPeter Brune 
31*f6dfbefdSBarry Smith    Collective on snes
32*f6dfbefdSBarry Smith 
33d8d19677SJose E. Roman    Input Parameters:
34*f6dfbefdSBarry Smith +  snes - the `SNESFAS` nonlinear solver context
35*f6dfbefdSBarry Smith -  flg - `PETSC_TRUE` to use the projection process
36ab8d36c9SPeter Brune 
37ab8d36c9SPeter Brune    Level: advanced
38ab8d36c9SPeter Brune 
39*f6dfbefdSBarry Smith .seealso: `SNESFAS`, `SNESFASSetLevels()`, `SNESFASGetGalerkin()`
40ab8d36c9SPeter Brune @*/
419371c9d4SSatish Balay PetscErrorCode SNESFASSetGalerkin(SNES snes, PetscBool flg) {
42f833ba53SLisandro Dalcin   SNES_FAS *fas;
435fd66863SKarl Rupp 
44ab8d36c9SPeter Brune   PetscFunctionBegin;
45f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
46f833ba53SLisandro Dalcin   fas           = (SNES_FAS *)snes->data;
47ab8d36c9SPeter Brune   fas->galerkin = flg;
489566063dSJacob Faibussowitsch   if (fas->next) PetscCall(SNESFASSetGalerkin(fas->next, flg));
49ab8d36c9SPeter Brune   PetscFunctionReturn(0);
50ab8d36c9SPeter Brune }
516273346dSPeter Brune 
5225acbd8eSLisandro Dalcin /*@C
5325acbd8eSLisandro Dalcin    SNESFASGalerkinFunctionDefault - Computes the Galerkin FAS function
546273346dSPeter Brune 
55*f6dfbefdSBarry Smith    Collective on snes
56*f6dfbefdSBarry Smith 
5725acbd8eSLisandro Dalcin    Input Parameters:
58*f6dfbefdSBarry Smith +  snes - the `SNESFAS` nonlinear solver context
5925acbd8eSLisandro Dalcin .  X - input vector
60*f6dfbefdSBarry Smith -  ctx - the application context
6125acbd8eSLisandro Dalcin 
6225acbd8eSLisandro Dalcin    Output Parameter:
6325acbd8eSLisandro Dalcin .  F - output vector
6425acbd8eSLisandro Dalcin 
65*f6dfbefdSBarry Smith    Note:
6625acbd8eSLisandro Dalcin    The Galerkin FAS function evalutation is defined as
6725acbd8eSLisandro Dalcin $  F^l(x^l) = I^l_0 F^0(P^0_l x^l)
6825acbd8eSLisandro Dalcin 
6925acbd8eSLisandro Dalcin    Level: developer
7025acbd8eSLisandro Dalcin 
71*f6dfbefdSBarry Smith .seealso: `SNESFAS`, `SNESFASGetGalerkin()`, `SNESFASSetGalerkin()`
7225acbd8eSLisandro Dalcin @*/
739371c9d4SSatish Balay PetscErrorCode SNESFASGalerkinFunctionDefault(SNES snes, Vec X, Vec F, void *ctx) {
746273346dSPeter Brune   SNES      fassnes;
756273346dSPeter Brune   SNES_FAS *fas;
766273346dSPeter Brune   SNES_FAS *prevfas;
776273346dSPeter Brune   SNES      prevsnes;
7875d4ebe3SPeter Brune   Vec       b_temp;
790adebc6cSBarry Smith 
806273346dSPeter Brune   PetscFunctionBegin;
816273346dSPeter Brune   /* prolong to the fine level and evaluate there. */
826273346dSPeter Brune   fassnes  = (SNES)ctx;
836273346dSPeter Brune   fas      = (SNES_FAS *)fassnes->data;
846273346dSPeter Brune   prevsnes = fas->previous;
856273346dSPeter Brune   prevfas  = (SNES_FAS *)prevsnes->data;
866273346dSPeter Brune   /* interpolate down the solution */
879566063dSJacob Faibussowitsch   PetscCall(MatInterpolate(prevfas->interpolate, X, prevfas->Xg));
8875d4ebe3SPeter Brune   /* the RHS we care about is at the coarsest level */
8975d4ebe3SPeter Brune   b_temp            = prevsnes->vec_rhs;
900298fd71SBarry Smith   prevsnes->vec_rhs = NULL;
919566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(prevsnes, prevfas->Xg, prevfas->Fg));
9275d4ebe3SPeter Brune   prevsnes->vec_rhs = b_temp;
936273346dSPeter Brune   /* restrict up the function */
949566063dSJacob Faibussowitsch   PetscCall(MatRestrict(prevfas->restrct, prevfas->Fg, F));
956273346dSPeter Brune   PetscFunctionReturn(0);
966273346dSPeter Brune }
97