Actual source code: petsc-snesimpl.h
petsc-3.4.2 2013-07-02

      2: #ifndef __SNESIMPL_H

      5: #include <petscsnes.h>
      6: #include <petsc-private/petscimpl.h>

      8: typedef struct _SNESOps *SNESOps;

     10: struct _SNESOps {
     11:   PetscErrorCode (*computeinitialguess)(SNES,Vec,void*);
     12:   PetscErrorCode (*computescaling)(Vec,Vec,void*);
     13:   PetscErrorCode (*update)(SNES, PetscInt);                     /* General purpose function for update */
     14:   PetscErrorCode (*converged)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*);
     15:   PetscErrorCode (*convergeddestroy)(void*);
     16:   PetscErrorCode (*setup)(SNES);                                /* routine to set up the nonlinear solver */
     17:   PetscErrorCode (*solve)(SNES);                                /* actual nonlinear solver */
     18:   PetscErrorCode (*view)(SNES,PetscViewer);
     19:   PetscErrorCode (*setfromoptions)(SNES);                       /* sets options from database */
     20:   PetscErrorCode (*destroy)(SNES);
     21:   PetscErrorCode (*reset)(SNES);
     22:   PetscErrorCode (*usercompute)(SNES,void**);
     23:   PetscErrorCode (*userdestroy)(void**);
     24:   PetscErrorCode (*computevariablebounds)(SNES,Vec,Vec);        /* user provided routine to set box constrained variable bounds */
     25:   PetscErrorCode (*computepfunction)(SNES,Vec,Vec,void*);
     26:   PetscErrorCode (*computepjacobian)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
     27:   PetscErrorCode (*load)(SNES,PetscViewer);
     28: };

     30: /*
     31:    Nonlinear solver context
     32:  */
     33: #define MAXSNESMONITORS 5

     35: struct _p_SNES {
     36:   PETSCHEADER(struct _SNESOps);
     37:   DM        dm;
     38:   PetscBool dmAuto;             /* SNES created currently used DM automatically */
     39:   SNES      pc;
     40:   PCSide    pcside;
     41:   PetscBool usespc;

     43:   /*  ------------------------ User-provided stuff -------------------------------*/
     44:   void  *user;                   /* user-defined context */

     46:   Vec  vec_rhs;                  /* If non-null, solve F(x) = rhs */
     47:   Vec  vec_sol;                  /* pointer to solution */

     49:   Vec  vec_func;                 /* pointer to function */

     51:   Mat  jacobian;                 /* Jacobian matrix */
     52:   Mat  jacobian_pre;             /* preconditioner matrix */
     53:   void *initialguessP;           /* user-defined initial guess context */
     54:   KSP  ksp;                      /* linear solver context */
     55:   SNESLineSearch linesearch;     /* line search context */
     56:   PetscBool usesksp;
     57:   MatStructure matstruct;        /* Used by Picard solver */

     59:   Vec  vec_sol_update;           /* pointer to solution update */

     61:   Vec  scaling;                  /* scaling vector */
     62:   void *scaP;                    /* scaling context */

     64:   PetscReal precheck_picard_angle; /* For use with SNESLineSearchPreCheckPicard */

     66:   /* ------------------------Time stepping hooks-----------------------------------*/

     68:   /* ---------------- PETSc-provided (or user-provided) stuff ---------------------*/

     70:   PetscErrorCode      (*monitor[MAXSNESMONITORS])(SNES,PetscInt,PetscReal,void*); /* monitor routine */
     71:   PetscErrorCode      (*monitordestroy[MAXSNESMONITORS])(void**);                 /* monitor context destroy routine */
     72:   void                *monitorcontext[MAXSNESMONITORS];                           /* monitor context */
     73:   PetscInt            numbermonitors;                                             /* number of monitors */
     74:   void                *cnvP;                                                      /* convergence context */
     75:   SNESConvergedReason reason;
     76:   PetscBool           errorifnotconverged;

     78:   /* --- Routines and data that are unique to each particular solver --- */

     80:   PetscBool      setupcalled;                /* true if setup has been called */
     81:   void           *data;                      /* implementation-specific data */

     83:   /* --------------------------  Parameters -------------------------------------- */

     85:   PetscInt    max_its;            /* max number of iterations */
     86:   PetscInt    max_funcs;          /* max number of function evals */
     87:   PetscInt    nfuncs;             /* number of function evaluations */
     88:   PetscInt    iter;               /* global iteration number */
     89:   PetscInt    linear_its;         /* total number of linear solver iterations */
     90:   PetscReal   norm;               /* residual norm of current iterate */
     91:   PetscReal   rtol;               /* relative tolerance */
     92:   PetscReal   abstol;             /* absolute tolerance */
     93:   PetscReal   stol;               /* step length tolerance*/
     94:   PetscReal   deltatol;           /* trust region convergence tolerance */
     95:   PetscBool   printreason;        /* print reason for convergence/divergence after each solve */
     96:   PetscInt    lagpreconditioner;  /* SNESSetLagPreconditioner() */
     97:   PetscInt    lagjacobian;        /* SNESSetLagJacobian() */
     98:   PetscInt    gridsequence;       /* number of grid sequence steps to take; defaults to zero */

    100:   PetscBool   tolerancesset;      /* SNESSetTolerances() called and tolerances should persist through SNESCreate_XXX()*/

    102:   PetscReal   norm_init;          /* the initial norm value */
    103:   PetscBool   norm_init_set;      /* the initial norm has been set */
    104:   PetscBool   vec_func_init_set;  /* the initial function has been set */

    106:   SNESNormType normtype;          /* Norm computation type for SNES instance */

    108:   /* ------------------------ Default work-area management ---------------------- */

    110:   PetscInt    nwork;
    111:   Vec         *work;

    113:   /* ------------------------- Miscellaneous Information ------------------------ */

    115:   PetscReal   *conv_hist;         /* If !0, stores function norm (or
    116:                                     gradient norm) at each iteration */
    117:   PetscInt    *conv_hist_its;     /* linear iterations for each Newton step */
    118:   PetscInt    conv_hist_len;      /* size of convergence history array */
    119:   PetscInt    conv_hist_max;      /* actual amount of data in conv_history */
    120:   PetscBool   conv_hist_reset;    /* reset counter for each new SNES solve */
    121:   PetscBool   conv_malloc;

    123:   /* the next two are used for failures in the line search; they should be put elsewhere */
    124:   PetscInt    numFailures;        /* number of unsuccessful step attempts */
    125:   PetscInt    maxFailures;        /* maximum number of unsuccessful step attempts */

    127:   PetscInt    numLinearSolveFailures;
    128:   PetscInt    maxLinearSolveFailures;

    130:   PetscBool   domainerror;       /* set with SNESSetFunctionDomainError() */

    132:   PetscBool   ksp_ewconv;        /* flag indicating use of Eisenstat-Walker KSP convergence criteria */
    133:   void        *kspconvctx;       /* Eisenstat-Walker KSP convergence context */

    135:   PetscReal   ttol;           /* used by default convergence test routine */

    137:   Vec         *vwork;            /* more work vectors for Jacobian approx */
    138:   PetscInt    nvwork;

    140:   PetscBool   mf;               /* -snes_mf was used on this snes */
    141:   PetscBool   mf_operator;      /* -snes_mf_operator was used on this snes */
    142:   PetscInt    mf_version;       /* The version of snes_mf used */

    144:   Vec         xl,xu;             /* upper and lower bounds for box constrained VI problems */
    145:   PetscInt    ntruebounds;       /* number of non-infinite bounds set for VI box constraints */
    146:   PetscBool   usersetbounds;     /* bounds have been set via SNESVISetVariableBounds(), rather than via computevariablebounds() callback. */
    147: };

    149: typedef struct _p_DMSNES *DMSNES;
    150: typedef struct _DMSNESOps *DMSNESOps;
    151: struct _DMSNESOps {
    152:   PetscErrorCode (*computefunction)(SNES,Vec,Vec,void*);
    153:   PetscErrorCode (*computejacobian)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);

    155:   /* objective */
    156:   PetscErrorCode (*computeobjective)(SNES,Vec,PetscReal*,void*);

    158:   /* Picard iteration functions */
    159:   PetscErrorCode (*computepfunction)(SNES,Vec,Vec,void*);
    160:   PetscErrorCode (*computepjacobian)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);

    162:   /* User-defined smoother */
    163:   PetscErrorCode (*computegs)(SNES,Vec,Vec,void*);

    165:   PetscErrorCode (*destroy)(DMSNES);
    166:   PetscErrorCode (*duplicate)(DMSNES,DMSNES);
    167: };

    169: struct _p_DMSNES {
    170:   PETSCHEADER(struct _DMSNESOps);
    171:   void *functionctx;
    172:   void *gsctx;
    173:   void *pctx;
    174:   void *jacobianctx;
    175:   void *objectivectx;

    177:   void *data;

    179:   /* This is NOT reference counted. The DM on which this context was first created is cached here to implement one-way
    180:    * copy-on-write. When DMGetDMSNESWrite() sees a request using a different DM, it makes a copy. Thus, if a user
    181:    * only interacts directly with one level, e.g., using SNESSetFunction(), then SNESSetUp_FAS() is called to build
    182:    * coarse levels, then the user changes the routine with another call to SNESSetFunction(), it automatically
    183:    * propagates to all the levels. If instead, they get out a specific level and set the function on that level,
    184:    * subsequent changes to the original level will no longer propagate to that level.
    185:    */
    186:   DM originaldm;
    187: };
    188: PETSC_EXTERN PetscErrorCode DMGetDMSNES(DM,DMSNES*);
    189: PETSC_EXTERN PetscErrorCode DMSNESView(DMSNES,PetscViewer);
    190: PETSC_EXTERN PetscErrorCode DMSNESLoad(DMSNES,PetscViewer);
    191: PETSC_EXTERN PetscErrorCode DMGetDMSNESWrite(DM,DMSNES*);
    192: PETSC_EXTERN PetscErrorCode DMCopyDMSNES(DM,DM);

    195: /* Context for Eisenstat-Walker convergence criteria for KSP solvers */
    196: typedef struct {
    197:   PetscInt  version;             /* flag indicating version 1 or 2 of test */
    198:   PetscReal rtol_0;              /* initial rtol */
    199:   PetscReal rtol_last;           /* last rtol */
    200:   PetscReal rtol_max;            /* maximum rtol */
    201:   PetscReal gamma;               /* mult. factor for version 2 rtol computation */
    202:   PetscReal alpha;               /* power for version 2 rtol computation */
    203:   PetscReal alpha2;              /* power for safeguard */
    204:   PetscReal threshold;           /* threshold for imposing safeguard */
    205:   PetscReal lresid_last;         /* linear residual from last iteration */
    206:   PetscReal norm_last;           /* function norm from last iteration */
    207: } SNESKSPEW;

    211: PETSC_STATIC_INLINE PetscErrorCode SNESLogConvergenceHistory(SNES snes,PetscReal res,PetscInt its)
    212: {

    216:   PetscObjectAMSTakeAccess((PetscObject)snes);
    217:   if (snes->conv_hist && snes->conv_hist_max > snes->conv_hist_len) {
    218:     if (snes->conv_hist)     snes->conv_hist[snes->conv_hist_len]     = res;
    219:     if (snes->conv_hist_its) snes->conv_hist_its[snes->conv_hist_len] = its;
    220:     snes->conv_hist_len++;
    221:   }
    222:   PetscObjectAMSGrantAccess((PetscObject)snes);
    223:   return(0);
    224: }

    226: PETSC_EXTERN PetscErrorCode SNESVIProjectOntoBounds(SNES,Vec);
    227: PETSC_INTERN PetscErrorCode SNESVICheckLocalMin_Private(SNES,Mat,Vec,Vec,PetscReal,PetscBool*);
    228: PETSC_INTERN PetscErrorCode SNESReset_VI(SNES);
    229: PETSC_INTERN PetscErrorCode SNESDestroy_VI(SNES);
    230: PETSC_INTERN PetscErrorCode SNESView_VI(SNES,PetscViewer);
    231: PETSC_INTERN PetscErrorCode SNESSetFromOptions_VI(SNES);
    232: PETSC_INTERN PetscErrorCode SNESSetUp_VI(SNES);
    233: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*SNESVIComputeVariableBoundsFunction)(SNES,Vec,Vec);
    234: PETSC_INTERN PetscErrorCode SNESVISetComputeVariableBounds_VI(SNES,SNESVIComputeVariableBoundsFunction);
    235: PETSC_INTERN PetscErrorCode SNESVISetVariableBounds_VI(SNES,Vec,Vec);
    236: PETSC_INTERN PetscErrorCode SNESConvergedDefault_VI(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*);

    238: PetscErrorCode SNESScaleStep_Private(SNES,Vec,PetscReal*,PetscReal*,PetscReal*,PetscReal*);

    240: PETSC_EXTERN PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval, SNES_NPCSolve;

    242: #endif