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

     72:   $$
     73:   F^l(x^l) = I^l_0 F^0(P^0_l x^l)
     74:   $$

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

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