xref: /petsc/src/snes/impls/fas/fasgalerkin.c (revision 20f4b53cbb5e9bd9ef12b76a8697d60d197cda17)
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*20f4b53cSBarry Smith    Not Collective but the result would be the same on all MPI ranks
7f6dfbefdSBarry Smith 
8ab8d36c9SPeter Brune    Input Parameter:
9f6dfbefdSBarry Smith .  snes - the `SNESFAS` nonlinear solver context
10ab8d36c9SPeter Brune 
11ab8d36c9SPeter Brune    Output parameter:
12f6dfbefdSBarry Smith .  flg - `PETSC_TRUE` if the coarse problem is formed by projection
13ab8d36c9SPeter Brune 
14ab8d36c9SPeter Brune    Level: advanced
15ab8d36c9SPeter Brune 
16f6dfbefdSBarry Smith .seealso: `SNESFAS`, `SNESFASSetLevels()`, `SNESFASSetGalerkin()`
17ab8d36c9SPeter Brune @*/
18d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESFASGetGalerkin(SNES snes, PetscBool *flg)
19d71ae5a4SJacob Faibussowitsch {
20f833ba53SLisandro Dalcin   SNES_FAS *fas;
215fd66863SKarl Rupp 
22ab8d36c9SPeter Brune   PetscFunctionBegin;
23f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
24f833ba53SLisandro Dalcin   fas  = (SNES_FAS *)snes->data;
25ab8d36c9SPeter Brune   *flg = fas->galerkin;
263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
27ab8d36c9SPeter Brune }
28ab8d36c9SPeter Brune 
29ab8d36c9SPeter Brune /*@
30ab8d36c9SPeter Brune    SNESFASSetGalerkin - Sets coarse problems as formed by projection to the fine problem
31ab8d36c9SPeter Brune 
32c3339decSBarry Smith    Collective
33f6dfbefdSBarry Smith 
34d8d19677SJose E. Roman    Input Parameters:
35f6dfbefdSBarry Smith +  snes - the `SNESFAS` nonlinear solver context
36f6dfbefdSBarry Smith -  flg - `PETSC_TRUE` to use the projection process
37ab8d36c9SPeter Brune 
38ab8d36c9SPeter Brune    Level: advanced
39ab8d36c9SPeter Brune 
40f6dfbefdSBarry Smith .seealso: `SNESFAS`, `SNESFASSetLevels()`, `SNESFASGetGalerkin()`
41ab8d36c9SPeter Brune @*/
42d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESFASSetGalerkin(SNES snes, PetscBool flg)
43d71ae5a4SJacob Faibussowitsch {
44f833ba53SLisandro Dalcin   SNES_FAS *fas;
455fd66863SKarl Rupp 
46ab8d36c9SPeter Brune   PetscFunctionBegin;
47f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
48f833ba53SLisandro Dalcin   fas           = (SNES_FAS *)snes->data;
49ab8d36c9SPeter Brune   fas->galerkin = flg;
509566063dSJacob Faibussowitsch   if (fas->next) PetscCall(SNESFASSetGalerkin(fas->next, flg));
513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
52ab8d36c9SPeter Brune }
536273346dSPeter Brune 
5425acbd8eSLisandro Dalcin /*@C
5525acbd8eSLisandro Dalcin    SNESFASGalerkinFunctionDefault - Computes the Galerkin FAS function
566273346dSPeter Brune 
57c3339decSBarry Smith    Collective
58f6dfbefdSBarry Smith 
5925acbd8eSLisandro Dalcin    Input Parameters:
60f6dfbefdSBarry Smith +  snes - the `SNESFAS` nonlinear solver context
6125acbd8eSLisandro Dalcin .  X - input vector
62f6dfbefdSBarry Smith -  ctx - the application context
6325acbd8eSLisandro Dalcin 
6425acbd8eSLisandro Dalcin    Output Parameter:
6525acbd8eSLisandro Dalcin .  F - output vector
6625acbd8eSLisandro Dalcin 
67*20f4b53cSBarry Smith    Level: developer
68*20f4b53cSBarry Smith 
69f6dfbefdSBarry Smith    Note:
70da81f932SPierre Jolivet    The Galerkin FAS function evaluation is defined as
7125acbd8eSLisandro Dalcin $  F^l(x^l) = I^l_0 F^0(P^0_l x^l)
7225acbd8eSLisandro Dalcin 
73f6dfbefdSBarry Smith .seealso: `SNESFAS`, `SNESFASGetGalerkin()`, `SNESFASSetGalerkin()`
7425acbd8eSLisandro Dalcin @*/
75d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESFASGalerkinFunctionDefault(SNES snes, Vec X, Vec F, void *ctx)
76d71ae5a4SJacob Faibussowitsch {
776273346dSPeter Brune   SNES      fassnes;
786273346dSPeter Brune   SNES_FAS *fas;
796273346dSPeter Brune   SNES_FAS *prevfas;
806273346dSPeter Brune   SNES      prevsnes;
8175d4ebe3SPeter Brune   Vec       b_temp;
820adebc6cSBarry Smith 
836273346dSPeter Brune   PetscFunctionBegin;
846273346dSPeter Brune   /* prolong to the fine level and evaluate there. */
856273346dSPeter Brune   fassnes  = (SNES)ctx;
866273346dSPeter Brune   fas      = (SNES_FAS *)fassnes->data;
876273346dSPeter Brune   prevsnes = fas->previous;
886273346dSPeter Brune   prevfas  = (SNES_FAS *)prevsnes->data;
896273346dSPeter Brune   /* interpolate down the solution */
909566063dSJacob Faibussowitsch   PetscCall(MatInterpolate(prevfas->interpolate, X, prevfas->Xg));
9175d4ebe3SPeter Brune   /* the RHS we care about is at the coarsest level */
9275d4ebe3SPeter Brune   b_temp            = prevsnes->vec_rhs;
930298fd71SBarry Smith   prevsnes->vec_rhs = NULL;
949566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(prevsnes, prevfas->Xg, prevfas->Fg));
9575d4ebe3SPeter Brune   prevsnes->vec_rhs = b_temp;
966273346dSPeter Brune   /* restrict up the function */
979566063dSJacob Faibussowitsch   PetscCall(MatRestrict(prevfas->restrct, prevfas->Fg, F));
983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
996273346dSPeter Brune }
100