Actual source code: tsimpl.h
petsc-3.13.6 2020-09-29
Report Typos and Errors

      1: #ifndef __TSIMPL_H

      4:  #include <petscts.h>
      5:  #include <petsc/private/petscimpl.h>

      7: /*
      8:     Timesteping context.
      9:       General DAE: F(t,U,U_t) = 0, required Jacobian is G'(U) where G(U) = F(t,U,U0+a*U)
     10:       General ODE: U_t = F(t,U) <-- the right-hand-side function
     11:       Linear  ODE: U_t = A(t) U <-- the right-hand-side matrix
     12:       Linear (no time) ODE: U_t = A U <-- the right-hand-side matrix
     13: */

     15: /*
     16:      Maximum number of monitors you can run with a single TS
     17: */
     18: #define MAXTSMONITORS 10

     20: PETSC_EXTERN PetscBool TSRegisterAllCalled;
     21: PETSC_EXTERN PetscErrorCode TSRegisterAll(void);
     22: PETSC_EXTERN PetscErrorCode TSAdaptRegisterAll(void);

     24: PETSC_EXTERN PetscErrorCode TSRKRegisterAll(void);
     25: PETSC_EXTERN PetscErrorCode TSMPRKRegisterAll(void);
     26: PETSC_EXTERN PetscErrorCode TSARKIMEXRegisterAll(void);
     27: PETSC_EXTERN PetscErrorCode TSRosWRegisterAll(void);
     28: PETSC_EXTERN PetscErrorCode TSGLLERegisterAll(void);
     29: PETSC_EXTERN PetscErrorCode TSGLLEAdaptRegisterAll(void);

     31: typedef struct _TSOps *TSOps;

     33: struct _TSOps {
     34:   PetscErrorCode (*snesfunction)(SNES,Vec,Vec,TS);
     35:   PetscErrorCode (*snesjacobian)(SNES,Vec,Mat,Mat,TS);
     36:   PetscErrorCode (*setup)(TS);
     37:   PetscErrorCode (*step)(TS);
     38:   PetscErrorCode (*solve)(TS);
     39:   PetscErrorCode (*interpolate)(TS,PetscReal,Vec);
     40:   PetscErrorCode (*evaluatewlte)(TS,NormType,PetscInt*,PetscReal*);
     41:   PetscErrorCode (*evaluatestep)(TS,PetscInt,Vec,PetscBool*);
     42:   PetscErrorCode (*setfromoptions)(PetscOptionItems*,TS);
     43:   PetscErrorCode (*destroy)(TS);
     44:   PetscErrorCode (*view)(TS,PetscViewer);
     45:   PetscErrorCode (*reset)(TS);
     46:   PetscErrorCode (*linearstability)(TS,PetscReal,PetscReal,PetscReal*,PetscReal*);
     47:   PetscErrorCode (*load)(TS,PetscViewer);
     48:   PetscErrorCode (*rollback)(TS);
     49:   PetscErrorCode (*getstages)(TS,PetscInt*,Vec**);
     50:   PetscErrorCode (*adjointstep)(TS);
     51:   PetscErrorCode (*adjointsetup)(TS);
     52:   PetscErrorCode (*adjointreset)(TS);
     53:   PetscErrorCode (*adjointintegral)(TS);
     54:   PetscErrorCode (*forwardsetup)(TS);
     55:   PetscErrorCode (*forwardreset)(TS);
     56:   PetscErrorCode (*forwardstep)(TS);
     57:   PetscErrorCode (*forwardintegral)(TS);
     58:   PetscErrorCode (*forwardgetstages)(TS,PetscInt*,Mat**);
     59:   PetscErrorCode (*getsolutioncomponents)(TS,PetscInt*,Vec*);
     60:   PetscErrorCode (*getauxsolution)(TS,Vec*);
     61:   PetscErrorCode (*gettimeerror)(TS,PetscInt,Vec*);
     62:   PetscErrorCode (*settimeerror)(TS,Vec);
     63:   PetscErrorCode (*startingmethod) (TS);
     64:   PetscErrorCode (*initcondition)(TS,Vec);
     65:   PetscErrorCode (*exacterror)(TS,Vec,Vec);
     66: };

     68: /*
     69:    TSEvent - Abstract object to handle event monitoring
     70: */
     71: typedef struct _n_TSEvent *TSEvent;

     73: typedef struct _TSTrajectoryOps *TSTrajectoryOps;

     75: struct _TSTrajectoryOps {
     76:   PetscErrorCode (*view)(TSTrajectory,PetscViewer);
     77:   PetscErrorCode (*reset)(TSTrajectory);
     78:   PetscErrorCode (*destroy)(TSTrajectory);
     79:   PetscErrorCode (*set)(TSTrajectory,TS,PetscInt,PetscReal,Vec);
     80:   PetscErrorCode (*get)(TSTrajectory,TS,PetscInt,PetscReal*);
     81:   PetscErrorCode (*setfromoptions)(PetscOptionItems*,TSTrajectory);
     82:   PetscErrorCode (*setup)(TSTrajectory,TS);
     83: };

     85: /* TSHistory is an helper object that allows inquiring
     86:    the TSTrajectory by time and not by the step number only */
     87: typedef struct _n_TSHistory* TSHistory;

     89: struct _p_TSTrajectory {
     90:   PETSCHEADER(struct _TSTrajectoryOps);
     91:   TSHistory tsh;        /* associates times to unique step ids */
     92:   /* stores necessary data to reconstruct states and derivatives via Lagrangian interpolation */
     93:   struct {
     94:     PetscInt    order;  /* interpolation order */
     95:     Vec         *W;     /* work vectors */
     96:     PetscScalar *L;     /* workspace for Lagrange basis */
     97:     PetscReal   *T;     /* Lagrange times (stored) */
     98:     Vec         *WW;    /* just an array of pointers */
     99:     PetscBool   *TT;    /* workspace for Lagrange */
    100:     PetscReal   *TW;    /* Lagrange times (workspace) */

    102:     /* caching */
    103:     PetscBool caching;
    104:     struct {
    105:       PetscObjectId    id;
    106:       PetscObjectState state;
    107:       PetscReal        time;
    108:       PetscInt         step;
    109:     } Ucached;
    110:     struct {
    111:       PetscObjectId    id;
    112:       PetscObjectState state;
    113:       PetscReal        time;
    114:       PetscInt         step;
    115:     } Udotcached;
    116:   } lag;
    117:   Vec            U,Udot;                  /* used by TSTrajectory{Get|Restore}UpdatedHistoryVecs */
    118:   PetscBool      usehistory;              /* whether to use TSHistory */
    119:   PetscBool      solution_only;           /* whether we dump just the solution or also the stages */
    120:   PetscBool      adjoint_solve_mode;      /* whether we will use the Trajectory inside a TSAdjointSolve() or not */
    121:   PetscViewer    monitor;
    122:   PetscInt       setupcalled;             /* true if setup has been called */
    123:   PetscInt       recomps;                 /* counter for recomputations in the adjoint run */
    124:   PetscInt       diskreads,diskwrites;    /* counters for disk checkpoint reads and writes */
    125:   char           **names;                 /* the name of each variable; each process has only the local names */
    126:   PetscBool      keepfiles;               /* keep the files generated during the run after the run is complete */
    127:   char           *dirname,*filetemplate;  /* directory name and file name template for disk checkpoints */
    128:   char           *dirfiletemplate;        /* complete directory and file name template for disk checkpoints */
    129:   PetscErrorCode (*transform)(void*,Vec,Vec*);
    130:   PetscErrorCode (*transformdestroy)(void*);
    131:   void*          transformctx;
    132:   void           *data;
    133: };

    135: typedef struct _TS_RHSSplitLink *TS_RHSSplitLink;
    136: struct _TS_RHSSplitLink {
    137:   TS              ts;
    138:   char            *splitname;
    139:   IS              is;
    140:   TS_RHSSplitLink next;
    141:   PetscLogEvent   event;
    142: };

    144: struct _p_TS {
    145:   PETSCHEADER(struct _TSOps);
    146:   TSProblemType  problem_type;
    147:   TSEquationType equation_type;

    149:   DM             dm;
    150:   Vec            vec_sol; /* solution vector in first and second order equations */
    151:   Vec            vec_dot; /* time derivative vector in second order equations */
    152:   TSAdapt        adapt;
    153:   TSAdaptType    default_adapt_type;
    154:   TSEvent        event;

    156:   /* ---------------- User (or PETSc) Provided stuff ---------------------*/
    157:   PetscErrorCode (*monitor[MAXTSMONITORS])(TS,PetscInt,PetscReal,Vec,void*);
    158:   PetscErrorCode (*monitordestroy[MAXTSMONITORS])(void**);
    159:   void *monitorcontext[MAXTSMONITORS];
    160:   PetscInt  numbermonitors;
    161:   PetscErrorCode (*adjointmonitor[MAXTSMONITORS])(TS,PetscInt,PetscReal,Vec,PetscInt,Vec*,Vec*,void*);
    162:   PetscErrorCode (*adjointmonitordestroy[MAXTSMONITORS])(void**);
    163:   void *adjointmonitorcontext[MAXTSMONITORS];
    164:   PetscInt  numberadjointmonitors;

    166:   PetscErrorCode (*prestep)(TS);
    167:   PetscErrorCode (*prestage)(TS,PetscReal);
    168:   PetscErrorCode (*poststage)(TS,PetscReal,PetscInt,Vec*);
    169:   PetscErrorCode (*postevaluate)(TS);
    170:   PetscErrorCode (*poststep)(TS);
    171:   PetscErrorCode (*functiondomainerror)(TS,PetscReal,Vec,PetscBool*);

    173:   /* ---------------------- Sensitivity Analysis support -----------------*/
    174:   TSTrajectory trajectory;          /* All solutions are kept here for the entire time integration process */
    175:   Vec       *vecs_sensi;            /* one vector for each cost function */
    176:   Vec       *vecs_sensip;
    177:   PetscInt  numcost;                /* number of cost functions */
    178:   Vec       vec_costintegral;
    179:   PetscInt  adjointsetupcalled;
    180:   PetscInt  adjoint_steps;
    181:   PetscInt  adjoint_max_steps;
    182:   PetscBool adjoint_solve;          /* immediately call TSAdjointSolve() after TSSolve() is complete */
    183:   PetscBool costintegralfwd;        /* cost integral is evaluated in the forward run if true */
    184:   Vec       vec_costintegrand;      /* workspace for Adjoint computations */
    185:   Mat       Jacp,Jacprhs;
    186:   void      *ijacobianpctx,*rhsjacobianpctx;
    187:   void      *costintegrandctx;
    188:   Vec       *vecs_drdu;
    189:   Vec       *vecs_drdp;
    190:   Vec       vec_drdu_col,vec_drdp_col;

    192:   /* first-order adjoint */
    193:   PetscErrorCode (*rhsjacobianp)(TS,PetscReal,Vec,Mat,void*);
    194:   PetscErrorCode (*ijacobianp)(TS,PetscReal,Vec,Vec,PetscReal,Mat,void*);
    195:   PetscErrorCode (*costintegrand)(TS,PetscReal,Vec,Vec,void*);
    196:   PetscErrorCode (*drdufunction)(TS,PetscReal,Vec,Vec*,void*);
    197:   PetscErrorCode (*drdpfunction)(TS,PetscReal,Vec,Vec*,void*);

    199:   /* second-order adjoint */
    200:   Vec *vecs_sensi2;
    201:   Vec *vecs_sensi2p;
    202:   Vec vec_dir; /* directional vector for optimization */
    203:   Vec *vecs_fuu,*vecs_guu;
    204:   Vec *vecs_fup,*vecs_gup;
    205:   Vec *vecs_fpu,*vecs_gpu;
    206:   Vec *vecs_fpp,*vecs_gpp;
    207:   void *ihessianproductctx,*rhshessianproductctx;
    208:   PetscErrorCode (*ihessianproduct_fuu)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);
    209:   PetscErrorCode (*ihessianproduct_fup)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);
    210:   PetscErrorCode (*ihessianproduct_fpu)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);
    211:   PetscErrorCode (*ihessianproduct_fpp)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);
    212:   PetscErrorCode (*rhshessianproduct_guu)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);
    213:   PetscErrorCode (*rhshessianproduct_gup)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);
    214:   PetscErrorCode (*rhshessianproduct_gpu)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);
    215:   PetscErrorCode (*rhshessianproduct_gpp)(TS,PetscReal,Vec,Vec*,Vec,Vec*,void*);

    217:   /* specific to forward sensitivity analysis */
    218:   Mat       mat_sensip;              /* matrix storing forward sensitivities */
    219:   Vec       vec_sensip_col;          /* space for a column of the sensip matrix */
    220:   Vec       *vecs_integral_sensip;   /* one vector for each integral */
    221:   PetscInt  num_parameters;
    222:   PetscInt  num_initialvalues;
    223:   void      *vecsrhsjacobianpctx;
    224:   PetscInt  forwardsetupcalled;
    225:   PetscBool forward_solve;
    226:   PetscErrorCode (*vecsrhsjacobianp)(TS,PetscReal,Vec,Vec*,void*);

    228:   /* ---------------------- IMEX support ---------------------------------*/
    229:   /* These extra slots are only used when the user provides both Implicit and RHS */
    230:   Mat Arhs;     /* Right hand side matrix */
    231:   Mat Brhs;     /* Right hand side preconditioning matrix */
    232:   Vec Frhs;     /* Right hand side function value */

    234:   /* This is a general caching scheme to avoid recomputing the Jacobian at a place that has been previously been evaluated.
    235:    * The present use case is that TSComputeRHSFunctionLinear() evaluates the Jacobian once and we don't want it to be immeditely re-evaluated.
    236:    */
    237:   struct {
    238:     PetscReal        time;          /* The time at which the matrices were last evaluated */
    239:     PetscObjectId    Xid;           /* Unique ID of solution vector at which the Jacobian was last evaluated */
    240:     PetscObjectState Xstate;        /* State of the solution vector */
    241:     MatStructure     mstructure;    /* The structure returned */
    242:     /* Flag to unshift Jacobian before calling the IJacobian or RHSJacobian functions.  This is useful
    243:      * if the user would like to reuse (part of) the Jacobian from the last evaluation. */
    244:     PetscBool        reuse;
    245:     PetscReal        scale,shift;
    246:   } rhsjacobian;

    248:   struct {
    249:     PetscReal shift;            /* The derivative of the lhs wrt to Xdot */
    250:   } ijacobian;

    252:   /* --------------------Nonlinear Iteration------------------------------*/
    253:   SNES     snes;
    254:   PetscBool usessnes;   /* Flag set by each TSType to indicate if the type actually uses a SNES;
    255:                            this works around the design flaw that a SNES is ALWAYS created with TS even when it is not needed.*/
    256:   PetscInt ksp_its;                /* total number of linear solver iterations */
    257:   PetscInt snes_its;               /* total number of nonlinear solver iterations */
    258:   PetscInt num_snes_failures;
    259:   PetscInt max_snes_failures;

    261:   /* --- Data that is unique to each particular solver --- */
    262:   PetscInt setupcalled;             /* true if setup has been called */
    263:   void     *data;                   /* implementationspecific data */
    264:   void     *user;                   /* user context */

    266:   /* ------------------  Parameters -------------------------------------- */
    267:   PetscInt  max_steps;              /* max number of steps */
    268:   PetscReal max_time;               /* max time allowed */

    270:   /* --------------------------------------------------------------------- */

    272:   PetscBool steprollback;           /* flag to indicate that the step was rolled back */
    273:   PetscBool steprestart;            /* flag to indicate that the timestepper has to discard any history and restart */
    274:   PetscInt  steps;                  /* steps taken so far in all successive calls to TSSolve() */
    275:   PetscReal ptime;                  /* time at the start of the current step (stage time is internal if it exists) */
    276:   PetscReal time_step;              /* current time increment */
    277:   PetscReal ptime_prev;             /* time at the start of the previous step */
    278:   PetscReal ptime_prev_rollback;    /* time at the start of the 2nd previous step to recover from rollback */
    279:   PetscReal solvetime;              /* time at the conclusion of TSSolve() */

    281:   TSConvergedReason reason;
    282:   PetscBool errorifstepfailed;
    283:   PetscInt  reject,max_reject;
    284:   TSExactFinalTimeOption exact_final_time;

    286:   PetscReal atol,rtol;              /* Relative and absolute tolerance for local truncation error */
    287:   Vec       vatol,vrtol;            /* Relative and absolute tolerance in vector form */
    288:   PetscReal cfltime,cfltime_local;

    290:   PetscBool testjacobian;
    291:   PetscBool testjacobiantranspose;
    292:   /* ------------------- Default work-area management ------------------ */
    293:   PetscInt nwork;
    294:   Vec      *work;

    296:   /* ---------------------- RHS splitting support ---------------------------------*/
    297:   PetscInt        num_rhs_splits;
    298:   TS_RHSSplitLink tsrhssplit;
    299:   PetscBool       use_splitrhsfunction;

    301:   /* ---------------------- Quadrature integration support ---------------------------------*/
    302:   TS quadraturets;
    303: };

    305: struct _TSAdaptOps {
    306:   PetscErrorCode (*choose)(TSAdapt,TS,PetscReal,PetscInt*,PetscReal*,PetscBool*,PetscReal*,PetscReal*,PetscReal*);
    307:   PetscErrorCode (*destroy)(TSAdapt);
    308:   PetscErrorCode (*reset)(TSAdapt);
    309:   PetscErrorCode (*view)(TSAdapt,PetscViewer);
    310:   PetscErrorCode (*setfromoptions)(PetscOptionItems*,TSAdapt);
    311:   PetscErrorCode (*load)(TSAdapt,PetscViewer);
    312: };

    314: struct _p_TSAdapt {
    315:   PETSCHEADER(struct _TSAdaptOps);
    316:   void *data;
    317:   PetscErrorCode (*checkstage)(TSAdapt,TS,PetscReal,Vec,PetscBool*);
    318:   struct {
    319:     PetscInt   n;                /* number of candidate schemes, including the one currently in use */
    320:     PetscBool  inuse_set;        /* the current scheme has been set */
    321:     const char *name[16];        /* name of the scheme */
    322:     PetscInt   order[16];        /* classical order of each scheme */
    323:     PetscInt   stageorder[16];   /* stage order of each scheme */
    324:     PetscReal  ccfl[16];         /* stability limit relative to explicit Euler */
    325:     PetscReal  cost[16];         /* relative measure of the amount of work required for each scheme */
    326:   } candidates;
    327:   PetscBool   always_accept;
    328:   PetscReal   safety;             /* safety factor relative to target error/stability goal */
    329:   PetscReal   reject_safety;      /* extra safety factor if the last step was rejected */
    330:   PetscReal   clip[2];            /* admissible time step decrease/increase factors */
    331:   PetscReal   dt_min,dt_max;      /* admissible minimum and maximum time step */
    332:   PetscReal   ignore_max;         /* minimum value of the solution to be considered by the adaptor */
    333:   PetscBool   glee_use_local;     /* GLEE adaptor uses global or local error */
    334:   PetscReal   scale_solve_failed; /* scale step by this factor if solver (linear or nonlinear) fails. */
    335:   PetscReal   matchstepfac[2];    /* factors to control the behaviour of matchstep */
    336:   NormType    wnormtype;
    337:   PetscViewer monitor;
    338:   PetscInt    timestepjustdecreased_delay; /* number of timesteps after a decrease in the timestep before the timestep can be increased */
    339:   PetscInt    timestepjustdecreased;
    340: };

    342: typedef struct _p_DMTS *DMTS;
    343: typedef struct _DMTSOps *DMTSOps;
    344: struct _DMTSOps {
    345:   TSRHSFunction rhsfunction;
    346:   TSRHSJacobian rhsjacobian;

    348:   TSIFunction ifunction;
    349:   PetscErrorCode (*ifunctionview)(void*,PetscViewer);
    350:   PetscErrorCode (*ifunctionload)(void**,PetscViewer);

    352:   TSIJacobian ijacobian;
    353:   PetscErrorCode (*ijacobianview)(void*,PetscViewer);
    354:   PetscErrorCode (*ijacobianload)(void**,PetscViewer);

    356:   TSI2Function i2function;
    357:   TSI2Jacobian i2jacobian;

    359:   TSTransientVariable transientvar;

    361:   TSSolutionFunction solution;
    362:   TSForcingFunction  forcing;

    364:   PetscErrorCode (*destroy)(DMTS);
    365:   PetscErrorCode (*duplicate)(DMTS,DMTS);
    366: };

    368: struct _p_DMTS {
    369:   PETSCHEADER(struct _DMTSOps);
    370:   void *rhsfunctionctx;
    371:   void *rhsjacobianctx;

    373:   void *ifunctionctx;
    374:   void *ijacobianctx;

    376:   void *i2functionctx;
    377:   void *i2jacobianctx;

    379:   void *transientvarctx;

    381:   void *solutionctx;
    382:   void *forcingctx;

    384:   void *data;

    386:   /* This is NOT reference counted. The DM on which this context was first created is cached here to implement one-way
    387:    * copy-on-write. When DMGetDMTSWrite() sees a request using a different DM, it makes a copy. Thus, if a user
    388:    * only interacts directly with one level, e.g., using TSSetIFunction(), then coarse levels of a multilevel item
    389:    * integrator are built, then the user changes the routine with another call to TSSetIFunction(), it automatically
    390:    * propagates to all the levels. If instead, they get out a specific level and set the function on that level,
    391:    * subsequent changes to the original level will no longer propagate to that level.
    392:    */
    393:   DM originaldm;
    394: };

    396: PETSC_EXTERN PetscErrorCode DMGetDMTS(DM,DMTS*);
    397: PETSC_EXTERN PetscErrorCode DMGetDMTSWrite(DM,DMTS*);
    398: PETSC_EXTERN PetscErrorCode DMCopyDMTS(DM,DM);
    399: PETSC_EXTERN PetscErrorCode DMTSView(DMTS,PetscViewer);
    400: PETSC_EXTERN PetscErrorCode DMTSLoad(DMTS,PetscViewer);
    401: PETSC_EXTERN PetscErrorCode DMTSCopy(DMTS,DMTS);

    403: typedef enum {TSEVENT_NONE,TSEVENT_LOCATED_INTERVAL,TSEVENT_PROCESSING,TSEVENT_ZERO,TSEVENT_RESET_NEXTSTEP} TSEventStatus;

    405: struct _n_TSEvent {
    406:   PetscScalar    *fvalue;          /* value of event function at the end of the step*/
    407:   PetscScalar    *fvalue_prev;     /* value of event function at start of the step (left end-point of event interval) */
    408:   PetscReal       ptime_prev;      /* time at step start (left end-point of event interval) */
    409:   PetscReal       ptime_end;       /* end time of step (when an event interval is detected, ptime_end is fixed to the time at step end during event processing) */
    410:   PetscReal       ptime_right;     /* time on the right end-point of the event interval */
    411:   PetscScalar    *fvalue_right;    /* value of event function at the right end-point of the event interval */
    412:   PetscInt       *side;            /* Used for detecting repetition of end-point, -1 => left, +1 => right */
    413:   PetscReal       timestep_prev;   /* previous time step */
    414:   PetscReal       timestep_posteventinterval;  /* time step immediately after the event interval */
    415:   PetscBool      *zerocrossing;    /* Flag to signal zero crossing detection */
    416:   PetscErrorCode  (*eventhandler)(TS,PetscReal,Vec,PetscScalar*,void*); /* User event handler function */
    417:   PetscErrorCode  (*postevent)(TS,PetscInt,PetscInt[],PetscReal,Vec,PetscBool,void*); /* User post event function */
    418:   void           *ctx;              /* User context for event handler and post even functions */
    419:   PetscInt       *direction;        /* Zero crossing direction: 1 -> Going positive, -1 -> Going negative, 0 -> Any */
    420:   PetscBool      *terminate;        /* 1 -> Terminate time stepping, 0 -> continue */
    421:   PetscInt        nevents;          /* Number of events to handle */
    422:   PetscInt        nevents_zero;     /* Number of event zero detected */
    423:   PetscInt       *events_zero;      /* List of events that have reached zero */
    424:   PetscReal      *vtol;             /* Vector tolerances for event zero check */
    425:   TSEventStatus   status;           /* Event status */
    426:   PetscInt        iterctr;          /* Iteration counter */
    427:   PetscViewer     monitor;
    428:   /* Struct to record the events */
    429:   struct {
    430:     PetscInt  ctr;        /* recorder counter */
    431:     PetscReal *time;      /* Event times */
    432:     PetscInt  *stepnum;   /* Step numbers */
    433:     PetscInt  *nevents;   /* Number of events occuring at the event times */
    434:     PetscInt  **eventidx; /* Local indices of the events in the event list */
    435:   } recorder;
    436:   PetscInt  recsize; /* Size of recorder stack */
    437:   PetscInt  refct; /* reference count */
    438: };

    440: PETSC_EXTERN PetscErrorCode TSEventInitialize(TSEvent,TS,PetscReal,Vec);
    441: PETSC_EXTERN PetscErrorCode TSEventDestroy(TSEvent*);
    442: PETSC_EXTERN PetscErrorCode TSEventHandler(TS);
    443: PETSC_EXTERN PetscErrorCode TSAdjointEventHandler(TS);

    445: PETSC_EXTERN PetscLogEvent TS_AdjointStep;
    446: PETSC_EXTERN PetscLogEvent TS_Step;
    447: PETSC_EXTERN PetscLogEvent TS_PseudoComputeTimeStep;
    448: PETSC_EXTERN PetscLogEvent TS_FunctionEval;
    449: PETSC_EXTERN PetscLogEvent TS_JacobianEval;
    450: PETSC_EXTERN PetscLogEvent TS_ForwardStep;

    452: typedef enum {TS_STEP_INCOMPLETE, /* vec_sol, ptime, etc point to beginning of step */
    453:               TS_STEP_PENDING,    /* vec_sol advanced, but step has not been accepted yet */
    454:               TS_STEP_COMPLETE    /* step accepted and ptime, steps, etc have been advanced */
    455: } TSStepStatus;

    457: struct _n_TSMonitorLGCtx {
    458:   PetscDrawLG    lg;
    459:   PetscBool      semilogy;
    460:   PetscInt       howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
    461:   PetscInt       ksp_its,snes_its;
    462:   char           **names;
    463:   char           **displaynames;
    464:   PetscInt       ndisplayvariables;
    465:   PetscInt       *displayvariables;
    466:   PetscReal      *displayvalues;
    467:   PetscErrorCode (*transform)(void*,Vec,Vec*);
    468:   PetscErrorCode (*transformdestroy)(void*);
    469:   void           *transformctx;
    470: };

    472: struct _n_TSMonitorSPCtx{
    473:   PetscDrawSP    sp;
    474:   PetscInt       howoften; /* when > 0 uses step % howoften, when negative only final solution plotted */
    475:   PetscInt       ksp_its, snes_its;
    476: };

    478: struct _n_TSMonitorEnvelopeCtx {
    479:   Vec max,min;
    480: };

    482: /*
    483:     Checks if the user provide a TSSetIFunction() but an explicit method is called; generate an error in that case
    484: */
    485: PETSC_STATIC_INLINE PetscErrorCode TSCheckImplicitTerm(TS ts)
    486: {
    487:   TSIFunction      ifunction;
    488:   DM               dm;
    489:   PetscErrorCode   ierr;

    492:   TSGetDM(ts,&dm);
    493:   DMTSGetIFunction(dm,&ifunction,NULL);
    494:   if (ifunction) SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_INCOMP,"You are attempting to use an explicit ODE integrator but provided an implicit function definition with TSSetIFunction()");
    495:   return(0);
    496: }

    498: PETSC_EXTERN PetscErrorCode TSGetRHSMats_Private(TS,Mat*,Mat*);
    499: /* this is declared here as TSHistory is not public */
    500: PETSC_EXTERN PetscErrorCode TSAdaptHistorySetTSHistory(TSAdapt,TSHistory,PetscBool);

    502: PETSC_INTERN PetscErrorCode TSTrajectoryReconstruct_Private(TSTrajectory,TS,PetscReal,Vec,Vec);
    503: PETSC_INTERN PetscErrorCode TSTrajectorySetUp_Basic(TSTrajectory,TS);

    505: PETSC_EXTERN PetscLogEvent TSTrajectory_Set;
    506: PETSC_EXTERN PetscLogEvent TSTrajectory_Get;
    507: PETSC_EXTERN PetscLogEvent TSTrajectory_GetVecs;
    508: PETSC_EXTERN PetscLogEvent TSTrajectory_DiskWrite;
    509: PETSC_EXTERN PetscLogEvent TSTrajectory_DiskRead;

    511: struct _n_TSMonitorDrawCtx {
    512:   PetscViewer   viewer;
    513:   Vec           initialsolution;
    514:   PetscBool     showinitial;
    515:   PetscInt      howoften;  /* when > 0 uses step % howoften, when negative only final solution plotted */
    516:   PetscBool     showtimestepandtime;
    517: };
    518: #endif