xref: /petsc/src/snes/impls/fas/fasgalerkin.c (revision e4094ef18e7e53fda86cf35f3a47fda48a8e77d8)
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 
620f4b53cSBarry 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 
11*e4094ef1SJacob Faibussowitsch   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 
6720f4b53cSBarry Smith   Level: developer
6820f4b53cSBarry 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