xref: /petsc/src/snes/impls/fas/fasgalerkin.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
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 
6ab8d36c9SPeter Brune    Input Parameter:
7ab8d36c9SPeter Brune .  snes - the nonlinear solver context
8ab8d36c9SPeter Brune 
9ab8d36c9SPeter Brune    Output parameter:
10ab8d36c9SPeter Brune .  flg - the status of the galerkin problem
11ab8d36c9SPeter Brune 
12ab8d36c9SPeter Brune    Level: advanced
13ab8d36c9SPeter Brune 
14db781477SPatrick Sanan .seealso: `SNESFASSetLevels()`, `SNESFASSetGalerkin()`
15ab8d36c9SPeter Brune @*/
16*9371c9d4SSatish Balay PetscErrorCode SNESFASGetGalerkin(SNES snes, PetscBool *flg) {
17f833ba53SLisandro Dalcin   SNES_FAS *fas;
185fd66863SKarl Rupp 
19ab8d36c9SPeter Brune   PetscFunctionBegin;
20f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
21f833ba53SLisandro Dalcin   fas  = (SNES_FAS *)snes->data;
22ab8d36c9SPeter Brune   *flg = fas->galerkin;
23ab8d36c9SPeter Brune   PetscFunctionReturn(0);
24ab8d36c9SPeter Brune }
25ab8d36c9SPeter Brune 
26ab8d36c9SPeter Brune /*@
27ab8d36c9SPeter Brune    SNESFASSetGalerkin - Sets coarse problems as formed by projection to the fine problem
28ab8d36c9SPeter Brune 
29d8d19677SJose E. Roman    Input Parameters:
30a2b725a8SWilliam Gropp +  snes - the nonlinear solver context
31a2b725a8SWilliam Gropp -  flg - the status of the galerkin problem
32ab8d36c9SPeter Brune 
33ab8d36c9SPeter Brune    Level: advanced
34ab8d36c9SPeter Brune 
35db781477SPatrick Sanan .seealso: `SNESFASSetLevels()`, `SNESFASGetGalerkin()`
36ab8d36c9SPeter Brune @*/
37*9371c9d4SSatish Balay PetscErrorCode SNESFASSetGalerkin(SNES snes, PetscBool flg) {
38f833ba53SLisandro Dalcin   SNES_FAS *fas;
395fd66863SKarl Rupp 
40ab8d36c9SPeter Brune   PetscFunctionBegin;
41f833ba53SLisandro Dalcin   PetscValidHeaderSpecificType(snes, SNES_CLASSID, 1, SNESFAS);
42f833ba53SLisandro Dalcin   fas           = (SNES_FAS *)snes->data;
43ab8d36c9SPeter Brune   fas->galerkin = flg;
449566063dSJacob Faibussowitsch   if (fas->next) PetscCall(SNESFASSetGalerkin(fas->next, flg));
45ab8d36c9SPeter Brune   PetscFunctionReturn(0);
46ab8d36c9SPeter Brune }
476273346dSPeter Brune 
4825acbd8eSLisandro Dalcin /*@C
4925acbd8eSLisandro Dalcin    SNESFASGalerkinFunctionDefault - Computes the Galerkin FAS function
506273346dSPeter Brune 
5125acbd8eSLisandro Dalcin    Input Parameters:
52a2b725a8SWilliam Gropp +  snes - the nonlinear solver context
5325acbd8eSLisandro Dalcin .  X - input vector
54a2b725a8SWilliam Gropp -  ctx - the FAS context
5525acbd8eSLisandro Dalcin 
5625acbd8eSLisandro Dalcin    Output Parameter:
5725acbd8eSLisandro Dalcin .  F - output vector
5825acbd8eSLisandro Dalcin 
5925acbd8eSLisandro Dalcin    Notes:
6025acbd8eSLisandro Dalcin    The Galerkin FAS function evalutation is defined as
6125acbd8eSLisandro Dalcin $  F^l(x^l) = I^l_0 F^0(P^0_l x^l)
6225acbd8eSLisandro Dalcin 
6325acbd8eSLisandro Dalcin    Level: developer
6425acbd8eSLisandro Dalcin 
65db781477SPatrick Sanan .seealso: `SNESFASGetGalerkin()`, `SNESFASSetGalerkin()`
6625acbd8eSLisandro Dalcin @*/
67*9371c9d4SSatish Balay PetscErrorCode SNESFASGalerkinFunctionDefault(SNES snes, Vec X, Vec F, void *ctx) {
686273346dSPeter Brune   SNES      fassnes;
696273346dSPeter Brune   SNES_FAS *fas;
706273346dSPeter Brune   SNES_FAS *prevfas;
716273346dSPeter Brune   SNES      prevsnes;
7275d4ebe3SPeter Brune   Vec       b_temp;
730adebc6cSBarry Smith 
746273346dSPeter Brune   PetscFunctionBegin;
756273346dSPeter Brune   /* prolong to the fine level and evaluate there. */
766273346dSPeter Brune   fassnes  = (SNES)ctx;
776273346dSPeter Brune   fas      = (SNES_FAS *)fassnes->data;
786273346dSPeter Brune   prevsnes = fas->previous;
796273346dSPeter Brune   prevfas  = (SNES_FAS *)prevsnes->data;
806273346dSPeter Brune   /* interpolate down the solution */
819566063dSJacob Faibussowitsch   PetscCall(MatInterpolate(prevfas->interpolate, X, prevfas->Xg));
8275d4ebe3SPeter Brune   /* the RHS we care about is at the coarsest level */
8375d4ebe3SPeter Brune   b_temp            = prevsnes->vec_rhs;
840298fd71SBarry Smith   prevsnes->vec_rhs = NULL;
859566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(prevsnes, prevfas->Xg, prevfas->Fg));
8675d4ebe3SPeter Brune   prevsnes->vec_rhs = b_temp;
876273346dSPeter Brune   /* restrict up the function */
889566063dSJacob Faibussowitsch   PetscCall(MatRestrict(prevfas->restrct, prevfas->Fg, F));
896273346dSPeter Brune   PetscFunctionReturn(0);
906273346dSPeter Brune }
91