Actual source code: fasgalerkin.c

  1: #include <../src/snes/impls/fas/fasimpls.h>

  3: /*@
  4:   SNESFASGetGalerkin - Gets if the coarse problems are formed by projection to the fine problem

  6:   Not Collective but the result would be the same on all MPI processes

  8:   Input Parameter:
  9: . snes - the `SNESFAS` nonlinear solver context

 11:   Output Parameter:
 12: . flg - `PETSC_TRUE` if the coarse problem is formed by projection

 14:   Level: advanced

 16: .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASSetLevels()`, `SNESFASSetGalerkin()`
 17: @*/
 18: PetscErrorCode SNESFASGetGalerkin(SNES snes, PetscBool *flg)
 19: {
 20:   SNES_FAS *fas;

 22:   PetscFunctionBegin;
 24:   fas  = (SNES_FAS *)snes->data;
 25:   *flg = fas->galerkin;
 26:   PetscFunctionReturn(PETSC_SUCCESS);
 27: }

 29: /*@
 30:   SNESFASSetGalerkin - Sets coarse problems as formed by projection to the fine problem

 32:   Logically Collective

 34:   Input Parameters:
 35: + snes - the `SNESFAS` nonlinear solver context
 36: - flg  - `PETSC_TRUE` to use the projection process

 38:   Level: advanced

 40: .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASSetLevels()`, `SNESFASGetGalerkin()`
 41: @*/
 42: PetscErrorCode SNESFASSetGalerkin(SNES snes, PetscBool flg)
 43: {
 44:   SNES_FAS *fas;

 46:   PetscFunctionBegin;
 48:   fas           = (SNES_FAS *)snes->data;
 49:   fas->galerkin = flg;
 50:   if (fas->next) PetscCall(SNESFASSetGalerkin(fas->next, flg));
 51:   PetscFunctionReturn(PETSC_SUCCESS);
 52: }

 54: /*@C
 55:   SNESFASGalerkinFunctionDefault - Computes the Galerkin FAS function

 57:   Collective

 59:   Input Parameters:
 60: + snes - the `SNESFAS` nonlinear solver context
 61: . X    - input vector
 62: - ctx  - the application context

 64:   Output Parameter:
 65: . F - output vector

 67:   Level: developer

 69:   Note:
 70:   The Galerkin FAS function evaluation is defined as
 71: $  F^l(x^l) = I^l_0 F^0(P^0_l x^l)

 73: .seealso: [](ch_snes), `SNES`, `SNESFAS`, `SNESFASGetGalerkin()`, `SNESFASSetGalerkin()`
 74: @*/
 75: PetscErrorCode SNESFASGalerkinFunctionDefault(SNES snes, Vec X, Vec F, void *ctx)
 76: {
 77:   SNES      fassnes;
 78:   SNES_FAS *fas;
 79:   SNES_FAS *prevfas;
 80:   SNES      prevsnes;
 81:   Vec       b_temp;

 83:   PetscFunctionBegin;
 84:   /* prolong to the fine level and evaluate there. */
 85:   fassnes  = (SNES)ctx;
 86:   fas      = (SNES_FAS *)fassnes->data;
 87:   prevsnes = fas->previous;
 88:   prevfas  = (SNES_FAS *)prevsnes->data;
 89:   /* interpolate down the solution */
 90:   PetscCall(MatInterpolate(prevfas->interpolate, X, prevfas->Xg));
 91:   /* the RHS we care about is at the coarsest level */
 92:   b_temp            = prevsnes->vec_rhs;
 93:   prevsnes->vec_rhs = NULL;
 94:   PetscCall(SNESComputeFunction(prevsnes, prevfas->Xg, prevfas->Fg));
 95:   prevsnes->vec_rhs = b_temp;
 96:   /* restrict up the function */
 97:   PetscCall(MatRestrict(prevfas->restrct, prevfas->Fg, F));
 98:   PetscFunctionReturn(PETSC_SUCCESS);
 99: }