xref: /petsc/src/ts/interface/ts.c (revision 188af4bf1b9cf194d1407690fd963ae1ba8cff5d)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h"  I*/
21e25c274SJed Brown #include <petscdmda.h>
360e16b1bSMatthew G. Knepley #include <petscdmshell.h>
460e16b1bSMatthew G. Knepley #include <petscdmplex.h>  // For TSSetFromOptions()
560e16b1bSMatthew G. Knepley #include <petscdmswarm.h> // For TSSetFromOptions()
62d5ee99bSBarry Smith #include <petscviewer.h>
72d5ee99bSBarry Smith #include <petscdraw.h>
8900f6b5bSMatthew G. Knepley #include <petscconvest.h>
9d763cef2SBarry Smith 
10d5ba7fb7SMatthew Knepley /* Logging support */
11d74926cbSBarry Smith PetscClassId  TS_CLASSID, DMTS_CLASSID;
12a05bf03eSHong Zhang PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
13d405a339SMatthew Knepley 
14c793f718SLisandro Dalcin const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED", "STEPOVER", "INTERPOLATE", "MATCHSTEP", "TSExactFinalTimeOption", "TS_EXACTFINALTIME_", NULL};
1549354f04SShri Abhyankar 
16d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdaptSetDefaultType(TSAdapt adapt, TSAdaptType default_type)
17d71ae5a4SJacob Faibussowitsch {
182ffb9264SLisandro Dalcin   PetscFunctionBegin;
19b92453a8SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
204f572ea9SToby Isaac   PetscAssertPointer(default_type, 2);
211e66621cSBarry Smith   if (!((PetscObject)adapt)->type_name) PetscCall(TSAdaptSetType(adapt, default_type));
223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
232ffb9264SLisandro Dalcin }
242ffb9264SLisandro Dalcin 
25bdad233fSMatthew Knepley /*@
26195e9b02SBarry Smith   TSSetFromOptions - Sets various `TS` parameters from the options database
27bdad233fSMatthew Knepley 
28c3339decSBarry Smith   Collective
29bdad233fSMatthew Knepley 
30bdad233fSMatthew Knepley   Input Parameter:
31bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
32bdad233fSMatthew Knepley 
33bdad233fSMatthew Knepley   Options Database Keys:
34195e9b02SBarry Smith + -ts_type <type>                                                    - EULER, BEULER, SUNDIALS, PSEUDO, CN, RK, THETA, ALPHA, GLLE,  SSP, GLEE, BSYMP, IRK, see `TSType`
35ef222394SBarry Smith . -ts_save_trajectory                                                - checkpoint the solution at each time-step
36ef85077eSLisandro Dalcin . -ts_max_time <time>                                                - maximum time to compute to
378343f784SJames Wright . -ts_time_span <t0,...tf>                                           - sets the time span, solutions are computed and stored for each indicated time, init_time and max_time are set
388343f784SJames Wright . -ts_eval_times <t0,...tn>                                          - time points where solutions are computed and stored for each indicated time
398e562f8dSJames Wright . -ts_max_steps <steps>                                              - maximum time-step number to execute until (possibly with nonzero starting value)
40*188af4bfSBarry Smith . -ts_run_steps <steps>                                              - maximum number of time steps for `TSSolve()` to take on each call
41ef85077eSLisandro Dalcin . -ts_init_time <time>                                               - initial time to start computation
42195e9b02SBarry Smith . -ts_final_time <time>                                              - final time to compute to (deprecated: use `-ts_max_time`)
43*188af4bfSBarry Smith . -ts_time_step <dt>                                                 - initial time step (only a suggestion, the actual initial time step used differ)
441628793fSSatish Balay . -ts_exact_final_time <stepover,interpolate,matchstep>              - whether to stop at the exact given final time and how to compute the solution at that time
45a3cdaa26SBarry Smith . -ts_max_snes_failures <maxfailures>                                - Maximum number of nonlinear solve failures allowed
46*188af4bfSBarry Smith . -ts_max_step_rejections <maxrejects>                               - Maximum number of step rejections before step fails
47a3cdaa26SBarry Smith . -ts_error_if_step_fails <true,false>                               - Error if no step succeeds
48a3cdaa26SBarry Smith . -ts_rtol <rtol>                                                    - relative tolerance for local truncation error
4967b8a455SSatish Balay . -ts_atol <atol>                                                    - Absolute tolerance for local truncation error
50f3b1f45cSBarry Smith . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view               - test the Jacobian at each iteration against finite difference with RHS function
51b43aa488SJacob Faibussowitsch . -ts_rhs_jacobian_test_mult_transpose                               - test the Jacobian at each iteration against finite difference with RHS function
52195e9b02SBarry Smith . -ts_adjoint_solve <yes,no>                                         - After solving the ODE/DAE solve the adjoint problem (requires `-ts_save_trajectory`)
53847ff0e1SMatthew G. Knepley . -ts_fd_color                                                       - Use finite differences with coloring to compute IJacobian
54bdad233fSMatthew Knepley . -ts_monitor                                                        - print information at each timestep
55aee7a9fbSMatthew G. Knepley . -ts_monitor_cancel                                                 - Cancel all monitors
56340b794cSJed Brown . -ts_monitor_wall_clock_time                                        - Monitor wall-clock time, KSP iterations, and SNES iterations per step
57de06c3feSJed Brown . -ts_monitor_lg_solution                                            - Monitor solution graphically
58de06c3feSJed Brown . -ts_monitor_lg_error                                               - Monitor error graphically
597cf37e64SBarry Smith . -ts_monitor_error                                                  - Monitors norm of error
606934998bSLisandro Dalcin . -ts_monitor_lg_timestep                                            - Monitor timestep size graphically
618b668821SLisandro Dalcin . -ts_monitor_lg_timestep_log                                        - Monitor log timestep size graphically
62de06c3feSJed Brown . -ts_monitor_lg_snes_iterations                                     - Monitor number nonlinear iterations for each timestep graphically
63de06c3feSJed Brown . -ts_monitor_lg_ksp_iterations                                      - Monitor number nonlinear iterations for each timestep graphically
64de06c3feSJed Brown . -ts_monitor_sp_eig                                                 - Monitor eigenvalues of linearized operator graphically
65de06c3feSJed Brown . -ts_monitor_draw_solution                                          - Monitor solution graphically
663e4cdcaaSBarry Smith . -ts_monitor_draw_solution_phase  <xleft,yleft,xright,yright>       - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom
673e4cdcaaSBarry Smith . -ts_monitor_draw_error                                             - Monitor error graphically, requires use to have provided TSSetSolutionFunction()
68fde5950dSBarry Smith . -ts_monitor_solution [ascii binary draw][:filename][:viewerformat] - monitors the solution at each timestep
69c17ba870SStefano Zampini . -ts_monitor_solution_interval <interval>                           - output once every interval (default=1) time steps. Use -1 to only output at the end of the simulation
708e562f8dSJames Wright . -ts_monitor_solution_skip_initial                                  - skip writing of initial condition
7163a3b9bcSJacob Faibussowitsch . -ts_monitor_solution_vtk <filename.vts,filename.vtu>               - Save each time step to a binary file, use filename-%%03" PetscInt_FMT ".vts (filename-%%03" PetscInt_FMT ".vtu)
72c17ba870SStefano Zampini . -ts_monitor_solution_vtk_interval <interval>                       - output once every interval (default=1) time steps. Use -1 to only output at the end of the simulation
739e336e28SPatrick Sanan - -ts_monitor_envelope                                               - determine maximum and minimum value of each component of the solution over the solution time
7453ea634cSHong Zhang 
75bcf0153eSBarry Smith   Level: beginner
763d5a8a6aSBarry Smith 
77bcf0153eSBarry Smith   Notes:
78bcf0153eSBarry Smith   See `SNESSetFromOptions()` and `KSPSetFromOptions()` for how to control the nonlinear and linear solves used by the time-stepper.
79bcf0153eSBarry Smith 
80195e9b02SBarry Smith   Certain `SNES` options get reset for each new nonlinear solver, for example `-snes_lag_jacobian its` and `-snes_lag_preconditioner its`, in order
810d56bcf9SIlya Fursov   to retain them over the multiple nonlinear solves that `TS` uses you must also provide `-snes_lag_jacobian_persists true` and
82195e9b02SBarry Smith   `-snes_lag_preconditioner_persists true`
833d5a8a6aSBarry Smith 
84b43aa488SJacob Faibussowitsch   Developer Notes:
859e336e28SPatrick Sanan   We should unify all the -ts_monitor options in the way that -xxx_view has been unified
86bdad233fSMatthew Knepley 
871cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetType()`
88bdad233fSMatthew Knepley @*/
89d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetFromOptions(TS ts)
90d71ae5a4SJacob Faibussowitsch {
91bc952696SBarry Smith   PetscBool              opt, flg, tflg;
92eabae89aSBarry Smith   char                   monfilename[PETSC_MAX_PATH_LEN];
93acc0c1feSStefano Zampini   PetscReal              time_step, eval_times[100] = {0};
94136cf249SJames Wright   PetscInt               num_eval_times = PETSC_STATIC_ARRAY_LENGTH(eval_times);
9549354f04SShri Abhyankar   TSExactFinalTimeOption eftopt;
96d1212d36SBarry Smith   char                   dir[16];
978434afd1SBarry Smith   TSIFunctionFn         *ifun;
986991f827SBarry Smith   const char            *defaultType;
996991f827SBarry Smith   char                   typeName[256];
100bdad233fSMatthew Knepley 
101bdad233fSMatthew Knepley   PetscFunctionBegin;
1020700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1036991f827SBarry Smith 
1049566063dSJacob Faibussowitsch   PetscCall(TSRegisterAll());
1059566063dSJacob Faibussowitsch   PetscCall(TSGetIFunction(ts, NULL, &ifun, NULL));
106cd11d68dSLisandro Dalcin 
107d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)ts);
1081ef27442SStefano Zampini   if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name;
1091ef27442SStefano Zampini   else defaultType = ifun ? TSBEULER : TSEULER;
1109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-ts_type", "TS method", "TSSetType", TSList, defaultType, typeName, 256, &opt));
1111e66621cSBarry Smith   if (opt) PetscCall(TSSetType(ts, typeName));
1121e66621cSBarry Smith   else PetscCall(TSSetType(ts, defaultType));
113bdad233fSMatthew Knepley 
114bdad233fSMatthew Knepley   /* Handle generic TS options */
1159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDeprecated("-ts_final_time", "-ts_max_time", "3.10", NULL));
1169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_max_time", "Maximum time to run to", "TSSetMaxTime", ts->max_time, &ts->max_time, NULL));
117136cf249SJames Wright   PetscCall(PetscOptionsRealArray("-ts_time_span", "Time span", "TSSetTimeSpan", eval_times, &num_eval_times, &flg));
118136cf249SJames Wright   if (flg) PetscCall(TSSetTimeSpan(ts, num_eval_times, eval_times));
119136cf249SJames Wright   num_eval_times = PETSC_STATIC_ARRAY_LENGTH(eval_times);
120136cf249SJames Wright   PetscCall(PetscOptionsRealArray("-ts_eval_times", "Evaluation time points", "TSSetEvaluationTimes", eval_times, &num_eval_times, &opt));
1218343f784SJames Wright   PetscCheck(flg != opt || (!flg && !opt), PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "May not provide -ts_time_span and -ts_eval_times simultaneously");
122136cf249SJames Wright   if (opt) PetscCall(TSSetEvaluationTimes(ts, num_eval_times, eval_times));
1238e562f8dSJames Wright   PetscCall(PetscOptionsInt("-ts_max_steps", "Maximum time step number to execute to (possibly with non-zero starting value)", "TSSetMaxSteps", ts->max_steps, &ts->max_steps, NULL));
1248e562f8dSJames Wright   PetscCall(PetscOptionsInt("-ts_run_steps", "Maximum number of time steps to take on each call to TSSolve()", "TSSetRunSteps", ts->run_steps, &ts->run_steps, NULL));
1259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_init_time", "Initial time", "TSSetTime", ts->ptime, &ts->ptime, NULL));
126*188af4bfSBarry Smith   PetscCall(PetscOptionsDeprecated("-ts_dt", "-ts_time_step", "3.25", NULL));
127*188af4bfSBarry Smith   PetscCall(PetscOptionsReal("-ts_time_step", "Initial time step", "TSSetTimeStep", ts->time_step, &time_step, &flg));
1289566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetTimeStep(ts, time_step));
1299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-ts_exact_final_time", "Option for handling of final time step", "TSSetExactFinalTime", TSExactFinalTimeOptions, (PetscEnum)ts->exact_final_time, (PetscEnum *)&eftopt, &flg));
1309566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetExactFinalTime(ts, eftopt));
13109cb0f53SBarry Smith   PetscCall(PetscOptionsInt("-ts_max_snes_failures", "Maximum number of nonlinear solve failures", "TSSetMaxSNESFailures", ts->max_snes_failures, &ts->max_snes_failures, &flg));
13209cb0f53SBarry Smith   if (flg) PetscCall(TSSetMaxSNESFailures(ts, ts->max_snes_failures));
133*188af4bfSBarry Smith   PetscCall(PetscOptionsDeprecated("-ts_max_reject", "-ts_max_step_rejections", "3.25", NULL));
134*188af4bfSBarry Smith   PetscCall(PetscOptionsInt("-ts_max_step_rejections", "Maximum number of step rejections before step fails", "TSSetMaxStepRejections", ts->max_reject, &ts->max_reject, &flg));
13509cb0f53SBarry Smith   if (flg) PetscCall(TSSetMaxStepRejections(ts, ts->max_reject));
1369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_error_if_step_fails", "Error if no step succeeds", "TSSetErrorIfStepFails", ts->errorifstepfailed, &ts->errorifstepfailed, NULL));
13709cb0f53SBarry Smith   PetscCall(PetscOptionsBoundedReal("-ts_rtol", "Relative tolerance for local truncation error", "TSSetTolerances", ts->rtol, &ts->rtol, NULL, 0));
13809cb0f53SBarry Smith   PetscCall(PetscOptionsBoundedReal("-ts_atol", "Absolute tolerance for local truncation error", "TSSetTolerances", ts->atol, &ts->atol, NULL, 0));
139bdad233fSMatthew Knepley 
1409566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_rhs_jacobian_test_mult", "Test the RHS Jacobian for consistency with RHS at each solve ", "None", ts->testjacobian, &ts->testjacobian, NULL));
1419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_rhs_jacobian_test_mult_transpose", "Test the RHS Jacobian transpose for consistency with RHS at each solve ", "None", ts->testjacobiantranspose, &ts->testjacobiantranspose, NULL));
1429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_use_splitrhsfunction", "Use the split RHS function for multirate solvers ", "TSSetUseSplitRHSFunction", ts->use_splitrhsfunction, &ts->use_splitrhsfunction, NULL));
14356f85f32SBarry Smith #if defined(PETSC_HAVE_SAWS)
14456f85f32SBarry Smith   {
14556f85f32SBarry Smith     PetscBool set;
14656f85f32SBarry Smith     flg = PETSC_FALSE;
1479566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-ts_saws_block", "Block for SAWs memory snooper at end of TSSolve", "PetscObjectSAWsBlock", ((PetscObject)ts)->amspublishblock, &flg, &set));
1481baa6e33SBarry Smith     if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)ts, flg));
14956f85f32SBarry Smith   }
15056f85f32SBarry Smith #endif
15156f85f32SBarry Smith 
152bdad233fSMatthew Knepley   /* Monitor options */
15341d17464SJames Wright   PetscCall(PetscOptionsDeprecated("-ts_monitor_frequency", "-ts_dmswarm_monitor_moments_interval", "3.24", "Retired in favor of monitor-specific intervals (ts_dmswarm_monitor_moments was the only monitor to use ts_monitor_frequency)"));
1549566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor", "Monitor time and timestep size", "TSMonitorDefault", TSMonitorDefault, NULL));
155340b794cSJed Brown   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_wall_clock_time", "Monitor wall-clock time, KSP iterations, and SNES iterations per step", "TSMonitorWallClockTime", TSMonitorWallClockTime, TSMonitorWallClockTimeSetUp));
1569566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_extreme", "Monitor extreme values of the solution", "TSMonitorExtreme", TSMonitorExtreme, NULL));
1578e562f8dSJames Wright   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_solution", "View the solution at each timestep", "TSMonitorSolution", TSMonitorSolution, TSMonitorSolutionSetup));
1589566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_dmswarm_monitor_moments", "Monitor moments of particle distribution", "TSDMSwarmMonitorMoments", TSDMSwarmMonitorMoments, NULL));
1599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_python", "Use Python function", "TSMonitorSet", NULL, monfilename, sizeof(monfilename), &flg));
1609566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)ts, monfilename));
1615180491cSLisandro Dalcin 
1629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_solution", "Monitor solution graphically", "TSMonitorLGSolution", &opt));
163b3603a34SBarry Smith   if (opt) {
1643923b477SBarry Smith     PetscInt  howoften = 1;
165e669de00SBarry Smith     DM        dm;
166e669de00SBarry Smith     PetscBool net;
167b3603a34SBarry Smith 
1689566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_solution", "Monitor solution graphically", "TSMonitorLGSolution", howoften, &howoften, NULL));
1699566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
1709566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMNETWORK, &net));
171e669de00SBarry Smith     if (net) {
172e669de00SBarry Smith       TSMonitorLGCtxNetwork ctx;
1739566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxNetworkCreate(ts, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 600, 400, howoften, &ctx));
17449abdd8aSBarry Smith       PetscCall(TSMonitorSet(ts, TSMonitorLGCtxNetworkSolution, ctx, (PetscCtxDestroyFn *)TSMonitorLGCtxNetworkDestroy));
1759566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_lg_solution_semilogy", "Plot the solution with a semi-log axis", "", ctx->semilogy, &ctx->semilogy, NULL));
176e669de00SBarry Smith     } else {
177e669de00SBarry Smith       TSMonitorLGCtx ctx;
1789566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
17949abdd8aSBarry Smith       PetscCall(TSMonitorSet(ts, TSMonitorLGSolution, ctx, (PetscCtxDestroyFn *)TSMonitorLGCtxDestroy));
180bdad233fSMatthew Knepley     }
181e669de00SBarry Smith   }
1826ba87a44SLisandro Dalcin 
1839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_error", "Monitor error graphically", "TSMonitorLGError", &opt));
184ef20d060SBarry Smith   if (opt) {
1850b039ecaSBarry Smith     TSMonitorLGCtx ctx;
1863923b477SBarry Smith     PetscInt       howoften = 1;
187ef20d060SBarry Smith 
1889566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_error", "Monitor error graphically", "TSMonitorLGError", howoften, &howoften, NULL));
1899566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
19049abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorLGError, ctx, (PetscCtxDestroyFn *)TSMonitorLGCtxDestroy));
191ef20d060SBarry Smith   }
1929566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_error", "View the error at each timestep", "TSMonitorError", TSMonitorError, NULL));
1937cf37e64SBarry Smith 
1949566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep", "Monitor timestep size graphically", "TSMonitorLGTimeStep", &opt));
1956934998bSLisandro Dalcin   if (opt) {
1966934998bSLisandro Dalcin     TSMonitorLGCtx ctx;
1976934998bSLisandro Dalcin     PetscInt       howoften = 1;
1986934998bSLisandro Dalcin 
1999566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep", "Monitor timestep size graphically", "TSMonitorLGTimeStep", howoften, &howoften, NULL));
2009566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
20149abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorLGTimeStep, ctx, (PetscCtxDestroyFn *)TSMonitorLGCtxDestroy));
2026934998bSLisandro Dalcin   }
2039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep_log", "Monitor log timestep size graphically", "TSMonitorLGTimeStep", &opt));
2048b668821SLisandro Dalcin   if (opt) {
2058b668821SLisandro Dalcin     TSMonitorLGCtx ctx;
2068b668821SLisandro Dalcin     PetscInt       howoften = 1;
2078b668821SLisandro Dalcin 
2089566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep_log", "Monitor log timestep size graphically", "TSMonitorLGTimeStep", howoften, &howoften, NULL));
2099566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
21049abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorLGTimeStep, ctx, (PetscCtxDestroyFn *)TSMonitorLGCtxDestroy));
2118b668821SLisandro Dalcin     ctx->semilogy = PETSC_TRUE;
2128b668821SLisandro Dalcin   }
2138b668821SLisandro Dalcin 
2149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_snes_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGSNESIterations", &opt));
215201da799SBarry Smith   if (opt) {
216201da799SBarry Smith     TSMonitorLGCtx ctx;
217201da799SBarry Smith     PetscInt       howoften = 1;
218201da799SBarry Smith 
2199566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_snes_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGSNESIterations", howoften, &howoften, NULL));
2209566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
22149abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorLGSNESIterations, ctx, (PetscCtxDestroyFn *)TSMonitorLGCtxDestroy));
222201da799SBarry Smith   }
2239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_ksp_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGKSPIterations", &opt));
224201da799SBarry Smith   if (opt) {
225201da799SBarry Smith     TSMonitorLGCtx ctx;
226201da799SBarry Smith     PetscInt       howoften = 1;
227201da799SBarry Smith 
2289566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_ksp_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGKSPIterations", howoften, &howoften, NULL));
2299566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
23049abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorLGKSPIterations, ctx, (PetscCtxDestroyFn *)TSMonitorLGCtxDestroy));
231201da799SBarry Smith   }
2329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_sp_eig", "Monitor eigenvalues of linearized operator graphically", "TSMonitorSPEig", &opt));
2338189c53fSBarry Smith   if (opt) {
2348189c53fSBarry Smith     TSMonitorSPEigCtx ctx;
2358189c53fSBarry Smith     PetscInt          howoften = 1;
2368189c53fSBarry Smith 
2379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_sp_eig", "Monitor eigenvalues of linearized operator graphically", "TSMonitorSPEig", howoften, &howoften, NULL));
2389566063dSJacob Faibussowitsch     PetscCall(TSMonitorSPEigCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
23949abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorSPEig, ctx, (PetscCtxDestroyFn *)TSMonitorSPEigCtxDestroy));
2408189c53fSBarry Smith   }
24160e16b1bSMatthew G. Knepley   PetscCall(PetscOptionsName("-ts_monitor_sp_swarm", "Display particle phase space from the DMSwarm", "TSMonitorSPSwarm", &opt));
2421b575b74SJoseph Pusztay   if (opt) {
2431b575b74SJoseph Pusztay     TSMonitorSPCtx ctx;
244d7462660SMatthew Knepley     PetscInt       howoften = 1, retain = 0;
24560e16b1bSMatthew G. Knepley     PetscBool      phase = PETSC_TRUE, create = PETSC_TRUE, multispecies = PETSC_FALSE;
246d7462660SMatthew Knepley 
2479371c9d4SSatish Balay     for (PetscInt i = 0; i < ts->numbermonitors; ++i)
2489371c9d4SSatish Balay       if (ts->monitor[i] == TSMonitorSPSwarmSolution) {
2499371c9d4SSatish Balay         create = PETSC_FALSE;
2509371c9d4SSatish Balay         break;
2519371c9d4SSatish Balay       }
2526a5217c0SMatthew G. Knepley     if (create) {
25360e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm", "Display particles phase space from the DMSwarm", "TSMonitorSPSwarm", howoften, &howoften, NULL));
2549566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm_retain", "Retain n points plotted to show trajectory, -1 for all points", "TSMonitorSPSwarm", retain, &retain, NULL));
2559566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_sp_swarm_phase", "Plot in phase space rather than coordinate space", "TSMonitorSPSwarm", phase, &phase, NULL));
25660e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsBool("-ts_monitor_sp_swarm_multi_species", "Color particles by particle species", "TSMonitorSPSwarm", multispecies, &multispecies, NULL));
25760e16b1bSMatthew G. Knepley       PetscCall(TSMonitorSPCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, retain, phase, multispecies, &ctx));
25849abdd8aSBarry Smith       PetscCall(TSMonitorSet(ts, TSMonitorSPSwarmSolution, ctx, (PetscCtxDestroyFn *)TSMonitorSPCtxDestroy));
2591b575b74SJoseph Pusztay     }
2606a5217c0SMatthew G. Knepley   }
26160e16b1bSMatthew G. Knepley   PetscCall(PetscOptionsName("-ts_monitor_hg_swarm", "Display particle histogram from the DMSwarm", "TSMonitorHGSwarm", &opt));
26260e16b1bSMatthew G. Knepley   if (opt) {
26360e16b1bSMatthew G. Knepley     TSMonitorHGCtx ctx;
26460e16b1bSMatthew G. Knepley     PetscInt       howoften = 1, Ns = 1;
26560e16b1bSMatthew G. Knepley     PetscBool      velocity = PETSC_FALSE, create = PETSC_TRUE;
26660e16b1bSMatthew G. Knepley 
26760e16b1bSMatthew G. Knepley     for (PetscInt i = 0; i < ts->numbermonitors; ++i)
26860e16b1bSMatthew G. Knepley       if (ts->monitor[i] == TSMonitorHGSwarmSolution) {
26960e16b1bSMatthew G. Knepley         create = PETSC_FALSE;
27060e16b1bSMatthew G. Knepley         break;
27160e16b1bSMatthew G. Knepley       }
27260e16b1bSMatthew G. Knepley     if (create) {
27360e16b1bSMatthew G. Knepley       DM       sw, dm;
27460e16b1bSMatthew G. Knepley       PetscInt Nc, Nb;
27560e16b1bSMatthew G. Knepley 
27660e16b1bSMatthew G. Knepley       PetscCall(TSGetDM(ts, &sw));
27760e16b1bSMatthew G. Knepley       PetscCall(DMSwarmGetCellDM(sw, &dm));
27860e16b1bSMatthew G. Knepley       PetscCall(DMPlexGetHeightStratum(dm, 0, NULL, &Nc));
27960e16b1bSMatthew G. Knepley       Nb = PetscMin(20, PetscMax(10, Nc));
28060e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_hg_swarm", "Display particles histogram from the DMSwarm", "TSMonitorHGSwarm", howoften, &howoften, NULL));
28160e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsBool("-ts_monitor_hg_swarm_velocity", "Plot in velocity space rather than coordinate space", "TSMonitorHGSwarm", velocity, &velocity, NULL));
28260e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_hg_swarm_species", "Number of species to histogram", "TSMonitorHGSwarm", Ns, &Ns, NULL));
28360e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_hg_swarm_bins", "Number of histogram bins", "TSMonitorHGSwarm", Nb, &Nb, NULL));
28460e16b1bSMatthew G. Knepley       PetscCall(TSMonitorHGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, Ns, Nb, velocity, &ctx));
28549abdd8aSBarry Smith       PetscCall(TSMonitorSet(ts, TSMonitorHGSwarmSolution, ctx, (PetscCtxDestroyFn *)TSMonitorHGCtxDestroy));
28660e16b1bSMatthew G. Knepley     }
28760e16b1bSMatthew G. Knepley   }
288ef20d060SBarry Smith   opt = PETSC_FALSE;
2899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution", "Monitor solution graphically", "TSMonitorDrawSolution", &opt));
290a7cc72afSBarry Smith   if (opt) {
29183a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
29283a4ac43SBarry Smith     PetscInt         howoften = 1;
293a80ad3e0SBarry Smith 
2949566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution", "Monitor solution graphically", "TSMonitorDrawSolution", howoften, &howoften, NULL));
2959566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Computed Solution", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
29649abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolution, ctx, (PetscCtxDestroyFn *)TSMonitorDrawCtxDestroy));
297bdad233fSMatthew Knepley   }
298fb1732b5SBarry Smith   opt = PETSC_FALSE;
2999566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_phase", "Monitor solution graphically", "TSMonitorDrawSolutionPhase", &opt));
3002d5ee99bSBarry Smith   if (opt) {
3012d5ee99bSBarry Smith     TSMonitorDrawCtx ctx;
3022d5ee99bSBarry Smith     PetscReal        bounds[4];
3032d5ee99bSBarry Smith     PetscInt         n = 4;
3042d5ee99bSBarry Smith     PetscDraw        draw;
3056934998bSLisandro Dalcin     PetscDrawAxis    axis;
3062d5ee99bSBarry Smith 
3079566063dSJacob Faibussowitsch     PetscCall(PetscOptionsRealArray("-ts_monitor_draw_solution_phase", "Monitor solution graphically", "TSMonitorDrawSolutionPhase", bounds, &n, NULL));
3083c633725SBarry Smith     PetscCheck(n == 4, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Must provide bounding box of phase field");
3099566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, 1, &ctx));
3109566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ctx->viewer, 0, &draw));
3119566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDrawAxis(ctx->viewer, 0, &axis));
3129566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLimits(axis, bounds[0], bounds[2], bounds[1], bounds[3]));
3139566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Phase Diagram", "Variable 1", "Variable 2"));
31449abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolutionPhase, ctx, (PetscCtxDestroyFn *)TSMonitorDrawCtxDestroy));
3152d5ee99bSBarry Smith   }
3162d5ee99bSBarry Smith   opt = PETSC_FALSE;
3179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_error", "Monitor error graphically", "TSMonitorDrawError", &opt));
3183a471f94SBarry Smith   if (opt) {
31983a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
32083a4ac43SBarry Smith     PetscInt         howoften = 1;
3213a471f94SBarry Smith 
3229566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_error", "Monitor error graphically", "TSMonitorDrawError", howoften, &howoften, NULL));
3239566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Error", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
32449abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorDrawError, ctx, (PetscCtxDestroyFn *)TSMonitorDrawCtxDestroy));
3253a471f94SBarry Smith   }
3260ed3bfb6SBarry Smith   opt = PETSC_FALSE;
3279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_function", "Monitor solution provided by TSMonitorSetSolutionFunction() graphically", "TSMonitorDrawSolutionFunction", &opt));
3280ed3bfb6SBarry Smith   if (opt) {
3290ed3bfb6SBarry Smith     TSMonitorDrawCtx ctx;
3300ed3bfb6SBarry Smith     PetscInt         howoften = 1;
3310ed3bfb6SBarry Smith 
3329566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution_function", "Monitor solution provided by TSMonitorSetSolutionFunction() graphically", "TSMonitorDrawSolutionFunction", howoften, &howoften, NULL));
3339566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Solution provided by user function", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
33449abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolutionFunction, ctx, (PetscCtxDestroyFn *)TSMonitorDrawCtxDestroy));
3350ed3bfb6SBarry Smith   }
336fde5950dSBarry Smith 
337ed81e22dSJed Brown   opt = PETSC_FALSE;
33863a3b9bcSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_solution_vtk", "Save each time step to a binary file, use filename-%%03" PetscInt_FMT ".vts", "TSMonitorSolutionVTK", NULL, monfilename, sizeof(monfilename), &flg));
339ed81e22dSJed Brown   if (flg) {
3407f27e910SStefano Zampini     TSMonitorVTKCtx ctx;
3417f27e910SStefano Zampini 
3427f27e910SStefano Zampini     PetscCall(TSMonitorSolutionVTKCtxCreate(monfilename, &ctx));
343c17ba870SStefano Zampini     PetscCall(PetscOptionsInt("-ts_monitor_solution_vtk_interval", "Save every interval time step (-1 for last step only)", NULL, ctx->interval, &ctx->interval, NULL));
34449abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, (PetscErrorCode (*)(TS, PetscInt, PetscReal, Vec, void *))TSMonitorSolutionVTK, ctx, (PetscCtxDestroyFn *)TSMonitorSolutionVTKDestroy));
345ed81e22dSJed Brown   }
346bdad233fSMatthew Knepley 
3479566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_dmda_ray", "Display a ray of the solution", "None", "y=0", dir, sizeof(dir), &flg));
348d1212d36SBarry Smith   if (flg) {
349d1212d36SBarry Smith     TSMonitorDMDARayCtx *rayctx;
350d1212d36SBarry Smith     int                  ray = 0;
3513ee9839eSMatthew G. Knepley     DMDirection          ddir;
352d1212d36SBarry Smith     DM                   da;
353d1212d36SBarry Smith     PetscMPIInt          rank;
354d1212d36SBarry Smith 
3553c633725SBarry Smith     PetscCheck(dir[1] == '=', PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray %s", dir);
3563ee9839eSMatthew G. Knepley     if (dir[0] == 'x') ddir = DM_X;
3573ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
35898921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray %s", dir);
359d1212d36SBarry Smith     sscanf(dir + 2, "%d", &ray);
360d1212d36SBarry Smith 
361835f2295SStefano Zampini     PetscCall(PetscInfo(ts, "Displaying DMDA ray %c = %d\n", dir[0], ray));
3629566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3639566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &da));
3649566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter));
3659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)ts), &rank));
3661e66621cSBarry Smith     if (rank == 0) PetscCall(PetscViewerDrawOpen(PETSC_COMM_SELF, NULL, NULL, 0, 0, 600, 300, &rayctx->viewer));
36751b4a12fSMatthew G. Knepley     rayctx->lgctx = NULL;
3689566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDMDARay, rayctx, TSMonitorDMDARayDestroy));
369d1212d36SBarry Smith   }
3709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_lg_dmda_ray", "Display a ray of the solution", "None", "x=0", dir, sizeof(dir), &flg));
37151b4a12fSMatthew G. Knepley   if (flg) {
37251b4a12fSMatthew G. Knepley     TSMonitorDMDARayCtx *rayctx;
37351b4a12fSMatthew G. Knepley     int                  ray = 0;
3743ee9839eSMatthew G. Knepley     DMDirection          ddir;
37551b4a12fSMatthew G. Knepley     DM                   da;
37651b4a12fSMatthew G. Knepley     PetscInt             howoften = 1;
377d1212d36SBarry Smith 
3783c633725SBarry Smith     PetscCheck(dir[1] == '=', PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir);
3793ee9839eSMatthew G. Knepley     if (dir[0] == 'x') ddir = DM_X;
3803ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
38198921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir);
38251b4a12fSMatthew G. Knepley     sscanf(dir + 2, "%d", &ray);
3831c3436cfSJed Brown 
384835f2295SStefano Zampini     PetscCall(PetscInfo(ts, "Displaying LG DMDA ray %c = %d\n", dir[0], ray));
3859566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3869566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &da));
3879566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter));
3889566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 600, 400, howoften, &rayctx->lgctx));
3899566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy));
39051b4a12fSMatthew G. Knepley   }
391a7a1495cSBarry Smith 
3929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_envelope", "Monitor maximum and minimum value of each component of the solution", "TSMonitorEnvelope", &opt));
393b3d3934dSBarry Smith   if (opt) {
394b3d3934dSBarry Smith     TSMonitorEnvelopeCtx ctx;
395b3d3934dSBarry Smith 
3969566063dSJacob Faibussowitsch     PetscCall(TSMonitorEnvelopeCtxCreate(ts, &ctx));
39749abdd8aSBarry Smith     PetscCall(TSMonitorSet(ts, TSMonitorEnvelope, ctx, (PetscCtxDestroyFn *)TSMonitorEnvelopeCtxDestroy));
398b3d3934dSBarry Smith   }
399aee7a9fbSMatthew G. Knepley   flg = PETSC_FALSE;
4009566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_monitor_cancel", "Remove all monitors", "TSMonitorCancel", flg, &flg, &opt));
4019566063dSJacob Faibussowitsch   if (opt && flg) PetscCall(TSMonitorCancel(ts));
402b3d3934dSBarry Smith 
403847ff0e1SMatthew G. Knepley   flg = PETSC_FALSE;
404d7cfae9bSHong Zhang   PetscCall(PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeIJacobianDefaultColor", flg, &flg, NULL));
405847ff0e1SMatthew G. Knepley   if (flg) {
406847ff0e1SMatthew G. Knepley     DM dm;
407847ff0e1SMatthew G. Knepley 
4089371c9d4SSatish Balay     PetscCall(TSGetDM(ts, &dm));
4099371c9d4SSatish Balay     PetscCall(DMTSUnsetIJacobianContext_Internal(dm));
4109566063dSJacob Faibussowitsch     PetscCall(TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, NULL));
4119566063dSJacob Faibussowitsch     PetscCall(PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n"));
412847ff0e1SMatthew G. Knepley   }
413847ff0e1SMatthew G. Knepley 
414d763cef2SBarry Smith   /* Handle specific TS options */
415dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, setfromoptions, PetscOptionsObject);
416fbc52257SHong Zhang 
417a7bdc993SLisandro Dalcin   /* Handle TSAdapt options */
4189566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
4199566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
420dbbe0bcdSBarry Smith   PetscCall(TSAdaptSetFromOptions(ts->adapt, PetscOptionsObject));
421a7bdc993SLisandro Dalcin 
42268bece0bSHong Zhang   /* TS trajectory must be set after TS, since it may use some TS options above */
4234f122a70SLisandro Dalcin   tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE;
4249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_save_trajectory", "Save the solution at each timestep", "TSSetSaveTrajectory", tflg, &tflg, NULL));
4251baa6e33SBarry Smith   if (tflg) PetscCall(TSSetSaveTrajectory(ts));
426a05bf03eSHong Zhang 
427dbbe0bcdSBarry Smith   PetscCall(TSAdjointSetFromOptions(ts, PetscOptionsObject));
428d763cef2SBarry Smith 
429d763cef2SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
430dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)ts, PetscOptionsObject));
431d0609cedSBarry Smith   PetscOptionsEnd();
432d763cef2SBarry Smith 
4331baa6e33SBarry Smith   if (ts->trajectory) PetscCall(TSTrajectorySetFromOptions(ts->trajectory, ts));
43468bece0bSHong Zhang 
4351ef27442SStefano Zampini   /* why do we have to do this here and not during TSSetUp? */
4369566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &ts->snes));
4371ef27442SStefano Zampini   if (ts->problem_type == TS_LINEAR) {
4389566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes, &flg, SNESKSPONLY, SNESKSPTRANSPOSEONLY, ""));
4399566063dSJacob Faibussowitsch     if (!flg) PetscCall(SNESSetType(ts->snes, SNESKSPONLY));
4401ef27442SStefano Zampini   }
4419566063dSJacob Faibussowitsch   PetscCall(SNESSetFromOptions(ts->snes));
4423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
443d763cef2SBarry Smith }
444d763cef2SBarry Smith 
445d2daff3dSHong Zhang /*@
446bcf0153eSBarry Smith   TSGetTrajectory - Gets the trajectory from a `TS` if it exists
44778fbdcc8SBarry Smith 
448c3339decSBarry Smith   Collective
44978fbdcc8SBarry Smith 
4502fe279fdSBarry Smith   Input Parameter:
451bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
45278fbdcc8SBarry Smith 
4532fe279fdSBarry Smith   Output Parameter:
454bcf0153eSBarry Smith . tr - the `TSTrajectory` object, if it exists
45578fbdcc8SBarry Smith 
45678fbdcc8SBarry Smith   Level: advanced
45778fbdcc8SBarry Smith 
458bcf0153eSBarry Smith   Note:
459bcf0153eSBarry Smith   This routine should be called after all `TS` options have been set
46078fbdcc8SBarry Smith 
461b43aa488SJacob Faibussowitsch .seealso: [](ch_ts), `TS`, `TSTrajectory`, `TSAdjointSolve()`, `TSTrajectoryCreate()`
46278fbdcc8SBarry Smith @*/
463d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTrajectory(TS ts, TSTrajectory *tr)
464d71ae5a4SJacob Faibussowitsch {
46578fbdcc8SBarry Smith   PetscFunctionBegin;
46678fbdcc8SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
46778fbdcc8SBarry Smith   *tr = ts->trajectory;
4683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46978fbdcc8SBarry Smith }
47078fbdcc8SBarry Smith 
47178fbdcc8SBarry Smith /*@
472bcf0153eSBarry Smith   TSSetSaveTrajectory - Causes the `TS` to save its solutions as it iterates forward in time in a `TSTrajectory` object
473d2daff3dSHong Zhang 
474c3339decSBarry Smith   Collective
475d2daff3dSHong Zhang 
476f899ff85SJose E. Roman   Input Parameter:
477bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
478bc952696SBarry Smith 
479bcf0153eSBarry Smith   Options Database Keys:
48078fbdcc8SBarry Smith + -ts_save_trajectory      - saves the trajectory to a file
48167b8a455SSatish Balay - -ts_trajectory_type type - set trajectory type
48278fbdcc8SBarry Smith 
483d2daff3dSHong Zhang   Level: intermediate
484d2daff3dSHong Zhang 
485bcf0153eSBarry Smith   Notes:
486bcf0153eSBarry Smith   This routine should be called after all `TS` options have been set
487d2daff3dSHong Zhang 
488bcf0153eSBarry Smith   The `TSTRAJECTORYVISUALIZATION` files can be loaded into Python with $PETSC_DIR/lib/petsc/bin/PetscBinaryIOTrajectory.py and
489bcf0153eSBarry Smith   MATLAB with $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m
490bcf0153eSBarry Smith 
4911cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSTrajectory`, `TSGetTrajectory()`, `TSAdjointSolve()`
492d2daff3dSHong Zhang @*/
493d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetSaveTrajectory(TS ts)
494d71ae5a4SJacob Faibussowitsch {
495d2daff3dSHong Zhang   PetscFunctionBegin;
496d2daff3dSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
49763a3b9bcSJacob Faibussowitsch   if (!ts->trajectory) PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts), &ts->trajectory));
4983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
499d2daff3dSHong Zhang }
500d2daff3dSHong Zhang 
501a7a1495cSBarry Smith /*@
502bcf0153eSBarry Smith   TSResetTrajectory - Destroys and recreates the internal `TSTrajectory` object
5032d29f1f2SStefano Zampini 
504c3339decSBarry Smith   Collective
5052d29f1f2SStefano Zampini 
5062fe279fdSBarry Smith   Input Parameter:
507bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
5082d29f1f2SStefano Zampini 
5092d29f1f2SStefano Zampini   Level: intermediate
5102d29f1f2SStefano Zampini 
5111cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectory`, `TSGetTrajectory()`, `TSAdjointSolve()`, `TSRemoveTrajectory()`
5122d29f1f2SStefano Zampini @*/
513d71ae5a4SJacob Faibussowitsch PetscErrorCode TSResetTrajectory(TS ts)
514d71ae5a4SJacob Faibussowitsch {
5152d29f1f2SStefano Zampini   PetscFunctionBegin;
5162d29f1f2SStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5172d29f1f2SStefano Zampini   if (ts->trajectory) {
5189566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryDestroy(&ts->trajectory));
5199566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts), &ts->trajectory));
5202d29f1f2SStefano Zampini   }
5213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5222d29f1f2SStefano Zampini }
5232d29f1f2SStefano Zampini 
5242d29f1f2SStefano Zampini /*@
525195e9b02SBarry Smith   TSRemoveTrajectory - Destroys and removes the internal `TSTrajectory` object from a `TS`
52667a3cfb0SHong Zhang 
527c3339decSBarry Smith   Collective
52867a3cfb0SHong Zhang 
5292fe279fdSBarry Smith   Input Parameter:
530bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
53167a3cfb0SHong Zhang 
53267a3cfb0SHong Zhang   Level: intermediate
53367a3cfb0SHong Zhang 
5341cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectory`, `TSResetTrajectory()`, `TSAdjointSolve()`
53567a3cfb0SHong Zhang @*/
536d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRemoveTrajectory(TS ts)
537d71ae5a4SJacob Faibussowitsch {
53867a3cfb0SHong Zhang   PetscFunctionBegin;
53967a3cfb0SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5401e66621cSBarry Smith   if (ts->trajectory) PetscCall(TSTrajectoryDestroy(&ts->trajectory));
5413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
54267a3cfb0SHong Zhang }
54367a3cfb0SHong Zhang 
54467a3cfb0SHong Zhang /*@
545a7a1495cSBarry Smith   TSComputeRHSJacobian - Computes the Jacobian matrix that has been
546bcf0153eSBarry Smith   set with `TSSetRHSJacobian()`.
547a7a1495cSBarry Smith 
548c3339decSBarry Smith   Collective
549a7a1495cSBarry Smith 
550a7a1495cSBarry Smith   Input Parameters:
551bcf0153eSBarry Smith + ts - the `TS` context
552a7a1495cSBarry Smith . t  - current timestep
5530910c330SBarry Smith - U  - input vector
554a7a1495cSBarry Smith 
555a7a1495cSBarry Smith   Output Parameters:
556a7a1495cSBarry Smith + A - Jacobian matrix
5577addb90fSBarry Smith - B - optional matrix used to compute the preconditioner, often the same as `A`
558a7a1495cSBarry Smith 
559bcf0153eSBarry Smith   Level: developer
560bcf0153eSBarry Smith 
561bcf0153eSBarry Smith   Note:
562a7a1495cSBarry Smith   Most users should not need to explicitly call this routine, as it
5637addb90fSBarry Smith   is used internally within the ODE integrators.
564a7a1495cSBarry Smith 
5651cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSJacobian()`, `KSPSetOperators()`
566a7a1495cSBarry Smith @*/
567d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSJacobian(TS ts, PetscReal t, Vec U, Mat A, Mat B)
568d71ae5a4SJacob Faibussowitsch {
569270bf2e7SJed Brown   PetscObjectState Ustate;
5706c1e1eecSBarry Smith   PetscObjectId    Uid;
57124989b8cSPeter Brune   DM               dm;
572942e3340SBarry Smith   DMTS             tsdm;
5738434afd1SBarry Smith   TSRHSJacobianFn *rhsjacobianfunc;
57424989b8cSPeter Brune   void            *ctx;
5758434afd1SBarry Smith   TSRHSFunctionFn *rhsfunction;
576a7a1495cSBarry Smith 
577a7a1495cSBarry Smith   PetscFunctionBegin;
5780700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5790910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
5800910c330SBarry Smith   PetscCheckSameComm(ts, 1, U, 3);
5819566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
5829566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
5839566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
5849566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobianfunc, &ctx));
5859566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U, &Ustate));
5869566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U, &Uid));
587971015bcSStefano Zampini 
5883ba16761SJacob Faibussowitsch   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) PetscFunctionReturn(PETSC_SUCCESS);
589d90be118SSean Farley 
59063a3b9bcSJacob Faibussowitsch   PetscCheck(ts->rhsjacobian.shift == 0.0 || !ts->rhsjacobian.reuse, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Should not call TSComputeRHSJacobian() on a shifted matrix (shift=%lf) when RHSJacobian is reusable.", (double)ts->rhsjacobian.shift);
59124989b8cSPeter Brune   if (rhsjacobianfunc) {
592da023ba9SStefano Zampini     PetscCall(PetscLogEventBegin(TS_JacobianEval, U, ts, A, B));
593792fecdfSBarry Smith     PetscCallBack("TS callback Jacobian", (*rhsjacobianfunc)(ts, t, U, A, B, ctx));
594a6ab3590SBarry Smith     ts->rhsjacs++;
595da023ba9SStefano Zampini     PetscCall(PetscLogEventEnd(TS_JacobianEval, U, ts, A, B));
596ef66eb69SBarry Smith   } else {
5979566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(A));
5989566063dSJacob Faibussowitsch     if (B && A != B) PetscCall(MatZeroEntries(B));
599ef66eb69SBarry Smith   }
6000e4ef248SJed Brown   ts->rhsjacobian.time  = t;
601971015bcSStefano Zampini   ts->rhsjacobian.shift = 0;
602971015bcSStefano Zampini   ts->rhsjacobian.scale = 1.;
6039566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U, &ts->rhsjacobian.Xid));
6049566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U, &ts->rhsjacobian.Xstate));
6053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
606a7a1495cSBarry Smith }
607a7a1495cSBarry Smith 
608316643e7SJed Brown /*@
609bcf0153eSBarry Smith   TSComputeRHSFunction - Evaluates the right-hand-side function for a `TS`
610d763cef2SBarry Smith 
611c3339decSBarry Smith   Collective
612316643e7SJed Brown 
613316643e7SJed Brown   Input Parameters:
614bcf0153eSBarry Smith + ts - the `TS` context
615316643e7SJed Brown . t  - current time
6160910c330SBarry Smith - U  - state vector
617316643e7SJed Brown 
618316643e7SJed Brown   Output Parameter:
619dd8e379bSPierre Jolivet . y - right-hand side
620316643e7SJed Brown 
621bcf0153eSBarry Smith   Level: developer
622bcf0153eSBarry Smith 
623316643e7SJed Brown   Note:
624316643e7SJed Brown   Most users should not need to explicitly call this routine, as it
625316643e7SJed Brown   is used internally within the nonlinear solvers.
626316643e7SJed Brown 
6271cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSFunction()`, `TSComputeIFunction()`
628316643e7SJed Brown @*/
629d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSFunction(TS ts, PetscReal t, Vec U, Vec y)
630d71ae5a4SJacob Faibussowitsch {
6318434afd1SBarry Smith   TSRHSFunctionFn *rhsfunction;
6328434afd1SBarry Smith   TSIFunctionFn   *ifunction;
63324989b8cSPeter Brune   void            *ctx;
63424989b8cSPeter Brune   DM               dm;
63524989b8cSPeter Brune 
636d763cef2SBarry Smith   PetscFunctionBegin;
6370700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
6380910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
6390700a824SBarry Smith   PetscValidHeaderSpecific(y, VEC_CLASSID, 4);
6409566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
6419566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, &ctx));
6429566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, &ifunction, NULL));
643d763cef2SBarry Smith 
6443c633725SBarry Smith   PetscCheck(rhsfunction || ifunction, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSFunction() and / or TSSetIFunction()");
645d763cef2SBarry Smith 
64624989b8cSPeter Brune   if (rhsfunction) {
647da023ba9SStefano Zampini     PetscCall(PetscLogEventBegin(TS_FunctionEval, U, ts, y, 0));
6489566063dSJacob Faibussowitsch     PetscCall(VecLockReadPush(U));
649792fecdfSBarry Smith     PetscCallBack("TS callback right-hand-side", (*rhsfunction)(ts, t, U, y, ctx));
6509566063dSJacob Faibussowitsch     PetscCall(VecLockReadPop(U));
651a6ab3590SBarry Smith     ts->rhsfuncs++;
652da023ba9SStefano Zampini     PetscCall(PetscLogEventEnd(TS_FunctionEval, U, ts, y, 0));
6531e66621cSBarry Smith   } else PetscCall(VecZeroEntries(y));
6543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
655d763cef2SBarry Smith }
656d763cef2SBarry Smith 
657ef20d060SBarry Smith /*@
658ef20d060SBarry Smith   TSComputeSolutionFunction - Evaluates the solution function.
659ef20d060SBarry Smith 
660c3339decSBarry Smith   Collective
661ef20d060SBarry Smith 
662ef20d060SBarry Smith   Input Parameters:
663bcf0153eSBarry Smith + ts - the `TS` context
664ef20d060SBarry Smith - t  - current time
665ef20d060SBarry Smith 
666ef20d060SBarry Smith   Output Parameter:
6670910c330SBarry Smith . U - the solution
668ef20d060SBarry Smith 
669ef20d060SBarry Smith   Level: developer
670ef20d060SBarry Smith 
6711cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
672ef20d060SBarry Smith @*/
673d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeSolutionFunction(TS ts, PetscReal t, Vec U)
674d71ae5a4SJacob Faibussowitsch {
6758434afd1SBarry Smith   TSSolutionFn *solutionfunction;
676ef20d060SBarry Smith   void         *ctx;
677ef20d060SBarry Smith   DM            dm;
678ef20d060SBarry Smith 
679ef20d060SBarry Smith   PetscFunctionBegin;
680ef20d060SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
6810910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
6829566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
6839566063dSJacob Faibussowitsch   PetscCall(DMTSGetSolutionFunction(dm, &solutionfunction, &ctx));
684792fecdfSBarry Smith   if (solutionfunction) PetscCallBack("TS callback solution", (*solutionfunction)(ts, t, U, ctx));
6853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
686ef20d060SBarry Smith }
6879b7cd975SBarry Smith /*@
6889b7cd975SBarry Smith   TSComputeForcingFunction - Evaluates the forcing function.
6899b7cd975SBarry Smith 
690c3339decSBarry Smith   Collective
6919b7cd975SBarry Smith 
6929b7cd975SBarry Smith   Input Parameters:
693bcf0153eSBarry Smith + ts - the `TS` context
6949b7cd975SBarry Smith - t  - current time
6959b7cd975SBarry Smith 
6969b7cd975SBarry Smith   Output Parameter:
6979b7cd975SBarry Smith . U - the function value
6989b7cd975SBarry Smith 
6999b7cd975SBarry Smith   Level: developer
7009b7cd975SBarry Smith 
7011cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
7029b7cd975SBarry Smith @*/
703d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeForcingFunction(TS ts, PetscReal t, Vec U)
704d71ae5a4SJacob Faibussowitsch {
7059b7cd975SBarry Smith   void        *ctx;
7069b7cd975SBarry Smith   DM           dm;
7078434afd1SBarry Smith   TSForcingFn *forcing;
7089b7cd975SBarry Smith 
7099b7cd975SBarry Smith   PetscFunctionBegin;
7109b7cd975SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
7119b7cd975SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
7129566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
7139566063dSJacob Faibussowitsch   PetscCall(DMTSGetForcingFunction(dm, &forcing, &ctx));
7149b7cd975SBarry Smith 
715792fecdfSBarry Smith   if (forcing) PetscCallBack("TS callback forcing function", (*forcing)(ts, t, U, ctx));
7163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7179b7cd975SBarry Smith }
718ef20d060SBarry Smith 
719d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetRHSMats_Private(TS ts, Mat *Arhs, Mat *Brhs)
720d71ae5a4SJacob Faibussowitsch {
721214bc6a2SJed Brown   Mat            A, B;
7228434afd1SBarry Smith   TSIJacobianFn *ijacobian;
723214bc6a2SJed Brown 
724214bc6a2SJed Brown   PetscFunctionBegin;
725c0cd0301SJed Brown   if (Arhs) *Arhs = NULL;
726c0cd0301SJed Brown   if (Brhs) *Brhs = NULL;
7279566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts, &A, &B, &ijacobian, NULL));
728214bc6a2SJed Brown   if (Arhs) {
729214bc6a2SJed Brown     if (!ts->Arhs) {
73041a1d4d2SBarry Smith       if (ijacobian) {
7319566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &ts->Arhs));
7329566063dSJacob Faibussowitsch         PetscCall(TSSetMatStructure(ts, SAME_NONZERO_PATTERN));
73341a1d4d2SBarry Smith       } else {
73441a1d4d2SBarry Smith         ts->Arhs = A;
7359566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
73641a1d4d2SBarry Smith       }
7373565c898SBarry Smith     } else {
7383565c898SBarry Smith       PetscBool flg;
7399566063dSJacob Faibussowitsch       PetscCall(SNESGetUseMatrixFree(ts->snes, NULL, &flg));
7403565c898SBarry Smith       /* Handle case where user provided only RHSJacobian and used -snes_mf_operator */
7413565c898SBarry Smith       if (flg && !ijacobian && ts->Arhs == ts->Brhs) {
7429566063dSJacob Faibussowitsch         PetscCall(PetscObjectDereference((PetscObject)ts->Arhs));
7433565c898SBarry Smith         ts->Arhs = A;
7449566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
7453565c898SBarry Smith       }
746214bc6a2SJed Brown     }
747214bc6a2SJed Brown     *Arhs = ts->Arhs;
748214bc6a2SJed Brown   }
749214bc6a2SJed Brown   if (Brhs) {
750214bc6a2SJed Brown     if (!ts->Brhs) {
751bdb70873SJed Brown       if (A != B) {
75241a1d4d2SBarry Smith         if (ijacobian) {
7539566063dSJacob Faibussowitsch           PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &ts->Brhs));
754bdb70873SJed Brown         } else {
75541a1d4d2SBarry Smith           ts->Brhs = B;
7569566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)B));
75741a1d4d2SBarry Smith         }
75841a1d4d2SBarry Smith       } else {
7599566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)ts->Arhs));
76051699248SLisandro Dalcin         ts->Brhs = ts->Arhs;
761bdb70873SJed Brown       }
762214bc6a2SJed Brown     }
763214bc6a2SJed Brown     *Brhs = ts->Brhs;
764214bc6a2SJed Brown   }
7653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
766214bc6a2SJed Brown }
767214bc6a2SJed Brown 
768316643e7SJed Brown /*@
769195e9b02SBarry Smith   TSComputeIFunction - Evaluates the DAE residual written in the implicit form F(t,U,Udot)=0
770316643e7SJed Brown 
771c3339decSBarry Smith   Collective
772316643e7SJed Brown 
773316643e7SJed Brown   Input Parameters:
774bcf0153eSBarry Smith + ts   - the `TS` context
775316643e7SJed Brown . t    - current time
7760910c330SBarry Smith . U    - state vector
7770910c330SBarry Smith . Udot - time derivative of state vector
7783dddbd81SStefano Zampini - imex - flag indicates if the method is `TSARKIMEX` so that the RHSFunction should be kept separate
779316643e7SJed Brown 
780316643e7SJed Brown   Output Parameter:
781dd8e379bSPierre Jolivet . Y - right-hand side
782316643e7SJed Brown 
783bcf0153eSBarry Smith   Level: developer
784bcf0153eSBarry Smith 
785316643e7SJed Brown   Note:
786316643e7SJed Brown   Most users should not need to explicitly call this routine, as it
787316643e7SJed Brown   is used internally within the nonlinear solvers.
788316643e7SJed Brown 
78915229ffcSPierre Jolivet   If the user did not write their equations in implicit form, this
790316643e7SJed Brown   function recasts them in implicit form.
791316643e7SJed Brown 
7921cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetIFunction()`, `TSComputeRHSFunction()`
793316643e7SJed Brown @*/
794d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIFunction(TS ts, PetscReal t, Vec U, Vec Udot, Vec Y, PetscBool imex)
795d71ae5a4SJacob Faibussowitsch {
7968434afd1SBarry Smith   TSIFunctionFn   *ifunction;
7978434afd1SBarry Smith   TSRHSFunctionFn *rhsfunction;
79824989b8cSPeter Brune   void            *ctx;
79924989b8cSPeter Brune   DM               dm;
800316643e7SJed Brown 
801316643e7SJed Brown   PetscFunctionBegin;
8020700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
8030910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
8040910c330SBarry Smith   PetscValidHeaderSpecific(Udot, VEC_CLASSID, 4);
8050700a824SBarry Smith   PetscValidHeaderSpecific(Y, VEC_CLASSID, 5);
806316643e7SJed Brown 
8079566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
8089566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, &ifunction, &ctx));
8099566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
81024989b8cSPeter Brune 
8113c633725SBarry Smith   PetscCheck(rhsfunction || ifunction, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSFunction() and / or TSSetIFunction()");
812d90be118SSean Farley 
813da023ba9SStefano Zampini   PetscCall(PetscLogEventBegin(TS_FunctionEval, U, ts, Udot, Y));
81424989b8cSPeter Brune   if (ifunction) {
815792fecdfSBarry Smith     PetscCallBack("TS callback implicit function", (*ifunction)(ts, t, U, Udot, Y, ctx));
816a6ab3590SBarry Smith     ts->ifuncs++;
817214bc6a2SJed Brown   }
818214bc6a2SJed Brown   if (imex) {
8191e66621cSBarry Smith     if (!ifunction) PetscCall(VecCopy(Udot, Y));
82024989b8cSPeter Brune   } else if (rhsfunction) {
82124989b8cSPeter Brune     if (ifunction) {
822214bc6a2SJed Brown       Vec Frhs;
8238af0501fSStefano Zampini 
8248af0501fSStefano Zampini       PetscCall(DMGetGlobalVector(dm, &Frhs));
8259566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts, t, U, Frhs));
8269566063dSJacob Faibussowitsch       PetscCall(VecAXPY(Y, -1, Frhs));
8278af0501fSStefano Zampini       PetscCall(DMRestoreGlobalVector(dm, &Frhs));
8282dd45cf8SJed Brown     } else {
8299566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts, t, U, Y));
8309566063dSJacob Faibussowitsch       PetscCall(VecAYPX(Y, -1, Udot));
831316643e7SJed Brown     }
8324a6899ffSJed Brown   }
833da023ba9SStefano Zampini   PetscCall(PetscLogEventEnd(TS_FunctionEval, U, ts, Udot, Y));
8343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
835316643e7SJed Brown }
836316643e7SJed Brown 
837cfa8a9a2SHong Zhang /*
838195e9b02SBarry Smith    TSRecoverRHSJacobian - Recover the Jacobian matrix so that one can call `TSComputeRHSJacobian()` on it.
839cfa8a9a2SHong Zhang 
840cfa8a9a2SHong Zhang    Note:
841195e9b02SBarry Smith    This routine is needed when one switches from `TSComputeIJacobian()` to `TSComputeRHSJacobian()` because the Jacobian matrix may be shifted or scaled in `TSComputeIJacobian()`.
842cfa8a9a2SHong Zhang 
843cfa8a9a2SHong Zhang */
844d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRecoverRHSJacobian(TS ts, Mat A, Mat B)
845d71ae5a4SJacob Faibussowitsch {
846cfa8a9a2SHong Zhang   PetscFunctionBegin;
847cfa8a9a2SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
8483c633725SBarry Smith   PetscCheck(A == ts->Arhs, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Invalid Amat");
8493c633725SBarry Smith   PetscCheck(B == ts->Brhs, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Invalid Bmat");
850cfa8a9a2SHong Zhang 
8511baa6e33SBarry Smith   if (ts->rhsjacobian.shift) PetscCall(MatShift(A, -ts->rhsjacobian.shift));
85248a46eb9SPierre Jolivet   if (ts->rhsjacobian.scale == -1.) PetscCall(MatScale(A, -1));
853cfa8a9a2SHong Zhang   if (B && B == ts->Brhs && A != B) {
8541baa6e33SBarry Smith     if (ts->rhsjacobian.shift) PetscCall(MatShift(B, -ts->rhsjacobian.shift));
8551e66621cSBarry Smith     if (ts->rhsjacobian.scale == -1.) PetscCall(MatScale(B, -1));
856cfa8a9a2SHong Zhang   }
857cfa8a9a2SHong Zhang   ts->rhsjacobian.shift = 0;
858cfa8a9a2SHong Zhang   ts->rhsjacobian.scale = 1.;
8593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
860cfa8a9a2SHong Zhang }
861cfa8a9a2SHong Zhang 
862316643e7SJed Brown /*@
863316643e7SJed Brown   TSComputeIJacobian - Evaluates the Jacobian of the DAE
864316643e7SJed Brown 
865c3339decSBarry Smith   Collective
866316643e7SJed Brown 
867316643e7SJed Brown   Input Parameters:
868bcf0153eSBarry Smith + ts    - the `TS` context
869316643e7SJed Brown . t     - current timestep
8700910c330SBarry Smith . U     - state vector
8710910c330SBarry Smith . Udot  - time derivative of state vector
872214bc6a2SJed Brown . shift - shift to apply, see note below
8733dddbd81SStefano Zampini - imex  - flag indicates if the method is `TSARKIMEX` so that the RHSJacobian should be kept separate
874316643e7SJed Brown 
875316643e7SJed Brown   Output Parameters:
876316643e7SJed Brown + A - Jacobian matrix
877195e9b02SBarry Smith - B - matrix from which the preconditioner is constructed; often the same as `A`
878316643e7SJed Brown 
879bcf0153eSBarry Smith   Level: developer
880bcf0153eSBarry Smith 
881316643e7SJed Brown   Notes:
882efa39862SBarry Smith   If $ F(t,U,\dot{U})=0 $ is the DAE, the required Jacobian is
883195e9b02SBarry Smith .vb
8840910c330SBarry Smith    dF/dU + shift*dF/dUdot
885195e9b02SBarry Smith .ve
886316643e7SJed Brown   Most users should not need to explicitly call this routine, as it
887316643e7SJed Brown   is used internally within the nonlinear solvers.
888316643e7SJed Brown 
8891cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetIJacobian()`
89063495f91SJed Brown @*/
891d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIJacobian(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat A, Mat B, PetscBool imex)
892d71ae5a4SJacob Faibussowitsch {
8938434afd1SBarry Smith   TSIJacobianFn   *ijacobian;
8948434afd1SBarry Smith   TSRHSJacobianFn *rhsjacobian;
89524989b8cSPeter Brune   DM               dm;
89624989b8cSPeter Brune   void            *ctx;
897316643e7SJed Brown 
898316643e7SJed Brown   PetscFunctionBegin;
8990700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
9000910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
9010910c330SBarry Smith   PetscValidHeaderSpecific(Udot, VEC_CLASSID, 4);
90294ab13aaSBarry Smith   PetscValidHeaderSpecific(A, MAT_CLASSID, 6);
90394ab13aaSBarry Smith   PetscValidHeaderSpecific(B, MAT_CLASSID, 7);
90424989b8cSPeter Brune 
9059566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
9069566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijacobian, &ctx));
9079566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL));
90824989b8cSPeter Brune 
9093c633725SBarry Smith   PetscCheck(rhsjacobian || ijacobian, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
910316643e7SJed Brown 
911da023ba9SStefano Zampini   PetscCall(PetscLogEventBegin(TS_JacobianEval, U, ts, A, B));
91224989b8cSPeter Brune   if (ijacobian) {
913792fecdfSBarry Smith     PetscCallBack("TS callback implicit Jacobian", (*ijacobian)(ts, t, U, Udot, shift, A, B, ctx));
914a6ab3590SBarry Smith     ts->ijacs++;
9154a6899ffSJed Brown   }
916214bc6a2SJed Brown   if (imex) {
917b5abc632SBarry Smith     if (!ijacobian) { /* system was written as Udot = G(t,U) */
9184c26be97Sstefano_zampini       PetscBool assembled;
919971015bcSStefano Zampini       if (rhsjacobian) {
920971015bcSStefano Zampini         Mat Arhs = NULL;
9219566063dSJacob Faibussowitsch         PetscCall(TSGetRHSMats_Private(ts, &Arhs, NULL));
922971015bcSStefano Zampini         if (A == Arhs) {
9233c633725SBarry Smith           PetscCheck(rhsjacobian != TSComputeRHSJacobianConstant, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Unsupported operation! cannot use TSComputeRHSJacobianConstant"); /* there is no way to reconstruct shift*M-J since J cannot be reevaluated */
924971015bcSStefano Zampini           ts->rhsjacobian.time = PETSC_MIN_REAL;
925971015bcSStefano Zampini         }
926971015bcSStefano Zampini       }
9279566063dSJacob Faibussowitsch       PetscCall(MatZeroEntries(A));
9289566063dSJacob Faibussowitsch       PetscCall(MatAssembled(A, &assembled));
9294c26be97Sstefano_zampini       if (!assembled) {
9309566063dSJacob Faibussowitsch         PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
9319566063dSJacob Faibussowitsch         PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
9324c26be97Sstefano_zampini       }
9339566063dSJacob Faibussowitsch       PetscCall(MatShift(A, shift));
93494ab13aaSBarry Smith       if (A != B) {
9359566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(B));
9369566063dSJacob Faibussowitsch         PetscCall(MatAssembled(B, &assembled));
9374c26be97Sstefano_zampini         if (!assembled) {
9389566063dSJacob Faibussowitsch           PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
9399566063dSJacob Faibussowitsch           PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
9404c26be97Sstefano_zampini         }
9419566063dSJacob Faibussowitsch         PetscCall(MatShift(B, shift));
942214bc6a2SJed Brown       }
943214bc6a2SJed Brown     }
944214bc6a2SJed Brown   } else {
945e1244c69SJed Brown     Mat Arhs = NULL, Brhs = NULL;
9461e66621cSBarry Smith 
9471e66621cSBarry Smith     /* RHSJacobian needs to be converted to part of IJacobian if exists */
9481e66621cSBarry Smith     if (rhsjacobian) PetscCall(TSGetRHSMats_Private(ts, &Arhs, &Brhs));
949e8b1e424SHong Zhang     if (Arhs == A) { /* No IJacobian matrix, so we only have the RHS matrix */
950e8b1e424SHong Zhang       PetscObjectState Ustate;
951e8b1e424SHong Zhang       PetscObjectId    Uid;
9528434afd1SBarry Smith       TSRHSFunctionFn *rhsfunction;
953e8b1e424SHong Zhang 
9549566063dSJacob Faibussowitsch       PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
9559566063dSJacob Faibussowitsch       PetscCall(PetscObjectStateGet((PetscObject)U, &Ustate));
9569566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetId((PetscObject)U, &Uid));
9579371c9d4SSatish Balay       if ((rhsjacobian == TSComputeRHSJacobianConstant || (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && rhsfunction != TSComputeRHSFunctionLinear)) &&
9589371c9d4SSatish Balay           ts->rhsjacobian.scale == -1.) {                      /* No need to recompute RHSJacobian */
9599566063dSJacob Faibussowitsch         PetscCall(MatShift(A, shift - ts->rhsjacobian.shift)); /* revert the old shift and add the new shift with a single call to MatShift */
9601e66621cSBarry Smith         if (A != B) PetscCall(MatShift(B, shift - ts->rhsjacobian.shift));
961e8b1e424SHong Zhang       } else {
9623565c898SBarry Smith         PetscBool flg;
963e8b1e424SHong Zhang 
964e8b1e424SHong Zhang         if (ts->rhsjacobian.reuse) { /* Undo the damage */
965e8b1e424SHong Zhang           /* MatScale has a short path for this case.
966e8b1e424SHong Zhang              However, this code path is taken the first time TSComputeRHSJacobian is called
967e8b1e424SHong Zhang              and the matrices have not been assembled yet */
9689566063dSJacob Faibussowitsch           PetscCall(TSRecoverRHSJacobian(ts, A, B));
969e8b1e424SHong Zhang         }
9709566063dSJacob Faibussowitsch         PetscCall(TSComputeRHSJacobian(ts, t, U, A, B));
9719566063dSJacob Faibussowitsch         PetscCall(SNESGetUseMatrixFree(ts->snes, NULL, &flg));
9723565c898SBarry Smith         /* since -snes_mf_operator uses the full SNES function it does not need to be shifted or scaled here */
9733565c898SBarry Smith         if (!flg) {
9749566063dSJacob Faibussowitsch           PetscCall(MatScale(A, -1));
9759566063dSJacob Faibussowitsch           PetscCall(MatShift(A, shift));
9763565c898SBarry Smith         }
97794ab13aaSBarry Smith         if (A != B) {
9789566063dSJacob Faibussowitsch           PetscCall(MatScale(B, -1));
9799566063dSJacob Faibussowitsch           PetscCall(MatShift(B, shift));
980316643e7SJed Brown         }
981e8b1e424SHong Zhang       }
982e8b1e424SHong Zhang       ts->rhsjacobian.scale = -1;
983e8b1e424SHong Zhang       ts->rhsjacobian.shift = shift;
984d60b7d5cSBarry Smith     } else if (Arhs) {  /* Both IJacobian and RHSJacobian */
985e1244c69SJed Brown       if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */
9869566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(A));
9879566063dSJacob Faibussowitsch         PetscCall(MatShift(A, shift));
98894ab13aaSBarry Smith         if (A != B) {
9899566063dSJacob Faibussowitsch           PetscCall(MatZeroEntries(B));
9909566063dSJacob Faibussowitsch           PetscCall(MatShift(B, shift));
991214bc6a2SJed Brown         }
992316643e7SJed Brown       }
9939566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSJacobian(ts, t, U, Arhs, Brhs));
9949566063dSJacob Faibussowitsch       PetscCall(MatAXPY(A, -1, Arhs, ts->axpy_pattern));
9951e66621cSBarry Smith       if (A != B) PetscCall(MatAXPY(B, -1, Brhs, ts->axpy_pattern));
996316643e7SJed Brown     }
997316643e7SJed Brown   }
998da023ba9SStefano Zampini   PetscCall(PetscLogEventEnd(TS_JacobianEval, U, ts, A, B));
9993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1000316643e7SJed Brown }
1001316643e7SJed Brown 
1002d763cef2SBarry Smith /*@C
1003d763cef2SBarry Smith   TSSetRHSFunction - Sets the routine for evaluating the function,
1004b5abc632SBarry Smith   where U_t = G(t,u).
1005d763cef2SBarry Smith 
1006c3339decSBarry Smith   Logically Collective
1007d763cef2SBarry Smith 
1008d763cef2SBarry Smith   Input Parameters:
1009bcf0153eSBarry Smith + ts  - the `TS` context obtained from `TSCreate()`
1010dd8e379bSPierre Jolivet . r   - vector to put the computed right-hand side (or `NULL` to have it created)
1011d763cef2SBarry Smith . f   - routine for evaluating the right-hand-side function
1012195e9b02SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`)
1013d763cef2SBarry Smith 
1014d763cef2SBarry Smith   Level: beginner
1015d763cef2SBarry Smith 
1016bcf0153eSBarry Smith   Note:
1017bcf0153eSBarry Smith   You must call this function or `TSSetIFunction()` to define your ODE. You cannot use this function when solving a DAE.
10182bbac0d3SBarry Smith 
10198434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSRHSFunctionFn`, `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
1020d763cef2SBarry Smith @*/
10218434afd1SBarry Smith PetscErrorCode TSSetRHSFunction(TS ts, Vec r, TSRHSFunctionFn *f, void *ctx)
1022d71ae5a4SJacob Faibussowitsch {
1023089b2837SJed Brown   SNES snes;
10240298fd71SBarry Smith   Vec  ralloc = NULL;
102524989b8cSPeter Brune   DM   dm;
1026d763cef2SBarry Smith 
1027089b2837SJed Brown   PetscFunctionBegin;
10280700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1029ca94891dSJed Brown   if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
103024989b8cSPeter Brune 
10319566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
10329566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSFunction(dm, f, ctx));
10339566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
1034e856ceecSJed Brown   if (!r && !ts->dm && ts->vec_sol) {
10359566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol, &ralloc));
1036e856ceecSJed Brown     r = ralloc;
1037e856ceecSJed Brown   }
10389566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, r, SNESTSFormFunction, ts));
10399566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
10403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1041d763cef2SBarry Smith }
1042d763cef2SBarry Smith 
1043ef20d060SBarry Smith /*@C
1044abd5a294SJed Brown   TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
1045ef20d060SBarry Smith 
1046c3339decSBarry Smith   Logically Collective
1047ef20d060SBarry Smith 
1048ef20d060SBarry Smith   Input Parameters:
1049bcf0153eSBarry Smith + ts  - the `TS` context obtained from `TSCreate()`
1050ef20d060SBarry Smith . f   - routine for evaluating the solution
1051ef20d060SBarry Smith - ctx - [optional] user-defined context for private data for the
1052195e9b02SBarry Smith           function evaluation routine (may be `NULL`)
1053ef20d060SBarry Smith 
1054bcf0153eSBarry Smith   Options Database Keys:
1055bcf0153eSBarry Smith + -ts_monitor_lg_error   - create a graphical monitor of error history, requires user to have provided `TSSetSolutionFunction()`
1056bcf0153eSBarry Smith - -ts_monitor_draw_error - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()`
1057bcf0153eSBarry Smith 
1058bcf0153eSBarry Smith   Level: intermediate
10590ed3bfb6SBarry Smith 
1060abd5a294SJed Brown   Notes:
1061abd5a294SJed Brown   This routine is used for testing accuracy of time integration schemes when you already know the solution.
1062abd5a294SJed Brown   If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
1063abd5a294SJed Brown   create closed-form solutions with non-physical forcing terms.
1064abd5a294SJed Brown 
1065bcf0153eSBarry Smith   For low-dimensional problems solved in serial, such as small discrete systems, `TSMonitorLGError()` can be used to monitor the error history.
1066abd5a294SJed Brown 
10678434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSSolutionFn`, `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSComputeSolutionFunction()`, `TSSetForcingFunction()`, `TSSetSolution()`, `TSGetSolution()`, `TSMonitorLGError()`, `TSMonitorDrawError()`
1068ef20d060SBarry Smith @*/
10698434afd1SBarry Smith PetscErrorCode TSSetSolutionFunction(TS ts, TSSolutionFn *f, void *ctx)
1070d71ae5a4SJacob Faibussowitsch {
1071ef20d060SBarry Smith   DM dm;
1072ef20d060SBarry Smith 
1073ef20d060SBarry Smith   PetscFunctionBegin;
1074ef20d060SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
10759566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
10769566063dSJacob Faibussowitsch   PetscCall(DMTSSetSolutionFunction(dm, f, ctx));
10773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1078ef20d060SBarry Smith }
1079ef20d060SBarry Smith 
10809b7cd975SBarry Smith /*@C
10819b7cd975SBarry Smith   TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE
10829b7cd975SBarry Smith 
1083c3339decSBarry Smith   Logically Collective
10849b7cd975SBarry Smith 
10859b7cd975SBarry Smith   Input Parameters:
1086bcf0153eSBarry Smith + ts   - the `TS` context obtained from `TSCreate()`
1087e162b725SBarry Smith . func - routine for evaluating the forcing function
108814d0ab18SJacob Faibussowitsch - ctx  - [optional] user-defined context for private data for the function evaluation routine
108914d0ab18SJacob Faibussowitsch          (may be `NULL`)
10909b7cd975SBarry Smith 
1091bcf0153eSBarry Smith   Level: intermediate
1092bcf0153eSBarry Smith 
10939b7cd975SBarry Smith   Notes:
10949b7cd975SBarry Smith   This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to
1095e162b725SBarry Smith   create closed-form solutions with a non-physical forcing term. It allows you to use the Method of Manufactored Solution without directly editing the
1096e162b725SBarry Smith   definition of the problem you are solving and hence possibly introducing bugs.
1097e162b725SBarry Smith 
10988847d985SBarry Smith   This replaces the ODE F(u,u_t,t) = 0 the `TS` is solving with F(u,u_t,t) - func(t) = 0
1099e162b725SBarry Smith 
1100e162b725SBarry Smith   This forcing function does not depend on the solution to the equations, it can only depend on spatial location, time, and possibly parameters, the
1101e162b725SBarry Smith   parameters can be passed in the ctx variable.
11029b7cd975SBarry Smith 
1103bcf0153eSBarry Smith   For low-dimensional problems solved in serial, such as small discrete systems, `TSMonitorLGError()` can be used to monitor the error history.
11049b7cd975SBarry Smith 
11058434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSForcingFn`, `TSSetRHSJacobian()`, `TSSetIJacobian()`,
110614d0ab18SJacob Faibussowitsch `TSComputeSolutionFunction()`, `TSSetSolutionFunction()`
11079b7cd975SBarry Smith @*/
11088434afd1SBarry Smith PetscErrorCode TSSetForcingFunction(TS ts, TSForcingFn *func, void *ctx)
1109d71ae5a4SJacob Faibussowitsch {
11109b7cd975SBarry Smith   DM dm;
11119b7cd975SBarry Smith 
11129b7cd975SBarry Smith   PetscFunctionBegin;
11139b7cd975SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
11149566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
11159566063dSJacob Faibussowitsch   PetscCall(DMTSSetForcingFunction(dm, func, ctx));
11163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11179b7cd975SBarry Smith }
11189b7cd975SBarry Smith 
1119d763cef2SBarry Smith /*@C
1120f7ab8db6SBarry Smith   TSSetRHSJacobian - Sets the function to compute the Jacobian of G,
1121b5abc632SBarry Smith   where U_t = G(U,t), as well as the location to store the matrix.
1122d763cef2SBarry Smith 
1123c3339decSBarry Smith   Logically Collective
1124d763cef2SBarry Smith 
1125d763cef2SBarry Smith   Input Parameters:
1126bcf0153eSBarry Smith + ts   - the `TS` context obtained from `TSCreate()`
1127195e9b02SBarry Smith . Amat - (approximate) location to store Jacobian matrix entries computed by `f`
1128195e9b02SBarry Smith . Pmat - matrix from which preconditioner is to be constructed (usually the same as `Amat`)
1129d763cef2SBarry Smith . f    - the Jacobian evaluation routine
1130195e9b02SBarry Smith - ctx  - [optional] user-defined context for private data for the Jacobian evaluation routine (may be `NULL`)
1131d763cef2SBarry Smith 
1132bcf0153eSBarry Smith   Level: beginner
1133bcf0153eSBarry Smith 
11346cd88445SBarry Smith   Notes:
11356cd88445SBarry Smith   You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
11366cd88445SBarry Smith 
113714d0ab18SJacob Faibussowitsch   The `TS` solver may modify the nonzero structure and the entries of the matrices `Amat` and `Pmat` between the calls to `f()`
1138ca5f011dSBarry Smith   You should not assume the values are the same in the next call to f() as you set them in the previous call.
1139d763cef2SBarry Smith 
11408434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSRHSJacobianFn`, `SNESComputeJacobianDefaultColor()`,
11418434afd1SBarry Smith `TSSetRHSFunction()`, `TSRHSJacobianSetReuse()`, `TSSetIJacobian()`, `TSRHSFunctionFn`, `TSIFunctionFn`
1142d763cef2SBarry Smith @*/
11438434afd1SBarry Smith PetscErrorCode TSSetRHSJacobian(TS ts, Mat Amat, Mat Pmat, TSRHSJacobianFn *f, void *ctx)
1144d71ae5a4SJacob Faibussowitsch {
1145089b2837SJed Brown   SNES           snes;
114624989b8cSPeter Brune   DM             dm;
11478434afd1SBarry Smith   TSIJacobianFn *ijacobian;
1148277b19d0SLisandro Dalcin 
1149d763cef2SBarry Smith   PetscFunctionBegin;
11500700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1151e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
1152e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
1153e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts, 1, Amat, 2);
1154e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts, 1, Pmat, 3);
1155d763cef2SBarry Smith 
11569566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
11579566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSJacobian(dm, f, ctx));
11589566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijacobian, NULL));
11599566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
11601e66621cSBarry Smith   if (!ijacobian) PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESTSFormJacobian, ts));
1161e5d3d808SBarry Smith   if (Amat) {
11629566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Amat));
11639566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Arhs));
1164e5d3d808SBarry Smith     ts->Arhs = Amat;
11650e4ef248SJed Brown   }
1166e5d3d808SBarry Smith   if (Pmat) {
11679566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Pmat));
11689566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Brhs));
1169e5d3d808SBarry Smith     ts->Brhs = Pmat;
11700e4ef248SJed Brown   }
11713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1172d763cef2SBarry Smith }
1173d763cef2SBarry Smith 
1174316643e7SJed Brown /*@C
1175b5abc632SBarry Smith   TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
1176316643e7SJed Brown 
1177c3339decSBarry Smith   Logically Collective
1178316643e7SJed Brown 
1179316643e7SJed Brown   Input Parameters:
1180bcf0153eSBarry Smith + ts  - the `TS` context obtained from `TSCreate()`
1181195e9b02SBarry Smith . r   - vector to hold the residual (or `NULL` to have it created internally)
1182316643e7SJed Brown . f   - the function evaluation routine
1183195e9b02SBarry Smith - ctx - user-defined context for private data for the function evaluation routine (may be `NULL`)
1184316643e7SJed Brown 
1185316643e7SJed Brown   Level: beginner
1186316643e7SJed Brown 
1187bcf0153eSBarry Smith   Note:
1188bcf0153eSBarry Smith   The user MUST call either this routine or `TSSetRHSFunction()` to define the ODE.  When solving DAEs you must use this function.
1189bcf0153eSBarry Smith 
11908434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSIFunctionFn`, `TSSetRHSJacobian()`, `TSSetRHSFunction()`,
119114d0ab18SJacob Faibussowitsch `TSSetIJacobian()`
1192316643e7SJed Brown @*/
11938434afd1SBarry Smith PetscErrorCode TSSetIFunction(TS ts, Vec r, TSIFunctionFn *f, void *ctx)
1194d71ae5a4SJacob Faibussowitsch {
1195089b2837SJed Brown   SNES snes;
119651699248SLisandro Dalcin   Vec  ralloc = NULL;
119724989b8cSPeter Brune   DM   dm;
1198316643e7SJed Brown 
1199316643e7SJed Brown   PetscFunctionBegin;
12000700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
120151699248SLisandro Dalcin   if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
120224989b8cSPeter Brune 
12039566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12049566063dSJacob Faibussowitsch   PetscCall(DMTSSetIFunction(dm, f, ctx));
120524989b8cSPeter Brune 
12069566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
120751699248SLisandro Dalcin   if (!r && !ts->dm && ts->vec_sol) {
12089566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol, &ralloc));
120951699248SLisandro Dalcin     r = ralloc;
1210e856ceecSJed Brown   }
12119566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, r, SNESTSFormFunction, ts));
12129566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
12133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1214089b2837SJed Brown }
1215089b2837SJed Brown 
1216089b2837SJed Brown /*@C
1217a5b23f4aSJose E. Roman   TSGetIFunction - Returns the vector where the implicit residual is stored and the function/context to compute it.
1218089b2837SJed Brown 
1219089b2837SJed Brown   Not Collective
1220089b2837SJed Brown 
1221089b2837SJed Brown   Input Parameter:
1222bcf0153eSBarry Smith . ts - the `TS` context
1223089b2837SJed Brown 
1224d8d19677SJose E. Roman   Output Parameters:
1225195e9b02SBarry Smith + r    - vector to hold residual (or `NULL`)
1226195e9b02SBarry Smith . func - the function to compute residual (or `NULL`)
1227195e9b02SBarry Smith - ctx  - the function context (or `NULL`)
1228089b2837SJed Brown 
1229089b2837SJed Brown   Level: advanced
1230089b2837SJed Brown 
12311cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetIFunction()`, `SNESGetFunction()`
1232089b2837SJed Brown @*/
12338434afd1SBarry Smith PetscErrorCode TSGetIFunction(TS ts, Vec *r, TSIFunctionFn **func, void **ctx)
1234d71ae5a4SJacob Faibussowitsch {
1235089b2837SJed Brown   SNES snes;
123624989b8cSPeter Brune   DM   dm;
1237089b2837SJed Brown 
1238089b2837SJed Brown   PetscFunctionBegin;
1239089b2837SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
12409566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
12419566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
12429566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12439566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, func, ctx));
12443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1245089b2837SJed Brown }
1246089b2837SJed Brown 
1247089b2837SJed Brown /*@C
1248dd8e379bSPierre Jolivet   TSGetRHSFunction - Returns the vector where the right-hand side is stored and the function/context to compute it.
1249089b2837SJed Brown 
1250089b2837SJed Brown   Not Collective
1251089b2837SJed Brown 
1252089b2837SJed Brown   Input Parameter:
1253bcf0153eSBarry Smith . ts - the `TS` context
1254089b2837SJed Brown 
1255d8d19677SJose E. Roman   Output Parameters:
1256dd8e379bSPierre Jolivet + r    - vector to hold computed right-hand side (or `NULL`)
1257dd8e379bSPierre Jolivet . func - the function to compute right-hand side (or `NULL`)
1258195e9b02SBarry Smith - ctx  - the function context (or `NULL`)
1259089b2837SJed Brown 
1260089b2837SJed Brown   Level: advanced
1261089b2837SJed Brown 
12621cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSFunction()`, `SNESGetFunction()`
1263089b2837SJed Brown @*/
12648434afd1SBarry Smith PetscErrorCode TSGetRHSFunction(TS ts, Vec *r, TSRHSFunctionFn **func, void **ctx)
1265d71ae5a4SJacob Faibussowitsch {
1266089b2837SJed Brown   SNES snes;
126724989b8cSPeter Brune   DM   dm;
1268089b2837SJed Brown 
1269089b2837SJed Brown   PetscFunctionBegin;
1270089b2837SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
12719566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
12729566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
12739566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12749566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, func, ctx));
12753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1276316643e7SJed Brown }
1277316643e7SJed Brown 
1278316643e7SJed Brown /*@C
1279a4f0a591SBarry Smith   TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
1280bcf0153eSBarry Smith   provided with `TSSetIFunction()`.
1281316643e7SJed Brown 
1282c3339decSBarry Smith   Logically Collective
1283316643e7SJed Brown 
1284316643e7SJed Brown   Input Parameters:
1285bcf0153eSBarry Smith + ts   - the `TS` context obtained from `TSCreate()`
1286aaa8cc7dSPierre Jolivet . Amat - (approximate) matrix to store Jacobian entries computed by `f`
1287195e9b02SBarry Smith . Pmat - matrix used to compute preconditioner (usually the same as `Amat`)
1288316643e7SJed Brown . f    - the Jacobian evaluation routine
1289195e9b02SBarry Smith - ctx  - user-defined context for private data for the Jacobian evaluation routine (may be `NULL`)
1290316643e7SJed Brown 
1291bcf0153eSBarry Smith   Level: beginner
1292316643e7SJed Brown 
1293bcf0153eSBarry Smith   Notes:
1294195e9b02SBarry Smith   The matrices `Amat` and `Pmat` are exactly the matrices that are used by `SNES` for the nonlinear solve.
1295bcf0153eSBarry Smith 
1296bcf0153eSBarry Smith   If you know the operator Amat has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null
1297195e9b02SBarry Smith   space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process.
1298895c21f2SBarry Smith 
1299a4f0a591SBarry Smith   The matrix dF/dU + a*dF/dU_t you provide turns out to be
1300b5abc632SBarry Smith   the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1301a4f0a591SBarry Smith   The time integrator internally approximates U_t by W+a*U where the positive "shift"
1302a4f0a591SBarry Smith   a and vector W depend on the integration method, step size, and past states. For example with
1303a4f0a591SBarry Smith   the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1304a4f0a591SBarry Smith   W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1305a4f0a591SBarry Smith 
13066cd88445SBarry Smith   You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
13076cd88445SBarry Smith 
1308195e9b02SBarry Smith   The TS solver may modify the nonzero structure and the entries of the matrices `Amat` and `Pmat` between the calls to `f`
1309195e9b02SBarry Smith   You should not assume the values are the same in the next call to `f` as you set them in the previous call.
1310ca5f011dSBarry Smith 
1311bc7fdbb5SPierre Jolivet   In case `TSSetRHSJacobian()` is also used in conjunction with a fully-implicit solver,
1312d469ad21SStefano Zampini   multilevel linear solvers, e.g. `PCMG`, will likely not work due to the way `TS` handles rhs matrices.
1313d469ad21SStefano Zampini 
13148434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSIJacobianFn`, `TSSetIFunction()`, `TSSetRHSJacobian()`,
131514d0ab18SJacob Faibussowitsch `SNESComputeJacobianDefaultColor()`, `SNESComputeJacobianDefault()`, `TSSetRHSFunction()`
1316316643e7SJed Brown @*/
13178434afd1SBarry Smith PetscErrorCode TSSetIJacobian(TS ts, Mat Amat, Mat Pmat, TSIJacobianFn *f, void *ctx)
1318d71ae5a4SJacob Faibussowitsch {
1319089b2837SJed Brown   SNES snes;
132024989b8cSPeter Brune   DM   dm;
1321316643e7SJed Brown 
1322316643e7SJed Brown   PetscFunctionBegin;
13230700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1324e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
1325e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
1326e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts, 1, Amat, 2);
1327e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts, 1, Pmat, 3);
132824989b8cSPeter Brune 
13299566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
13309566063dSJacob Faibussowitsch   PetscCall(DMTSSetIJacobian(dm, f, ctx));
133124989b8cSPeter Brune 
13329566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
13339566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESTSFormJacobian, ts));
13343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1335316643e7SJed Brown }
1336316643e7SJed Brown 
1337e1244c69SJed Brown /*@
13388434afd1SBarry Smith   TSRHSJacobianSetReuse - restore the RHS Jacobian before calling the user-provided `TSRHSJacobianFn` function again
1339e1244c69SJed Brown 
1340e1244c69SJed Brown   Logically Collective
1341e1244c69SJed Brown 
13424165533cSJose E. Roman   Input Parameters:
1343bcf0153eSBarry Smith + ts    - `TS` context obtained from `TSCreate()`
1344bcf0153eSBarry Smith - reuse - `PETSC_TRUE` if the RHS Jacobian
1345e1244c69SJed Brown 
1346e1244c69SJed Brown   Level: intermediate
1347e1244c69SJed Brown 
134814d0ab18SJacob Faibussowitsch   Notes:
134914d0ab18SJacob Faibussowitsch   Without this flag, `TS` will change the sign and shift the RHS Jacobian for a
135014d0ab18SJacob Faibussowitsch   finite-time-step implicit solve, in which case the user function will need to recompute the
135114d0ab18SJacob Faibussowitsch   entire Jacobian.  The `reuse `flag must be set if the evaluation function assumes that the
135214d0ab18SJacob Faibussowitsch   matrix entries have not been changed by the `TS`.
135314d0ab18SJacob Faibussowitsch 
13541cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
1355e1244c69SJed Brown @*/
1356d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSJacobianSetReuse(TS ts, PetscBool reuse)
1357d71ae5a4SJacob Faibussowitsch {
1358e1244c69SJed Brown   PetscFunctionBegin;
1359e1244c69SJed Brown   ts->rhsjacobian.reuse = reuse;
13603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1361e1244c69SJed Brown }
1362e1244c69SJed Brown 
1363efe9872eSLisandro Dalcin /*@C
1364efe9872eSLisandro Dalcin   TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved.
1365efe9872eSLisandro Dalcin 
1366c3339decSBarry Smith   Logically Collective
1367efe9872eSLisandro Dalcin 
1368efe9872eSLisandro Dalcin   Input Parameters:
1369bcf0153eSBarry Smith + ts  - the `TS` context obtained from `TSCreate()`
1370195e9b02SBarry Smith . F   - vector to hold the residual (or `NULL` to have it created internally)
1371efe9872eSLisandro Dalcin . fun - the function evaluation routine
1372195e9b02SBarry Smith - ctx - user-defined context for private data for the function evaluation routine (may be `NULL`)
1373efe9872eSLisandro Dalcin 
1374efe9872eSLisandro Dalcin   Level: beginner
1375efe9872eSLisandro Dalcin 
13768434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSI2FunctionFn`, `TSSetI2Jacobian()`, `TSSetIFunction()`,
137714d0ab18SJacob Faibussowitsch `TSCreate()`, `TSSetRHSFunction()`
1378efe9872eSLisandro Dalcin @*/
13798434afd1SBarry Smith PetscErrorCode TSSetI2Function(TS ts, Vec F, TSI2FunctionFn *fun, void *ctx)
1380d71ae5a4SJacob Faibussowitsch {
1381efe9872eSLisandro Dalcin   DM dm;
1382efe9872eSLisandro Dalcin 
1383efe9872eSLisandro Dalcin   PetscFunctionBegin;
1384efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1385efe9872eSLisandro Dalcin   if (F) PetscValidHeaderSpecific(F, VEC_CLASSID, 2);
13869566063dSJacob Faibussowitsch   PetscCall(TSSetIFunction(ts, F, NULL, NULL));
13879566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
13889566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Function(dm, fun, ctx));
13893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1390efe9872eSLisandro Dalcin }
1391efe9872eSLisandro Dalcin 
1392efe9872eSLisandro Dalcin /*@C
1393a5b23f4aSJose E. Roman   TSGetI2Function - Returns the vector where the implicit residual is stored and the function/context to compute it.
1394efe9872eSLisandro Dalcin 
1395efe9872eSLisandro Dalcin   Not Collective
1396efe9872eSLisandro Dalcin 
1397efe9872eSLisandro Dalcin   Input Parameter:
1398bcf0153eSBarry Smith . ts - the `TS` context
1399efe9872eSLisandro Dalcin 
1400d8d19677SJose E. Roman   Output Parameters:
1401195e9b02SBarry Smith + r   - vector to hold residual (or `NULL`)
1402195e9b02SBarry Smith . fun - the function to compute residual (or `NULL`)
1403195e9b02SBarry Smith - ctx - the function context (or `NULL`)
1404efe9872eSLisandro Dalcin 
1405efe9872eSLisandro Dalcin   Level: advanced
1406efe9872eSLisandro Dalcin 
14071cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetIFunction()`, `SNESGetFunction()`, `TSCreate()`
1408efe9872eSLisandro Dalcin @*/
14098434afd1SBarry Smith PetscErrorCode TSGetI2Function(TS ts, Vec *r, TSI2FunctionFn **fun, void **ctx)
1410d71ae5a4SJacob Faibussowitsch {
1411efe9872eSLisandro Dalcin   SNES snes;
1412efe9872eSLisandro Dalcin   DM   dm;
1413efe9872eSLisandro Dalcin 
1414efe9872eSLisandro Dalcin   PetscFunctionBegin;
1415efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
14169566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
14179566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
14189566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14199566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm, fun, ctx));
14203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1421efe9872eSLisandro Dalcin }
1422efe9872eSLisandro Dalcin 
1423efe9872eSLisandro Dalcin /*@C
1424bc77d74cSLisandro Dalcin   TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t  + a*dF/dU_tt
1425bcf0153eSBarry Smith   where F(t,U,U_t,U_tt) is the function you provided with `TSSetI2Function()`.
1426efe9872eSLisandro Dalcin 
1427c3339decSBarry Smith   Logically Collective
1428efe9872eSLisandro Dalcin 
1429efe9872eSLisandro Dalcin   Input Parameters:
1430bcf0153eSBarry Smith + ts  - the `TS` context obtained from `TSCreate()`
1431195e9b02SBarry Smith . J   - matrix to hold the Jacobian values
1432195e9b02SBarry Smith . P   - matrix for constructing the preconditioner (may be same as `J`)
14338434afd1SBarry Smith . jac - the Jacobian evaluation routine, see `TSI2JacobianFn` for the calling sequence
1434195e9b02SBarry Smith - ctx - user-defined context for private data for the Jacobian evaluation routine (may be `NULL`)
1435efe9872eSLisandro Dalcin 
1436bcf0153eSBarry Smith   Level: beginner
1437bcf0153eSBarry Smith 
1438efe9872eSLisandro Dalcin   Notes:
1439195e9b02SBarry Smith   The matrices `J` and `P` are exactly the matrices that are used by `SNES` for the nonlinear solve.
1440efe9872eSLisandro Dalcin 
1441efe9872eSLisandro Dalcin   The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be
1442efe9872eSLisandro Dalcin   the Jacobian of G(U) = F(t,U,W+v*U,W'+a*U) where F(t,U,U_t,U_tt) = 0 is the DAE to be solved.
1443efe9872eSLisandro Dalcin   The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U  where the positive "shift"
1444bc77d74cSLisandro Dalcin   parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states.
1445efe9872eSLisandro Dalcin 
14468434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSI2JacobianFn`, `TSSetI2Function()`, `TSGetI2Jacobian()`
1447efe9872eSLisandro Dalcin @*/
14488434afd1SBarry Smith PetscErrorCode TSSetI2Jacobian(TS ts, Mat J, Mat P, TSI2JacobianFn *jac, void *ctx)
1449d71ae5a4SJacob Faibussowitsch {
1450efe9872eSLisandro Dalcin   DM dm;
1451efe9872eSLisandro Dalcin 
1452efe9872eSLisandro Dalcin   PetscFunctionBegin;
1453efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1454efe9872eSLisandro Dalcin   if (J) PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
1455efe9872eSLisandro Dalcin   if (P) PetscValidHeaderSpecific(P, MAT_CLASSID, 3);
14569566063dSJacob Faibussowitsch   PetscCall(TSSetIJacobian(ts, J, P, NULL, NULL));
14579566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14589566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Jacobian(dm, jac, ctx));
14593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1460efe9872eSLisandro Dalcin }
1461efe9872eSLisandro Dalcin 
1462efe9872eSLisandro Dalcin /*@C
1463efe9872eSLisandro Dalcin   TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep.
1464efe9872eSLisandro Dalcin 
1465bcf0153eSBarry Smith   Not Collective, but parallel objects are returned if `TS` is parallel
1466efe9872eSLisandro Dalcin 
1467efe9872eSLisandro Dalcin   Input Parameter:
1468bcf0153eSBarry Smith . ts - The `TS` context obtained from `TSCreate()`
1469efe9872eSLisandro Dalcin 
1470efe9872eSLisandro Dalcin   Output Parameters:
1471efe9872eSLisandro Dalcin + J   - The (approximate) Jacobian of F(t,U,U_t,U_tt)
1472195e9b02SBarry Smith . P   - The matrix from which the preconditioner is constructed, often the same as `J`
1473efe9872eSLisandro Dalcin . jac - The function to compute the Jacobian matrices
1474efe9872eSLisandro Dalcin - ctx - User-defined context for Jacobian evaluation routine
1475efe9872eSLisandro Dalcin 
1476bcf0153eSBarry Smith   Level: advanced
1477bcf0153eSBarry Smith 
1478195e9b02SBarry Smith   Note:
1479195e9b02SBarry Smith   You can pass in `NULL` for any return argument you do not need.
1480efe9872eSLisandro Dalcin 
14811cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`, `TSSetI2Jacobian()`, `TSGetI2Function()`, `TSCreate()`
1482efe9872eSLisandro Dalcin @*/
14838434afd1SBarry Smith PetscErrorCode TSGetI2Jacobian(TS ts, Mat *J, Mat *P, TSI2JacobianFn **jac, void **ctx)
1484d71ae5a4SJacob Faibussowitsch {
1485efe9872eSLisandro Dalcin   SNES snes;
1486efe9872eSLisandro Dalcin   DM   dm;
1487efe9872eSLisandro Dalcin 
1488efe9872eSLisandro Dalcin   PetscFunctionBegin;
14899566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
14909566063dSJacob Faibussowitsch   PetscCall(SNESSetUpMatrices(snes));
14919566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, J, P, NULL, NULL));
14929566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14939566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, jac, ctx));
14943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1495efe9872eSLisandro Dalcin }
1496efe9872eSLisandro Dalcin 
1497efe9872eSLisandro Dalcin /*@
1498efe9872eSLisandro Dalcin   TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0
1499efe9872eSLisandro Dalcin 
1500c3339decSBarry Smith   Collective
1501efe9872eSLisandro Dalcin 
1502efe9872eSLisandro Dalcin   Input Parameters:
1503bcf0153eSBarry Smith + ts - the `TS` context
1504efe9872eSLisandro Dalcin . t  - current time
1505efe9872eSLisandro Dalcin . U  - state vector
1506efe9872eSLisandro Dalcin . V  - time derivative of state vector (U_t)
1507efe9872eSLisandro Dalcin - A  - second time derivative of state vector (U_tt)
1508efe9872eSLisandro Dalcin 
1509efe9872eSLisandro Dalcin   Output Parameter:
1510efe9872eSLisandro Dalcin . F - the residual vector
1511efe9872eSLisandro Dalcin 
1512bcf0153eSBarry Smith   Level: developer
1513bcf0153eSBarry Smith 
1514efe9872eSLisandro Dalcin   Note:
1515efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
1516efe9872eSLisandro Dalcin   is used internally within the nonlinear solvers.
1517efe9872eSLisandro Dalcin 
15181cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetI2Function()`, `TSGetI2Function()`
1519efe9872eSLisandro Dalcin @*/
1520d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeI2Function(TS ts, PetscReal t, Vec U, Vec V, Vec A, Vec F)
1521d71ae5a4SJacob Faibussowitsch {
1522efe9872eSLisandro Dalcin   DM               dm;
15238434afd1SBarry Smith   TSI2FunctionFn  *I2Function;
1524efe9872eSLisandro Dalcin   void            *ctx;
15258434afd1SBarry Smith   TSRHSFunctionFn *rhsfunction;
1526efe9872eSLisandro Dalcin 
1527efe9872eSLisandro Dalcin   PetscFunctionBegin;
1528efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1529efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
1530efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V, VEC_CLASSID, 4);
1531efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A, VEC_CLASSID, 5);
1532efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(F, VEC_CLASSID, 6);
1533efe9872eSLisandro Dalcin 
15349566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
15359566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm, &I2Function, &ctx));
15369566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
1537efe9872eSLisandro Dalcin 
1538efe9872eSLisandro Dalcin   if (!I2Function) {
15399566063dSJacob Faibussowitsch     PetscCall(TSComputeIFunction(ts, t, U, A, F, PETSC_FALSE));
15403ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
1541efe9872eSLisandro Dalcin   }
1542efe9872eSLisandro Dalcin 
1543da023ba9SStefano Zampini   PetscCall(PetscLogEventBegin(TS_FunctionEval, U, ts, V, F));
1544efe9872eSLisandro Dalcin 
1545792fecdfSBarry Smith   PetscCallBack("TS callback implicit function", I2Function(ts, t, U, V, A, F, ctx));
1546efe9872eSLisandro Dalcin 
1547efe9872eSLisandro Dalcin   if (rhsfunction) {
1548efe9872eSLisandro Dalcin     Vec Frhs;
15498af0501fSStefano Zampini 
15508af0501fSStefano Zampini     PetscCall(DMGetGlobalVector(dm, &Frhs));
15519566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSFunction(ts, t, U, Frhs));
15529566063dSJacob Faibussowitsch     PetscCall(VecAXPY(F, -1, Frhs));
15538af0501fSStefano Zampini     PetscCall(DMRestoreGlobalVector(dm, &Frhs));
1554efe9872eSLisandro Dalcin   }
1555efe9872eSLisandro Dalcin 
1556da023ba9SStefano Zampini   PetscCall(PetscLogEventEnd(TS_FunctionEval, U, ts, V, F));
15573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1558efe9872eSLisandro Dalcin }
1559efe9872eSLisandro Dalcin 
1560efe9872eSLisandro Dalcin /*@
1561efe9872eSLisandro Dalcin   TSComputeI2Jacobian - Evaluates the Jacobian of the DAE
1562efe9872eSLisandro Dalcin 
1563c3339decSBarry Smith   Collective
1564efe9872eSLisandro Dalcin 
1565efe9872eSLisandro Dalcin   Input Parameters:
1566bcf0153eSBarry Smith + ts     - the `TS` context
1567efe9872eSLisandro Dalcin . t      - current timestep
1568efe9872eSLisandro Dalcin . U      - state vector
1569efe9872eSLisandro Dalcin . V      - time derivative of state vector
1570efe9872eSLisandro Dalcin . A      - second time derivative of state vector
1571efe9872eSLisandro Dalcin . shiftV - shift to apply, see note below
1572efe9872eSLisandro Dalcin - shiftA - shift to apply, see note below
1573efe9872eSLisandro Dalcin 
1574efe9872eSLisandro Dalcin   Output Parameters:
1575efe9872eSLisandro Dalcin + J - Jacobian matrix
15767addb90fSBarry Smith - P - optional matrix used to construct the preconditioner
1577efe9872eSLisandro Dalcin 
1578bcf0153eSBarry Smith   Level: developer
1579bcf0153eSBarry Smith 
1580efe9872eSLisandro Dalcin   Notes:
15817addb90fSBarry Smith   If $F(t,U,V,A) = 0$ is the DAE, the required Jacobian is
1582efe9872eSLisandro Dalcin 
15837addb90fSBarry Smith $$
1584efe9872eSLisandro Dalcin   dF/dU + shiftV*dF/dV + shiftA*dF/dA
15857addb90fSBarry Smith $$
1586efe9872eSLisandro Dalcin 
1587efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
15887addb90fSBarry Smith   is used internally within the ODE integrators.
1589efe9872eSLisandro Dalcin 
15901cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetI2Jacobian()`
1591efe9872eSLisandro Dalcin @*/
1592d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeI2Jacobian(TS ts, PetscReal t, Vec U, Vec V, Vec A, PetscReal shiftV, PetscReal shiftA, Mat J, Mat P)
1593d71ae5a4SJacob Faibussowitsch {
1594efe9872eSLisandro Dalcin   DM               dm;
15958434afd1SBarry Smith   TSI2JacobianFn  *I2Jacobian;
1596efe9872eSLisandro Dalcin   void            *ctx;
15978434afd1SBarry Smith   TSRHSJacobianFn *rhsjacobian;
1598efe9872eSLisandro Dalcin 
1599efe9872eSLisandro Dalcin   PetscFunctionBegin;
1600efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1601efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
1602efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V, VEC_CLASSID, 4);
1603efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A, VEC_CLASSID, 5);
1604efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(J, MAT_CLASSID, 8);
1605efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(P, MAT_CLASSID, 9);
1606efe9872eSLisandro Dalcin 
16079566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
16089566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, &I2Jacobian, &ctx));
16099566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL));
1610efe9872eSLisandro Dalcin 
1611efe9872eSLisandro Dalcin   if (!I2Jacobian) {
16129566063dSJacob Faibussowitsch     PetscCall(TSComputeIJacobian(ts, t, U, A, shiftA, J, P, PETSC_FALSE));
16133ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
1614efe9872eSLisandro Dalcin   }
1615efe9872eSLisandro Dalcin 
1616da023ba9SStefano Zampini   PetscCall(PetscLogEventBegin(TS_JacobianEval, U, ts, J, P));
1617792fecdfSBarry Smith   PetscCallBack("TS callback implicit Jacobian", I2Jacobian(ts, t, U, V, A, shiftV, shiftA, J, P, ctx));
1618efe9872eSLisandro Dalcin   if (rhsjacobian) {
1619d60b7d5cSBarry Smith     Mat Jrhs, Prhs;
16209566063dSJacob Faibussowitsch     PetscCall(TSGetRHSMats_Private(ts, &Jrhs, &Prhs));
16219566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSJacobian(ts, t, U, Jrhs, Prhs));
16229566063dSJacob Faibussowitsch     PetscCall(MatAXPY(J, -1, Jrhs, ts->axpy_pattern));
16239566063dSJacob Faibussowitsch     if (P != J) PetscCall(MatAXPY(P, -1, Prhs, ts->axpy_pattern));
1624efe9872eSLisandro Dalcin   }
1625efe9872eSLisandro Dalcin 
1626da023ba9SStefano Zampini   PetscCall(PetscLogEventEnd(TS_JacobianEval, U, ts, J, P));
16273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1628efe9872eSLisandro Dalcin }
1629efe9872eSLisandro Dalcin 
1630438f35afSJed Brown /*@C
1631438f35afSJed Brown   TSSetTransientVariable - sets function to transform from state to transient variables
1632438f35afSJed Brown 
1633438f35afSJed Brown   Logically Collective
1634438f35afSJed Brown 
16354165533cSJose E. Roman   Input Parameters:
1636438f35afSJed Brown + ts   - time stepping context on which to change the transient variable
16378434afd1SBarry Smith . tvar - a function that transforms to transient variables, see `TSTransientVariableFn` for the calling sequence
1638438f35afSJed Brown - ctx  - a context for tvar
1639438f35afSJed Brown 
1640438f35afSJed Brown   Level: advanced
1641438f35afSJed Brown 
1642438f35afSJed Brown   Notes:
1643bcf0153eSBarry Smith   This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., `TSBDF`)
1644438f35afSJed Brown   can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
1645438f35afSJed Brown   well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
1646438f35afSJed Brown   C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
1647438f35afSJed Brown   evaluated via the chain rule, as in
1648195e9b02SBarry Smith .vb
1649438f35afSJed Brown      dF/dP + shift * dF/dCdot dC/dP.
1650195e9b02SBarry Smith .ve
1651438f35afSJed Brown 
16528434afd1SBarry Smith .seealso: [](ch_ts), `TS`, `TSBDF`, `TSTransientVariableFn`, `DMTSSetTransientVariable()`, `DMTSGetTransientVariable()`, `TSSetIFunction()`, `TSSetIJacobian()`
1653438f35afSJed Brown @*/
16548434afd1SBarry Smith PetscErrorCode TSSetTransientVariable(TS ts, TSTransientVariableFn *tvar, void *ctx)
1655d71ae5a4SJacob Faibussowitsch {
1656438f35afSJed Brown   DM dm;
1657438f35afSJed Brown 
1658438f35afSJed Brown   PetscFunctionBegin;
1659438f35afSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
16609566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
16619566063dSJacob Faibussowitsch   PetscCall(DMTSSetTransientVariable(dm, tvar, ctx));
16623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1663438f35afSJed Brown }
1664438f35afSJed Brown 
1665efe9872eSLisandro Dalcin /*@
1666e3c11fc1SJed Brown   TSComputeTransientVariable - transforms state (primitive) variables to transient (conservative) variables
1667e3c11fc1SJed Brown 
1668e3c11fc1SJed Brown   Logically Collective
1669e3c11fc1SJed Brown 
1670e3c11fc1SJed Brown   Input Parameters:
1671e3c11fc1SJed Brown + ts - TS on which to compute
1672e3c11fc1SJed Brown - U  - state vector to be transformed to transient variables
1673e3c11fc1SJed Brown 
16742fe279fdSBarry Smith   Output Parameter:
1675e3c11fc1SJed Brown . C - transient (conservative) variable
1676e3c11fc1SJed Brown 
1677e3c11fc1SJed Brown   Level: developer
1678e3c11fc1SJed Brown 
1679b43aa488SJacob Faibussowitsch   Developer Notes:
1680195e9b02SBarry Smith   If `DMTSSetTransientVariable()` has not been called, then C is not modified in this routine and C = `NULL` is allowed.
1681bcf0153eSBarry Smith   This makes it safe to call without a guard.  One can use `TSHasTransientVariable()` to check if transient variables are
1682bcf0153eSBarry Smith   being used.
1683bcf0153eSBarry Smith 
16841cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSBDF`, `DMTSSetTransientVariable()`, `TSComputeIFunction()`, `TSComputeIJacobian()`
1685e3c11fc1SJed Brown @*/
1686d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeTransientVariable(TS ts, Vec U, Vec C)
1687d71ae5a4SJacob Faibussowitsch {
1688e3c11fc1SJed Brown   DM   dm;
1689e3c11fc1SJed Brown   DMTS dmts;
1690e3c11fc1SJed Brown 
1691e3c11fc1SJed Brown   PetscFunctionBegin;
1692e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1693e3c11fc1SJed Brown   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
16949566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
16959566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
1696e3c11fc1SJed Brown   if (dmts->ops->transientvar) {
1697e3c11fc1SJed Brown     PetscValidHeaderSpecific(C, VEC_CLASSID, 3);
16989566063dSJacob Faibussowitsch     PetscCall((*dmts->ops->transientvar)(ts, U, C, dmts->transientvarctx));
1699e3c11fc1SJed Brown   }
17003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1701e3c11fc1SJed Brown }
1702e3c11fc1SJed Brown 
1703e3c11fc1SJed Brown /*@
1704e3c11fc1SJed Brown   TSHasTransientVariable - determine whether transient variables have been set
1705e3c11fc1SJed Brown 
1706e3c11fc1SJed Brown   Logically Collective
1707e3c11fc1SJed Brown 
17082fe279fdSBarry Smith   Input Parameter:
1709195e9b02SBarry Smith . ts - `TS` on which to compute
1710e3c11fc1SJed Brown 
17112fe279fdSBarry Smith   Output Parameter:
1712bcf0153eSBarry Smith . has - `PETSC_TRUE` if transient variables have been set
1713e3c11fc1SJed Brown 
1714e3c11fc1SJed Brown   Level: developer
1715e3c11fc1SJed Brown 
17161cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSBDF`, `DMTSSetTransientVariable()`, `TSComputeTransientVariable()`
1717e3c11fc1SJed Brown @*/
1718d71ae5a4SJacob Faibussowitsch PetscErrorCode TSHasTransientVariable(TS ts, PetscBool *has)
1719d71ae5a4SJacob Faibussowitsch {
1720e3c11fc1SJed Brown   DM   dm;
1721e3c11fc1SJed Brown   DMTS dmts;
1722e3c11fc1SJed Brown 
1723e3c11fc1SJed Brown   PetscFunctionBegin;
1724e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
17259566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
17269566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
1727e3c11fc1SJed Brown   *has = dmts->ops->transientvar ? PETSC_TRUE : PETSC_FALSE;
17283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1729e3c11fc1SJed Brown }
1730e3c11fc1SJed Brown 
1731e3c11fc1SJed Brown /*@
1732efe9872eSLisandro Dalcin   TS2SetSolution - Sets the initial solution and time derivative vectors
1733bcf0153eSBarry Smith   for use by the `TS` routines handling second order equations.
1734efe9872eSLisandro Dalcin 
1735c3339decSBarry Smith   Logically Collective
1736efe9872eSLisandro Dalcin 
1737efe9872eSLisandro Dalcin   Input Parameters:
1738bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()`
1739efe9872eSLisandro Dalcin . u  - the solution vector
1740efe9872eSLisandro Dalcin - v  - the time derivative vector
1741efe9872eSLisandro Dalcin 
1742efe9872eSLisandro Dalcin   Level: beginner
1743efe9872eSLisandro Dalcin 
17441cc06b55SBarry Smith .seealso: [](ch_ts), `TS`
1745efe9872eSLisandro Dalcin @*/
1746d71ae5a4SJacob Faibussowitsch PetscErrorCode TS2SetSolution(TS ts, Vec u, Vec v)
1747d71ae5a4SJacob Faibussowitsch {
1748efe9872eSLisandro Dalcin   PetscFunctionBegin;
1749efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1750efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
1751efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(v, VEC_CLASSID, 3);
17529566063dSJacob Faibussowitsch   PetscCall(TSSetSolution(ts, u));
17539566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)v));
17549566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
1755efe9872eSLisandro Dalcin   ts->vec_dot = v;
17563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1757efe9872eSLisandro Dalcin }
1758efe9872eSLisandro Dalcin 
1759efe9872eSLisandro Dalcin /*@
1760efe9872eSLisandro Dalcin   TS2GetSolution - Returns the solution and time derivative at the present timestep
176114d0ab18SJacob Faibussowitsch   for second order equations.
1762efe9872eSLisandro Dalcin 
176314d0ab18SJacob Faibussowitsch   Not Collective
1764efe9872eSLisandro Dalcin 
1765efe9872eSLisandro Dalcin   Input Parameter:
1766bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
1767efe9872eSLisandro Dalcin 
1768d8d19677SJose E. Roman   Output Parameters:
1769efe9872eSLisandro Dalcin + u - the vector containing the solution
1770efe9872eSLisandro Dalcin - v - the vector containing the time derivative
1771efe9872eSLisandro Dalcin 
1772efe9872eSLisandro Dalcin   Level: intermediate
1773efe9872eSLisandro Dalcin 
177414d0ab18SJacob Faibussowitsch   Notes:
177514d0ab18SJacob Faibussowitsch   It is valid to call this routine inside the function
177614d0ab18SJacob Faibussowitsch   that you are evaluating in order to move to the new timestep. This vector not
177714d0ab18SJacob Faibussowitsch   changed until the solution at the next timestep has been calculated.
177814d0ab18SJacob Faibussowitsch 
17791cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TS2SetSolution()`, `TSGetTimeStep()`, `TSGetTime()`
1780efe9872eSLisandro Dalcin @*/
1781d71ae5a4SJacob Faibussowitsch PetscErrorCode TS2GetSolution(TS ts, Vec *u, Vec *v)
1782d71ae5a4SJacob Faibussowitsch {
1783efe9872eSLisandro Dalcin   PetscFunctionBegin;
1784efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
17854f572ea9SToby Isaac   if (u) PetscAssertPointer(u, 2);
17864f572ea9SToby Isaac   if (v) PetscAssertPointer(v, 3);
1787efe9872eSLisandro Dalcin   if (u) *u = ts->vec_sol;
1788efe9872eSLisandro Dalcin   if (v) *v = ts->vec_dot;
17893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1790efe9872eSLisandro Dalcin }
1791efe9872eSLisandro Dalcin 
1792ffeef943SBarry Smith /*@
1793bcf0153eSBarry Smith   TSLoad - Loads a `TS` that has been stored in binary  with `TSView()`.
179455849f57SBarry Smith 
1795c3339decSBarry Smith   Collective
179655849f57SBarry Smith 
179755849f57SBarry Smith   Input Parameters:
1798b43aa488SJacob Faibussowitsch + ts     - the newly loaded `TS`, this needs to have been created with `TSCreate()` or
1799bcf0153eSBarry Smith            some related function before a call to `TSLoad()`.
1800bcf0153eSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()`
180155849f57SBarry Smith 
180255849f57SBarry Smith   Level: intermediate
180355849f57SBarry Smith 
1804bcf0153eSBarry Smith   Note:
1805bcf0153eSBarry Smith   The type is determined by the data in the file, any type set into the `TS` before this call is ignored.
180655849f57SBarry Smith 
18071cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `PetscViewer`, `PetscViewerBinaryOpen()`, `TSView()`, `MatLoad()`, `VecLoad()`
180855849f57SBarry Smith @*/
1809d71ae5a4SJacob Faibussowitsch PetscErrorCode TSLoad(TS ts, PetscViewer viewer)
1810d71ae5a4SJacob Faibussowitsch {
181155849f57SBarry Smith   PetscBool isbinary;
181255849f57SBarry Smith   PetscInt  classid;
181355849f57SBarry Smith   char      type[256];
18142d53ad75SBarry Smith   DMTS      sdm;
1815ad6bc421SBarry Smith   DM        dm;
181655849f57SBarry Smith 
181755849f57SBarry Smith   PetscFunctionBegin;
1818f2c2a1b9SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
181955849f57SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
18209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
18213c633725SBarry Smith   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
182255849f57SBarry Smith 
18239566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT));
18243c633725SBarry Smith   PetscCheck(classid == TS_FILE_CLASSID, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Not TS next in file");
18259566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR));
18269566063dSJacob Faibussowitsch   PetscCall(TSSetType(ts, type));
1827dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, load, viewer);
18289566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)ts), &dm));
18299566063dSJacob Faibussowitsch   PetscCall(DMLoad(dm, viewer));
18309566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts, dm));
18319566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(ts->dm, &ts->vec_sol));
18329566063dSJacob Faibussowitsch   PetscCall(VecLoad(ts->vec_sol, viewer));
18339566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm, &sdm));
18349566063dSJacob Faibussowitsch   PetscCall(DMTSLoad(sdm, viewer));
18353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
183655849f57SBarry Smith }
183755849f57SBarry Smith 
18389804daf3SBarry Smith #include <petscdraw.h>
1839e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1840e04113cfSBarry Smith   #include <petscviewersaws.h>
1841f05ece33SBarry Smith #endif
1842fe2efc57SMark 
1843ffeef943SBarry Smith /*@
1844bcf0153eSBarry Smith   TSViewFromOptions - View a `TS` based on values in the options database
1845fe2efc57SMark 
1846c3339decSBarry Smith   Collective
1847fe2efc57SMark 
1848fe2efc57SMark   Input Parameters:
1849bcf0153eSBarry Smith + ts   - the `TS` context
1850bcf0153eSBarry Smith . obj  - Optional object that provides the prefix for the options database keys
1851bcf0153eSBarry Smith - name - command line option string to be passed by user
1852fe2efc57SMark 
1853fe2efc57SMark   Level: intermediate
1854bcf0153eSBarry Smith 
18551cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSView`, `PetscObjectViewFromOptions()`, `TSCreate()`
1856fe2efc57SMark @*/
1857bcf0153eSBarry Smith PetscErrorCode TSViewFromOptions(TS ts, PetscObject obj, const char name[])
1858d71ae5a4SJacob Faibussowitsch {
1859fe2efc57SMark   PetscFunctionBegin;
1860bcf0153eSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1861bcf0153eSBarry Smith   PetscCall(PetscObjectViewFromOptions((PetscObject)ts, obj, name));
18623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1863fe2efc57SMark }
1864fe2efc57SMark 
1865ffeef943SBarry Smith /*@
1866bcf0153eSBarry Smith   TSView - Prints the `TS` data structure.
1867d763cef2SBarry Smith 
1868c3339decSBarry Smith   Collective
1869d763cef2SBarry Smith 
1870d763cef2SBarry Smith   Input Parameters:
1871bcf0153eSBarry Smith + ts     - the `TS` context obtained from `TSCreate()`
1872d763cef2SBarry Smith - viewer - visualization context
1873d763cef2SBarry Smith 
1874d763cef2SBarry Smith   Options Database Key:
1875bcf0153eSBarry Smith . -ts_view - calls `TSView()` at end of `TSStep()`
1876bcf0153eSBarry Smith 
1877bcf0153eSBarry Smith   Level: beginner
1878d763cef2SBarry Smith 
1879d763cef2SBarry Smith   Notes:
1880d763cef2SBarry Smith   The available visualization contexts include
1881bcf0153eSBarry Smith +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
1882bcf0153eSBarry Smith -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
1883d763cef2SBarry Smith   output where only the first processor opens
1884d763cef2SBarry Smith   the file.  All other processors send their
1885d763cef2SBarry Smith   data to the first processor to print.
1886d763cef2SBarry Smith 
1887d763cef2SBarry Smith   The user can open an alternative visualization context with
1888bcf0153eSBarry Smith   `PetscViewerASCIIOpen()` - output to a specified file.
1889d763cef2SBarry Smith 
1890bcf0153eSBarry Smith   In the debugger you can do call `TSView`(ts,0) to display the `TS` solver. (The same holds for any PETSc object viewer).
1891595c91d4SBarry Smith 
1892*188af4bfSBarry Smith   The "initial time step" displayed is the default time step from `TSCreate()` or that set with `TSSetTimeStep()` or `-ts_time_step`
1893*188af4bfSBarry Smith 
18941cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `PetscViewer`, `PetscViewerASCIIOpen()`
1895d763cef2SBarry Smith @*/
1896d71ae5a4SJacob Faibussowitsch PetscErrorCode TSView(TS ts, PetscViewer viewer)
1897d71ae5a4SJacob Faibussowitsch {
189819fd82e9SBarry Smith   TSType    type;
18999f196a02SMartin Diehl   PetscBool isascii, isstring, issundials, isbinary, isdraw;
19002d53ad75SBarry Smith   DMTS      sdm;
1901e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1902536b137fSBarry Smith   PetscBool issaws;
1903f05ece33SBarry Smith #endif
1904d763cef2SBarry Smith 
1905d763cef2SBarry Smith   PetscFunctionBegin;
19060700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
19071e66621cSBarry Smith   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts), &viewer));
19080700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1909c9780b6fSBarry Smith   PetscCheckSameComm(ts, 1, viewer, 2);
1910fd16b177SBarry Smith 
19119f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
19129566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
19139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
19149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
1915e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
19169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
1917f05ece33SBarry Smith #endif
19189f196a02SMartin Diehl   if (isascii) {
19199566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ts, viewer));
1920efd4aadfSBarry Smith     if (ts->ops->view) {
19219566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1922dbbe0bcdSBarry Smith       PetscUseTypeMethod(ts, view, viewer);
19239566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
1924efd4aadfSBarry Smith     }
1925*188af4bfSBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  initial time step=%g\n", (double)ts->initial_time_step));
19261690c2aeSBarry Smith     if (ts->max_steps < PETSC_INT_MAX) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum steps=%" PetscInt_FMT "\n", ts->max_steps));
19278e562f8dSJames Wright     if (ts->run_steps < PETSC_INT_MAX) PetscCall(PetscViewerASCIIPrintf(viewer, "  run steps=%" PetscInt_FMT "\n", ts->run_steps));
19281e66621cSBarry Smith     if (ts->max_time < PETSC_MAX_REAL) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum time=%g\n", (double)ts->max_time));
1929*188af4bfSBarry Smith     if (ts->max_reject != PETSC_UNLIMITED) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum number of step rejections=%" PetscInt_FMT "\n", ts->max_reject));
1930*188af4bfSBarry Smith     if (ts->max_snes_failures != PETSC_UNLIMITED) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum number of SNES failures allowed=%" PetscInt_FMT "\n", ts->max_snes_failures));
19311e66621cSBarry Smith     if (ts->ifuncs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of I function evaluations=%" PetscInt_FMT "\n", ts->ifuncs));
19321e66621cSBarry Smith     if (ts->ijacs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of I Jacobian evaluations=%" PetscInt_FMT "\n", ts->ijacs));
19331e66621cSBarry Smith     if (ts->rhsfuncs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of RHS function evaluations=%" PetscInt_FMT "\n", ts->rhsfuncs));
19341e66621cSBarry Smith     if (ts->rhsjacs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of RHS Jacobian evaluations=%" PetscInt_FMT "\n", ts->rhsjacs));
1935efd4aadfSBarry Smith     if (ts->usessnes) {
1936efd4aadfSBarry Smith       PetscBool lin;
19371e66621cSBarry Smith       if (ts->problem_type == TS_NONLINEAR) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of nonlinear solver iterations=%" PetscInt_FMT "\n", ts->snes_its));
193863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of linear solver iterations=%" PetscInt_FMT "\n", ts->ksp_its));
19399566063dSJacob Faibussowitsch       PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes, &lin, SNESKSPONLY, SNESKSPTRANSPOSEONLY, ""));
194063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of %slinear solve failures=%" PetscInt_FMT "\n", lin ? "" : "non", ts->num_snes_failures));
1941efd4aadfSBarry Smith     }
194263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of rejected steps=%" PetscInt_FMT "\n", ts->reject));
19431e66621cSBarry Smith     if (ts->vrtol) PetscCall(PetscViewerASCIIPrintf(viewer, "  using vector of relative error tolerances, "));
19441e66621cSBarry Smith     else PetscCall(PetscViewerASCIIPrintf(viewer, "  using relative error tolerance of %g, ", (double)ts->rtol));
19451e66621cSBarry Smith     if (ts->vatol) PetscCall(PetscViewerASCIIPrintf(viewer, "using vector of absolute error tolerances\n"));
19461e66621cSBarry Smith     else PetscCall(PetscViewerASCIIPrintf(viewer, "using absolute error tolerance of %g\n", (double)ts->atol));
19479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
19489566063dSJacob Faibussowitsch     PetscCall(TSAdaptView(ts->adapt, viewer));
19499566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
19500f5bd95cSBarry Smith   } else if (isstring) {
19519566063dSJacob Faibussowitsch     PetscCall(TSGetType(ts, &type));
19529566063dSJacob Faibussowitsch     PetscCall(PetscViewerStringSPrintf(viewer, " TSType: %-7.7s", type));
1953dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
195455849f57SBarry Smith   } else if (isbinary) {
195555849f57SBarry Smith     PetscInt    classid = TS_FILE_CLASSID;
195655849f57SBarry Smith     MPI_Comm    comm;
195755849f57SBarry Smith     PetscMPIInt rank;
195855849f57SBarry Smith     char        type[256];
195955849f57SBarry Smith 
19609566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
19619566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
1962dd400576SPatrick Sanan     if (rank == 0) {
19639566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
19649566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(type, ((PetscObject)ts)->type_name, 256));
19659566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, type, 256, PETSC_CHAR));
196655849f57SBarry Smith     }
1967dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
19689566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt, viewer));
19699566063dSJacob Faibussowitsch     PetscCall(DMView(ts->dm, viewer));
19709566063dSJacob Faibussowitsch     PetscCall(VecView(ts->vec_sol, viewer));
19719566063dSJacob Faibussowitsch     PetscCall(DMGetDMTS(ts->dm, &sdm));
19729566063dSJacob Faibussowitsch     PetscCall(DMTSView(sdm, viewer));
19732b0a91c0SBarry Smith   } else if (isdraw) {
19742b0a91c0SBarry Smith     PetscDraw draw;
19752b0a91c0SBarry Smith     char      str[36];
197689fd9fafSBarry Smith     PetscReal x, y, bottom, h;
19772b0a91c0SBarry Smith 
19789566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
19799566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y));
1980c6a7a370SJeremy L Thompson     PetscCall(PetscStrncpy(str, "TS: ", sizeof(str)));
1981c6a7a370SJeremy L Thompson     PetscCall(PetscStrlcat(str, ((PetscObject)ts)->type_name, sizeof(str)));
19829566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLACK, PETSC_DRAW_BLACK, str, NULL, &h));
198389fd9fafSBarry Smith     bottom = y - h;
19849566063dSJacob Faibussowitsch     PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom));
1985dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
19869566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt, viewer));
19879566063dSJacob Faibussowitsch     if (ts->snes) PetscCall(SNESView(ts->snes, viewer));
19889566063dSJacob Faibussowitsch     PetscCall(PetscDrawPopCurrentPoint(draw));
1989e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1990536b137fSBarry Smith   } else if (issaws) {
1991d45a07a7SBarry Smith     PetscMPIInt rank;
19922657e9d9SBarry Smith     const char *name;
19932657e9d9SBarry Smith 
19949566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)ts, &name));
19959566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
1996dd400576SPatrick Sanan     if (!((PetscObject)ts)->amsmem && rank == 0) {
1997d45a07a7SBarry Smith       char dir[1024];
1998d45a07a7SBarry Smith 
19999566063dSJacob Faibussowitsch       PetscCall(PetscObjectViewSAWs((PetscObject)ts, viewer));
20009566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/time_step", name));
2001792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, &ts->steps, 1, SAWs_READ, SAWs_INT));
20029566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/time", name));
2003792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, &ts->ptime, 1, SAWs_READ, SAWs_DOUBLE));
2004d763cef2SBarry Smith     }
2005dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
2006f05ece33SBarry Smith #endif
2007f05ece33SBarry Smith   }
200836a9e3b9SBarry Smith   if (ts->snes && ts->usessnes) {
20099566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
20109566063dSJacob Faibussowitsch     PetscCall(SNESView(ts->snes, viewer));
20119566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
201236a9e3b9SBarry Smith   }
20139566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm, &sdm));
20149566063dSJacob Faibussowitsch   PetscCall(DMTSView(sdm, viewer));
2015f05ece33SBarry Smith 
20169566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
20179f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)ts, TSSUNDIALS, &issundials));
20189566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
20193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2020d763cef2SBarry Smith }
2021d763cef2SBarry Smith 
2022b07ff414SBarry Smith /*@
2023ce78bad3SBarry Smith   TSSetApplicationContext - Sets an optional user-defined context for the timesteppers that may be accessed, for example inside the user provided
2024ce78bad3SBarry Smith   `TS` callbacks with `TSGetApplicationContext()`
2025d763cef2SBarry Smith 
2026c3339decSBarry Smith   Logically Collective
2027d763cef2SBarry Smith 
2028d763cef2SBarry Smith   Input Parameters:
2029bcf0153eSBarry Smith + ts  - the `TS` context obtained from `TSCreate()`
203049abdd8aSBarry Smith - ctx - user context
2031daf670e6SBarry Smith 
2032d763cef2SBarry Smith   Level: intermediate
2033d763cef2SBarry Smith 
2034ce78bad3SBarry Smith   Fortran Note:
2035ce78bad3SBarry Smith   This only works when `ctx` is a Fortran derived type (it cannot be a `PetscObject`), we recommend writing a Fortran interface definition for this
2036ce78bad3SBarry Smith   function that tells the Fortran compiler the derived data type that is passed in as the `ctx` argument. See `TSGetApplicationContext()` for
2037ce78bad3SBarry Smith   an example.
2038bcf0153eSBarry Smith 
20391cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetApplicationContext()`
2040d763cef2SBarry Smith @*/
2041ce78bad3SBarry Smith PetscErrorCode TSSetApplicationContext(TS ts, PeCtx ctx)
2042d71ae5a4SJacob Faibussowitsch {
2043d763cef2SBarry Smith   PetscFunctionBegin;
20440700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
204549abdd8aSBarry Smith   ts->ctx = ctx;
20463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2047d763cef2SBarry Smith }
2048d763cef2SBarry Smith 
2049b07ff414SBarry Smith /*@
2050d763cef2SBarry Smith   TSGetApplicationContext - Gets the user-defined context for the
2051bcf0153eSBarry Smith   timestepper that was set with `TSSetApplicationContext()`
2052d763cef2SBarry Smith 
2053d763cef2SBarry Smith   Not Collective
2054d763cef2SBarry Smith 
2055d763cef2SBarry Smith   Input Parameter:
2056bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2057d763cef2SBarry Smith 
2058d763cef2SBarry Smith   Output Parameter:
2059ce78bad3SBarry Smith . ctx - a pointer to the user context
2060d763cef2SBarry Smith 
2061bcf0153eSBarry Smith   Level: intermediate
2062bcf0153eSBarry Smith 
2063b43aa488SJacob Faibussowitsch   Fortran Notes:
2064ce78bad3SBarry Smith   This only works when the context is a Fortran derived type (it cannot be a `PetscObject`) and you **must** write a Fortran interface definition for this
2065ce78bad3SBarry Smith   function that tells the Fortran compiler the derived data type that is returned as the `ctx` argument. For example,
2066ce78bad3SBarry Smith .vb
2067ce78bad3SBarry Smith   Interface TSGetApplicationContext
2068ce78bad3SBarry Smith     Subroutine TSGetApplicationContext(ts,ctx,ierr)
2069ce78bad3SBarry Smith   #include <petsc/finclude/petscts.h>
2070ce78bad3SBarry Smith       use petscts
2071ce78bad3SBarry Smith       TS ts
2072ce78bad3SBarry Smith       type(tUsertype), pointer :: ctx
2073ce78bad3SBarry Smith       PetscErrorCode ierr
2074ce78bad3SBarry Smith     End Subroutine
2075ce78bad3SBarry Smith   End Interface TSGetApplicationContext
2076ce78bad3SBarry Smith .ve
2077ce78bad3SBarry Smith 
2078bfe80ac4SPierre Jolivet   The prototype for `ctx` must be
2079ce78bad3SBarry Smith .vb
2080ce78bad3SBarry Smith   type(tUsertype), pointer :: ctx
2081ce78bad3SBarry Smith .ve
2082daf670e6SBarry Smith 
20831cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetApplicationContext()`
2084d763cef2SBarry Smith @*/
208549abdd8aSBarry Smith PetscErrorCode TSGetApplicationContext(TS ts, void *ctx)
2086d71ae5a4SJacob Faibussowitsch {
2087d763cef2SBarry Smith   PetscFunctionBegin;
20880700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
208949abdd8aSBarry Smith   *(void **)ctx = ts->ctx;
20903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2091d763cef2SBarry Smith }
2092d763cef2SBarry Smith 
2093d763cef2SBarry Smith /*@
2094bcf0153eSBarry Smith   TSGetStepNumber - Gets the number of time steps completed.
2095d763cef2SBarry Smith 
2096d763cef2SBarry Smith   Not Collective
2097d763cef2SBarry Smith 
2098d763cef2SBarry Smith   Input Parameter:
2099bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2100d763cef2SBarry Smith 
2101d763cef2SBarry Smith   Output Parameter:
210280275a0aSLisandro Dalcin . steps - number of steps completed so far
2103d763cef2SBarry Smith 
2104d763cef2SBarry Smith   Level: intermediate
2105d763cef2SBarry Smith 
21061cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetTime()`, `TSGetTimeStep()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`
2107d763cef2SBarry Smith @*/
2108d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetStepNumber(TS ts, PetscInt *steps)
2109d71ae5a4SJacob Faibussowitsch {
2110d763cef2SBarry Smith   PetscFunctionBegin;
21110700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
21124f572ea9SToby Isaac   PetscAssertPointer(steps, 2);
211380275a0aSLisandro Dalcin   *steps = ts->steps;
21143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
211580275a0aSLisandro Dalcin }
211680275a0aSLisandro Dalcin 
211780275a0aSLisandro Dalcin /*@
211880275a0aSLisandro Dalcin   TSSetStepNumber - Sets the number of steps completed.
211980275a0aSLisandro Dalcin 
2120c3339decSBarry Smith   Logically Collective
212180275a0aSLisandro Dalcin 
212280275a0aSLisandro Dalcin   Input Parameters:
2123bcf0153eSBarry Smith + ts    - the `TS` context
212480275a0aSLisandro Dalcin - steps - number of steps completed so far
212580275a0aSLisandro Dalcin 
2126bcf0153eSBarry Smith   Level: developer
2127bcf0153eSBarry Smith 
2128bcf0153eSBarry Smith   Note:
2129bcf0153eSBarry Smith   For most uses of the `TS` solvers the user need not explicitly call
2130bcf0153eSBarry Smith   `TSSetStepNumber()`, as the step counter is appropriately updated in
2131bcf0153eSBarry Smith   `TSSolve()`/`TSStep()`/`TSRollBack()`. Power users may call this routine to
213280275a0aSLisandro Dalcin   reinitialize timestepping by setting the step counter to zero (and time
213380275a0aSLisandro Dalcin   to the initial time) to solve a similar problem with different initial
213480275a0aSLisandro Dalcin   conditions or parameters. Other possible use case is to continue
2135195e9b02SBarry Smith   timestepping from a previously interrupted run in such a way that `TS`
213680275a0aSLisandro Dalcin   monitors will be called with a initial nonzero step counter.
213780275a0aSLisandro Dalcin 
21381cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetStepNumber()`, `TSSetTime()`, `TSSetTimeStep()`, `TSSetSolution()`
213980275a0aSLisandro Dalcin @*/
2140d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetStepNumber(TS ts, PetscInt steps)
2141d71ae5a4SJacob Faibussowitsch {
214280275a0aSLisandro Dalcin   PetscFunctionBegin;
214380275a0aSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
214480275a0aSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts, steps, 2);
21453c633725SBarry Smith   PetscCheck(steps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Step number must be non-negative");
214680275a0aSLisandro Dalcin   ts->steps = steps;
21473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2148d763cef2SBarry Smith }
2149d763cef2SBarry Smith 
2150d763cef2SBarry Smith /*@
2151*188af4bfSBarry Smith   TSSetTimeStep - Allows one to reset the timestep at any time.
2152d763cef2SBarry Smith 
2153c3339decSBarry Smith   Logically Collective
2154d763cef2SBarry Smith 
2155d763cef2SBarry Smith   Input Parameters:
2156bcf0153eSBarry Smith + ts        - the `TS` context obtained from `TSCreate()`
2157d763cef2SBarry Smith - time_step - the size of the timestep
2158d763cef2SBarry Smith 
2159*188af4bfSBarry Smith   Options Database Key:
2160*188af4bfSBarry Smith . -ts_time_step <dt> - provide the initial time step
2161*188af4bfSBarry Smith 
2162d763cef2SBarry Smith   Level: intermediate
2163d763cef2SBarry Smith 
2164*188af4bfSBarry Smith   Notes:
2165*188af4bfSBarry Smith   This is only a suggestion, the actual initial time step used may differ
2166*188af4bfSBarry Smith 
2167*188af4bfSBarry Smith   If this is called after `TSSetUp()`, it will not change the initial time step value printed by `TSView()`
2168*188af4bfSBarry Smith 
21691cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSPSEUDO`, `TSGetTimeStep()`, `TSSetTime()`
2170d763cef2SBarry Smith @*/
2171d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTimeStep(TS ts, PetscReal time_step)
2172d71ae5a4SJacob Faibussowitsch {
2173d763cef2SBarry Smith   PetscFunctionBegin;
21740700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2175c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts, time_step, 2);
2176d763cef2SBarry Smith   ts->time_step = time_step;
2177*188af4bfSBarry Smith   if (ts->setupcalled == PETSC_FALSE) ts->initial_time_step = time_step;
21783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2179d763cef2SBarry Smith }
2180d763cef2SBarry Smith 
2181a43b19c4SJed Brown /*@
218249354f04SShri Abhyankar   TSSetExactFinalTime - Determines whether to adapt the final time step to
21830b4b7b1cSBarry Smith   match the exact final time, to interpolate the solution to the exact final time,
21840b4b7b1cSBarry Smith   or to just return at the final time `TS` computed (which may be slightly larger
21850b4b7b1cSBarry Smith   than the requested final time).
2186a43b19c4SJed Brown 
2187c3339decSBarry Smith   Logically Collective
2188a43b19c4SJed Brown 
2189d8d19677SJose E. Roman   Input Parameters:
2190a43b19c4SJed Brown + ts     - the time-step context
219149354f04SShri Abhyankar - eftopt - exact final time option
2192bcf0153eSBarry Smith .vb
21930b4b7b1cSBarry Smith   TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded, just use it
21940b4b7b1cSBarry Smith   TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time if the final time is exceeded
21950b4b7b1cSBarry Smith   TS_EXACTFINALTIME_MATCHSTEP   - Adapt final time step to ensure the computed final time exactly equals the requested final time
2196bcf0153eSBarry Smith .ve
2197a43b19c4SJed Brown 
2198bcf0153eSBarry Smith   Options Database Key:
21990b4b7b1cSBarry Smith . -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step approach at runtime
2200feed9e9dSBarry Smith 
2201a43b19c4SJed Brown   Level: beginner
2202a43b19c4SJed Brown 
2203bcf0153eSBarry Smith   Note:
2204bcf0153eSBarry Smith   If you use the option `TS_EXACTFINALTIME_STEPOVER` the solution may be at a very different time
2205bcf0153eSBarry Smith   then the final time you selected.
2206bcf0153eSBarry Smith 
22071cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSExactFinalTimeOption`, `TSGetExactFinalTime()`
2208a43b19c4SJed Brown @*/
2209d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetExactFinalTime(TS ts, TSExactFinalTimeOption eftopt)
2210d71ae5a4SJacob Faibussowitsch {
2211a43b19c4SJed Brown   PetscFunctionBegin;
2212a43b19c4SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
221349354f04SShri Abhyankar   PetscValidLogicalCollectiveEnum(ts, eftopt, 2);
221449354f04SShri Abhyankar   ts->exact_final_time = eftopt;
22153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2216a43b19c4SJed Brown }
2217a43b19c4SJed Brown 
2218d763cef2SBarry Smith /*@
2219bcf0153eSBarry Smith   TSGetExactFinalTime - Gets the exact final time option set with `TSSetExactFinalTime()`
2220f6953c82SLisandro Dalcin 
2221f6953c82SLisandro Dalcin   Not Collective
2222f6953c82SLisandro Dalcin 
2223f6953c82SLisandro Dalcin   Input Parameter:
2224bcf0153eSBarry Smith . ts - the `TS` context
2225f6953c82SLisandro Dalcin 
2226f6953c82SLisandro Dalcin   Output Parameter:
2227f6953c82SLisandro Dalcin . eftopt - exact final time option
2228f6953c82SLisandro Dalcin 
2229f6953c82SLisandro Dalcin   Level: beginner
2230f6953c82SLisandro Dalcin 
22311cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSExactFinalTimeOption`, `TSSetExactFinalTime()`
2232f6953c82SLisandro Dalcin @*/
2233d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetExactFinalTime(TS ts, TSExactFinalTimeOption *eftopt)
2234d71ae5a4SJacob Faibussowitsch {
2235f6953c82SLisandro Dalcin   PetscFunctionBegin;
2236f6953c82SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
22374f572ea9SToby Isaac   PetscAssertPointer(eftopt, 2);
2238f6953c82SLisandro Dalcin   *eftopt = ts->exact_final_time;
22393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2240f6953c82SLisandro Dalcin }
2241f6953c82SLisandro Dalcin 
2242f6953c82SLisandro Dalcin /*@
2243d763cef2SBarry Smith   TSGetTimeStep - Gets the current timestep size.
2244d763cef2SBarry Smith 
2245d763cef2SBarry Smith   Not Collective
2246d763cef2SBarry Smith 
2247d763cef2SBarry Smith   Input Parameter:
2248bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2249d763cef2SBarry Smith 
2250d763cef2SBarry Smith   Output Parameter:
2251d763cef2SBarry Smith . dt - the current timestep size
2252d763cef2SBarry Smith 
2253d763cef2SBarry Smith   Level: intermediate
2254d763cef2SBarry Smith 
22551cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetTimeStep()`, `TSGetTime()`
2256d763cef2SBarry Smith @*/
2257d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeStep(TS ts, PetscReal *dt)
2258d71ae5a4SJacob Faibussowitsch {
2259d763cef2SBarry Smith   PetscFunctionBegin;
22600700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
22614f572ea9SToby Isaac   PetscAssertPointer(dt, 2);
2262d763cef2SBarry Smith   *dt = ts->time_step;
22633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2264d763cef2SBarry Smith }
2265d763cef2SBarry Smith 
2266d8e5e3e6SSatish Balay /*@
2267d763cef2SBarry Smith   TSGetSolution - Returns the solution at the present timestep. It
2268d763cef2SBarry Smith   is valid to call this routine inside the function that you are evaluating
2269d763cef2SBarry Smith   in order to move to the new timestep. This vector not changed until
2270d763cef2SBarry Smith   the solution at the next timestep has been calculated.
2271d763cef2SBarry Smith 
2272bcf0153eSBarry Smith   Not Collective, but v returned is parallel if ts is parallel
2273d763cef2SBarry Smith 
2274d763cef2SBarry Smith   Input Parameter:
2275bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2276d763cef2SBarry Smith 
2277d763cef2SBarry Smith   Output Parameter:
2278d763cef2SBarry Smith . v - the vector containing the solution
2279d763cef2SBarry Smith 
2280d763cef2SBarry Smith   Level: intermediate
2281d763cef2SBarry Smith 
2282bcf0153eSBarry Smith   Note:
2283bcf0153eSBarry Smith   If you used `TSSetExactFinalTime`(ts,`TS_EXACTFINALTIME_MATCHSTEP`); this does not return the solution at the requested
2284bcf0153eSBarry Smith   final time. It returns the solution at the next timestep.
2285d763cef2SBarry Smith 
22861cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetTimeStep()`, `TSGetTime()`, `TSGetSolveTime()`, `TSGetSolutionComponents()`, `TSSetSolutionFunction()`
2287d763cef2SBarry Smith @*/
2288d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSolution(TS ts, Vec *v)
2289d71ae5a4SJacob Faibussowitsch {
2290d763cef2SBarry Smith   PetscFunctionBegin;
22910700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
22924f572ea9SToby Isaac   PetscAssertPointer(v, 2);
22938737fe31SLisandro Dalcin   *v = ts->vec_sol;
22943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2295d763cef2SBarry Smith }
2296d763cef2SBarry Smith 
229703fe5f5eSDebojyoti Ghosh /*@
2298b2bf4f3aSDebojyoti Ghosh   TSGetSolutionComponents - Returns any solution components at the present
229903fe5f5eSDebojyoti Ghosh   timestep, if available for the time integration method being used.
2300b2bf4f3aSDebojyoti Ghosh   Solution components are quantities that share the same size and
230103fe5f5eSDebojyoti Ghosh   structure as the solution vector.
230203fe5f5eSDebojyoti Ghosh 
2303bcf0153eSBarry Smith   Not Collective, but v returned is parallel if ts is parallel
230403fe5f5eSDebojyoti Ghosh 
2305b43aa488SJacob Faibussowitsch   Input Parameters:
2306bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` (input parameter).
2307195e9b02SBarry Smith . n  - If v is `NULL`, then the number of solution components is
2308b2bf4f3aSDebojyoti Ghosh        returned through n, else the n-th solution component is
230903fe5f5eSDebojyoti Ghosh        returned in v.
2310a2b725a8SWilliam Gropp - v  - the vector containing the n-th solution component
2311195e9b02SBarry Smith        (may be `NULL` to use this function to find out
2312b2bf4f3aSDebojyoti Ghosh         the number of solutions components).
231303fe5f5eSDebojyoti Ghosh 
23144cdd57e5SDebojyoti Ghosh   Level: advanced
231503fe5f5eSDebojyoti Ghosh 
23161cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetSolution()`
231703fe5f5eSDebojyoti Ghosh @*/
2318d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSolutionComponents(TS ts, PetscInt *n, Vec *v)
2319d71ae5a4SJacob Faibussowitsch {
232003fe5f5eSDebojyoti Ghosh   PetscFunctionBegin;
232103fe5f5eSDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2322b2bf4f3aSDebojyoti Ghosh   if (!ts->ops->getsolutioncomponents) *n = 0;
2323dbbe0bcdSBarry Smith   else PetscUseTypeMethod(ts, getsolutioncomponents, n, v);
23243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
232503fe5f5eSDebojyoti Ghosh }
232603fe5f5eSDebojyoti Ghosh 
23274cdd57e5SDebojyoti Ghosh /*@
23284cdd57e5SDebojyoti Ghosh   TSGetAuxSolution - Returns an auxiliary solution at the present
23294cdd57e5SDebojyoti Ghosh   timestep, if available for the time integration method being used.
23304cdd57e5SDebojyoti Ghosh 
2331bcf0153eSBarry Smith   Not Collective, but v returned is parallel if ts is parallel
23324cdd57e5SDebojyoti Ghosh 
2333b43aa488SJacob Faibussowitsch   Input Parameters:
2334bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` (input parameter).
2335a2b725a8SWilliam Gropp - v  - the vector containing the auxiliary solution
23364cdd57e5SDebojyoti Ghosh 
23374cdd57e5SDebojyoti Ghosh   Level: intermediate
23384cdd57e5SDebojyoti Ghosh 
23391cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetSolution()`
23404cdd57e5SDebojyoti Ghosh @*/
2341d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetAuxSolution(TS ts, Vec *v)
2342d71ae5a4SJacob Faibussowitsch {
23434cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
23444cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2345dbbe0bcdSBarry Smith   if (ts->ops->getauxsolution) PetscUseTypeMethod(ts, getauxsolution, v);
23461e66621cSBarry Smith   else PetscCall(VecZeroEntries(*v));
23473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23484cdd57e5SDebojyoti Ghosh }
23494cdd57e5SDebojyoti Ghosh 
23504cdd57e5SDebojyoti Ghosh /*@
23514cdd57e5SDebojyoti Ghosh   TSGetTimeError - Returns the estimated error vector, if the chosen
2352bcf0153eSBarry Smith   `TSType` has an error estimation functionality and `TSSetTimeError()` was called
23534cdd57e5SDebojyoti Ghosh 
2354bcf0153eSBarry Smith   Not Collective, but v returned is parallel if ts is parallel
23559657682dSDebojyoti Ghosh 
2356b43aa488SJacob Faibussowitsch   Input Parameters:
2357bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` (input parameter).
2358657c1e31SEmil Constantinescu . n  - current estimate (n=0) or previous one (n=-1)
2359a2b725a8SWilliam Gropp - v  - the vector containing the error (same size as the solution).
23604cdd57e5SDebojyoti Ghosh 
23614cdd57e5SDebojyoti Ghosh   Level: intermediate
23624cdd57e5SDebojyoti Ghosh 
2363bcf0153eSBarry Smith   Note:
2364bcf0153eSBarry Smith   MUST call after `TSSetUp()`
23654cdd57e5SDebojyoti Ghosh 
23661cc06b55SBarry Smith .seealso: [](ch_ts), `TSGetSolution()`, `TSSetTimeError()`
23674cdd57e5SDebojyoti Ghosh @*/
2368d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeError(TS ts, PetscInt n, Vec *v)
2369d71ae5a4SJacob Faibussowitsch {
23704cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
23714cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2372dbbe0bcdSBarry Smith   if (ts->ops->gettimeerror) PetscUseTypeMethod(ts, gettimeerror, n, v);
23731e66621cSBarry Smith   else PetscCall(VecZeroEntries(*v));
23743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23754cdd57e5SDebojyoti Ghosh }
23764cdd57e5SDebojyoti Ghosh 
237757df6a1bSDebojyoti Ghosh /*@
237857df6a1bSDebojyoti Ghosh   TSSetTimeError - Sets the estimated error vector, if the chosen
2379bcf0153eSBarry Smith   `TSType` has an error estimation functionality. This can be used
238057df6a1bSDebojyoti Ghosh   to restart such a time integrator with a given error vector.
238157df6a1bSDebojyoti Ghosh 
2382bcf0153eSBarry Smith   Not Collective, but v returned is parallel if ts is parallel
238357df6a1bSDebojyoti Ghosh 
2384b43aa488SJacob Faibussowitsch   Input Parameters:
2385bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()` (input parameter).
2386a2b725a8SWilliam Gropp - v  - the vector containing the error (same size as the solution).
238757df6a1bSDebojyoti Ghosh 
238857df6a1bSDebojyoti Ghosh   Level: intermediate
238957df6a1bSDebojyoti Ghosh 
2390b43aa488SJacob Faibussowitsch .seealso: [](ch_ts), `TS`, `TSSetSolution()`, `TSGetTimeError()`
239157df6a1bSDebojyoti Ghosh @*/
2392d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTimeError(TS ts, Vec v)
2393d71ae5a4SJacob Faibussowitsch {
239457df6a1bSDebojyoti Ghosh   PetscFunctionBegin;
239557df6a1bSDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
23963c633725SBarry Smith   PetscCheck(ts->setupcalled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetUp() first");
2397dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, settimeerror, v);
23983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
239957df6a1bSDebojyoti Ghosh }
240057df6a1bSDebojyoti Ghosh 
2401bdad233fSMatthew Knepley /* ----- Routines to initialize and destroy a timestepper ---- */
2402d8e5e3e6SSatish Balay /*@
2403bdad233fSMatthew Knepley   TSSetProblemType - Sets the type of problem to be solved.
2404d763cef2SBarry Smith 
2405bdad233fSMatthew Knepley   Not collective
2406d763cef2SBarry Smith 
2407bdad233fSMatthew Knepley   Input Parameters:
2408bcf0153eSBarry Smith + ts   - The `TS`
2409bcf0153eSBarry Smith - type - One of `TS_LINEAR`, `TS_NONLINEAR` where these types refer to problems of the forms
2410d763cef2SBarry Smith .vb
24110910c330SBarry Smith          U_t - A U = 0      (linear)
24120910c330SBarry Smith          U_t - A(t) U = 0   (linear)
24130910c330SBarry Smith          F(t,U,U_t) = 0     (nonlinear)
2414d763cef2SBarry Smith .ve
2415d763cef2SBarry Smith 
2416d763cef2SBarry Smith   Level: beginner
2417d763cef2SBarry Smith 
24181cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetUp()`, `TSProblemType`, `TS`
2419d763cef2SBarry Smith @*/
2420d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetProblemType(TS ts, TSProblemType type)
2421d71ae5a4SJacob Faibussowitsch {
2422d763cef2SBarry Smith   PetscFunctionBegin;
24230700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2424bdad233fSMatthew Knepley   ts->problem_type = type;
24259e2a6581SJed Brown   if (type == TS_LINEAR) {
24269e2a6581SJed Brown     SNES snes;
24279566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
24289566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes, SNESKSPONLY));
24299e2a6581SJed Brown   }
24303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2431d763cef2SBarry Smith }
2432d763cef2SBarry Smith 
2433cc4c1da9SBarry Smith /*@
2434bdad233fSMatthew Knepley   TSGetProblemType - Gets the type of problem to be solved.
2435bdad233fSMatthew Knepley 
2436bdad233fSMatthew Knepley   Not collective
2437bdad233fSMatthew Knepley 
2438bdad233fSMatthew Knepley   Input Parameter:
2439bcf0153eSBarry Smith . ts - The `TS`
2440bdad233fSMatthew Knepley 
2441bdad233fSMatthew Knepley   Output Parameter:
2442bcf0153eSBarry Smith . type - One of `TS_LINEAR`, `TS_NONLINEAR` where these types refer to problems of the forms
2443bdad233fSMatthew Knepley .vb
2444089b2837SJed Brown          M U_t = A U
2445089b2837SJed Brown          M(t) U_t = A(t) U
2446b5abc632SBarry Smith          F(t,U,U_t)
2447bdad233fSMatthew Knepley .ve
2448bdad233fSMatthew Knepley 
2449bdad233fSMatthew Knepley   Level: beginner
2450bdad233fSMatthew Knepley 
24511cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetUp()`, `TSProblemType`, `TS`
2452bdad233fSMatthew Knepley @*/
2453d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type)
2454d71ae5a4SJacob Faibussowitsch {
2455bdad233fSMatthew Knepley   PetscFunctionBegin;
24560700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
24574f572ea9SToby Isaac   PetscAssertPointer(type, 2);
2458bdad233fSMatthew Knepley   *type = ts->problem_type;
24593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2460bdad233fSMatthew Knepley }
2461d763cef2SBarry Smith 
2462303a5415SBarry Smith /*
2463303a5415SBarry Smith     Attempt to check/preset a default value for the exact final time option. This is needed at the beginning of TSSolve() and in TSSetUp()
2464303a5415SBarry Smith */
2465d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetExactFinalTimeDefault(TS ts)
2466d71ae5a4SJacob Faibussowitsch {
2467303a5415SBarry Smith   PetscBool isnone;
2468303a5415SBarry Smith 
2469303a5415SBarry Smith   PetscFunctionBegin;
24709566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
24719566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
2472303a5415SBarry Smith 
24739566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ts->adapt, TSADAPTNONE, &isnone));
24741e66621cSBarry Smith   if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP;
24751e66621cSBarry Smith   else if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) ts->exact_final_time = TS_EXACTFINALTIME_INTERPOLATE;
24763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2477303a5415SBarry Smith }
2478303a5415SBarry Smith 
2479d763cef2SBarry Smith /*@
2480303a5415SBarry Smith   TSSetUp - Sets up the internal data structures for the later use of a timestepper.
2481d763cef2SBarry Smith 
2482c3339decSBarry Smith   Collective
2483d763cef2SBarry Smith 
2484d763cef2SBarry Smith   Input Parameter:
2485bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2486d763cef2SBarry Smith 
2487d763cef2SBarry Smith   Level: advanced
2488d763cef2SBarry Smith 
2489bcf0153eSBarry Smith   Note:
2490bcf0153eSBarry Smith   For basic use of the `TS` solvers the user need not explicitly call
2491bcf0153eSBarry Smith   `TSSetUp()`, since these actions will automatically occur during
2492bcf0153eSBarry Smith   the call to `TSStep()` or `TSSolve()`.  However, if one wishes to control this
2493bcf0153eSBarry Smith   phase separately, `TSSetUp()` should be called after `TSCreate()`
2494bcf0153eSBarry Smith   and optional routines of the form TSSetXXX(), but before `TSStep()` and `TSSolve()`.
2495bcf0153eSBarry Smith 
24961cc06b55SBarry Smith .seealso: [](ch_ts), `TSCreate()`, `TS`, `TSStep()`, `TSDestroy()`, `TSSolve()`
2497d763cef2SBarry Smith @*/
2498d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetUp(TS ts)
2499d71ae5a4SJacob Faibussowitsch {
25006c6b9e74SPeter Brune   DM dm;
25016c6b9e74SPeter Brune   PetscErrorCode (*func)(SNES, Vec, Vec, void *);
2502d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *);
25038434afd1SBarry Smith   TSIFunctionFn   *ifun;
25048434afd1SBarry Smith   TSIJacobianFn   *ijac;
25058434afd1SBarry Smith   TSI2JacobianFn  *i2jac;
25068434afd1SBarry Smith   TSRHSJacobianFn *rhsjac;
2507d763cef2SBarry Smith 
2508d763cef2SBarry Smith   PetscFunctionBegin;
25090700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
25103ba16761SJacob Faibussowitsch   if (ts->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
2511277b19d0SLisandro Dalcin 
25127adad957SLisandro Dalcin   if (!((PetscObject)ts)->type_name) {
25139566063dSJacob Faibussowitsch     PetscCall(TSGetIFunction(ts, NULL, &ifun, NULL));
25149566063dSJacob Faibussowitsch     PetscCall(TSSetType(ts, ifun ? TSBEULER : TSEULER));
2515d763cef2SBarry Smith   }
2516277b19d0SLisandro Dalcin 
25171a638600SStefano Zampini   if (!ts->vec_sol) {
25181e66621cSBarry Smith     PetscCheck(ts->dm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetSolution() first");
25199566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(ts->dm, &ts->vec_sol));
25201a638600SStefano Zampini   }
2521277b19d0SLisandro Dalcin 
2522298bade4SHong Zhang   if (!ts->Jacp && ts->Jacprhs) { /* IJacobianP shares the same matrix with RHSJacobianP if only RHSJacobianP is provided */
25239566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)ts->Jacprhs));
2524298bade4SHong Zhang     ts->Jacp = ts->Jacprhs;
2525298bade4SHong Zhang   }
2526298bade4SHong Zhang 
2527cd4cee2dSHong Zhang   if (ts->quadraturets) {
25289566063dSJacob Faibussowitsch     PetscCall(TSSetUp(ts->quadraturets));
25299566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
25309566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->quadraturets->vec_sol, &ts->vec_costintegrand));
2531cd4cee2dSHong Zhang   }
2532cd4cee2dSHong Zhang 
25339566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, NULL, NULL, &rhsjac, NULL));
2534f23ba4b3SHong Zhang   if (rhsjac == TSComputeRHSJacobianConstant) {
2535e1244c69SJed Brown     Mat  Amat, Pmat;
2536e1244c69SJed Brown     SNES snes;
25379566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
25389566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, &Amat, &Pmat, NULL, NULL));
2539e1244c69SJed Brown     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2540e1244c69SJed Brown      * have displaced the RHS matrix */
2541971015bcSStefano Zampini     if (Amat && Amat == ts->Arhs) {
2542abc0d4abSBarry Smith       /* we need to copy the values of the matrix because for the constant Jacobian case the user will never set the numerical values in this new location */
25439566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat));
25449566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes, Amat, NULL, NULL, NULL));
25459566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Amat));
2546e1244c69SJed Brown     }
2547971015bcSStefano Zampini     if (Pmat && Pmat == ts->Brhs) {
25489566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Brhs, MAT_COPY_VALUES, &Pmat));
25499566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes, NULL, Pmat, NULL, NULL));
25509566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Pmat));
2551e1244c69SJed Brown     }
2552e1244c69SJed Brown   }
25532ffb9264SLisandro Dalcin 
25549566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
25559566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
25562ffb9264SLisandro Dalcin 
2557dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, setup);
2558277b19d0SLisandro Dalcin 
25599566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
25602ffb9264SLisandro Dalcin 
2561a6772fa2SLisandro Dalcin   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
25626c6b9e74SPeter Brune      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
25636c6b9e74SPeter Brune    */
25649566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
25659566063dSJacob Faibussowitsch   PetscCall(DMSNESGetFunction(dm, &func, NULL));
25661e66621cSBarry Smith   if (!func) PetscCall(DMSNESSetFunction(dm, SNESTSFormFunction, ts));
25671e66621cSBarry Smith 
2568a6772fa2SLisandro Dalcin   /* If the SNES doesn't have a jacobian set and the TS has an ijacobian or rhsjacobian set, set the SNES to use it.
25696c6b9e74SPeter Brune      Otherwise, the SNES will use coloring internally to form the Jacobian.
25706c6b9e74SPeter Brune    */
25719566063dSJacob Faibussowitsch   PetscCall(DMSNESGetJacobian(dm, &jac, NULL));
25729566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijac, NULL));
25739566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, &i2jac, NULL));
25749566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjac, NULL));
25751e66621cSBarry Smith   if (!jac && (ijac || i2jac || rhsjac)) PetscCall(DMSNESSetJacobian(dm, SNESTSFormJacobian, ts));
2576c0517034SDebojyoti Ghosh 
2577c0517034SDebojyoti Ghosh   /* if time integration scheme has a starting method, call it */
2578dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, startingmethod);
2579c0517034SDebojyoti Ghosh 
2580277b19d0SLisandro Dalcin   ts->setupcalled = PETSC_TRUE;
25813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2582277b19d0SLisandro Dalcin }
2583277b19d0SLisandro Dalcin 
2584f6a906c0SBarry Smith /*@
25850b4b7b1cSBarry Smith   TSReset - Resets a `TS` context to the state it was in before `TSSetUp()` was called and removes any allocated `Vec` and `Mat` from its data structures
2586277b19d0SLisandro Dalcin 
2587c3339decSBarry Smith   Collective
2588277b19d0SLisandro Dalcin 
2589277b19d0SLisandro Dalcin   Input Parameter:
2590bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2591277b19d0SLisandro Dalcin 
25920b4b7b1cSBarry Smith   Level: developer
2593277b19d0SLisandro Dalcin 
25940b4b7b1cSBarry Smith   Notes:
25950b4b7b1cSBarry Smith   Any options set on the `TS` object, including those set with `TSSetFromOptions()` remain.
25960b4b7b1cSBarry Smith 
25970b4b7b1cSBarry Smith   See also `TSSetResize()` to change the size of the system being integrated (for example by adaptive mesh refinement) during the time integration.
25980b4b7b1cSBarry Smith 
2599bfe80ac4SPierre Jolivet .seealso: [](ch_ts), `TS`, `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSetResize()`
2600277b19d0SLisandro Dalcin @*/
2601d71ae5a4SJacob Faibussowitsch PetscErrorCode TSReset(TS ts)
2602d71ae5a4SJacob Faibussowitsch {
26031d06f6b3SHong Zhang   TS_RHSSplitLink ilink = ts->tsrhssplit, next;
2604277b19d0SLisandro Dalcin 
2605277b19d0SLisandro Dalcin   PetscFunctionBegin;
2606277b19d0SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2607b18ea86cSHong Zhang 
2608dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, reset);
26099566063dSJacob Faibussowitsch   if (ts->snes) PetscCall(SNESReset(ts->snes));
26109566063dSJacob Faibussowitsch   if (ts->adapt) PetscCall(TSAdaptReset(ts->adapt));
2611bbd56ea5SKarl Rupp 
26129566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Arhs));
26139566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Brhs));
26149566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->Frhs));
26159566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
2616c61711c8SStefano Zampini   PetscCall(VecDestroy(&ts->vec_sol0));
26179566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
26189566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vatol));
26199566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vrtol));
26209566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(ts->nwork, &ts->work));
2621bbd56ea5SKarl Rupp 
26229566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacprhs));
26239566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacp));
26241baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardReset(ts));
2625cd4cee2dSHong Zhang   if (ts->quadraturets) {
26269566063dSJacob Faibussowitsch     PetscCall(TSReset(ts->quadraturets));
26279566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
2628cd4cee2dSHong Zhang   }
26291d06f6b3SHong Zhang   while (ilink) {
26301d06f6b3SHong Zhang     next = ilink->next;
26319566063dSJacob Faibussowitsch     PetscCall(TSDestroy(&ilink->ts));
26329566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink->splitname));
26339566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ilink->is));
26349566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink));
26351d06f6b3SHong Zhang     ilink = next;
263687f4e208SHong Zhang   }
26376bf673ebSJoe Pusztay   ts->tsrhssplit     = NULL;
2638545aaa6fSHong Zhang   ts->num_rhs_splits = 0;
2639136cf249SJames Wright   if (ts->eval_times) {
2640136cf249SJames Wright     PetscCall(PetscFree(ts->eval_times->time_points));
2641136cf249SJames Wright     PetscCall(PetscFree(ts->eval_times->sol_times));
2642136cf249SJames Wright     PetscCall(VecDestroyVecs(ts->eval_times->num_time_points, &ts->eval_times->sol_vecs));
2643136cf249SJames Wright     PetscCall(PetscFree(ts->eval_times));
26444a658b32SHong Zhang   }
2645b3a72457SStefano Zampini   ts->rhsjacobian.time  = PETSC_MIN_REAL;
2646b3a72457SStefano Zampini   ts->rhsjacobian.scale = 1.0;
2647b3a72457SStefano Zampini   ts->ijacobian.shift   = 1.0;
2648277b19d0SLisandro Dalcin   ts->setupcalled       = PETSC_FALSE;
26493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2650d763cef2SBarry Smith }
2651d763cef2SBarry Smith 
265214d0ab18SJacob Faibussowitsch static PetscErrorCode TSResizeReset(TS);
265314d0ab18SJacob Faibussowitsch 
26540764c050SBarry Smith /*@
2655d763cef2SBarry Smith   TSDestroy - Destroys the timestepper context that was created
2656bcf0153eSBarry Smith   with `TSCreate()`.
2657d763cef2SBarry Smith 
2658c3339decSBarry Smith   Collective
2659d763cef2SBarry Smith 
2660d763cef2SBarry Smith   Input Parameter:
2661bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2662d763cef2SBarry Smith 
2663d763cef2SBarry Smith   Level: beginner
2664d763cef2SBarry Smith 
26651cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSCreate()`, `TSSetUp()`, `TSSolve()`
2666d763cef2SBarry Smith @*/
2667d71ae5a4SJacob Faibussowitsch PetscErrorCode TSDestroy(TS *ts)
2668d71ae5a4SJacob Faibussowitsch {
2669d763cef2SBarry Smith   PetscFunctionBegin;
26703ba16761SJacob Faibussowitsch   if (!*ts) PetscFunctionReturn(PETSC_SUCCESS);
2671ecf68647SHong Zhang   PetscValidHeaderSpecific(*ts, TS_CLASSID, 1);
2672f4f49eeaSPierre Jolivet   if (--((PetscObject)*ts)->refct > 0) {
26739371c9d4SSatish Balay     *ts = NULL;
26743ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
26759371c9d4SSatish Balay   }
2676d763cef2SBarry Smith 
26779566063dSJacob Faibussowitsch   PetscCall(TSReset(*ts));
26789566063dSJacob Faibussowitsch   PetscCall(TSAdjointReset(*ts));
26791e66621cSBarry Smith   if ((*ts)->forward_solve) PetscCall(TSForwardReset(*ts));
26806bd3a4fdSStefano Zampini   PetscCall(TSResizeReset(*ts));
26811e66621cSBarry Smith 
2682e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
26839566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*ts));
2684f4f49eeaSPierre Jolivet   PetscTryTypeMethod(*ts, destroy);
26856d4c513bSLisandro Dalcin 
26869566063dSJacob Faibussowitsch   PetscCall(TSTrajectoryDestroy(&(*ts)->trajectory));
2687bc952696SBarry Smith 
26889566063dSJacob Faibussowitsch   PetscCall(TSAdaptDestroy(&(*ts)->adapt));
26899566063dSJacob Faibussowitsch   PetscCall(TSEventDestroy(&(*ts)->event));
26906427ac75SLisandro Dalcin 
26919566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&(*ts)->snes));
26924bd3aaa3SHong Zhang   PetscCall(SNESDestroy(&(*ts)->snesrhssplit));
26939566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&(*ts)->dm));
2694f4f49eeaSPierre Jolivet   PetscCall(TSMonitorCancel(*ts));
2695f4f49eeaSPierre Jolivet   PetscCall(TSAdjointMonitorCancel(*ts));
26966d4c513bSLisandro Dalcin 
26979566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&(*ts)->quadraturets));
26989566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ts));
26993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2700d763cef2SBarry Smith }
2701d763cef2SBarry Smith 
2702d8e5e3e6SSatish Balay /*@
2703bcf0153eSBarry Smith   TSGetSNES - Returns the `SNES` (nonlinear solver) associated with
2704bcf0153eSBarry Smith   a `TS` (timestepper) context. Valid only for nonlinear problems.
2705d763cef2SBarry Smith 
2706bcf0153eSBarry Smith   Not Collective, but snes is parallel if ts is parallel
2707d763cef2SBarry Smith 
2708d763cef2SBarry Smith   Input Parameter:
2709bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2710d763cef2SBarry Smith 
2711d763cef2SBarry Smith   Output Parameter:
2712d763cef2SBarry Smith . snes - the nonlinear solver context
2713d763cef2SBarry Smith 
2714d763cef2SBarry Smith   Level: beginner
2715d763cef2SBarry Smith 
2716bcf0153eSBarry Smith   Notes:
2717bcf0153eSBarry Smith   The user can then directly manipulate the `SNES` context to set various
2718bcf0153eSBarry Smith   options, etc.  Likewise, the user can then extract and manipulate the
2719bcf0153eSBarry Smith   `KSP`, and `PC` contexts as well.
2720bcf0153eSBarry Smith 
2721bcf0153eSBarry Smith   `TSGetSNES()` does not work for integrators that do not use `SNES`; in
2722195e9b02SBarry Smith   this case `TSGetSNES()` returns `NULL` in `snes`.
2723bcf0153eSBarry Smith 
27241cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `SNES`, `TSCreate()`, `TSSetUp()`, `TSSolve()`
2725d763cef2SBarry Smith @*/
2726d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSNES(TS ts, SNES *snes)
2727d71ae5a4SJacob Faibussowitsch {
2728d763cef2SBarry Smith   PetscFunctionBegin;
27290700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
27304f572ea9SToby Isaac   PetscAssertPointer(snes, 2);
2731d372ba47SLisandro Dalcin   if (!ts->snes) {
27329566063dSJacob Faibussowitsch     PetscCall(SNESCreate(PetscObjectComm((PetscObject)ts), &ts->snes));
27339566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)ts->snes, ((PetscObject)ts)->options));
27349566063dSJacob Faibussowitsch     PetscCall(SNESSetFunction(ts->snes, NULL, SNESTSFormFunction, ts));
27359566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->snes, (PetscObject)ts, 1));
27364bd3aaa3SHong Zhang     if (ts->dm) PetscCall(SNESSetDM(ts->snes, ts->dm));
27371e66621cSBarry Smith     if (ts->problem_type == TS_LINEAR) PetscCall(SNESSetType(ts->snes, SNESKSPONLY));
2738d372ba47SLisandro Dalcin   }
2739d763cef2SBarry Smith   *snes = ts->snes;
27403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2741d763cef2SBarry Smith }
2742d763cef2SBarry Smith 
2743deb2cd25SJed Brown /*@
27440b4b7b1cSBarry Smith   TSSetSNES - Set the `SNES` (nonlinear solver) to be used by the `TS` timestepping context
2745deb2cd25SJed Brown 
2746deb2cd25SJed Brown   Collective
2747deb2cd25SJed Brown 
2748d8d19677SJose E. Roman   Input Parameters:
2749bcf0153eSBarry Smith + ts   - the `TS` context obtained from `TSCreate()`
2750deb2cd25SJed Brown - snes - the nonlinear solver context
2751deb2cd25SJed Brown 
2752deb2cd25SJed Brown   Level: developer
2753deb2cd25SJed Brown 
2754bcf0153eSBarry Smith   Note:
2755bcf0153eSBarry Smith   Most users should have the `TS` created by calling `TSGetSNES()`
2756bcf0153eSBarry Smith 
27571cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `SNES`, `TSCreate()`, `TSSetUp()`, `TSSolve()`, `TSGetSNES()`
2758deb2cd25SJed Brown @*/
2759d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetSNES(TS ts, SNES snes)
2760d71ae5a4SJacob Faibussowitsch {
2761d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
2762deb2cd25SJed Brown 
2763deb2cd25SJed Brown   PetscFunctionBegin;
2764deb2cd25SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2765deb2cd25SJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 2);
27669566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)snes));
27679566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&ts->snes));
2768bbd56ea5SKarl Rupp 
2769deb2cd25SJed Brown   ts->snes = snes;
2770bbd56ea5SKarl Rupp 
27719566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(ts->snes, NULL, SNESTSFormFunction, ts));
27729566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(ts->snes, NULL, NULL, &func, NULL));
27731e66621cSBarry Smith   if (func == SNESTSFormJacobian) PetscCall(SNESSetJacobian(ts->snes, NULL, NULL, SNESTSFormJacobian, ts));
27743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2775deb2cd25SJed Brown }
2776deb2cd25SJed Brown 
2777d8e5e3e6SSatish Balay /*@
2778bcf0153eSBarry Smith   TSGetKSP - Returns the `KSP` (linear solver) associated with
2779bcf0153eSBarry Smith   a `TS` (timestepper) context.
2780d763cef2SBarry Smith 
2781195e9b02SBarry Smith   Not Collective, but `ksp` is parallel if `ts` is parallel
2782d763cef2SBarry Smith 
2783d763cef2SBarry Smith   Input Parameter:
2784bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2785d763cef2SBarry Smith 
2786d763cef2SBarry Smith   Output Parameter:
278794b7f48cSBarry Smith . ksp - the nonlinear solver context
2788d763cef2SBarry Smith 
2789d763cef2SBarry Smith   Level: beginner
2790d763cef2SBarry Smith 
2791bcf0153eSBarry Smith   Notes:
2792bcf0153eSBarry Smith   The user can then directly manipulate the `KSP` context to set various
2793bcf0153eSBarry Smith   options, etc.  Likewise, the user can then extract and manipulate the
2794bcf0153eSBarry Smith   `PC` context as well.
2795bcf0153eSBarry Smith 
2796bcf0153eSBarry Smith   `TSGetKSP()` does not work for integrators that do not use `KSP`;
2797195e9b02SBarry Smith   in this case `TSGetKSP()` returns `NULL` in `ksp`.
2798bcf0153eSBarry Smith 
27991cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `SNES`, `KSP`, `TSCreate()`, `TSSetUp()`, `TSSolve()`, `TSGetSNES()`
2800d763cef2SBarry Smith @*/
2801d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetKSP(TS ts, KSP *ksp)
2802d71ae5a4SJacob Faibussowitsch {
2803089b2837SJed Brown   SNES snes;
2804d372ba47SLisandro Dalcin 
2805d763cef2SBarry Smith   PetscFunctionBegin;
28060700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
28074f572ea9SToby Isaac   PetscAssertPointer(ksp, 2);
28083c633725SBarry Smith   PetscCheck(((PetscObject)ts)->type_name, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "KSP is not created yet. Call TSSetType() first");
28093c633725SBarry Smith   PetscCheck(ts->problem_type == TS_LINEAR, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Linear only; use TSGetSNES()");
28109566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
28119566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, ksp));
28123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2813d763cef2SBarry Smith }
2814d763cef2SBarry Smith 
2815d763cef2SBarry Smith /* ----------- Routines to set solver parameters ---------- */
2816d763cef2SBarry Smith 
2817adb62b0dSMatthew Knepley /*@
2818618ce8baSLisandro Dalcin   TSSetMaxSteps - Sets the maximum number of steps to use.
2819618ce8baSLisandro Dalcin 
2820c3339decSBarry Smith   Logically Collective
2821618ce8baSLisandro Dalcin 
2822618ce8baSLisandro Dalcin   Input Parameters:
2823bcf0153eSBarry Smith + ts       - the `TS` context obtained from `TSCreate()`
2824618ce8baSLisandro Dalcin - maxsteps - maximum number of steps to use
2825618ce8baSLisandro Dalcin 
2826bcf0153eSBarry Smith   Options Database Key:
2827618ce8baSLisandro Dalcin . -ts_max_steps <maxsteps> - Sets maxsteps
2828618ce8baSLisandro Dalcin 
2829618ce8baSLisandro Dalcin   Level: intermediate
2830618ce8baSLisandro Dalcin 
2831bcf0153eSBarry Smith   Note:
283209cb0f53SBarry Smith   Use `PETSC_DETERMINE` to reset the maximum number of steps to the default from when the object's type was set
283309cb0f53SBarry Smith 
283409cb0f53SBarry Smith   The default maximum number of steps is 5,000
283509cb0f53SBarry Smith 
283609cb0f53SBarry Smith   Fortran Note:
283709cb0f53SBarry Smith   Use `PETSC_DETERMINE_INTEGER`
2838bcf0153eSBarry Smith 
28391cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetMaxSteps()`, `TSSetMaxTime()`, `TSSetExactFinalTime()`
2840618ce8baSLisandro Dalcin @*/
2841d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxSteps(TS ts, PetscInt maxsteps)
2842d71ae5a4SJacob Faibussowitsch {
2843618ce8baSLisandro Dalcin   PetscFunctionBegin;
2844618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2845618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts, maxsteps, 2);
284609cb0f53SBarry Smith   if (maxsteps == PETSC_DETERMINE) {
284709cb0f53SBarry Smith     ts->max_steps = ts->default_max_steps;
284809cb0f53SBarry Smith   } else {
28493c633725SBarry Smith     PetscCheck(maxsteps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of steps must be non-negative");
2850618ce8baSLisandro Dalcin     ts->max_steps = maxsteps;
285109cb0f53SBarry Smith   }
28523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2853618ce8baSLisandro Dalcin }
2854618ce8baSLisandro Dalcin 
2855618ce8baSLisandro Dalcin /*@
2856618ce8baSLisandro Dalcin   TSGetMaxSteps - Gets the maximum number of steps to use.
2857618ce8baSLisandro Dalcin 
2858618ce8baSLisandro Dalcin   Not Collective
2859618ce8baSLisandro Dalcin 
28602fe279fdSBarry Smith   Input Parameter:
2861bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2862618ce8baSLisandro Dalcin 
2863618ce8baSLisandro Dalcin   Output Parameter:
2864618ce8baSLisandro Dalcin . maxsteps - maximum number of steps to use
2865618ce8baSLisandro Dalcin 
2866618ce8baSLisandro Dalcin   Level: advanced
2867618ce8baSLisandro Dalcin 
28681cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetMaxSteps()`, `TSGetMaxTime()`, `TSSetMaxTime()`
2869618ce8baSLisandro Dalcin @*/
2870d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetMaxSteps(TS ts, PetscInt *maxsteps)
2871d71ae5a4SJacob Faibussowitsch {
2872618ce8baSLisandro Dalcin   PetscFunctionBegin;
2873618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
28744f572ea9SToby Isaac   PetscAssertPointer(maxsteps, 2);
2875618ce8baSLisandro Dalcin   *maxsteps = ts->max_steps;
28763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2877618ce8baSLisandro Dalcin }
2878618ce8baSLisandro Dalcin 
2879618ce8baSLisandro Dalcin /*@
28808e562f8dSJames Wright   TSSetRunSteps - Sets the maximum number of steps to take in each call to `TSSolve()`.
28818e562f8dSJames Wright 
28828e562f8dSJames Wright   If the step count when `TSSolve()` is `start_step`, this will stop the simulation once `current_step - start_step >= run_steps`.
28838e562f8dSJames Wright   Comparatively, `TSSetMaxSteps()` will stop if `current_step >= max_steps`.
28848e562f8dSJames Wright   The simulation will stop when either condition is reached.
28858e562f8dSJames Wright 
28868e562f8dSJames Wright   Logically Collective
28878e562f8dSJames Wright 
28888e562f8dSJames Wright   Input Parameters:
28898e562f8dSJames Wright + ts       - the `TS` context obtained from `TSCreate()`
28908e562f8dSJames Wright - runsteps - maximum number of steps to take in each call to `TSSolve()`;
28918e562f8dSJames Wright 
28928e562f8dSJames Wright   Options Database Key:
28938e562f8dSJames Wright . -ts_run_steps <runsteps> - Sets runsteps
28948e562f8dSJames Wright 
28958e562f8dSJames Wright   Level: intermediate
28968e562f8dSJames Wright 
28978e562f8dSJames Wright   Note:
28988e562f8dSJames Wright   The default is `PETSC_UNLIMITED`
28998e562f8dSJames Wright 
29008e562f8dSJames Wright .seealso: [](ch_ts), `TS`, `TSGetRunSteps()`, `TSSetMaxTime()`, `TSSetExactFinalTime()`, `TSSetMaxSteps()`
29018e562f8dSJames Wright @*/
29028e562f8dSJames Wright PetscErrorCode TSSetRunSteps(TS ts, PetscInt runsteps)
29038e562f8dSJames Wright {
29048e562f8dSJames Wright   PetscFunctionBegin;
29058e562f8dSJames Wright   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
29068e562f8dSJames Wright   PetscValidLogicalCollectiveInt(ts, runsteps, 2);
29078e562f8dSJames Wright   if (runsteps == PETSC_DETERMINE) {
29088e562f8dSJames Wright     ts->run_steps = PETSC_UNLIMITED;
29098e562f8dSJames Wright   } else {
29108e562f8dSJames Wright     PetscCheck(runsteps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Max number of steps to take in each call to TSSolve must be non-negative");
29118e562f8dSJames Wright     ts->run_steps = runsteps;
29128e562f8dSJames Wright   }
29138e562f8dSJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
29148e562f8dSJames Wright }
29158e562f8dSJames Wright 
29168e562f8dSJames Wright /*@
29178e562f8dSJames Wright   TSGetRunSteps - Gets the maximum number of steps to take in each call to `TSSolve()`.
29188e562f8dSJames Wright 
29198e562f8dSJames Wright   Not Collective
29208e562f8dSJames Wright 
29218e562f8dSJames Wright   Input Parameter:
29228e562f8dSJames Wright . ts - the `TS` context obtained from `TSCreate()`
29238e562f8dSJames Wright 
29248e562f8dSJames Wright   Output Parameter:
29258e562f8dSJames Wright . runsteps - maximum number of steps to take in each call to `TSSolve`.
29268e562f8dSJames Wright 
29278e562f8dSJames Wright   Level: advanced
29288e562f8dSJames Wright 
29298e562f8dSJames Wright .seealso: [](ch_ts), `TS`, `TSSetRunSteps()`, `TSGetMaxTime()`, `TSSetMaxTime()`, `TSGetMaxSteps()`
29308e562f8dSJames Wright @*/
29318e562f8dSJames Wright PetscErrorCode TSGetRunSteps(TS ts, PetscInt *runsteps)
29328e562f8dSJames Wright {
29338e562f8dSJames Wright   PetscFunctionBegin;
29348e562f8dSJames Wright   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
29358e562f8dSJames Wright   PetscAssertPointer(runsteps, 2);
29368e562f8dSJames Wright   *runsteps = ts->run_steps;
29378e562f8dSJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
29388e562f8dSJames Wright }
29398e562f8dSJames Wright 
29408e562f8dSJames Wright /*@
2941618ce8baSLisandro Dalcin   TSSetMaxTime - Sets the maximum (or final) time for timestepping.
2942618ce8baSLisandro Dalcin 
2943c3339decSBarry Smith   Logically Collective
2944618ce8baSLisandro Dalcin 
2945618ce8baSLisandro Dalcin   Input Parameters:
2946bcf0153eSBarry Smith + ts      - the `TS` context obtained from `TSCreate()`
2947618ce8baSLisandro Dalcin - maxtime - final time to step to
2948618ce8baSLisandro Dalcin 
2949bcf0153eSBarry Smith   Options Database Key:
2950ef85077eSLisandro Dalcin . -ts_max_time <maxtime> - Sets maxtime
2951618ce8baSLisandro Dalcin 
2952bcf0153eSBarry Smith   Level: intermediate
2953bcf0153eSBarry Smith 
2954618ce8baSLisandro Dalcin   Notes:
295509cb0f53SBarry Smith   Use `PETSC_DETERMINE` to reset the maximum time to the default from when the object's type was set
295609cb0f53SBarry Smith 
2957618ce8baSLisandro Dalcin   The default maximum time is 5.0
2958618ce8baSLisandro Dalcin 
295909cb0f53SBarry Smith   Fortran Note:
296009cb0f53SBarry Smith   Use `PETSC_DETERMINE_REAL`
296109cb0f53SBarry Smith 
29621cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetMaxTime()`, `TSSetMaxSteps()`, `TSSetExactFinalTime()`
2963618ce8baSLisandro Dalcin @*/
2964d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxTime(TS ts, PetscReal maxtime)
2965d71ae5a4SJacob Faibussowitsch {
2966618ce8baSLisandro Dalcin   PetscFunctionBegin;
2967618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2968618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveReal(ts, maxtime, 2);
296909cb0f53SBarry Smith   if (maxtime == PETSC_DETERMINE) {
297009cb0f53SBarry Smith     ts->max_time = ts->default_max_time;
297109cb0f53SBarry Smith   } else {
2972618ce8baSLisandro Dalcin     ts->max_time = maxtime;
297309cb0f53SBarry Smith   }
29743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2975618ce8baSLisandro Dalcin }
2976618ce8baSLisandro Dalcin 
2977618ce8baSLisandro Dalcin /*@
2978618ce8baSLisandro Dalcin   TSGetMaxTime - Gets the maximum (or final) time for timestepping.
2979618ce8baSLisandro Dalcin 
2980618ce8baSLisandro Dalcin   Not Collective
2981618ce8baSLisandro Dalcin 
29822fe279fdSBarry Smith   Input Parameter:
2983bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
2984618ce8baSLisandro Dalcin 
2985618ce8baSLisandro Dalcin   Output Parameter:
2986618ce8baSLisandro Dalcin . maxtime - final time to step to
2987618ce8baSLisandro Dalcin 
2988618ce8baSLisandro Dalcin   Level: advanced
2989618ce8baSLisandro Dalcin 
29901cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetMaxTime()`, `TSGetMaxSteps()`, `TSSetMaxSteps()`
2991618ce8baSLisandro Dalcin @*/
2992d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetMaxTime(TS ts, PetscReal *maxtime)
2993d71ae5a4SJacob Faibussowitsch {
2994618ce8baSLisandro Dalcin   PetscFunctionBegin;
2995618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
29964f572ea9SToby Isaac   PetscAssertPointer(maxtime, 2);
2997618ce8baSLisandro Dalcin   *maxtime = ts->max_time;
29983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2999618ce8baSLisandro Dalcin }
3000618ce8baSLisandro Dalcin 
300114d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-*
3002618ce8baSLisandro Dalcin /*@
3003bcf0153eSBarry Smith   TSSetInitialTimeStep - Deprecated, use `TSSetTime()` and `TSSetTimeStep()`.
3004edc382c3SSatish Balay 
3005edc382c3SSatish Balay   Level: deprecated
3006edc382c3SSatish Balay 
3007aaa6c58dSLisandro Dalcin @*/
3008d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetInitialTimeStep(TS ts, PetscReal initial_time, PetscReal time_step)
3009d71ae5a4SJacob Faibussowitsch {
3010aaa6c58dSLisandro Dalcin   PetscFunctionBegin;
3011aaa6c58dSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
30129566063dSJacob Faibussowitsch   PetscCall(TSSetTime(ts, initial_time));
30139566063dSJacob Faibussowitsch   PetscCall(TSSetTimeStep(ts, time_step));
30143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3015aaa6c58dSLisandro Dalcin }
3016aaa6c58dSLisandro Dalcin 
301714d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-*
3018aaa6c58dSLisandro Dalcin /*@
3019bcf0153eSBarry Smith   TSGetDuration - Deprecated, use `TSGetMaxSteps()` and `TSGetMaxTime()`.
3020edc382c3SSatish Balay 
3021edc382c3SSatish Balay   Level: deprecated
3022edc382c3SSatish Balay 
3023adb62b0dSMatthew Knepley @*/
3024d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
3025d71ae5a4SJacob Faibussowitsch {
3026adb62b0dSMatthew Knepley   PetscFunctionBegin;
30270700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3028abc0a331SBarry Smith   if (maxsteps) {
30294f572ea9SToby Isaac     PetscAssertPointer(maxsteps, 2);
3030adb62b0dSMatthew Knepley     *maxsteps = ts->max_steps;
3031adb62b0dSMatthew Knepley   }
3032abc0a331SBarry Smith   if (maxtime) {
30334f572ea9SToby Isaac     PetscAssertPointer(maxtime, 3);
3034adb62b0dSMatthew Knepley     *maxtime = ts->max_time;
3035adb62b0dSMatthew Knepley   }
30363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3037adb62b0dSMatthew Knepley }
3038adb62b0dSMatthew Knepley 
303914d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-*
3040d763cef2SBarry Smith /*@
3041bcf0153eSBarry Smith   TSSetDuration - Deprecated, use `TSSetMaxSteps()` and `TSSetMaxTime()`.
3042edc382c3SSatish Balay 
3043edc382c3SSatish Balay   Level: deprecated
3044edc382c3SSatish Balay 
3045d763cef2SBarry Smith @*/
3046d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetDuration(TS ts, PetscInt maxsteps, PetscReal maxtime)
3047d71ae5a4SJacob Faibussowitsch {
3048d763cef2SBarry Smith   PetscFunctionBegin;
3049835f2295SStefano Zampini   if (maxsteps != PETSC_CURRENT) PetscCall(TSSetMaxSteps(ts, maxsteps));
305009cb0f53SBarry Smith   if (maxtime != (PetscReal)PETSC_CURRENT) PetscCall(TSSetMaxTime(ts, maxtime));
30513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3052d763cef2SBarry Smith }
3053d763cef2SBarry Smith 
305414d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-*
3055d763cef2SBarry Smith /*@
3056bcf0153eSBarry Smith   TSGetTimeStepNumber - Deprecated, use `TSGetStepNumber()`.
3057edc382c3SSatish Balay 
3058edc382c3SSatish Balay   Level: deprecated
3059edc382c3SSatish Balay 
30605c5f5948SLisandro Dalcin @*/
3061d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeStepNumber(TS ts, PetscInt *steps)
3062d71ae5a4SJacob Faibussowitsch {
30639371c9d4SSatish Balay   return TSGetStepNumber(ts, steps);
30649371c9d4SSatish Balay }
30655c5f5948SLisandro Dalcin 
306614d0ab18SJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc-*
306719eac22cSLisandro Dalcin /*@
3068bcf0153eSBarry Smith   TSGetTotalSteps - Deprecated, use `TSGetStepNumber()`.
3069edc382c3SSatish Balay 
3070edc382c3SSatish Balay   Level: deprecated
3071edc382c3SSatish Balay 
30724f4e0956SLisandro Dalcin @*/
3073d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTotalSteps(TS ts, PetscInt *steps)
3074d71ae5a4SJacob Faibussowitsch {
30759371c9d4SSatish Balay   return TSGetStepNumber(ts, steps);
30769371c9d4SSatish Balay }
30774f4e0956SLisandro Dalcin 
30784f4e0956SLisandro Dalcin /*@
3079d763cef2SBarry Smith   TSSetSolution - Sets the initial solution vector
3080bcf0153eSBarry Smith   for use by the `TS` routines.
3081d763cef2SBarry Smith 
3082c3339decSBarry Smith   Logically Collective
3083d763cef2SBarry Smith 
3084d763cef2SBarry Smith   Input Parameters:
3085bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()`
30860910c330SBarry Smith - u  - the solution vector
3087d763cef2SBarry Smith 
3088d763cef2SBarry Smith   Level: beginner
3089d763cef2SBarry Smith 
30901cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetSolutionFunction()`, `TSGetSolution()`, `TSCreate()`
3091d763cef2SBarry Smith @*/
3092d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetSolution(TS ts, Vec u)
3093d71ae5a4SJacob Faibussowitsch {
3094496e6a7aSJed Brown   DM dm;
30958737fe31SLisandro Dalcin 
3096d763cef2SBarry Smith   PetscFunctionBegin;
30970700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
30980910c330SBarry Smith   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
30999566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)u));
31009566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
31010910c330SBarry Smith   ts->vec_sol = u;
3102bbd56ea5SKarl Rupp 
31039566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
31049566063dSJacob Faibussowitsch   PetscCall(DMShellSetGlobalVector(dm, u));
31053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3106d763cef2SBarry Smith }
3107d763cef2SBarry Smith 
3108ac226902SBarry Smith /*@C
3109000e7ae3SMatthew Knepley   TSSetPreStep - Sets the general-purpose function
31103f2090d5SJed Brown   called once at the beginning of each time step.
3111000e7ae3SMatthew Knepley 
3112c3339decSBarry Smith   Logically Collective
3113000e7ae3SMatthew Knepley 
3114000e7ae3SMatthew Knepley   Input Parameters:
3115bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3116000e7ae3SMatthew Knepley - func - The function
3117000e7ae3SMatthew Knepley 
311820f4b53cSBarry Smith   Calling sequence of `func`:
311914d0ab18SJacob Faibussowitsch . ts - the `TS` context
3120000e7ae3SMatthew Knepley 
3121000e7ae3SMatthew Knepley   Level: intermediate
3122000e7ae3SMatthew Knepley 
31231cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`, `TSStep()`, `TSRestartStep()`
3124000e7ae3SMatthew Knepley @*/
312514d0ab18SJacob Faibussowitsch PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS ts))
3126d71ae5a4SJacob Faibussowitsch {
3127000e7ae3SMatthew Knepley   PetscFunctionBegin;
31280700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3129ae60f76fSBarry Smith   ts->prestep = func;
31303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3131000e7ae3SMatthew Knepley }
3132000e7ae3SMatthew Knepley 
313309ee8438SJed Brown /*@
3134bcf0153eSBarry Smith   TSPreStep - Runs the user-defined pre-step function provided with `TSSetPreStep()`
31353f2090d5SJed Brown 
3136c3339decSBarry Smith   Collective
31373f2090d5SJed Brown 
31382fe279fdSBarry Smith   Input Parameter:
3139bcf0153eSBarry Smith . ts - The `TS` context obtained from `TSCreate()`
31403f2090d5SJed Brown 
31413f2090d5SJed Brown   Level: developer
31423f2090d5SJed Brown 
3143bcf0153eSBarry Smith   Note:
3144bcf0153eSBarry Smith   `TSPreStep()` is typically used within time stepping implementations,
3145bcf0153eSBarry Smith   so most users would not generally call this routine themselves.
3146bcf0153eSBarry Smith 
31471cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetPreStep()`, `TSPreStage()`, `TSPostStage()`, `TSPostStep()`
31483f2090d5SJed Brown @*/
3149d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPreStep(TS ts)
3150d71ae5a4SJacob Faibussowitsch {
31513f2090d5SJed Brown   PetscFunctionBegin;
31520700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3153ae60f76fSBarry Smith   if (ts->prestep) {
31545efd42a4SStefano Zampini     Vec              U;
3155ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3156ef8d1ce0SJohann Rudi     PetscBool        sameObject;
31575efd42a4SStefano Zampini     PetscObjectState sprev, spost;
31585efd42a4SStefano Zampini 
31599566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
31609566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U, &idprev));
31619566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
316225e27a38SBarry Smith     PetscCallBack("TS callback preset", (*ts->prestep)(ts));
31639566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
31649566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U, idprev, &sameObject));
31659566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
31669566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
3167312ce896SJed Brown   }
31683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31693f2090d5SJed Brown }
31703f2090d5SJed Brown 
3171b8123daeSJed Brown /*@C
3172b8123daeSJed Brown   TSSetPreStage - Sets the general-purpose function
3173b8123daeSJed Brown   called once at the beginning of each stage.
3174b8123daeSJed Brown 
3175c3339decSBarry Smith   Logically Collective
3176b8123daeSJed Brown 
3177b8123daeSJed Brown   Input Parameters:
3178bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3179b8123daeSJed Brown - func - The function
3180b8123daeSJed Brown 
318120f4b53cSBarry Smith   Calling sequence of `func`:
318214d0ab18SJacob Faibussowitsch + ts        - the `TS` context
318314d0ab18SJacob Faibussowitsch - stagetime - the stage time
3184b8123daeSJed Brown 
3185b8123daeSJed Brown   Level: intermediate
3186b8123daeSJed Brown 
3187b8123daeSJed Brown   Note:
3188b8123daeSJed Brown   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3189bcf0153eSBarry Smith   The time step number being computed can be queried using `TSGetStepNumber()` and the total size of the step being
3190bcf0153eSBarry Smith   attempted can be obtained using `TSGetTimeStep()`. The time at the start of the step is available via `TSGetTime()`.
3191b8123daeSJed Brown 
31921cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetPostStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3193b8123daeSJed Brown @*/
319414d0ab18SJacob Faibussowitsch PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS ts, PetscReal stagetime))
3195d71ae5a4SJacob Faibussowitsch {
3196b8123daeSJed Brown   PetscFunctionBegin;
3197b8123daeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3198ae60f76fSBarry Smith   ts->prestage = func;
31993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3200b8123daeSJed Brown }
3201b8123daeSJed Brown 
32029be3e283SDebojyoti Ghosh /*@C
32030d56bcf9SIlya Fursov   TSSetPostStage - Sets the general-purpose function
32049be3e283SDebojyoti Ghosh   called once at the end of each stage.
32059be3e283SDebojyoti Ghosh 
3206c3339decSBarry Smith   Logically Collective
32079be3e283SDebojyoti Ghosh 
32089be3e283SDebojyoti Ghosh   Input Parameters:
3209bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
32109be3e283SDebojyoti Ghosh - func - The function
32119be3e283SDebojyoti Ghosh 
321220f4b53cSBarry Smith   Calling sequence of `func`:
321314d0ab18SJacob Faibussowitsch + ts         - the `TS` context
321414d0ab18SJacob Faibussowitsch . stagetime  - the stage time
321514d0ab18SJacob Faibussowitsch . stageindex - the stage index
321614d0ab18SJacob Faibussowitsch - Y          - Array of vectors (of size = total number of stages) with the stage solutions
32179be3e283SDebojyoti Ghosh 
32189be3e283SDebojyoti Ghosh   Level: intermediate
32199be3e283SDebojyoti Ghosh 
32209be3e283SDebojyoti Ghosh   Note:
32219be3e283SDebojyoti Ghosh   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3222bcf0153eSBarry Smith   The time step number being computed can be queried using `TSGetStepNumber()` and the total size of the step being
3223bcf0153eSBarry Smith   attempted can be obtained using `TSGetTimeStep()`. The time at the start of the step is available via `TSGetTime()`.
32249be3e283SDebojyoti Ghosh 
32251cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
32269be3e283SDebojyoti Ghosh @*/
322714d0ab18SJacob Faibussowitsch PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y))
3228d71ae5a4SJacob Faibussowitsch {
32299be3e283SDebojyoti Ghosh   PetscFunctionBegin;
32309be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
32319be3e283SDebojyoti Ghosh   ts->poststage = func;
32323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32339be3e283SDebojyoti Ghosh }
32349be3e283SDebojyoti Ghosh 
3235c688d042SShri Abhyankar /*@C
3236c688d042SShri Abhyankar   TSSetPostEvaluate - Sets the general-purpose function
32370d56bcf9SIlya Fursov   called at the end of each step evaluation.
3238c688d042SShri Abhyankar 
3239c3339decSBarry Smith   Logically Collective
3240c688d042SShri Abhyankar 
3241c688d042SShri Abhyankar   Input Parameters:
3242bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3243c688d042SShri Abhyankar - func - The function
3244c688d042SShri Abhyankar 
324520f4b53cSBarry Smith   Calling sequence of `func`:
324614d0ab18SJacob Faibussowitsch . ts - the `TS` context
3247c688d042SShri Abhyankar 
3248c688d042SShri Abhyankar   Level: intermediate
3249c688d042SShri Abhyankar 
3250c688d042SShri Abhyankar   Note:
32510d56bcf9SIlya Fursov   The function set by `TSSetPostEvaluate()` is called after the solution is evaluated, or after the step rollback.
32520d56bcf9SIlya Fursov   Inside the `func` callback, the solution vector can be obtained with `TSGetSolution()`, and modified, if need be.
32530d56bcf9SIlya Fursov   The time step can be obtained with `TSGetTimeStep()`, and the time at the start of the step - via `TSGetTime()`.
32540d56bcf9SIlya Fursov   The potential changes to the solution vector introduced by event handling (`postevent()`) are not relevant for `TSSetPostEvaluate()`,
32550d56bcf9SIlya Fursov   but are relevant for `TSSetPostStep()`, according to the function call scheme in `TSSolve()`, as shown below
32560d56bcf9SIlya Fursov .vb
32570d56bcf9SIlya Fursov   ...
32580d56bcf9SIlya Fursov   Step()
32590d56bcf9SIlya Fursov   PostEvaluate()
32600d56bcf9SIlya Fursov   EventHandling()
32610d56bcf9SIlya Fursov   step_rollback ? PostEvaluate() : PostStep()
32620d56bcf9SIlya Fursov   ...
32630d56bcf9SIlya Fursov .ve
32640d56bcf9SIlya Fursov   where EventHandling() may result in one of the following three outcomes
32650d56bcf9SIlya Fursov .vb
32660d56bcf9SIlya Fursov   (1) | successful step | solution intact
32670d56bcf9SIlya Fursov   (2) | successful step | solution modified by `postevent()`
32680d56bcf9SIlya Fursov   (3) | step_rollback   | solution rolled back
32690d56bcf9SIlya Fursov .ve
3270c688d042SShri Abhyankar 
32711cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3272c688d042SShri Abhyankar @*/
327314d0ab18SJacob Faibussowitsch PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS ts))
3274d71ae5a4SJacob Faibussowitsch {
3275c688d042SShri Abhyankar   PetscFunctionBegin;
3276c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3277c688d042SShri Abhyankar   ts->postevaluate = func;
32783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3279c688d042SShri Abhyankar }
3280c688d042SShri Abhyankar 
3281b8123daeSJed Brown /*@
3282bcf0153eSBarry Smith   TSPreStage - Runs the user-defined pre-stage function set using `TSSetPreStage()`
3283b8123daeSJed Brown 
3284c3339decSBarry Smith   Collective
3285b8123daeSJed Brown 
3286b8123daeSJed Brown   Input Parameters:
328714d0ab18SJacob Faibussowitsch + ts        - The `TS` context obtained from `TSCreate()`
328814d0ab18SJacob Faibussowitsch - stagetime - The absolute time of the current stage
3289b8123daeSJed Brown 
3290b8123daeSJed Brown   Level: developer
3291b8123daeSJed Brown 
3292bcf0153eSBarry Smith   Note:
3293bcf0153eSBarry Smith   `TSPreStage()` is typically used within time stepping implementations,
3294bcf0153eSBarry Smith   most users would not generally call this routine themselves.
3295bcf0153eSBarry Smith 
32961cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSPostStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3297b8123daeSJed Brown @*/
3298d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPreStage(TS ts, PetscReal stagetime)
3299d71ae5a4SJacob Faibussowitsch {
3300b8123daeSJed Brown   PetscFunctionBegin;
3301b8123daeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
33021e66621cSBarry Smith   if (ts->prestage) PetscCallBack("TS callback prestage", (*ts->prestage)(ts, stagetime));
33033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3304b8123daeSJed Brown }
3305b8123daeSJed Brown 
33069be3e283SDebojyoti Ghosh /*@
3307bcf0153eSBarry Smith   TSPostStage - Runs the user-defined post-stage function set using `TSSetPostStage()`
33089be3e283SDebojyoti Ghosh 
3309c3339decSBarry Smith   Collective
33109be3e283SDebojyoti Ghosh 
33119be3e283SDebojyoti Ghosh   Input Parameters:
331214d0ab18SJacob Faibussowitsch + ts         - The `TS` context obtained from `TSCreate()`
331314d0ab18SJacob Faibussowitsch . stagetime  - The absolute time of the current stage
331414d0ab18SJacob Faibussowitsch . stageindex - Stage number
331514d0ab18SJacob Faibussowitsch - Y          - Array of vectors (of size = total number of stages) with the stage solutions
33169be3e283SDebojyoti Ghosh 
33179be3e283SDebojyoti Ghosh   Level: developer
33189be3e283SDebojyoti Ghosh 
3319bcf0153eSBarry Smith   Note:
3320bcf0153eSBarry Smith   `TSPostStage()` is typically used within time stepping implementations,
3321bcf0153eSBarry Smith   most users would not generally call this routine themselves.
3322bcf0153eSBarry Smith 
33231cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSPreStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
33249be3e283SDebojyoti Ghosh @*/
33250fc7ecceSBarry Smith PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec Y[])
3326d71ae5a4SJacob Faibussowitsch {
33279be3e283SDebojyoti Ghosh   PetscFunctionBegin;
33289be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
33291e66621cSBarry Smith   if (ts->poststage) PetscCallBack("TS callback poststage", (*ts->poststage)(ts, stagetime, stageindex, Y));
33303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33319be3e283SDebojyoti Ghosh }
33329be3e283SDebojyoti Ghosh 
3333c688d042SShri Abhyankar /*@
3334bcf0153eSBarry Smith   TSPostEvaluate - Runs the user-defined post-evaluate function set using `TSSetPostEvaluate()`
3335c688d042SShri Abhyankar 
3336c3339decSBarry Smith   Collective
3337c688d042SShri Abhyankar 
33382fe279fdSBarry Smith   Input Parameter:
3339bcf0153eSBarry Smith . ts - The `TS` context obtained from `TSCreate()`
3340c688d042SShri Abhyankar 
3341c688d042SShri Abhyankar   Level: developer
3342c688d042SShri Abhyankar 
3343bcf0153eSBarry Smith   Note:
3344bcf0153eSBarry Smith   `TSPostEvaluate()` is typically used within time stepping implementations,
3345bcf0153eSBarry Smith   most users would not generally call this routine themselves.
3346bcf0153eSBarry Smith 
33471cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetPostEvaluate()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3348c688d042SShri Abhyankar @*/
3349d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPostEvaluate(TS ts)
3350d71ae5a4SJacob Faibussowitsch {
3351c688d042SShri Abhyankar   PetscFunctionBegin;
3352c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3353c688d042SShri Abhyankar   if (ts->postevaluate) {
3354dcb233daSLisandro Dalcin     Vec              U;
3355dcb233daSLisandro Dalcin     PetscObjectState sprev, spost;
3356dcb233daSLisandro Dalcin 
33579566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
33589566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
335925e27a38SBarry Smith     PetscCallBack("TS callback postevaluate", (*ts->postevaluate)(ts));
33609566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
33619566063dSJacob Faibussowitsch     if (sprev != spost) PetscCall(TSRestartStep(ts));
3362c688d042SShri Abhyankar   }
33633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3364c688d042SShri Abhyankar }
3365c688d042SShri Abhyankar 
3366ac226902SBarry Smith /*@C
3367000e7ae3SMatthew Knepley   TSSetPostStep - Sets the general-purpose function
33680d56bcf9SIlya Fursov   called once at the end of each successful time step.
3369000e7ae3SMatthew Knepley 
3370c3339decSBarry Smith   Logically Collective
3371000e7ae3SMatthew Knepley 
3372000e7ae3SMatthew Knepley   Input Parameters:
3373bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3374000e7ae3SMatthew Knepley - func - The function
3375000e7ae3SMatthew Knepley 
337620f4b53cSBarry Smith   Calling sequence of `func`:
337714d0ab18SJacob Faibussowitsch . ts - the `TS` context
3378000e7ae3SMatthew Knepley 
3379000e7ae3SMatthew Knepley   Level: intermediate
3380000e7ae3SMatthew Knepley 
3381bcf0153eSBarry Smith   Note:
33820d56bcf9SIlya Fursov   The function set by `TSSetPostStep()` is called after each successful step. If the event handler locates an event at the
33830d56bcf9SIlya Fursov   given step, and `postevent()` modifies the solution vector, the solution vector obtained by `TSGetSolution()` inside `func` will
33840d56bcf9SIlya Fursov   contain the changes. To get the solution without these changes, use `TSSetPostEvaluate()` to set the appropriate callback.
33850d56bcf9SIlya Fursov   The scheme of the relevant function calls in `TSSolve()` is shown below
33860d56bcf9SIlya Fursov .vb
33870d56bcf9SIlya Fursov   ...
33880d56bcf9SIlya Fursov   Step()
33890d56bcf9SIlya Fursov   PostEvaluate()
33900d56bcf9SIlya Fursov   EventHandling()
33910d56bcf9SIlya Fursov   step_rollback ? PostEvaluate() : PostStep()
33920d56bcf9SIlya Fursov   ...
33930d56bcf9SIlya Fursov .ve
33940d56bcf9SIlya Fursov   where EventHandling() may result in one of the following three outcomes
33950d56bcf9SIlya Fursov .vb
33960d56bcf9SIlya Fursov   (1) | successful step | solution intact
33970d56bcf9SIlya Fursov   (2) | successful step | solution modified by `postevent()`
33980d56bcf9SIlya Fursov   (3) | step_rollback   | solution rolled back
33990d56bcf9SIlya Fursov .ve
3400bcf0153eSBarry Smith 
34011cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostEvaluate()`, `TSGetTimeStep()`, `TSGetStepNumber()`, `TSGetTime()`, `TSRestartStep()`
3402000e7ae3SMatthew Knepley @*/
340314d0ab18SJacob Faibussowitsch PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS ts))
3404d71ae5a4SJacob Faibussowitsch {
3405000e7ae3SMatthew Knepley   PetscFunctionBegin;
34060700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3407ae60f76fSBarry Smith   ts->poststep = func;
34083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3409000e7ae3SMatthew Knepley }
3410000e7ae3SMatthew Knepley 
341109ee8438SJed Brown /*@
3412195e9b02SBarry Smith   TSPostStep - Runs the user-defined post-step function that was set with `TSSetPostStep()`
34133f2090d5SJed Brown 
3414c3339decSBarry Smith   Collective
34153f2090d5SJed Brown 
34162fe279fdSBarry Smith   Input Parameter:
3417bcf0153eSBarry Smith . ts - The `TS` context obtained from `TSCreate()`
34183f2090d5SJed Brown 
3419bcf0153eSBarry Smith   Note:
3420bcf0153eSBarry Smith   `TSPostStep()` is typically used within time stepping implementations,
34213f2090d5SJed Brown   so most users would not generally call this routine themselves.
34223f2090d5SJed Brown 
34233f2090d5SJed Brown   Level: developer
34243f2090d5SJed Brown 
3425bfe80ac4SPierre Jolivet .seealso: [](ch_ts), `TS`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostEvaluate()`, `TSGetTimeStep()`, `TSGetStepNumber()`, `TSGetTime()`, `TSSetPostStep()`
34263f2090d5SJed Brown @*/
3427d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPostStep(TS ts)
3428d71ae5a4SJacob Faibussowitsch {
34293f2090d5SJed Brown   PetscFunctionBegin;
34300700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3431ae60f76fSBarry Smith   if (ts->poststep) {
34325efd42a4SStefano Zampini     Vec              U;
3433ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3434ef8d1ce0SJohann Rudi     PetscBool        sameObject;
34355efd42a4SStefano Zampini     PetscObjectState sprev, spost;
34365efd42a4SStefano Zampini 
34379566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
34389566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U, &idprev));
34399566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
344025e27a38SBarry Smith     PetscCallBack("TS callback poststep", (*ts->poststep)(ts));
34419566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
34429566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U, idprev, &sameObject));
34439566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
34449566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
344572ac3e02SJed Brown   }
34463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34473f2090d5SJed Brown }
34483f2090d5SJed Brown 
3449cd652676SJed Brown /*@
3450cd652676SJed Brown   TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3451cd652676SJed Brown 
3452c3339decSBarry Smith   Collective
3453cd652676SJed Brown 
34544165533cSJose E. Roman   Input Parameters:
3455cd652676SJed Brown + ts - time stepping context
3456cd652676SJed Brown - t  - time to interpolate to
3457cd652676SJed Brown 
34584165533cSJose E. Roman   Output Parameter:
34590910c330SBarry Smith . U - state at given time
3460cd652676SJed Brown 
3461cd652676SJed Brown   Level: intermediate
3462cd652676SJed Brown 
3463b43aa488SJacob Faibussowitsch   Developer Notes:
3464bcf0153eSBarry Smith   `TSInterpolate()` and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3465cd652676SJed Brown 
34661cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetExactFinalTime()`, `TSSolve()`
3467cd652676SJed Brown @*/
3468d71ae5a4SJacob Faibussowitsch PetscErrorCode TSInterpolate(TS ts, PetscReal t, Vec U)
3469d71ae5a4SJacob Faibussowitsch {
3470cd652676SJed Brown   PetscFunctionBegin;
3471cd652676SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3472b06615a5SLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
347363a3b9bcSJacob Faibussowitsch   PetscCheck(t >= ts->ptime_prev && t <= ts->ptime, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Requested time %g not in last time steps [%g,%g]", (double)t, (double)ts->ptime_prev, (double)ts->ptime);
3474dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, interpolate, t, U);
34753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3476cd652676SJed Brown }
3477cd652676SJed Brown 
3478d763cef2SBarry Smith /*@
34796d9e5789SSean Farley   TSStep - Steps one time step
3480d763cef2SBarry Smith 
3481c3339decSBarry Smith   Collective
3482d763cef2SBarry Smith 
3483d763cef2SBarry Smith   Input Parameter:
3484bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
3485d763cef2SBarry Smith 
348627829d71SBarry Smith   Level: developer
3487d763cef2SBarry Smith 
3488b8123daeSJed Brown   Notes:
3489bcf0153eSBarry Smith   The public interface for the ODE/DAE solvers is `TSSolve()`, you should almost for sure be using that routine and not this routine.
349027829d71SBarry Smith 
3491bcf0153eSBarry Smith   The hook set using `TSSetPreStep()` is called before each attempt to take the step. In general, the time step size may
3492b8123daeSJed Brown   be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3493b8123daeSJed Brown 
3494bcf0153eSBarry Smith   This may over-step the final time provided in `TSSetMaxTime()` depending on the time-step used. `TSSolve()` interpolates to exactly the
3495bcf0153eSBarry Smith   time provided in `TSSetMaxTime()`. One can use `TSInterpolate()` to determine an interpolated solution within the final timestep.
349625cb2221SBarry Smith 
34971cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSInterpolate()`
3498d763cef2SBarry Smith @*/
3499d71ae5a4SJacob Faibussowitsch PetscErrorCode TSStep(TS ts)
3500d71ae5a4SJacob Faibussowitsch {
3501fffbeea8SBarry Smith   static PetscBool cite = PETSC_FALSE;
3502be5899b3SLisandro Dalcin   PetscReal        ptime;
3503d763cef2SBarry Smith 
3504d763cef2SBarry Smith   PetscFunctionBegin;
35050700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3506d0609cedSBarry Smith   PetscCall(PetscCitationsRegister("@article{tspaper,\n"
3507fffbeea8SBarry Smith                                    "  title         = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3508f1d62c27SHong Zhang                                    "  author        = {Abhyankar, Shrirang and Brown, Jed and Constantinescu, Emil and Ghosh, Debojyoti and Smith, Barry F. and Zhang, Hong},\n"
3509f1d62c27SHong Zhang                                    "  journal       = {arXiv e-preprints},\n"
3510f1d62c27SHong Zhang                                    "  eprint        = {1806.01437},\n"
3511f1d62c27SHong Zhang                                    "  archivePrefix = {arXiv},\n"
35129371c9d4SSatish Balay                                    "  year          = {2018}\n}\n",
35139371c9d4SSatish Balay                                    &cite));
35149566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
35159566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory, ts));
3516136cf249SJames Wright   if (ts->eval_times)
3517136cf249SJames Wright     ts->eval_times->worktol = 0; /* In each step of TSSolve() 'eval_times->worktol' will be meaningfully defined (later) only once:
3518ca4445c7SIlya Fursov                                                    in TSAdaptChoose() or TSEvent_dt_cap(), and then reused till the end of the step */
3519d405a339SMatthew Knepley 
35208e562f8dSJames Wright   PetscCheck(ts->max_time < PETSC_MAX_REAL || ts->run_steps != PETSC_INT_MAX || ts->max_steps != PETSC_INT_MAX, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "You must call TSSetMaxTime(), TSSetMaxSteps(), or TSSetRunSteps() or use -ts_max_time <time>, -ts_max_steps <steps>, -ts_run_steps <steps>");
35213c633725SBarry Smith   PetscCheck(ts->exact_final_time != TS_EXACTFINALTIME_UNSPECIFIED, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSStep()");
35223c633725SBarry Smith   PetscCheck(ts->exact_final_time != TS_EXACTFINALTIME_MATCHSTEP || ts->adapt, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE");
3523a6772fa2SLisandro Dalcin 
3524c61711c8SStefano Zampini   if (!ts->vec_sol0) PetscCall(VecDuplicate(ts->vec_sol, &ts->vec_sol0));
3525c61711c8SStefano Zampini   PetscCall(VecCopy(ts->vec_sol, ts->vec_sol0));
3526c61711c8SStefano Zampini   ts->time_step0 = ts->time_step;
3527c61711c8SStefano Zampini 
3528be5899b3SLisandro Dalcin   if (!ts->steps) ts->ptime_prev = ts->ptime;
35299371c9d4SSatish Balay   ptime = ts->ptime;
3530c61711c8SStefano Zampini 
35319371c9d4SSatish Balay   ts->ptime_prev_rollback = ts->ptime_prev;
35322808aa04SLisandro Dalcin   ts->reason              = TS_CONVERGED_ITERATING;
3533fc8dbba5SLisandro Dalcin 
35349566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_Step, ts, 0, 0, 0));
3535dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, step);
35369566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_Step, ts, 0, 0, 0));
3537fc8dbba5SLisandro Dalcin 
3538fc8dbba5SLisandro Dalcin   if (ts->reason >= 0) {
3539be5899b3SLisandro Dalcin     ts->ptime_prev = ptime;
35402808aa04SLisandro Dalcin     ts->steps++;
3541be5899b3SLisandro Dalcin     ts->steprollback = PETSC_FALSE;
354228d5b5d6SLisandro Dalcin     ts->steprestart  = PETSC_FALSE;
3543c6bf8827SStefano Zampini     ts->stepresize   = PETSC_FALSE;
3544d2daff3dSHong Zhang   }
3545fc8dbba5SLisandro Dalcin 
35465c9bbc89SJed Brown   if (ts->reason < 0 && ts->errorifstepfailed) {
35475c9bbc89SJed Brown     PetscCall(TSMonitorCancel(ts));
3548764c9dfdSStefano Zampini     if (ts->usessnes && ts->snes) PetscCall(SNESMonitorCancel(ts->snes));
354909cb0f53SBarry Smith     PetscCheck(ts->reason != TS_DIVERGED_NONLINEAR_SOLVE, PetscObjectComm((PetscObject)ts), PETSC_ERR_NOT_CONVERGED, "TSStep has failed due to %s, increase -ts_max_snes_failures or use unlimited to attempt recovery", TSConvergedReasons[ts->reason]);
35505c9bbc89SJed Brown     SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_NOT_CONVERGED, "TSStep has failed due to %s", TSConvergedReasons[ts->reason]);
35515c9bbc89SJed Brown   }
35523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
355308c7845fSBarry Smith }
355408c7845fSBarry Smith 
355508c7845fSBarry Smith /*@
35567cbde773SLisandro Dalcin   TSEvaluateWLTE - Evaluate the weighted local truncation error norm
35577cbde773SLisandro Dalcin   at the end of a time step with a given order of accuracy.
35587cbde773SLisandro Dalcin 
3559c3339decSBarry Smith   Collective
35607cbde773SLisandro Dalcin 
35614165533cSJose E. Roman   Input Parameters:
35627cbde773SLisandro Dalcin + ts        - time stepping context
3563bcf0153eSBarry Smith - wnormtype - norm type, either `NORM_2` or `NORM_INFINITY`
35647cbde773SLisandro Dalcin 
356597bb3fdcSJose E. Roman   Input/Output Parameter:
3566bcf0153eSBarry Smith . order - optional, desired order for the error evaluation or `PETSC_DECIDE`;
356797bb3fdcSJose E. Roman            on output, the actual order of the error evaluation
356897bb3fdcSJose E. Roman 
356997bb3fdcSJose E. Roman   Output Parameter:
357097bb3fdcSJose E. Roman . wlte - the weighted local truncation error norm
35717cbde773SLisandro Dalcin 
35727cbde773SLisandro Dalcin   Level: advanced
35737cbde773SLisandro Dalcin 
3574bcf0153eSBarry Smith   Note:
35757cbde773SLisandro Dalcin   If the timestepper cannot evaluate the error in a particular step
35767cbde773SLisandro Dalcin   (eg. in the first step or restart steps after event handling),
35777cbde773SLisandro Dalcin   this routine returns wlte=-1.0 .
35787cbde773SLisandro Dalcin 
35791cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSStep()`, `TSAdapt`, `TSErrorWeightedNorm()`
35807cbde773SLisandro Dalcin @*/
3581d71ae5a4SJacob Faibussowitsch PetscErrorCode TSEvaluateWLTE(TS ts, NormType wnormtype, PetscInt *order, PetscReal *wlte)
3582d71ae5a4SJacob Faibussowitsch {
35837cbde773SLisandro Dalcin   PetscFunctionBegin;
35847cbde773SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
35857cbde773SLisandro Dalcin   PetscValidType(ts, 1);
3586064a246eSJacob Faibussowitsch   PetscValidLogicalCollectiveEnum(ts, wnormtype, 2);
35874f572ea9SToby Isaac   if (order) PetscAssertPointer(order, 3);
35887cbde773SLisandro Dalcin   if (order) PetscValidLogicalCollectiveInt(ts, *order, 3);
35894f572ea9SToby Isaac   PetscAssertPointer(wlte, 4);
35903c633725SBarry Smith   PetscCheck(wnormtype == NORM_2 || wnormtype == NORM_INFINITY, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
3591dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, evaluatewlte, wnormtype, order, wlte);
35923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35937cbde773SLisandro Dalcin }
35947cbde773SLisandro Dalcin 
359505175c85SJed Brown /*@
359605175c85SJed Brown   TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
359705175c85SJed Brown 
3598c3339decSBarry Smith   Collective
359905175c85SJed Brown 
36004165533cSJose E. Roman   Input Parameters:
36011c3436cfSJed Brown + ts    - time stepping context
36021c3436cfSJed Brown . order - desired order of accuracy
3603195e9b02SBarry Smith - done  - whether the step was evaluated at this order (pass `NULL` to generate an error if not available)
360405175c85SJed Brown 
36054165533cSJose E. Roman   Output Parameter:
36060910c330SBarry Smith . U - state at the end of the current step
360705175c85SJed Brown 
360805175c85SJed Brown   Level: advanced
360905175c85SJed Brown 
3610108c343cSJed Brown   Notes:
3611108c343cSJed Brown   This function cannot be called until all stages have been evaluated.
3612108c343cSJed Brown 
3613bcf0153eSBarry Smith   It is normally called by adaptive controllers before a step has been accepted and may also be called by the user after `TSStep()` has returned.
3614bcf0153eSBarry Smith 
36151cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSStep()`, `TSAdapt`
361605175c85SJed Brown @*/
3617d71ae5a4SJacob Faibussowitsch PetscErrorCode TSEvaluateStep(TS ts, PetscInt order, Vec U, PetscBool *done)
3618d71ae5a4SJacob Faibussowitsch {
361905175c85SJed Brown   PetscFunctionBegin;
362005175c85SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
362105175c85SJed Brown   PetscValidType(ts, 1);
36220910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
3623dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, evaluatestep, order, U, done);
36243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
362505175c85SJed Brown }
362605175c85SJed Brown 
3627aad739acSMatthew G. Knepley /*@C
36282e61be88SMatthew G. Knepley   TSGetComputeInitialCondition - Get the function used to automatically compute an initial condition for the timestepping.
3629aad739acSMatthew G. Knepley 
3630aad739acSMatthew G. Knepley   Not collective
3631aad739acSMatthew G. Knepley 
36324165533cSJose E. Roman   Input Parameter:
3633aad739acSMatthew G. Knepley . ts - time stepping context
3634aad739acSMatthew G. Knepley 
36354165533cSJose E. Roman   Output Parameter:
3636b43aa488SJacob Faibussowitsch . initCondition - The function which computes an initial condition
3637aad739acSMatthew G. Knepley 
363820f4b53cSBarry Smith   Calling sequence of `initCondition`:
363920f4b53cSBarry Smith + ts - The timestepping context
364020f4b53cSBarry Smith - u  - The input vector in which the initial condition is stored
3641bcf0153eSBarry Smith 
3642aad739acSMatthew G. Knepley   Level: advanced
3643aad739acSMatthew G. Knepley 
36441cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetComputeInitialCondition()`, `TSComputeInitialCondition()`
3645aad739acSMatthew G. Knepley @*/
364614d0ab18SJacob Faibussowitsch PetscErrorCode TSGetComputeInitialCondition(TS ts, PetscErrorCode (**initCondition)(TS ts, Vec u))
3647d71ae5a4SJacob Faibussowitsch {
3648aad739acSMatthew G. Knepley   PetscFunctionBegin;
3649aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
36504f572ea9SToby Isaac   PetscAssertPointer(initCondition, 2);
36512e61be88SMatthew G. Knepley   *initCondition = ts->ops->initcondition;
36523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3653aad739acSMatthew G. Knepley }
3654aad739acSMatthew G. Knepley 
3655aad739acSMatthew G. Knepley /*@C
36562e61be88SMatthew G. Knepley   TSSetComputeInitialCondition - Set the function used to automatically compute an initial condition for the timestepping.
3657aad739acSMatthew G. Knepley 
3658c3339decSBarry Smith   Logically collective
3659aad739acSMatthew G. Knepley 
36604165533cSJose E. Roman   Input Parameters:
3661aad739acSMatthew G. Knepley + ts            - time stepping context
36622e61be88SMatthew G. Knepley - initCondition - The function which computes an initial condition
3663aad739acSMatthew G. Knepley 
366420f4b53cSBarry Smith   Calling sequence of `initCondition`:
3665a96d6ef6SBarry Smith + ts - The timestepping context
366614d0ab18SJacob Faibussowitsch - e  - The input vector in which the initial condition is to be stored
3667aad739acSMatthew G. Knepley 
3668bcf0153eSBarry Smith   Level: advanced
3669bcf0153eSBarry Smith 
36701cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetComputeInitialCondition()`, `TSComputeInitialCondition()`
3671aad739acSMatthew G. Knepley @*/
367214d0ab18SJacob Faibussowitsch PetscErrorCode TSSetComputeInitialCondition(TS ts, PetscErrorCode (*initCondition)(TS ts, Vec e))
3673d71ae5a4SJacob Faibussowitsch {
3674aad739acSMatthew G. Knepley   PetscFunctionBegin;
3675aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
36762e61be88SMatthew G. Knepley   PetscValidFunction(initCondition, 2);
36772e61be88SMatthew G. Knepley   ts->ops->initcondition = initCondition;
36783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3679aad739acSMatthew G. Knepley }
3680aad739acSMatthew G. Knepley 
3681aad739acSMatthew G. Knepley /*@
3682bcf0153eSBarry Smith   TSComputeInitialCondition - Compute an initial condition for the timestepping using the function previously set with `TSSetComputeInitialCondition()`
3683aad739acSMatthew G. Knepley 
3684c3339decSBarry Smith   Collective
3685aad739acSMatthew G. Knepley 
36864165533cSJose E. Roman   Input Parameters:
3687aad739acSMatthew G. Knepley + ts - time stepping context
3688bcf0153eSBarry Smith - u  - The `Vec` to store the condition in which will be used in `TSSolve()`
3689aad739acSMatthew G. Knepley 
3690aad739acSMatthew G. Knepley   Level: advanced
3691aad739acSMatthew G. Knepley 
36921cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3693aad739acSMatthew G. Knepley @*/
3694d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeInitialCondition(TS ts, Vec u)
3695d71ae5a4SJacob Faibussowitsch {
3696aad739acSMatthew G. Knepley   PetscFunctionBegin;
3697aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3698aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3699dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, initcondition, u);
37003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3701aad739acSMatthew G. Knepley }
3702aad739acSMatthew G. Knepley 
3703aad739acSMatthew G. Knepley /*@C
3704aad739acSMatthew G. Knepley   TSGetComputeExactError - Get the function used to automatically compute the exact error for the timestepping.
3705aad739acSMatthew G. Knepley 
3706aad739acSMatthew G. Knepley   Not collective
3707aad739acSMatthew G. Knepley 
37084165533cSJose E. Roman   Input Parameter:
3709aad739acSMatthew G. Knepley . ts - time stepping context
3710aad739acSMatthew G. Knepley 
37114165533cSJose E. Roman   Output Parameter:
3712aad739acSMatthew G. Knepley . exactError - The function which computes the solution error
3713aad739acSMatthew G. Knepley 
371420f4b53cSBarry Smith   Calling sequence of `exactError`:
3715a96d6ef6SBarry Smith + ts - The timestepping context
3716a96d6ef6SBarry Smith . u  - The approximate solution vector
371720f4b53cSBarry Smith - e  - The vector in which the error is stored
3718aad739acSMatthew G. Knepley 
3719bcf0153eSBarry Smith   Level: advanced
3720bcf0153eSBarry Smith 
372142747ad1SJacob Faibussowitsch .seealso: [](ch_ts), `TS`, `TSComputeExactError()`
3722aad739acSMatthew G. Knepley @*/
372314d0ab18SJacob Faibussowitsch PetscErrorCode TSGetComputeExactError(TS ts, PetscErrorCode (**exactError)(TS ts, Vec u, Vec e))
3724d71ae5a4SJacob Faibussowitsch {
3725aad739acSMatthew G. Knepley   PetscFunctionBegin;
3726aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
37274f572ea9SToby Isaac   PetscAssertPointer(exactError, 2);
3728aad739acSMatthew G. Knepley   *exactError = ts->ops->exacterror;
37293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3730aad739acSMatthew G. Knepley }
3731aad739acSMatthew G. Knepley 
3732aad739acSMatthew G. Knepley /*@C
3733aad739acSMatthew G. Knepley   TSSetComputeExactError - Set the function used to automatically compute the exact error for the timestepping.
3734aad739acSMatthew G. Knepley 
3735c3339decSBarry Smith   Logically collective
3736aad739acSMatthew G. Knepley 
37374165533cSJose E. Roman   Input Parameters:
3738aad739acSMatthew G. Knepley + ts         - time stepping context
3739aad739acSMatthew G. Knepley - exactError - The function which computes the solution error
3740aad739acSMatthew G. Knepley 
374120f4b53cSBarry Smith   Calling sequence of `exactError`:
3742a96d6ef6SBarry Smith + ts - The timestepping context
3743a96d6ef6SBarry Smith . u  - The approximate solution vector
374420f4b53cSBarry Smith - e  - The  vector in which the error is stored
3745aad739acSMatthew G. Knepley 
3746bcf0153eSBarry Smith   Level: advanced
3747bcf0153eSBarry Smith 
37481cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetComputeExactError()`, `TSComputeExactError()`
3749aad739acSMatthew G. Knepley @*/
375014d0ab18SJacob Faibussowitsch PetscErrorCode TSSetComputeExactError(TS ts, PetscErrorCode (*exactError)(TS ts, Vec u, Vec e))
3751d71ae5a4SJacob Faibussowitsch {
3752aad739acSMatthew G. Knepley   PetscFunctionBegin;
3753aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3754f907fdbfSMatthew G. Knepley   PetscValidFunction(exactError, 2);
3755aad739acSMatthew G. Knepley   ts->ops->exacterror = exactError;
37563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3757aad739acSMatthew G. Knepley }
3758aad739acSMatthew G. Knepley 
3759aad739acSMatthew G. Knepley /*@
3760bcf0153eSBarry Smith   TSComputeExactError - Compute the solution error for the timestepping using the function previously set with `TSSetComputeExactError()`
3761aad739acSMatthew G. Knepley 
3762c3339decSBarry Smith   Collective
3763aad739acSMatthew G. Knepley 
37644165533cSJose E. Roman   Input Parameters:
3765aad739acSMatthew G. Knepley + ts - time stepping context
3766aad739acSMatthew G. Knepley . u  - The approximate solution
3767bcf0153eSBarry Smith - e  - The `Vec` used to store the error
3768aad739acSMatthew G. Knepley 
3769aad739acSMatthew G. Knepley   Level: advanced
3770aad739acSMatthew G. Knepley 
37711cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3772aad739acSMatthew G. Knepley @*/
3773d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeExactError(TS ts, Vec u, Vec e)
3774d71ae5a4SJacob Faibussowitsch {
3775aad739acSMatthew G. Knepley   PetscFunctionBegin;
3776aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3777aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3778aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(e, VEC_CLASSID, 3);
3779dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, exacterror, u, e);
37803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3781aad739acSMatthew G. Knepley }
3782aad739acSMatthew G. Knepley 
37836bd3a4fdSStefano Zampini /*@C
37846bd3a4fdSStefano Zampini   TSSetResize - Sets the resize callbacks.
37856bd3a4fdSStefano Zampini 
37866bd3a4fdSStefano Zampini   Logically Collective
37876bd3a4fdSStefano Zampini 
37886bd3a4fdSStefano Zampini   Input Parameters:
37896bd3a4fdSStefano Zampini + ts       - The `TS` context obtained from `TSCreate()`
3790ecc87898SStefano Zampini . rollback - Whether a resize will restart the step
37916bd3a4fdSStefano Zampini . setup    - The setup function
379214d0ab18SJacob Faibussowitsch . transfer - The transfer function
379314d0ab18SJacob Faibussowitsch - ctx      - [optional] The user-defined context
37946bd3a4fdSStefano Zampini 
37956bd3a4fdSStefano Zampini   Calling sequence of `setup`:
37968847d985SBarry Smith + ts     - the `TS` context
37976bd3a4fdSStefano Zampini . step   - the current step
37986bd3a4fdSStefano Zampini . time   - the current time
37996bd3a4fdSStefano Zampini . state  - the current vector of state
38006bd3a4fdSStefano Zampini . resize - (output parameter) `PETSC_TRUE` if need resizing, `PETSC_FALSE` otherwise
38016bd3a4fdSStefano Zampini - ctx    - user defined context
38026bd3a4fdSStefano Zampini 
38036bd3a4fdSStefano Zampini   Calling sequence of `transfer`:
38048847d985SBarry Smith + ts      - the `TS` context
38056bd3a4fdSStefano Zampini . nv      - the number of vectors to be transferred
38066bd3a4fdSStefano Zampini . vecsin  - array of vectors to be transferred
38076bd3a4fdSStefano Zampini . vecsout - array of transferred vectors
38086bd3a4fdSStefano Zampini - ctx     - user defined context
38096bd3a4fdSStefano Zampini 
38106bd3a4fdSStefano Zampini   Notes:
3811ecc87898SStefano Zampini   The `setup` function is called inside `TSSolve()` after `TSEventHandler()` or after `TSPostStep()`
3812ecc87898SStefano Zampini   depending on the `rollback` value: if `rollback` is true, then these callbacks behave as error indicators
3813ecc87898SStefano Zampini   and will flag the need to remesh and restart the current step. Otherwise, they will simply flag the solver
3814ecc87898SStefano Zampini   that the size of the discrete problem has changed.
3815ecc87898SStefano Zampini   In both cases, the solver will collect the needed vectors that will be
3816ecc87898SStefano Zampini   transferred from the old to the new sizes using the `transfer` callback. These vectors will include the
3817ecc87898SStefano Zampini   current solution vector, and other vectors needed by the specific solver used.
38186bd3a4fdSStefano Zampini   For example, `TSBDF` uses previous solutions vectors to solve for the next time step.
38196bd3a4fdSStefano Zampini   Other application specific objects associated with the solver, i.e. Jacobian matrices and `DM`,
38206bd3a4fdSStefano Zampini   will be automatically reset if the sizes are changed and they must be specified again by the user
38216bd3a4fdSStefano Zampini   inside the `transfer` function.
38226bd3a4fdSStefano Zampini   The input and output arrays passed to `transfer` are allocated by PETSc.
38236bd3a4fdSStefano Zampini   Vectors in `vecsout` must be created by the user.
38246bd3a4fdSStefano Zampini   Ownership of vectors in `vecsout` is transferred to PETSc.
38256bd3a4fdSStefano Zampini 
38266bd3a4fdSStefano Zampini   Level: advanced
38276bd3a4fdSStefano Zampini 
38286bd3a4fdSStefano Zampini .seealso: [](ch_ts), `TS`, `TSSetDM()`, `TSSetIJacobian()`, `TSSetRHSJacobian()`
38296bd3a4fdSStefano Zampini @*/
3830ecc87898SStefano Zampini PetscErrorCode TSSetResize(TS ts, PetscBool rollback, PetscErrorCode (*setup)(TS ts, PetscInt step, PetscReal time, Vec state, PetscBool *resize, void *ctx), PetscErrorCode (*transfer)(TS ts, PetscInt nv, Vec vecsin[], Vec vecsout[], void *ctx), void *ctx)
38316bd3a4fdSStefano Zampini {
38326bd3a4fdSStefano Zampini   PetscFunctionBegin;
38336bd3a4fdSStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3834ecc87898SStefano Zampini   ts->resizerollback = rollback;
38356bd3a4fdSStefano Zampini   ts->resizesetup    = setup;
38366bd3a4fdSStefano Zampini   ts->resizetransfer = transfer;
38376bd3a4fdSStefano Zampini   ts->resizectx      = ctx;
38386bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
38396bd3a4fdSStefano Zampini }
38406bd3a4fdSStefano Zampini 
384114d0ab18SJacob Faibussowitsch /*
38426bd3a4fdSStefano Zampini   TSResizeRegisterOrRetrieve - Register or import vectors transferred with `TSResize()`.
38436bd3a4fdSStefano Zampini 
38446bd3a4fdSStefano Zampini   Collective
38456bd3a4fdSStefano Zampini 
38466bd3a4fdSStefano Zampini   Input Parameters:
38476bd3a4fdSStefano Zampini + ts   - The `TS` context obtained from `TSCreate()`
38486bd3a4fdSStefano Zampini - flg - If `PETSC_TRUE` each TS implementation (e.g. `TSBDF`) will register vectors to be transferred, if `PETSC_FALSE` vectors will be imported from transferred vectors.
38496bd3a4fdSStefano Zampini 
38506bd3a4fdSStefano Zampini   Level: developer
38516bd3a4fdSStefano Zampini 
38526bd3a4fdSStefano Zampini   Note:
38536bd3a4fdSStefano Zampini   `TSResizeRegisterOrRetrieve()` is declared PETSC_INTERN since it is
38546bd3a4fdSStefano Zampini    used within time stepping implementations,
38556bd3a4fdSStefano Zampini    so most users would not generally call this routine themselves.
38566bd3a4fdSStefano Zampini 
38576bd3a4fdSStefano Zampini .seealso: [](ch_ts), `TS`, `TSSetResize()`
38586bd3a4fdSStefano Zampini @*/
385914d0ab18SJacob Faibussowitsch static PetscErrorCode TSResizeRegisterOrRetrieve(TS ts, PetscBool flg)
38606bd3a4fdSStefano Zampini {
38616bd3a4fdSStefano Zampini   PetscFunctionBegin;
38626bd3a4fdSStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
38636bd3a4fdSStefano Zampini   PetscTryTypeMethod(ts, resizeregister, flg);
38646bd3a4fdSStefano Zampini   /* PetscTryTypeMethod(adapt, resizeregister, flg); */
38656bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
38666bd3a4fdSStefano Zampini }
38676bd3a4fdSStefano Zampini 
386814d0ab18SJacob Faibussowitsch static PetscErrorCode TSResizeReset(TS ts)
38696bd3a4fdSStefano Zampini {
38706bd3a4fdSStefano Zampini   PetscFunctionBegin;
38716bd3a4fdSStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
38726bd3a4fdSStefano Zampini   PetscCall(PetscObjectListDestroy(&ts->resizetransferobjs));
38736bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
38746bd3a4fdSStefano Zampini }
38756bd3a4fdSStefano Zampini 
38766bd3a4fdSStefano Zampini static PetscErrorCode TSResizeTransferVecs(TS ts, PetscInt cnt, Vec vecsin[], Vec vecsout[])
38776bd3a4fdSStefano Zampini {
38786bd3a4fdSStefano Zampini   PetscFunctionBegin;
38796bd3a4fdSStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
38806bd3a4fdSStefano Zampini   PetscValidLogicalCollectiveInt(ts, cnt, 2);
38816bd3a4fdSStefano Zampini   for (PetscInt i = 0; i < cnt; i++) PetscCall(VecLockReadPush(vecsin[i]));
38826bd3a4fdSStefano Zampini   if (ts->resizetransfer) {
38836bd3a4fdSStefano Zampini     PetscCall(PetscInfo(ts, "Transferring %" PetscInt_FMT " vectors\n", cnt));
38846bd3a4fdSStefano Zampini     PetscCallBack("TS callback resize transfer", (*ts->resizetransfer)(ts, cnt, vecsin, vecsout, ts->resizectx));
38856bd3a4fdSStefano Zampini   }
38866bd3a4fdSStefano Zampini   for (PetscInt i = 0; i < cnt; i++) PetscCall(VecLockReadPop(vecsin[i]));
38876bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
38886bd3a4fdSStefano Zampini }
38896bd3a4fdSStefano Zampini 
38906bd3a4fdSStefano Zampini /*@C
38916bd3a4fdSStefano Zampini   TSResizeRegisterVec - Register a vector to be transferred with `TSResize()`.
38926bd3a4fdSStefano Zampini 
38936bd3a4fdSStefano Zampini   Collective
38946bd3a4fdSStefano Zampini 
38956bd3a4fdSStefano Zampini   Input Parameters:
38966bd3a4fdSStefano Zampini + ts   - The `TS` context obtained from `TSCreate()`
3897baca6076SPierre Jolivet . name - A string identifying the vector
38986bd3a4fdSStefano Zampini - vec  - The vector
38996bd3a4fdSStefano Zampini 
39006bd3a4fdSStefano Zampini   Level: developer
39016bd3a4fdSStefano Zampini 
39026bd3a4fdSStefano Zampini   Note:
39036bd3a4fdSStefano Zampini   `TSResizeRegisterVec()` is typically used within time stepping implementations,
39046bd3a4fdSStefano Zampini   so most users would not generally call this routine themselves.
39056bd3a4fdSStefano Zampini 
39066bd3a4fdSStefano Zampini .seealso: [](ch_ts), `TS`, `TSSetResize()`, `TSResize()`, `TSResizeRetrieveVec()`
39076bd3a4fdSStefano Zampini @*/
3908cc4c1da9SBarry Smith PetscErrorCode TSResizeRegisterVec(TS ts, const char name[], Vec vec)
39096bd3a4fdSStefano Zampini {
39106bd3a4fdSStefano Zampini   PetscFunctionBegin;
39116bd3a4fdSStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
39124f572ea9SToby Isaac   PetscAssertPointer(name, 2);
39136bd3a4fdSStefano Zampini   if (vec) PetscValidHeaderSpecific(vec, VEC_CLASSID, 3);
39146bd3a4fdSStefano Zampini   PetscCall(PetscObjectListAdd(&ts->resizetransferobjs, name, (PetscObject)vec));
39156bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
39166bd3a4fdSStefano Zampini }
39176bd3a4fdSStefano Zampini 
39186bd3a4fdSStefano Zampini /*@C
39196bd3a4fdSStefano Zampini   TSResizeRetrieveVec - Retrieve a vector registered with `TSResizeRegisterVec()`.
39206bd3a4fdSStefano Zampini 
39216bd3a4fdSStefano Zampini   Collective
39226bd3a4fdSStefano Zampini 
39236bd3a4fdSStefano Zampini   Input Parameters:
39246bd3a4fdSStefano Zampini + ts   - The `TS` context obtained from `TSCreate()`
3925baca6076SPierre Jolivet . name - A string identifying the vector
39266bd3a4fdSStefano Zampini - vec  - The vector
39276bd3a4fdSStefano Zampini 
39286bd3a4fdSStefano Zampini   Level: developer
39296bd3a4fdSStefano Zampini 
39306bd3a4fdSStefano Zampini   Note:
39316bd3a4fdSStefano Zampini   `TSResizeRetrieveVec()` is typically used within time stepping implementations,
39326bd3a4fdSStefano Zampini   so most users would not generally call this routine themselves.
39336bd3a4fdSStefano Zampini 
39346bd3a4fdSStefano Zampini .seealso: [](ch_ts), `TS`, `TSSetResize()`, `TSResize()`, `TSResizeRegisterVec()`
39356bd3a4fdSStefano Zampini @*/
3936cc4c1da9SBarry Smith PetscErrorCode TSResizeRetrieveVec(TS ts, const char name[], Vec *vec)
39376bd3a4fdSStefano Zampini {
39386bd3a4fdSStefano Zampini   PetscFunctionBegin;
39396bd3a4fdSStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
39404f572ea9SToby Isaac   PetscAssertPointer(name, 2);
39414f572ea9SToby Isaac   PetscAssertPointer(vec, 3);
39426bd3a4fdSStefano Zampini   PetscCall(PetscObjectListFind(ts->resizetransferobjs, name, (PetscObject *)vec));
39436bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
39446bd3a4fdSStefano Zampini }
39456bd3a4fdSStefano Zampini 
39466bd3a4fdSStefano Zampini static PetscErrorCode TSResizeGetVecArray(TS ts, PetscInt *nv, const char **names[], Vec *vecs[])
39476bd3a4fdSStefano Zampini {
39486bd3a4fdSStefano Zampini   PetscInt        cnt;
39496bd3a4fdSStefano Zampini   PetscObjectList tmp;
39506bd3a4fdSStefano Zampini   Vec            *vecsin  = NULL;
39516bd3a4fdSStefano Zampini   const char    **namesin = NULL;
39526bd3a4fdSStefano Zampini 
39536bd3a4fdSStefano Zampini   PetscFunctionBegin;
39546bd3a4fdSStefano Zampini   for (tmp = ts->resizetransferobjs, cnt = 0; tmp; tmp = tmp->next)
39556bd3a4fdSStefano Zampini     if (tmp->obj && tmp->obj->classid == VEC_CLASSID) cnt++;
395603ba6ac9SBarry Smith   if (names) PetscCall(PetscMalloc1(cnt, &namesin));
395703ba6ac9SBarry Smith   if (vecs) PetscCall(PetscMalloc1(cnt, &vecsin));
39586bd3a4fdSStefano Zampini   for (tmp = ts->resizetransferobjs, cnt = 0; tmp; tmp = tmp->next) {
39596bd3a4fdSStefano Zampini     if (tmp->obj && tmp->obj->classid == VEC_CLASSID) {
39606bd3a4fdSStefano Zampini       if (vecs) vecsin[cnt] = (Vec)tmp->obj;
39616bd3a4fdSStefano Zampini       if (names) namesin[cnt] = tmp->name;
39626bd3a4fdSStefano Zampini       cnt++;
39636bd3a4fdSStefano Zampini     }
39646bd3a4fdSStefano Zampini   }
39656bd3a4fdSStefano Zampini   if (nv) *nv = cnt;
39666bd3a4fdSStefano Zampini   if (names) *names = namesin;
39676bd3a4fdSStefano Zampini   if (vecs) *vecs = vecsin;
39686bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
39696bd3a4fdSStefano Zampini }
39706bd3a4fdSStefano Zampini 
39716bd3a4fdSStefano Zampini /*@
39726bd3a4fdSStefano Zampini   TSResize - Runs the user-defined transfer functions provided with `TSSetResize()`
39736bd3a4fdSStefano Zampini 
39746bd3a4fdSStefano Zampini   Collective
39756bd3a4fdSStefano Zampini 
39766bd3a4fdSStefano Zampini   Input Parameter:
39776bd3a4fdSStefano Zampini . ts - The `TS` context obtained from `TSCreate()`
39786bd3a4fdSStefano Zampini 
39796bd3a4fdSStefano Zampini   Level: developer
39806bd3a4fdSStefano Zampini 
39816bd3a4fdSStefano Zampini   Note:
39826bd3a4fdSStefano Zampini   `TSResize()` is typically used within time stepping implementations,
39836bd3a4fdSStefano Zampini   so most users would not generally call this routine themselves.
39846bd3a4fdSStefano Zampini 
39856bd3a4fdSStefano Zampini .seealso: [](ch_ts), `TS`, `TSSetResize()`
39866bd3a4fdSStefano Zampini @*/
39876bd3a4fdSStefano Zampini PetscErrorCode TSResize(TS ts)
39886bd3a4fdSStefano Zampini {
39896bd3a4fdSStefano Zampini   PetscInt     nv      = 0;
39906bd3a4fdSStefano Zampini   const char **names   = NULL;
39916bd3a4fdSStefano Zampini   Vec         *vecsin  = NULL;
39926bd3a4fdSStefano Zampini   const char  *solname = "ts:vec_sol";
39936bd3a4fdSStefano Zampini 
39946bd3a4fdSStefano Zampini   PetscFunctionBegin;
39956bd3a4fdSStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3996ecc87898SStefano Zampini   if (!ts->resizesetup) PetscFunctionReturn(PETSC_SUCCESS);
39976bd3a4fdSStefano Zampini   if (ts->resizesetup) {
39986bd3a4fdSStefano Zampini     PetscCall(VecLockReadPush(ts->vec_sol));
3999c6bf8827SStefano Zampini     PetscCallBack("TS callback resize setup", (*ts->resizesetup)(ts, ts->steps, ts->ptime, ts->vec_sol, &ts->stepresize, ts->resizectx));
40006bd3a4fdSStefano Zampini     PetscCall(VecLockReadPop(ts->vec_sol));
4001c6bf8827SStefano Zampini     if (ts->stepresize) {
4002ecc87898SStefano Zampini       if (ts->resizerollback) {
4003ecc87898SStefano Zampini         PetscCall(TSRollBack(ts));
4004ecc87898SStefano Zampini         ts->time_step = ts->time_step0;
4005ecc87898SStefano Zampini       }
40066bd3a4fdSStefano Zampini       PetscCall(TSResizeRegisterVec(ts, solname, ts->vec_sol));
40076bd3a4fdSStefano Zampini       PetscCall(TSResizeRegisterOrRetrieve(ts, PETSC_TRUE)); /* specific impls register their own objects */
40086bd3a4fdSStefano Zampini     }
40096bd3a4fdSStefano Zampini   }
40106bd3a4fdSStefano Zampini 
40116bd3a4fdSStefano Zampini   PetscCall(TSResizeGetVecArray(ts, &nv, &names, &vecsin));
40126bd3a4fdSStefano Zampini   if (nv) {
40136bd3a4fdSStefano Zampini     Vec *vecsout, vecsol;
40146bd3a4fdSStefano Zampini 
40156bd3a4fdSStefano Zampini     /* Reset internal objects */
40166bd3a4fdSStefano Zampini     PetscCall(TSReset(ts));
40176bd3a4fdSStefano Zampini 
4018ecc87898SStefano Zampini     /* Transfer needed vectors (users can call SetJacobian, SetDM, etc. here) */
40196bd3a4fdSStefano Zampini     PetscCall(PetscCalloc1(nv, &vecsout));
40206bd3a4fdSStefano Zampini     PetscCall(TSResizeTransferVecs(ts, nv, vecsin, vecsout));
40216bd3a4fdSStefano Zampini     for (PetscInt i = 0; i < nv; i++) {
4022ecc87898SStefano Zampini       const char *name;
4023ecc87898SStefano Zampini       char       *oname;
4024ecc87898SStefano Zampini 
4025ecc87898SStefano Zampini       PetscCall(PetscObjectGetName((PetscObject)vecsin[i], &name));
4026ecc87898SStefano Zampini       PetscCall(PetscStrallocpy(name, &oname));
40276bd3a4fdSStefano Zampini       PetscCall(TSResizeRegisterVec(ts, names[i], vecsout[i]));
4028ecc87898SStefano Zampini       if (vecsout[i]) PetscCall(PetscObjectSetName((PetscObject)vecsout[i], oname));
4029ecc87898SStefano Zampini       PetscCall(PetscFree(oname));
40306bd3a4fdSStefano Zampini       PetscCall(VecDestroy(&vecsout[i]));
40316bd3a4fdSStefano Zampini     }
40326bd3a4fdSStefano Zampini     PetscCall(PetscFree(vecsout));
40336bd3a4fdSStefano Zampini     PetscCall(TSResizeRegisterOrRetrieve(ts, PETSC_FALSE)); /* specific impls import the transferred objects */
40346bd3a4fdSStefano Zampini 
40356bd3a4fdSStefano Zampini     PetscCall(TSResizeRetrieveVec(ts, solname, &vecsol));
40366bd3a4fdSStefano Zampini     if (vecsol) PetscCall(TSSetSolution(ts, vecsol));
40376bd3a4fdSStefano Zampini     PetscAssert(ts->vec_sol, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_NULL, "Missing TS solution");
40386bd3a4fdSStefano Zampini   }
40396bd3a4fdSStefano Zampini 
40406bd3a4fdSStefano Zampini   PetscCall(PetscFree(names));
40416bd3a4fdSStefano Zampini   PetscCall(PetscFree(vecsin));
40426bd3a4fdSStefano Zampini   PetscCall(TSResizeReset(ts));
40436bd3a4fdSStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
40446bd3a4fdSStefano Zampini }
40456bd3a4fdSStefano Zampini 
4046b1cb36f3SHong Zhang /*@
40476a4d4014SLisandro Dalcin   TSSolve - Steps the requested number of timesteps.
40486a4d4014SLisandro Dalcin 
4049c3339decSBarry Smith   Collective
40506a4d4014SLisandro Dalcin 
4051d8d19677SJose E. Roman   Input Parameters:
4052bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()`
4053bcf0153eSBarry Smith - u  - the solution vector  (can be null if `TSSetSolution()` was used and `TSSetExactFinalTime`(ts,`TS_EXACTFINALTIME_MATCHSTEP`) was not used,
40540b4b7b1cSBarry Smith        otherwise it must contain the initial conditions and will contain the solution at the final requested time
40555a3a76d0SJed Brown 
40566a4d4014SLisandro Dalcin   Level: beginner
40576a4d4014SLisandro Dalcin 
40585a3a76d0SJed Brown   Notes:
40595a3a76d0SJed Brown   The final time returned by this function may be different from the time of the internally
4060bcf0153eSBarry Smith   held state accessible by `TSGetSolution()` and `TSGetTime()` because the method may have
40615a3a76d0SJed Brown   stepped over the final time.
40625a3a76d0SJed Brown 
40631cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSCreate()`, `TSSetSolution()`, `TSStep()`, `TSGetTime()`, `TSGetSolveTime()`
40646a4d4014SLisandro Dalcin @*/
4065d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSolve(TS ts, Vec u)
4066d71ae5a4SJacob Faibussowitsch {
4067b06615a5SLisandro Dalcin   Vec solution;
4068f22f69f0SBarry Smith 
40696a4d4014SLisandro Dalcin   PetscFunctionBegin;
40700700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4071f2c2a1b9SBarry Smith   if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
4072303a5415SBarry Smith 
40739566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
4074ee41a567SStefano Zampini   if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && u) { /* Need ts->vec_sol to be distinct so it is not overwritten when we interpolate at the end */
40750910c330SBarry Smith     if (!ts->vec_sol || u == ts->vec_sol) {
40769566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u, &solution));
40779566063dSJacob Faibussowitsch       PetscCall(TSSetSolution(ts, solution));
40789566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&solution)); /* grant ownership */
40795a3a76d0SJed Brown     }
40809566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ts->vec_sol));
40813c633725SBarry Smith     PetscCheck(!ts->forward_solve, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE");
40821baa6e33SBarry Smith   } else if (u) PetscCall(TSSetSolution(ts, u));
40839566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
40849566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory, ts));
4085a6772fa2SLisandro Dalcin 
40868e562f8dSJames Wright   PetscCheck(ts->max_time < PETSC_MAX_REAL || ts->run_steps != PETSC_INT_MAX || ts->max_steps != PETSC_INT_MAX, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "You must call TSSetMaxTime(), TSSetMaxSteps(), or TSSetRunSteps() or use -ts_max_time <time>, -ts_max_steps <steps>, -ts_run_steps <steps>");
40873c633725SBarry Smith   PetscCheck(ts->exact_final_time != TS_EXACTFINALTIME_UNSPECIFIED, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "You must call TSSetExactFinalTime() or use -ts_exact_final_time <stepover,interpolate,matchstep> before calling TSSolve()");
40883c633725SBarry Smith   PetscCheck(ts->exact_final_time != TS_EXACTFINALTIME_MATCHSTEP || ts->adapt, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Since TS is not adaptive you cannot use TS_EXACTFINALTIME_MATCHSTEP, suggest TS_EXACTFINALTIME_INTERPOLATE");
4089136cf249SJames Wright   PetscCheck(!(ts->eval_times && ts->exact_final_time != TS_EXACTFINALTIME_MATCHSTEP), PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "You must use TS_EXACTFINALTIME_MATCHSTEP when using time span or evaluation times");
40904a658b32SHong Zhang 
4091136cf249SJames Wright   if (ts->eval_times) {
4092264c38b7SJames Wright     if (!ts->eval_times->sol_vecs) PetscCall(VecDuplicateVecs(ts->vec_sol, ts->eval_times->num_time_points, &ts->eval_times->sol_vecs));
4093136cf249SJames Wright     for (PetscInt i = 0; i < ts->eval_times->num_time_points; i++) {
4094136cf249SJames Wright       PetscBool is_close = PetscIsCloseAtTol(ts->ptime, ts->eval_times->time_points[i], ts->eval_times->reltol * ts->time_step + ts->eval_times->abstol, 0);
4095136cf249SJames Wright       if (ts->ptime <= ts->eval_times->time_points[i] || is_close) {
4096136cf249SJames Wright         ts->eval_times->time_point_idx = i;
4097264c38b7SJames Wright 
4098264c38b7SJames Wright         PetscBool is_ptime_in_sol_times = PETSC_FALSE; // If current solution has already been saved, we should not save it again
4099264c38b7SJames Wright         if (ts->eval_times->sol_idx > 0) is_ptime_in_sol_times = PetscIsCloseAtTol(ts->ptime, ts->eval_times->sol_times[ts->eval_times->sol_idx - 1], ts->eval_times->reltol * ts->time_step + ts->eval_times->abstol, 0);
4100264c38b7SJames Wright         if (is_close && !is_ptime_in_sol_times) {
4101264c38b7SJames Wright           PetscCall(VecCopy(ts->vec_sol, ts->eval_times->sol_vecs[ts->eval_times->sol_idx]));
4102264c38b7SJames Wright           ts->eval_times->sol_times[ts->eval_times->sol_idx] = ts->ptime;
4103264c38b7SJames Wright           ts->eval_times->sol_idx++;
4104136cf249SJames Wright           ts->eval_times->time_point_idx++;
41058343f784SJames Wright         }
41068343f784SJames Wright         break;
41078343f784SJames Wright       }
41088343f784SJames Wright     }
41094a658b32SHong Zhang   }
4110a6772fa2SLisandro Dalcin 
41111baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardSetUp(ts));
4112715f1b00SHong Zhang 
4113e7069c78SShri   /* reset number of steps only when the step is not restarted. ARKIMEX
4114715f1b00SHong Zhang      restarts the step after an event. Resetting these counters in such case causes
4115e7069c78SShri      TSTrajectory to incorrectly save the output files
4116e7069c78SShri   */
4117715f1b00SHong Zhang   /* reset time step and iteration counters */
41182808aa04SLisandro Dalcin   if (!ts->steps) {
41195ef26d82SJed Brown     ts->ksp_its           = 0;
41205ef26d82SJed Brown     ts->snes_its          = 0;
4121c610991cSLisandro Dalcin     ts->num_snes_failures = 0;
4122c610991cSLisandro Dalcin     ts->reject            = 0;
41232808aa04SLisandro Dalcin     ts->steprestart       = PETSC_TRUE;
41242808aa04SLisandro Dalcin     ts->steprollback      = PETSC_FALSE;
4125c6bf8827SStefano Zampini     ts->stepresize        = PETSC_FALSE;
41267d51462cSStefano Zampini     ts->rhsjacobian.time  = PETSC_MIN_REAL;
41272808aa04SLisandro Dalcin   }
4128e97c63d7SStefano Zampini 
4129136cf249SJames Wright   /* make sure initial time step does not overshoot final time or the next point in evaluation times */
4130e97c63d7SStefano Zampini   if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
41314a658b32SHong Zhang     PetscReal maxdt;
4132e97c63d7SStefano Zampini     PetscReal dt = ts->time_step;
4133e97c63d7SStefano Zampini 
4134136cf249SJames Wright     if (ts->eval_times) maxdt = ts->eval_times->time_points[ts->eval_times->time_point_idx] - ts->ptime;
41354a658b32SHong Zhang     else maxdt = ts->max_time - ts->ptime;
4136e97c63d7SStefano Zampini     ts->time_step = dt >= maxdt ? maxdt : (PetscIsCloseAtTol(dt, maxdt, 10 * PETSC_MACHINE_EPSILON, 0) ? maxdt : dt);
4137e97c63d7SStefano Zampini   }
4138193ac0bcSJed Brown   ts->reason = TS_CONVERGED_ITERATING;
4139193ac0bcSJed Brown 
4140900f6b5bSMatthew G. Knepley   {
4141900f6b5bSMatthew G. Knepley     PetscViewer       viewer;
4142900f6b5bSMatthew G. Knepley     PetscViewerFormat format;
4143900f6b5bSMatthew G. Knepley     PetscBool         flg;
4144900f6b5bSMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
4145900f6b5bSMatthew G. Knepley 
4146900f6b5bSMatthew G. Knepley     if (!incall) {
4147900f6b5bSMatthew G. Knepley       /* Estimate the convergence rate of the time discretization */
4148648c30bcSBarry Smith       PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_convergence_estimate", &viewer, &format, &flg));
4149900f6b5bSMatthew G. Knepley       if (flg) {
4150900f6b5bSMatthew G. Knepley         PetscConvEst conv;
4151900f6b5bSMatthew G. Knepley         DM           dm;
4152900f6b5bSMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
4153900f6b5bSMatthew G. Knepley         PetscInt     Nf;
4154f2ed2dc7SMatthew G. Knepley         PetscBool    checkTemporal = PETSC_TRUE;
4155900f6b5bSMatthew G. Knepley 
4156900f6b5bSMatthew G. Knepley         incall = PETSC_TRUE;
41579566063dSJacob Faibussowitsch         PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_convergence_temporal", &checkTemporal, &flg));
41589566063dSJacob Faibussowitsch         PetscCall(TSGetDM(ts, &dm));
41599566063dSJacob Faibussowitsch         PetscCall(DMGetNumFields(dm, &Nf));
41609566063dSJacob Faibussowitsch         PetscCall(PetscCalloc1(PetscMax(Nf, 1), &alpha));
41619566063dSJacob Faibussowitsch         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)ts), &conv));
41629566063dSJacob Faibussowitsch         PetscCall(PetscConvEstUseTS(conv, checkTemporal));
41639566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetSolver(conv, (PetscObject)ts));
41649566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetFromOptions(conv));
41659566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetUp(conv));
41669566063dSJacob Faibussowitsch         PetscCall(PetscConvEstGetConvRate(conv, alpha));
41679566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(viewer, format));
41689566063dSJacob Faibussowitsch         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
41699566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(viewer));
4170648c30bcSBarry Smith         PetscCall(PetscViewerDestroy(&viewer));
41719566063dSJacob Faibussowitsch         PetscCall(PetscConvEstDestroy(&conv));
41729566063dSJacob Faibussowitsch         PetscCall(PetscFree(alpha));
4173900f6b5bSMatthew G. Knepley         incall = PETSC_FALSE;
4174900f6b5bSMatthew G. Knepley       }
4175900f6b5bSMatthew G. Knepley     }
4176900f6b5bSMatthew G. Knepley   }
4177900f6b5bSMatthew G. Knepley 
41789566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts, NULL, "-ts_view_pre"));
4179f05ece33SBarry Smith 
4180193ac0bcSJed Brown   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
4181dbbe0bcdSBarry Smith     PetscUseTypeMethod(ts, solve);
41829566063dSJacob Faibussowitsch     if (u) PetscCall(VecCopy(ts->vec_sol, u));
4183cc708dedSBarry Smith     ts->solvetime = ts->ptime;
4184a6772fa2SLisandro Dalcin     solution      = ts->vec_sol;
4185be5899b3SLisandro Dalcin   } else { /* Step the requested number of timesteps. */
4186db4deed7SKarl Rupp     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
4187db4deed7SKarl Rupp     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
4188e7069c78SShri 
41892808aa04SLisandro Dalcin     if (!ts->steps) {
41909566063dSJacob Faibussowitsch       PetscCall(TSTrajectorySet(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
41919566063dSJacob Faibussowitsch       PetscCall(TSEventInitialize(ts->event, ts, ts->ptime, ts->vec_sol));
41922808aa04SLisandro Dalcin     }
41936427ac75SLisandro Dalcin 
41948e562f8dSJames Wright     ts->start_step = ts->steps; // records starting step
4195e1a7a14fSJed Brown     while (!ts->reason) {
41969566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts, ts->steps, ts->ptime, ts->vec_sol));
4197c6bf8827SStefano Zampini       if (!ts->steprollback || (ts->stepresize && ts->resizerollback)) PetscCall(TSPreStep(ts));
41989566063dSJacob Faibussowitsch       PetscCall(TSStep(ts));
41991baa6e33SBarry Smith       if (ts->testjacobian) PetscCall(TSRHSJacobianTest(ts, NULL));
42001baa6e33SBarry Smith       if (ts->testjacobiantranspose) PetscCall(TSRHSJacobianTestTranspose(ts, NULL));
4201cd4cee2dSHong Zhang       if (ts->quadraturets && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
42027b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--;            /* Revert the step number changed by TSStep() */
42039566063dSJacob Faibussowitsch         PetscCall(TSForwardCostIntegral(ts));
42047b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
4205b1cb36f3SHong Zhang       }
420658818c2dSLisandro Dalcin       if (ts->forward_solve) {            /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */
42077b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */
42089566063dSJacob Faibussowitsch         PetscCall(TSForwardStep(ts));
42097b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
4210715f1b00SHong Zhang       }
42119566063dSJacob Faibussowitsch       PetscCall(TSPostEvaluate(ts));
42129566063dSJacob Faibussowitsch       PetscCall(TSEventHandler(ts)); /* The right-hand side may be changed due to event. Be careful with Any computation using the RHS information after this point. */
42131baa6e33SBarry Smith       if (ts->steprollback) PetscCall(TSPostEvaluate(ts));
4214ecc87898SStefano Zampini       if (!ts->steprollback && ts->resizerollback) PetscCall(TSResize(ts));
421590d719a4SStefano Zampini       /* check convergence */
421690d719a4SStefano Zampini       if (!ts->reason) {
42178e562f8dSJames Wright         if ((ts->steps - ts->start_step) >= ts->run_steps) ts->reason = TS_CONVERGED_ITS;
42188e562f8dSJames Wright         else if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
421990d719a4SStefano Zampini         else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
422090d719a4SStefano Zampini       }
4221e783b05fSHong Zhang       if (!ts->steprollback) {
42229566063dSJacob Faibussowitsch         PetscCall(TSTrajectorySet(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
42239566063dSJacob Faibussowitsch         PetscCall(TSPostStep(ts));
4224ecc87898SStefano Zampini         if (!ts->resizerollback) PetscCall(TSResize(ts));
4225ca4445c7SIlya Fursov 
422626077dccSJames Wright         if (ts->eval_times && ts->eval_times->time_point_idx < ts->eval_times->num_time_points && ts->reason >= 0) {
4227136cf249SJames Wright           PetscCheck(ts->eval_times->worktol > 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Unexpected state !(eval_times->worktol > 0) in TSSolve()");
4228136cf249SJames Wright           if (PetscIsCloseAtTol(ts->ptime, ts->eval_times->time_points[ts->eval_times->time_point_idx], ts->eval_times->worktol, 0)) {
4229264c38b7SJames Wright             ts->eval_times->sol_times[ts->eval_times->sol_idx] = ts->ptime;
4230264c38b7SJames Wright             PetscCall(VecCopy(ts->vec_sol, ts->eval_times->sol_vecs[ts->eval_times->sol_idx]));
4231264c38b7SJames Wright             ts->eval_times->sol_idx++;
4232136cf249SJames Wright             ts->eval_times->time_point_idx++;
42338343f784SJames Wright           }
4234ca4445c7SIlya Fursov         }
4235aeb4809dSShri Abhyankar       }
4236193ac0bcSJed Brown     }
42379566063dSJacob Faibussowitsch     PetscCall(TSMonitor(ts, ts->steps, ts->ptime, ts->vec_sol));
42386427ac75SLisandro Dalcin 
423949354f04SShri Abhyankar     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
42405dbbf88eSStefano Zampini       if (!u) u = ts->vec_sol;
42419566063dSJacob Faibussowitsch       PetscCall(TSInterpolate(ts, ts->max_time, u));
4242cc708dedSBarry Smith       ts->solvetime = ts->max_time;
4243b06615a5SLisandro Dalcin       solution      = u;
42449566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts, -1, ts->solvetime, solution));
42450574a7fbSJed Brown     } else {
42469566063dSJacob Faibussowitsch       if (u) PetscCall(VecCopy(ts->vec_sol, u));
4247cc708dedSBarry Smith       ts->solvetime = ts->ptime;
4248b06615a5SLisandro Dalcin       solution      = ts->vec_sol;
42490574a7fbSJed Brown     }
4250193ac0bcSJed Brown   }
4251d2daff3dSHong Zhang 
42529566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts, NULL, "-ts_view"));
42539566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(solution, (PetscObject)ts, "-ts_view_solution"));
42549566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsBlock((PetscObject)ts));
42551baa6e33SBarry Smith   if (ts->adjoint_solve) PetscCall(TSAdjointSolve(ts));
42563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42576a4d4014SLisandro Dalcin }
42586a4d4014SLisandro Dalcin 
4259d763cef2SBarry Smith /*@
4260b8123daeSJed Brown   TSGetTime - Gets the time of the most recently completed step.
4261d763cef2SBarry Smith 
4262d763cef2SBarry Smith   Not Collective
4263d763cef2SBarry Smith 
4264d763cef2SBarry Smith   Input Parameter:
4265bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
4266d763cef2SBarry Smith 
4267d763cef2SBarry Smith   Output Parameter:
4268bcf0153eSBarry Smith . t - the current time. This time may not corresponds to the final time set with `TSSetMaxTime()`, use `TSGetSolveTime()`.
4269d763cef2SBarry Smith 
4270d763cef2SBarry Smith   Level: beginner
4271d763cef2SBarry Smith 
4272b8123daeSJed Brown   Note:
4273bcf0153eSBarry Smith   When called during time step evaluation (e.g. during residual evaluation or via hooks set using `TSSetPreStep()`,
4274bcf0153eSBarry Smith   `TSSetPreStage()`, `TSSetPostStage()`, or `TSSetPostStep()`), the time is the time at the start of the step being evaluated.
4275b8123daeSJed Brown 
4276a94f484eSPierre Jolivet .seealso: [](ch_ts), `TS`, `TSGetSolveTime()`, `TSSetTime()`, `TSGetTimeStep()`, `TSGetStepNumber()`
4277d763cef2SBarry Smith @*/
4278d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTime(TS ts, PetscReal *t)
4279d71ae5a4SJacob Faibussowitsch {
4280d763cef2SBarry Smith   PetscFunctionBegin;
42810700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
42824f572ea9SToby Isaac   PetscAssertPointer(t, 2);
4283d763cef2SBarry Smith   *t = ts->ptime;
42843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4285d763cef2SBarry Smith }
4286d763cef2SBarry Smith 
4287e5e524a1SHong Zhang /*@
4288e5e524a1SHong Zhang   TSGetPrevTime - Gets the starting time of the previously completed step.
4289e5e524a1SHong Zhang 
4290e5e524a1SHong Zhang   Not Collective
4291e5e524a1SHong Zhang 
4292e5e524a1SHong Zhang   Input Parameter:
4293bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
4294e5e524a1SHong Zhang 
4295e5e524a1SHong Zhang   Output Parameter:
4296e5e524a1SHong Zhang . t - the previous time
4297e5e524a1SHong Zhang 
4298e5e524a1SHong Zhang   Level: beginner
4299e5e524a1SHong Zhang 
4300a94f484eSPierre Jolivet .seealso: [](ch_ts), `TS`, `TSGetTime()`, `TSGetSolveTime()`, `TSGetTimeStep()`
4301e5e524a1SHong Zhang @*/
4302d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetPrevTime(TS ts, PetscReal *t)
4303d71ae5a4SJacob Faibussowitsch {
4304e5e524a1SHong Zhang   PetscFunctionBegin;
4305e5e524a1SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
43064f572ea9SToby Isaac   PetscAssertPointer(t, 2);
4307e5e524a1SHong Zhang   *t = ts->ptime_prev;
43083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4309e5e524a1SHong Zhang }
4310e5e524a1SHong Zhang 
43116a4d4014SLisandro Dalcin /*@
43126a4d4014SLisandro Dalcin   TSSetTime - Allows one to reset the time.
43136a4d4014SLisandro Dalcin 
4314c3339decSBarry Smith   Logically Collective
43156a4d4014SLisandro Dalcin 
43166a4d4014SLisandro Dalcin   Input Parameters:
4317bcf0153eSBarry Smith + ts - the `TS` context obtained from `TSCreate()`
4318b43aa488SJacob Faibussowitsch - t  - the time
43196a4d4014SLisandro Dalcin 
43206a4d4014SLisandro Dalcin   Level: intermediate
43216a4d4014SLisandro Dalcin 
43221cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetTime()`, `TSSetMaxSteps()`
43236a4d4014SLisandro Dalcin @*/
4324d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTime(TS ts, PetscReal t)
4325d71ae5a4SJacob Faibussowitsch {
43266a4d4014SLisandro Dalcin   PetscFunctionBegin;
43270700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4328c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts, t, 2);
43296a4d4014SLisandro Dalcin   ts->ptime = t;
43303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43316a4d4014SLisandro Dalcin }
43326a4d4014SLisandro Dalcin 
4333cc4c1da9SBarry Smith /*@
4334d763cef2SBarry Smith   TSSetOptionsPrefix - Sets the prefix used for searching for all
4335d763cef2SBarry Smith   TS options in the database.
4336d763cef2SBarry Smith 
4337c3339decSBarry Smith   Logically Collective
4338d763cef2SBarry Smith 
4339d8d19677SJose E. Roman   Input Parameters:
4340bcf0153eSBarry Smith + ts     - The `TS` context
4341d763cef2SBarry Smith - prefix - The prefix to prepend to all option names
4342d763cef2SBarry Smith 
4343bcf0153eSBarry Smith   Level: advanced
4344bcf0153eSBarry Smith 
4345bcf0153eSBarry Smith   Note:
4346d763cef2SBarry Smith   A hyphen (-) must NOT be given at the beginning of the prefix name.
4347d763cef2SBarry Smith   The first character of all runtime options is AUTOMATICALLY the
4348d763cef2SBarry Smith   hyphen.
4349d763cef2SBarry Smith 
43501cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetFromOptions()`, `TSAppendOptionsPrefix()`
4351d763cef2SBarry Smith @*/
4352d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetOptionsPrefix(TS ts, const char prefix[])
4353d71ae5a4SJacob Faibussowitsch {
4354089b2837SJed Brown   SNES snes;
4355d763cef2SBarry Smith 
4356d763cef2SBarry Smith   PetscFunctionBegin;
43570700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
43589566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ts, prefix));
43599566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
43609566063dSJacob Faibussowitsch   PetscCall(SNESSetOptionsPrefix(snes, prefix));
43613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4362d763cef2SBarry Smith }
4363d763cef2SBarry Smith 
4364cc4c1da9SBarry Smith /*@
4365d763cef2SBarry Smith   TSAppendOptionsPrefix - Appends to the prefix used for searching for all
4366d763cef2SBarry Smith   TS options in the database.
4367d763cef2SBarry Smith 
4368c3339decSBarry Smith   Logically Collective
4369d763cef2SBarry Smith 
4370d8d19677SJose E. Roman   Input Parameters:
4371bcf0153eSBarry Smith + ts     - The `TS` context
4372d763cef2SBarry Smith - prefix - The prefix to prepend to all option names
4373d763cef2SBarry Smith 
4374bcf0153eSBarry Smith   Level: advanced
4375bcf0153eSBarry Smith 
4376bcf0153eSBarry Smith   Note:
4377d763cef2SBarry Smith   A hyphen (-) must NOT be given at the beginning of the prefix name.
4378d763cef2SBarry Smith   The first character of all runtime options is AUTOMATICALLY the
4379d763cef2SBarry Smith   hyphen.
4380d763cef2SBarry Smith 
43811cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetOptionsPrefix()`, `TSSetOptionsPrefix()`, `TSSetFromOptions()`
4382d763cef2SBarry Smith @*/
4383d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAppendOptionsPrefix(TS ts, const char prefix[])
4384d71ae5a4SJacob Faibussowitsch {
4385089b2837SJed Brown   SNES snes;
4386d763cef2SBarry Smith 
4387d763cef2SBarry Smith   PetscFunctionBegin;
43880700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
43899566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)ts, prefix));
43909566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
43919566063dSJacob Faibussowitsch   PetscCall(SNESAppendOptionsPrefix(snes, prefix));
43923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4393d763cef2SBarry Smith }
4394d763cef2SBarry Smith 
4395cc4c1da9SBarry Smith /*@
4396d763cef2SBarry Smith   TSGetOptionsPrefix - Sets the prefix used for searching for all
4397bcf0153eSBarry Smith   `TS` options in the database.
4398d763cef2SBarry Smith 
4399d763cef2SBarry Smith   Not Collective
4400d763cef2SBarry Smith 
4401d763cef2SBarry Smith   Input Parameter:
4402bcf0153eSBarry Smith . ts - The `TS` context
4403d763cef2SBarry Smith 
4404d763cef2SBarry Smith   Output Parameter:
4405d763cef2SBarry Smith . prefix - A pointer to the prefix string used
4406d763cef2SBarry Smith 
4407d763cef2SBarry Smith   Level: intermediate
4408d763cef2SBarry Smith 
44091cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAppendOptionsPrefix()`, `TSSetFromOptions()`
4410d763cef2SBarry Smith @*/
4411d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetOptionsPrefix(TS ts, const char *prefix[])
4412d71ae5a4SJacob Faibussowitsch {
4413d763cef2SBarry Smith   PetscFunctionBegin;
44140700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
44154f572ea9SToby Isaac   PetscAssertPointer(prefix, 2);
44169566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, prefix));
44173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4418d763cef2SBarry Smith }
4419d763cef2SBarry Smith 
4420d763cef2SBarry Smith /*@C
4421d763cef2SBarry Smith   TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4422d763cef2SBarry Smith 
4423bcf0153eSBarry Smith   Not Collective, but parallel objects are returned if ts is parallel
4424d763cef2SBarry Smith 
4425d763cef2SBarry Smith   Input Parameter:
4426bcf0153eSBarry Smith . ts - The `TS` context obtained from `TSCreate()`
4427d763cef2SBarry Smith 
4428d763cef2SBarry Smith   Output Parameters:
4429195e9b02SBarry Smith + Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or `NULL`)
4430195e9b02SBarry Smith . Pmat - The matrix from which the preconditioner is constructed, usually the same as `Amat`  (or `NULL`)
4431195e9b02SBarry Smith . func - Function to compute the Jacobian of the RHS  (or `NULL`)
4432195e9b02SBarry Smith - ctx  - User-defined context for Jacobian evaluation routine  (or `NULL`)
4433d763cef2SBarry Smith 
4434d763cef2SBarry Smith   Level: intermediate
4435d763cef2SBarry Smith 
4436bcf0153eSBarry Smith   Note:
4437195e9b02SBarry Smith   You can pass in `NULL` for any return argument you do not need.
4438bcf0153eSBarry Smith 
44391cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
4440d763cef2SBarry Smith 
4441d763cef2SBarry Smith @*/
44428434afd1SBarry Smith PetscErrorCode TSGetRHSJacobian(TS ts, Mat *Amat, Mat *Pmat, TSRHSJacobianFn **func, void **ctx)
4443d71ae5a4SJacob Faibussowitsch {
444424989b8cSPeter Brune   DM dm;
4445089b2837SJed Brown 
4446d763cef2SBarry Smith   PetscFunctionBegin;
444723a57915SBarry Smith   if (Amat || Pmat) {
444823a57915SBarry Smith     SNES snes;
44499566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
44509566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
44519566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
445223a57915SBarry Smith   }
44539566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
44549566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, func, ctx));
44553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4456d763cef2SBarry Smith }
4457d763cef2SBarry Smith 
44582eca1d9cSJed Brown /*@C
44592eca1d9cSJed Brown   TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
44602eca1d9cSJed Brown 
4461bcf0153eSBarry Smith   Not Collective, but parallel objects are returned if ts is parallel
44622eca1d9cSJed Brown 
44632eca1d9cSJed Brown   Input Parameter:
4464bcf0153eSBarry Smith . ts - The `TS` context obtained from `TSCreate()`
44652eca1d9cSJed Brown 
44662eca1d9cSJed Brown   Output Parameters:
4467e4357dc4SBarry Smith + Amat - The (approximate) Jacobian of F(t,U,U_t)
4468195e9b02SBarry Smith . Pmat - The matrix from which the preconditioner is constructed, often the same as `Amat`
44692eca1d9cSJed Brown . f    - The function to compute the matrices
44702eca1d9cSJed Brown - ctx  - User-defined context for Jacobian evaluation routine
44712eca1d9cSJed Brown 
44722eca1d9cSJed Brown   Level: advanced
44732eca1d9cSJed Brown 
4474bcf0153eSBarry Smith   Note:
4475195e9b02SBarry Smith   You can pass in `NULL` for any return argument you do not need.
4476bcf0153eSBarry Smith 
44771cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetTimeStep()`, `TSGetRHSJacobian()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
44782eca1d9cSJed Brown @*/
44798434afd1SBarry Smith PetscErrorCode TSGetIJacobian(TS ts, Mat *Amat, Mat *Pmat, TSIJacobianFn **f, void **ctx)
4480d71ae5a4SJacob Faibussowitsch {
448124989b8cSPeter Brune   DM dm;
44820910c330SBarry Smith 
44832eca1d9cSJed Brown   PetscFunctionBegin;
4484c0aab802Sstefano_zampini   if (Amat || Pmat) {
4485c0aab802Sstefano_zampini     SNES snes;
44869566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
44879566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
44889566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
4489c0aab802Sstefano_zampini   }
44909566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
44919566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, f, ctx));
44923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44932eca1d9cSJed Brown }
44942eca1d9cSJed Brown 
4495af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
44966c699258SBarry Smith /*@
4497bcf0153eSBarry Smith   TSSetDM - Sets the `DM` that may be used by some nonlinear solvers or preconditioners under the `TS`
44986c699258SBarry Smith 
4499c3339decSBarry Smith   Logically Collective
45006c699258SBarry Smith 
45016c699258SBarry Smith   Input Parameters:
4502bcf0153eSBarry Smith + ts - the `TS` integrator object
4503195e9b02SBarry Smith - dm - the dm, cannot be `NULL`
45046c699258SBarry Smith 
45056c699258SBarry Smith   Level: intermediate
45066c699258SBarry Smith 
4507bcf0153eSBarry Smith   Notes:
4508bcf0153eSBarry Smith   A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`,
4509bcf0153eSBarry Smith   even when not using interfaces like `DMTSSetIFunction()`.  Use `DMClone()` to get a distinct `DM` when solving
4510bcf0153eSBarry Smith   different problems using the same function space.
4511bcf0153eSBarry Smith 
45121cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `DM`, `TSGetDM()`, `SNESSetDM()`, `SNESGetDM()`
45136c699258SBarry Smith @*/
4514d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetDM(TS ts, DM dm)
4515d71ae5a4SJacob Faibussowitsch {
4516089b2837SJed Brown   SNES snes;
4517942e3340SBarry Smith   DMTS tsdm;
45186c699258SBarry Smith 
45196c699258SBarry Smith   PetscFunctionBegin;
45200700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
45212a808120SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
45229566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)dm));
4523942e3340SBarry Smith   if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */
45242a34c10cSBarry Smith     if (ts->dm->dmts && !dm->dmts) {
45259566063dSJacob Faibussowitsch       PetscCall(DMCopyDMTS(ts->dm, dm));
45269566063dSJacob Faibussowitsch       PetscCall(DMGetDMTS(ts->dm, &tsdm));
45271e66621cSBarry Smith       /* Grant write privileges to the replacement DM */
45281e66621cSBarry Smith       if (tsdm->originaldm == ts->dm) tsdm->originaldm = dm;
452924989b8cSPeter Brune     }
45309566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&ts->dm));
453124989b8cSPeter Brune   }
45326c699258SBarry Smith   ts->dm = dm;
4533bbd56ea5SKarl Rupp 
45349566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
45359566063dSJacob Faibussowitsch   PetscCall(SNESSetDM(snes, dm));
45363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45376c699258SBarry Smith }
45386c699258SBarry Smith 
45396c699258SBarry Smith /*@
4540bcf0153eSBarry Smith   TSGetDM - Gets the `DM` that may be used by some preconditioners
45416c699258SBarry Smith 
45423f9fe445SBarry Smith   Not Collective
45436c699258SBarry Smith 
45446c699258SBarry Smith   Input Parameter:
4545bcf0153eSBarry Smith . ts - the `TS`
45466c699258SBarry Smith 
45476c699258SBarry Smith   Output Parameter:
4548195e9b02SBarry Smith . dm - the `DM`
45496c699258SBarry Smith 
45506c699258SBarry Smith   Level: intermediate
45516c699258SBarry Smith 
45521cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `DM`, `TSSetDM()`, `SNESSetDM()`, `SNESGetDM()`
45536c699258SBarry Smith @*/
4554d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetDM(TS ts, DM *dm)
4555d71ae5a4SJacob Faibussowitsch {
45566c699258SBarry Smith   PetscFunctionBegin;
45570700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4558496e6a7aSJed Brown   if (!ts->dm) {
45599566063dSJacob Faibussowitsch     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)ts), &ts->dm));
45604bd3aaa3SHong Zhang     if (ts->snes) PetscCall(SNESSetDM(ts->snes, ts->dm));
4561496e6a7aSJed Brown   }
45626c699258SBarry Smith   *dm = ts->dm;
45633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45646c699258SBarry Smith }
45651713a123SBarry Smith 
45660f5c6efeSJed Brown /*@
45672ba42892SBarry Smith   SNESTSFormFunction - Function to evaluate nonlinear residual defined by an ODE solver algorithm implemented within `TS`
45680f5c6efeSJed Brown 
4569c3339decSBarry Smith   Logically Collective
45700f5c6efeSJed Brown 
4571d8d19677SJose E. Roman   Input Parameters:
4572d42a1c89SJed Brown + snes - nonlinear solver
45730910c330SBarry Smith . U    - the current state at which to evaluate the residual
45742ba42892SBarry Smith - ctx  - user context, must be a `TS`
45750f5c6efeSJed Brown 
45760f5c6efeSJed Brown   Output Parameter:
45770f5c6efeSJed Brown . F - the nonlinear residual
45780f5c6efeSJed Brown 
45792ba42892SBarry Smith   Level: developer
45800f5c6efeSJed Brown 
4581bcf0153eSBarry Smith   Note:
4582bcf0153eSBarry Smith   This function is not normally called by users and is automatically registered with the `SNES` used by `TS`.
4583bcf0153eSBarry Smith   It is most frequently passed to `MatFDColoringSetFunction()`.
4584bcf0153eSBarry Smith 
45851cc06b55SBarry Smith .seealso: [](ch_ts), `SNESSetFunction()`, `MatFDColoringSetFunction()`
45860f5c6efeSJed Brown @*/
4587d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTSFormFunction(SNES snes, Vec U, Vec F, void *ctx)
4588d71ae5a4SJacob Faibussowitsch {
45890f5c6efeSJed Brown   TS ts = (TS)ctx;
45900f5c6efeSJed Brown 
45910f5c6efeSJed Brown   PetscFunctionBegin;
45920f5c6efeSJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
45930910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
45940f5c6efeSJed Brown   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
45950f5c6efeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 4);
4596346ce620SStefano Zampini   PetscCheck(ts->ops->snesfunction, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "No method snesfunction for TS of type %s", ((PetscObject)ts)->type_name);
4597346ce620SStefano Zampini   PetscCall((*ts->ops->snesfunction)(snes, U, F, ts));
45983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45990f5c6efeSJed Brown }
46000f5c6efeSJed Brown 
46010f5c6efeSJed Brown /*@
46022ba42892SBarry Smith   SNESTSFormJacobian - Function to evaluate the Jacobian defined by an ODE solver algorithm implemented within `TS`
46030f5c6efeSJed Brown 
4604c3339decSBarry Smith   Collective
46050f5c6efeSJed Brown 
4606d8d19677SJose E. Roman   Input Parameters:
46070f5c6efeSJed Brown + snes - nonlinear solver
46080910c330SBarry Smith . U    - the current state at which to evaluate the residual
4609bcf0153eSBarry Smith - ctx  - user context, must be a `TS`
46100f5c6efeSJed Brown 
4611d8d19677SJose E. Roman   Output Parameters:
46120f5c6efeSJed Brown + A - the Jacobian
46137addb90fSBarry Smith - B - the matrix used to construct the preconditioner (often the same as `A`)
46140f5c6efeSJed Brown 
46150f5c6efeSJed Brown   Level: developer
46160f5c6efeSJed Brown 
4617bcf0153eSBarry Smith   Note:
4618bcf0153eSBarry Smith   This function is not normally called by users and is automatically registered with the `SNES` used by `TS`.
4619bcf0153eSBarry Smith 
46201cc06b55SBarry Smith .seealso: [](ch_ts), `SNESSetJacobian()`
46210f5c6efeSJed Brown @*/
4622d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTSFormJacobian(SNES snes, Vec U, Mat A, Mat B, void *ctx)
4623d71ae5a4SJacob Faibussowitsch {
46240f5c6efeSJed Brown   TS ts = (TS)ctx;
46250f5c6efeSJed Brown 
46260f5c6efeSJed Brown   PetscFunctionBegin;
46270f5c6efeSJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
46280910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
462994ab13aaSBarry Smith   PetscValidHeaderSpecific(A, MAT_CLASSID, 3);
463094ab13aaSBarry Smith   PetscValidHeaderSpecific(B, MAT_CLASSID, 4);
4631064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(ts, TS_CLASSID, 5);
4632346ce620SStefano Zampini   PetscCheck(ts->ops->snesjacobian, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "No method snesjacobian for TS of type %s", ((PetscObject)ts)->type_name);
4633346ce620SStefano Zampini   PetscCall((*ts->ops->snesjacobian)(snes, U, A, B, ts));
46343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46350f5c6efeSJed Brown }
4636325fc9f4SBarry Smith 
46370e4ef248SJed Brown /*@C
4638dd8e379bSPierre Jolivet   TSComputeRHSFunctionLinear - Evaluate the right-hand side via the user-provided Jacobian, for linear problems Udot = A U only
46390e4ef248SJed Brown 
4640c3339decSBarry Smith   Collective
46410e4ef248SJed Brown 
46424165533cSJose E. Roman   Input Parameters:
46430e4ef248SJed Brown + ts  - time stepping context
46440e4ef248SJed Brown . t   - time at which to evaluate
46450910c330SBarry Smith . U   - state at which to evaluate
46460e4ef248SJed Brown - ctx - context
46470e4ef248SJed Brown 
46484165533cSJose E. Roman   Output Parameter:
4649dd8e379bSPierre Jolivet . F - right-hand side
46500e4ef248SJed Brown 
46510e4ef248SJed Brown   Level: intermediate
46520e4ef248SJed Brown 
4653bcf0153eSBarry Smith   Note:
4654dd8e379bSPierre Jolivet   This function is intended to be passed to `TSSetRHSFunction()` to evaluate the right-hand side for linear problems.
4655bcf0153eSBarry Smith   The matrix (and optionally the evaluation context) should be passed to `TSSetRHSJacobian()`.
46560e4ef248SJed Brown 
46571cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
46580e4ef248SJed Brown @*/
4659d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSFunctionLinear(TS ts, PetscReal t, Vec U, Vec F, void *ctx)
4660d71ae5a4SJacob Faibussowitsch {
46610e4ef248SJed Brown   Mat Arhs, Brhs;
46620e4ef248SJed Brown 
46630e4ef248SJed Brown   PetscFunctionBegin;
46649566063dSJacob Faibussowitsch   PetscCall(TSGetRHSMats_Private(ts, &Arhs, &Brhs));
46652663174eSHong Zhang   /* undo the damage caused by shifting */
46669566063dSJacob Faibussowitsch   PetscCall(TSRecoverRHSJacobian(ts, Arhs, Brhs));
46679566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSJacobian(ts, t, U, Arhs, Brhs));
46689566063dSJacob Faibussowitsch   PetscCall(MatMult(Arhs, U, F));
46693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46700e4ef248SJed Brown }
46710e4ef248SJed Brown 
46720e4ef248SJed Brown /*@C
46730e4ef248SJed Brown   TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
46740e4ef248SJed Brown 
4675c3339decSBarry Smith   Collective
46760e4ef248SJed Brown 
46774165533cSJose E. Roman   Input Parameters:
46780e4ef248SJed Brown + ts  - time stepping context
46790e4ef248SJed Brown . t   - time at which to evaluate
46800910c330SBarry Smith . U   - state at which to evaluate
46810e4ef248SJed Brown - ctx - context
46820e4ef248SJed Brown 
46834165533cSJose E. Roman   Output Parameters:
46847addb90fSBarry Smith + A - Jacobian
46857addb90fSBarry Smith - B - matrix used to construct the preconditioner, often the same as `A`
46860e4ef248SJed Brown 
46870e4ef248SJed Brown   Level: intermediate
46880e4ef248SJed Brown 
4689bcf0153eSBarry Smith   Note:
4690bcf0153eSBarry Smith   This function is intended to be passed to `TSSetRHSJacobian()` to evaluate the Jacobian for linear time-independent problems.
46910e4ef248SJed Brown 
46921cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSFunctionLinear()`
46930e4ef248SJed Brown @*/
4694d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSJacobianConstant(TS ts, PetscReal t, Vec U, Mat A, Mat B, void *ctx)
4695d71ae5a4SJacob Faibussowitsch {
46960e4ef248SJed Brown   PetscFunctionBegin;
46973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46980e4ef248SJed Brown }
46990e4ef248SJed Brown 
47000026cea9SSean Farley /*@C
47010026cea9SSean Farley   TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
47020026cea9SSean Farley 
4703c3339decSBarry Smith   Collective
47040026cea9SSean Farley 
47054165533cSJose E. Roman   Input Parameters:
47060026cea9SSean Farley + ts   - time stepping context
47070026cea9SSean Farley . t    - time at which to evaluate
47080910c330SBarry Smith . U    - state at which to evaluate
47090910c330SBarry Smith . Udot - time derivative of state vector
47100026cea9SSean Farley - ctx  - context
47110026cea9SSean Farley 
47124165533cSJose E. Roman   Output Parameter:
47130026cea9SSean Farley . F - left hand side
47140026cea9SSean Farley 
47150026cea9SSean Farley   Level: intermediate
47160026cea9SSean Farley 
47170026cea9SSean Farley   Notes:
47180910c330SBarry Smith   The assumption here is that the left hand side is of the form A*Udot (and not A*Udot + B*U). For other cases, the
4719bcf0153eSBarry Smith   user is required to write their own `TSComputeIFunction()`.
4720bcf0153eSBarry Smith   This function is intended to be passed to `TSSetIFunction()` to evaluate the left hand side for linear problems.
4721bcf0153eSBarry Smith   The matrix (and optionally the evaluation context) should be passed to `TSSetIJacobian()`.
47220026cea9SSean Farley 
4723bcf0153eSBarry Smith   Note that using this function is NOT equivalent to using `TSComputeRHSFunctionLinear()` since that solves Udot = A U
47249ae8fd06SBarry Smith 
47251cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIJacobianConstant()`, `TSComputeRHSFunctionLinear()`
47260026cea9SSean Farley @*/
4727d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIFunctionLinear(TS ts, PetscReal t, Vec U, Vec Udot, Vec F, void *ctx)
4728d71ae5a4SJacob Faibussowitsch {
47290026cea9SSean Farley   Mat A, B;
47300026cea9SSean Farley 
47310026cea9SSean Farley   PetscFunctionBegin;
47329566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts, &A, &B, NULL, NULL));
47339566063dSJacob Faibussowitsch   PetscCall(TSComputeIJacobian(ts, t, U, Udot, 1.0, A, B, PETSC_TRUE));
47349566063dSJacob Faibussowitsch   PetscCall(MatMult(A, Udot, F));
47353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
47360026cea9SSean Farley }
47370026cea9SSean Farley 
47380026cea9SSean Farley /*@C
47398434afd1SBarry Smith   TSComputeIJacobianConstant - Reuses the matrix previously computed with the provided `TSIJacobianFn` for a semi-implicit DAE or ODE
47400026cea9SSean Farley 
4741c3339decSBarry Smith   Collective
47420026cea9SSean Farley 
47434165533cSJose E. Roman   Input Parameters:
47440026cea9SSean Farley + ts    - time stepping context
47450026cea9SSean Farley . t     - time at which to evaluate
47460910c330SBarry Smith . U     - state at which to evaluate
47470910c330SBarry Smith . Udot  - time derivative of state vector
47480026cea9SSean Farley . shift - shift to apply
47490026cea9SSean Farley - ctx   - context
47500026cea9SSean Farley 
47514165533cSJose E. Roman   Output Parameters:
47520026cea9SSean Farley + A - pointer to operator
4753d1c5d1fcSBarry Smith - B - pointer to matrix from which the preconditioner is built (often `A`)
47540026cea9SSean Farley 
4755b41af12eSJed Brown   Level: advanced
47560026cea9SSean Farley 
47570026cea9SSean Farley   Notes:
4758bcf0153eSBarry Smith   This function is intended to be passed to `TSSetIJacobian()` to evaluate the Jacobian for linear time-independent problems.
47590026cea9SSean Farley 
4760b41af12eSJed Brown   It is only appropriate for problems of the form
4761b41af12eSJed Brown 
4762d1c5d1fcSBarry Smith   $$
4763d1c5d1fcSBarry Smith   M \dot{U} = F(U,t)
4764d1c5d1fcSBarry Smith   $$
4765b41af12eSJed Brown 
4766bcf0153eSBarry Smith   where M is constant and F is non-stiff.  The user must pass M to `TSSetIJacobian()`.  The current implementation only
4767bcf0153eSBarry Smith   works with IMEX time integration methods such as `TSROSW` and `TSARKIMEX`, since there is no support for de-constructing
4768b41af12eSJed Brown   an implicit operator of the form
4769b41af12eSJed Brown 
4770d1c5d1fcSBarry Smith   $$
4771d1c5d1fcSBarry Smith   shift*M + J
4772d1c5d1fcSBarry Smith   $$
4773b41af12eSJed Brown 
4774b41af12eSJed Brown   where J is the Jacobian of -F(U).  Support may be added in a future version of PETSc, but for now, the user must store
4775b41af12eSJed Brown   a copy of M or reassemble it when requested.
4776b41af12eSJed Brown 
47771cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSROSW`, `TSARKIMEX`, `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIFunctionLinear()`
47780026cea9SSean Farley @*/
4779d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIJacobianConstant(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat A, Mat B, void *ctx)
4780d71ae5a4SJacob Faibussowitsch {
47810026cea9SSean Farley   PetscFunctionBegin;
47829566063dSJacob Faibussowitsch   PetscCall(MatScale(A, shift / ts->ijacobian.shift));
4783b41af12eSJed Brown   ts->ijacobian.shift = shift;
47843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
47850026cea9SSean Farley }
4786b41af12eSJed Brown 
4787e817cc15SEmil Constantinescu /*@
4788bcf0153eSBarry Smith   TSGetEquationType - Gets the type of the equation that `TS` is solving.
4789e817cc15SEmil Constantinescu 
4790e817cc15SEmil Constantinescu   Not Collective
4791e817cc15SEmil Constantinescu 
4792e817cc15SEmil Constantinescu   Input Parameter:
4793bcf0153eSBarry Smith . ts - the `TS` context
4794e817cc15SEmil Constantinescu 
4795e817cc15SEmil Constantinescu   Output Parameter:
4796bcf0153eSBarry Smith . equation_type - see `TSEquationType`
4797e817cc15SEmil Constantinescu 
4798e817cc15SEmil Constantinescu   Level: beginner
4799e817cc15SEmil Constantinescu 
48001cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetEquationType()`, `TSEquationType`
4801e817cc15SEmil Constantinescu @*/
4802d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetEquationType(TS ts, TSEquationType *equation_type)
4803d71ae5a4SJacob Faibussowitsch {
4804e817cc15SEmil Constantinescu   PetscFunctionBegin;
4805e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
48064f572ea9SToby Isaac   PetscAssertPointer(equation_type, 2);
4807e817cc15SEmil Constantinescu   *equation_type = ts->equation_type;
48083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4809e817cc15SEmil Constantinescu }
4810e817cc15SEmil Constantinescu 
4811e817cc15SEmil Constantinescu /*@
4812bcf0153eSBarry Smith   TSSetEquationType - Sets the type of the equation that `TS` is solving.
4813e817cc15SEmil Constantinescu 
4814e817cc15SEmil Constantinescu   Not Collective
4815e817cc15SEmil Constantinescu 
4816d8d19677SJose E. Roman   Input Parameters:
4817bcf0153eSBarry Smith + ts            - the `TS` context
4818bcf0153eSBarry Smith - equation_type - see `TSEquationType`
4819e817cc15SEmil Constantinescu 
4820e817cc15SEmil Constantinescu   Level: advanced
4821e817cc15SEmil Constantinescu 
48221cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetEquationType()`, `TSEquationType`
4823e817cc15SEmil Constantinescu @*/
4824d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetEquationType(TS ts, TSEquationType equation_type)
4825d71ae5a4SJacob Faibussowitsch {
4826e817cc15SEmil Constantinescu   PetscFunctionBegin;
4827e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4828e817cc15SEmil Constantinescu   ts->equation_type = equation_type;
48293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4830e817cc15SEmil Constantinescu }
48310026cea9SSean Farley 
48324af1b03aSJed Brown /*@
4833bcf0153eSBarry Smith   TSGetConvergedReason - Gets the reason the `TS` iteration was stopped.
48344af1b03aSJed Brown 
48354af1b03aSJed Brown   Not Collective
48364af1b03aSJed Brown 
48374af1b03aSJed Brown   Input Parameter:
4838bcf0153eSBarry Smith . ts - the `TS` context
48394af1b03aSJed Brown 
48404af1b03aSJed Brown   Output Parameter:
4841bcf0153eSBarry Smith . reason - negative value indicates diverged, positive value converged, see `TSConvergedReason` or the
48424af1b03aSJed Brown             manual pages for the individual convergence tests for complete lists
48434af1b03aSJed Brown 
4844487e0bb9SJed Brown   Level: beginner
48454af1b03aSJed Brown 
4846bcf0153eSBarry Smith   Note:
4847bcf0153eSBarry Smith   Can only be called after the call to `TSSolve()` is complete.
48484af1b03aSJed Brown 
48497d66147cSPierre Jolivet .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSConvergedReason`
48504af1b03aSJed Brown @*/
4851d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetConvergedReason(TS ts, TSConvergedReason *reason)
4852d71ae5a4SJacob Faibussowitsch {
48534af1b03aSJed Brown   PetscFunctionBegin;
48544af1b03aSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
48554f572ea9SToby Isaac   PetscAssertPointer(reason, 2);
48564af1b03aSJed Brown   *reason = ts->reason;
48573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
48584af1b03aSJed Brown }
48594af1b03aSJed Brown 
4860d6ad946cSShri Abhyankar /*@
4861bcf0153eSBarry Smith   TSSetConvergedReason - Sets the reason for handling the convergence of `TSSolve()`.
4862d6ad946cSShri Abhyankar 
48636b221cbeSPatrick Sanan   Logically Collective; reason must contain common value
4864d6ad946cSShri Abhyankar 
48656b221cbeSPatrick Sanan   Input Parameters:
4866bcf0153eSBarry Smith + ts     - the `TS` context
4867bcf0153eSBarry Smith - reason - negative value indicates diverged, positive value converged, see `TSConvergedReason` or the
4868d6ad946cSShri Abhyankar             manual pages for the individual convergence tests for complete lists
4869d6ad946cSShri Abhyankar 
4870f5abba47SShri Abhyankar   Level: advanced
4871d6ad946cSShri Abhyankar 
4872bcf0153eSBarry Smith   Note:
4873bcf0153eSBarry Smith   Can only be called while `TSSolve()` is active.
4874d6ad946cSShri Abhyankar 
48751cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSConvergedReason`
4876d6ad946cSShri Abhyankar @*/
4877d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetConvergedReason(TS ts, TSConvergedReason reason)
4878d71ae5a4SJacob Faibussowitsch {
4879d6ad946cSShri Abhyankar   PetscFunctionBegin;
4880d6ad946cSShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4881d6ad946cSShri Abhyankar   ts->reason = reason;
48823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4883d6ad946cSShri Abhyankar }
4884d6ad946cSShri Abhyankar 
4885cc708dedSBarry Smith /*@
4886bcf0153eSBarry Smith   TSGetSolveTime - Gets the time after a call to `TSSolve()`
4887cc708dedSBarry Smith 
4888cc708dedSBarry Smith   Not Collective
4889cc708dedSBarry Smith 
4890cc708dedSBarry Smith   Input Parameter:
4891bcf0153eSBarry Smith . ts - the `TS` context
4892cc708dedSBarry Smith 
4893cc708dedSBarry Smith   Output Parameter:
4894bcf0153eSBarry Smith . ftime - the final time. This time corresponds to the final time set with `TSSetMaxTime()`
4895cc708dedSBarry Smith 
4896487e0bb9SJed Brown   Level: beginner
4897cc708dedSBarry Smith 
4898bcf0153eSBarry Smith   Note:
4899bcf0153eSBarry Smith   Can only be called after the call to `TSSolve()` is complete.
4900cc708dedSBarry Smith 
49017d66147cSPierre Jolivet .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSConvergedReason`
4902cc708dedSBarry Smith @*/
4903d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSolveTime(TS ts, PetscReal *ftime)
4904d71ae5a4SJacob Faibussowitsch {
4905cc708dedSBarry Smith   PetscFunctionBegin;
4906cc708dedSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
49074f572ea9SToby Isaac   PetscAssertPointer(ftime, 2);
4908cc708dedSBarry Smith   *ftime = ts->solvetime;
49093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4910cc708dedSBarry Smith }
4911cc708dedSBarry Smith 
49122c18e0fdSBarry Smith /*@
49135ef26d82SJed Brown   TSGetSNESIterations - Gets the total number of nonlinear iterations
49149f67acb7SJed Brown   used by the time integrator.
49159f67acb7SJed Brown 
49169f67acb7SJed Brown   Not Collective
49179f67acb7SJed Brown 
49189f67acb7SJed Brown   Input Parameter:
4919bcf0153eSBarry Smith . ts - `TS` context
49209f67acb7SJed Brown 
49219f67acb7SJed Brown   Output Parameter:
49229f67acb7SJed Brown . nits - number of nonlinear iterations
49239f67acb7SJed Brown 
49249f67acb7SJed Brown   Level: intermediate
49259f67acb7SJed Brown 
4926195e9b02SBarry Smith   Note:
4927bcf0153eSBarry Smith   This counter is reset to zero for each successive call to `TSSolve()`.
4928bcf0153eSBarry Smith 
49291cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSGetKSPIterations()`
49309f67acb7SJed Brown @*/
4931d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSNESIterations(TS ts, PetscInt *nits)
4932d71ae5a4SJacob Faibussowitsch {
49339f67acb7SJed Brown   PetscFunctionBegin;
49349f67acb7SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
49354f572ea9SToby Isaac   PetscAssertPointer(nits, 2);
49365ef26d82SJed Brown   *nits = ts->snes_its;
49373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
49389f67acb7SJed Brown }
49399f67acb7SJed Brown 
49409f67acb7SJed Brown /*@
49415ef26d82SJed Brown   TSGetKSPIterations - Gets the total number of linear iterations
49429f67acb7SJed Brown   used by the time integrator.
49439f67acb7SJed Brown 
49449f67acb7SJed Brown   Not Collective
49459f67acb7SJed Brown 
49469f67acb7SJed Brown   Input Parameter:
4947bcf0153eSBarry Smith . ts - `TS` context
49489f67acb7SJed Brown 
49499f67acb7SJed Brown   Output Parameter:
49509f67acb7SJed Brown . lits - number of linear iterations
49519f67acb7SJed Brown 
49529f67acb7SJed Brown   Level: intermediate
49539f67acb7SJed Brown 
4954bcf0153eSBarry Smith   Note:
4955bcf0153eSBarry Smith   This counter is reset to zero for each successive call to `TSSolve()`.
4956bcf0153eSBarry Smith 
4957bfe80ac4SPierre Jolivet .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSGetSNESIterations()`
49589f67acb7SJed Brown @*/
4959d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetKSPIterations(TS ts, PetscInt *lits)
4960d71ae5a4SJacob Faibussowitsch {
49619f67acb7SJed Brown   PetscFunctionBegin;
49629f67acb7SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
49634f572ea9SToby Isaac   PetscAssertPointer(lits, 2);
49645ef26d82SJed Brown   *lits = ts->ksp_its;
49653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
49669f67acb7SJed Brown }
49679f67acb7SJed Brown 
4968cef5090cSJed Brown /*@
4969cef5090cSJed Brown   TSGetStepRejections - Gets the total number of rejected steps.
4970cef5090cSJed Brown 
4971cef5090cSJed Brown   Not Collective
4972cef5090cSJed Brown 
4973cef5090cSJed Brown   Input Parameter:
4974bcf0153eSBarry Smith . ts - `TS` context
4975cef5090cSJed Brown 
4976cef5090cSJed Brown   Output Parameter:
4977cef5090cSJed Brown . rejects - number of steps rejected
4978cef5090cSJed Brown 
4979cef5090cSJed Brown   Level: intermediate
4980cef5090cSJed Brown 
4981bcf0153eSBarry Smith   Note:
4982bcf0153eSBarry Smith   This counter is reset to zero for each successive call to `TSSolve()`.
4983bcf0153eSBarry Smith 
49841cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetSNESFailures()`, `TSSetMaxSNESFailures()`, `TSSetErrorIfStepFails()`
4985cef5090cSJed Brown @*/
4986d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetStepRejections(TS ts, PetscInt *rejects)
4987d71ae5a4SJacob Faibussowitsch {
4988cef5090cSJed Brown   PetscFunctionBegin;
4989cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
49904f572ea9SToby Isaac   PetscAssertPointer(rejects, 2);
4991cef5090cSJed Brown   *rejects = ts->reject;
49923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4993cef5090cSJed Brown }
4994cef5090cSJed Brown 
4995cef5090cSJed Brown /*@
4996bcf0153eSBarry Smith   TSGetSNESFailures - Gets the total number of failed `SNES` solves in a `TS`
4997cef5090cSJed Brown 
4998cef5090cSJed Brown   Not Collective
4999cef5090cSJed Brown 
5000cef5090cSJed Brown   Input Parameter:
5001bcf0153eSBarry Smith . ts - `TS` context
5002cef5090cSJed Brown 
5003cef5090cSJed Brown   Output Parameter:
5004cef5090cSJed Brown . fails - number of failed nonlinear solves
5005cef5090cSJed Brown 
5006cef5090cSJed Brown   Level: intermediate
5007cef5090cSJed Brown 
5008bcf0153eSBarry Smith   Note:
5009bcf0153eSBarry Smith   This counter is reset to zero for each successive call to `TSSolve()`.
5010bcf0153eSBarry Smith 
50111cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSolve()`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSSetMaxSNESFailures()`
5012cef5090cSJed Brown @*/
5013d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSNESFailures(TS ts, PetscInt *fails)
5014d71ae5a4SJacob Faibussowitsch {
5015cef5090cSJed Brown   PetscFunctionBegin;
5016cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
50174f572ea9SToby Isaac   PetscAssertPointer(fails, 2);
5018cef5090cSJed Brown   *fails = ts->num_snes_failures;
50193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5020cef5090cSJed Brown }
5021cef5090cSJed Brown 
5022cef5090cSJed Brown /*@
5023*188af4bfSBarry Smith   TSSetMaxStepRejections - Sets the maximum number of step rejections allowed in a single time-step attempt before a time step fails in `TSSolve()` with `TS_DIVERGED_STEP_REJECTED`
5024cef5090cSJed Brown 
5025cef5090cSJed Brown   Not Collective
5026cef5090cSJed Brown 
5027d8d19677SJose E. Roman   Input Parameters:
5028bcf0153eSBarry Smith + ts      - `TS` context
502909cb0f53SBarry Smith - rejects - maximum number of rejected steps, pass `PETSC_UNLIMITED` for unlimited
5030cef5090cSJed Brown 
5031cef5090cSJed Brown   Options Database Key:
5032*188af4bfSBarry Smith . -ts_max_step_rejections - Maximum number of step rejections before a step fails
5033cef5090cSJed Brown 
5034cef5090cSJed Brown   Level: intermediate
5035cef5090cSJed Brown 
503609cb0f53SBarry Smith   Developer Note:
503709cb0f53SBarry Smith   The options database name is incorrect.
503809cb0f53SBarry Smith 
5039*188af4bfSBarry Smith .seealso: [](ch_ts), `TS`, `SNES`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxSNESFailures()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSSetErrorIfStepFails()`,
5040*188af4bfSBarry Smith           `TSGetConvergedReason()`, `TSSolve()`, `TS_DIVERGED_STEP_REJECTED`
5041cef5090cSJed Brown @*/
5042d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxStepRejections(TS ts, PetscInt rejects)
5043d71ae5a4SJacob Faibussowitsch {
5044cef5090cSJed Brown   PetscFunctionBegin;
5045cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
504609cb0f53SBarry Smith   if (rejects == PETSC_UNLIMITED || rejects == -1) {
504709cb0f53SBarry Smith     ts->max_reject = PETSC_UNLIMITED;
504809cb0f53SBarry Smith   } else {
504909cb0f53SBarry Smith     PetscCheck(rejects >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have a negative maximum number of rejections");
5050cef5090cSJed Brown     ts->max_reject = rejects;
505109cb0f53SBarry Smith   }
50523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5053cef5090cSJed Brown }
5054cef5090cSJed Brown 
5055cef5090cSJed Brown /*@
5056*188af4bfSBarry Smith   TSSetMaxSNESFailures - Sets the maximum number of failed `SNES` solves allowed before `TSSolve()` is ended with a `TSConvergedReason` of `TS_DIVERGED_NONLINEAR_SOLVE`
5057cef5090cSJed Brown 
5058cef5090cSJed Brown   Not Collective
5059cef5090cSJed Brown 
5060d8d19677SJose E. Roman   Input Parameters:
5061bcf0153eSBarry Smith + ts    - `TS` context
506209cb0f53SBarry Smith - fails - maximum number of failed nonlinear solves, pass `PETSC_UNLIMITED` to allow any number of failures.
5063cef5090cSJed Brown 
5064cef5090cSJed Brown   Options Database Key:
5065cef5090cSJed Brown . -ts_max_snes_failures - Maximum number of nonlinear solve failures
5066cef5090cSJed Brown 
5067cef5090cSJed Brown   Level: intermediate
5068cef5090cSJed Brown 
5069*188af4bfSBarry Smith .seealso: [](ch_ts), `TS`, `SNES`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `SNESGetConvergedReason()`,
5070*188af4bfSBarry Smith           `TSGetConvergedReason()`, `TS_DIVERGED_NONLINEAR_SOLVE`, `TSConvergedReason`
5071cef5090cSJed Brown @*/
5072d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxSNESFailures(TS ts, PetscInt fails)
5073d71ae5a4SJacob Faibussowitsch {
5074cef5090cSJed Brown   PetscFunctionBegin;
5075cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
507609cb0f53SBarry Smith   if (fails == PETSC_UNLIMITED || fails == -1) {
507709cb0f53SBarry Smith     ts->max_snes_failures = PETSC_UNLIMITED;
507809cb0f53SBarry Smith   } else {
507909cb0f53SBarry Smith     PetscCheck(fails >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Cannot have a negative maximum number of failures");
5080cef5090cSJed Brown     ts->max_snes_failures = fails;
508109cb0f53SBarry Smith   }
50823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5083cef5090cSJed Brown }
5084cef5090cSJed Brown 
5085cef5090cSJed Brown /*@
5086195e9b02SBarry Smith   TSSetErrorIfStepFails - Immediately error if no step succeeds during `TSSolve()`
5087cef5090cSJed Brown 
5088cef5090cSJed Brown   Not Collective
5089cef5090cSJed Brown 
5090d8d19677SJose E. Roman   Input Parameters:
5091bcf0153eSBarry Smith + ts  - `TS` context
5092bcf0153eSBarry Smith - err - `PETSC_TRUE` to error if no step succeeds, `PETSC_FALSE` to return without failure
5093cef5090cSJed Brown 
5094cef5090cSJed Brown   Options Database Key:
5095cef5090cSJed Brown . -ts_error_if_step_fails - Error if no step succeeds
5096cef5090cSJed Brown 
5097cef5090cSJed Brown   Level: intermediate
5098cef5090cSJed Brown 
509942747ad1SJacob Faibussowitsch .seealso: [](ch_ts), `TS`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSGetConvergedReason()`
5100cef5090cSJed Brown @*/
5101d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetErrorIfStepFails(TS ts, PetscBool err)
5102d71ae5a4SJacob Faibussowitsch {
5103cef5090cSJed Brown   PetscFunctionBegin;
5104cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5105cef5090cSJed Brown   ts->errorifstepfailed = err;
51063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5107cef5090cSJed Brown }
5108cef5090cSJed Brown 
510984df9cb4SJed Brown /*@
5110552698daSJed Brown   TSGetAdapt - Get the adaptive controller context for the current method
511184df9cb4SJed Brown 
51128f14a041SBarry Smith   Collective if controller has not yet been created
511384df9cb4SJed Brown 
51144165533cSJose E. Roman   Input Parameter:
5115ed81e22dSJed Brown . ts - time stepping context
511684df9cb4SJed Brown 
51174165533cSJose E. Roman   Output Parameter:
5118ed81e22dSJed Brown . adapt - adaptive controller
511984df9cb4SJed Brown 
512084df9cb4SJed Brown   Level: intermediate
512184df9cb4SJed Brown 
51221cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdapt`, `TSAdaptSetType()`, `TSAdaptChoose()`
512384df9cb4SJed Brown @*/
5124d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetAdapt(TS ts, TSAdapt *adapt)
5125d71ae5a4SJacob Faibussowitsch {
512684df9cb4SJed Brown   PetscFunctionBegin;
512784df9cb4SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
51284f572ea9SToby Isaac   PetscAssertPointer(adapt, 2);
512984df9cb4SJed Brown   if (!ts->adapt) {
51309566063dSJacob Faibussowitsch     PetscCall(TSAdaptCreate(PetscObjectComm((PetscObject)ts), &ts->adapt));
51319566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->adapt, (PetscObject)ts, 1));
513284df9cb4SJed Brown   }
5133bec58848SLisandro Dalcin   *adapt = ts->adapt;
51343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
513584df9cb4SJed Brown }
5136d6ebe24aSShri Abhyankar 
51371c3436cfSJed Brown /*@
5138195e9b02SBarry Smith   TSSetTolerances - Set tolerances for local truncation error when using an adaptive controller
51391c3436cfSJed Brown 
51401c3436cfSJed Brown   Logically Collective
51411c3436cfSJed Brown 
51424165533cSJose E. Roman   Input Parameters:
51431c3436cfSJed Brown + ts    - time integration context
514409cb0f53SBarry Smith . atol  - scalar absolute tolerances
514509cb0f53SBarry Smith . vatol - vector of absolute tolerances or `NULL`, used in preference to `atol` if present
514609cb0f53SBarry Smith . rtol  - scalar relative tolerances
514709cb0f53SBarry Smith - vrtol - vector of relative tolerances or `NULL`, used in preference to `rtol` if present
51481c3436cfSJed Brown 
5149195e9b02SBarry Smith   Options Database Keys:
5150a3cdaa26SBarry Smith + -ts_rtol <rtol> - relative tolerance for local truncation error
515167b8a455SSatish Balay - -ts_atol <atol> - Absolute tolerance for local truncation error
5152a3cdaa26SBarry Smith 
5153bcf0153eSBarry Smith   Level: beginner
5154bcf0153eSBarry Smith 
51553ff766beSShri Abhyankar   Notes:
515609cb0f53SBarry Smith   `PETSC_CURRENT` or `PETSC_DETERMINE` may be used for `atol` or `rtol` to indicate the current value
515709cb0f53SBarry Smith   or the default value from when the object's type was set.
515809cb0f53SBarry Smith 
51593ff766beSShri Abhyankar   With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
51603ff766beSShri Abhyankar   (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
51613ff766beSShri Abhyankar   computed only for the differential or the algebraic part then this can be done using the vector of
51623ff766beSShri Abhyankar   tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
51633ff766beSShri Abhyankar   differential part and infinity for the algebraic part, the LTE calculation will include only the
51643ff766beSShri Abhyankar   differential variables.
51653ff766beSShri Abhyankar 
516609cb0f53SBarry Smith   Fortran Note:
516709cb0f53SBarry Smith   Use `PETSC_CURRENT_INTEGER` or `PETSC_DETERMINE_INTEGER`.
516809cb0f53SBarry Smith 
51691cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSGetTolerances()`
51701c3436cfSJed Brown @*/
5171d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTolerances(TS ts, PetscReal atol, Vec vatol, PetscReal rtol, Vec vrtol)
5172d71ae5a4SJacob Faibussowitsch {
51731c3436cfSJed Brown   PetscFunctionBegin;
517409cb0f53SBarry Smith   if (atol == (PetscReal)PETSC_DETERMINE) {
5175dd460d27SBarry Smith     ts->atol = ts->default_atol;
517609cb0f53SBarry Smith   } else if (atol != (PetscReal)PETSC_CURRENT) {
517709cb0f53SBarry Smith     PetscCheck(atol >= 0.0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)atol);
517809cb0f53SBarry Smith     ts->atol = atol;
517909cb0f53SBarry Smith   }
518009cb0f53SBarry Smith 
51811c3436cfSJed Brown   if (vatol) {
51829566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vatol));
51839566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vatol));
51841c3436cfSJed Brown     ts->vatol = vatol;
51851c3436cfSJed Brown   }
518609cb0f53SBarry Smith 
518709cb0f53SBarry Smith   if (rtol == (PetscReal)PETSC_DETERMINE) {
5188dd460d27SBarry Smith     ts->rtol = ts->default_rtol;
518909cb0f53SBarry Smith   } else if (rtol != (PetscReal)PETSC_CURRENT) {
519009cb0f53SBarry Smith     PetscCheck(rtol >= 0.0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Relative tolerance %g must be non-negative", (double)rtol);
519109cb0f53SBarry Smith     ts->rtol = rtol;
519209cb0f53SBarry Smith   }
519309cb0f53SBarry Smith 
51941c3436cfSJed Brown   if (vrtol) {
51959566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vrtol));
51969566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vrtol));
51971c3436cfSJed Brown     ts->vrtol = vrtol;
51981c3436cfSJed Brown   }
51993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
52001c3436cfSJed Brown }
52011c3436cfSJed Brown 
5202c5033834SJed Brown /*@
5203c5033834SJed Brown   TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
5204c5033834SJed Brown 
5205c5033834SJed Brown   Logically Collective
5206c5033834SJed Brown 
52074165533cSJose E. Roman   Input Parameter:
5208c5033834SJed Brown . ts - time integration context
5209c5033834SJed Brown 
52104165533cSJose E. Roman   Output Parameters:
5211195e9b02SBarry Smith + atol  - scalar absolute tolerances, `NULL` to ignore
5212195e9b02SBarry Smith . vatol - vector of absolute tolerances, `NULL` to ignore
5213195e9b02SBarry Smith . rtol  - scalar relative tolerances, `NULL` to ignore
5214195e9b02SBarry Smith - vrtol - vector of relative tolerances, `NULL` to ignore
5215c5033834SJed Brown 
5216c5033834SJed Brown   Level: beginner
5217c5033834SJed Brown 
52181cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSSetTolerances()`
5219c5033834SJed Brown @*/
5220d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTolerances(TS ts, PetscReal *atol, Vec *vatol, PetscReal *rtol, Vec *vrtol)
5221d71ae5a4SJacob Faibussowitsch {
5222c5033834SJed Brown   PetscFunctionBegin;
5223c5033834SJed Brown   if (atol) *atol = ts->atol;
5224c5033834SJed Brown   if (vatol) *vatol = ts->vatol;
5225c5033834SJed Brown   if (rtol) *rtol = ts->rtol;
5226c5033834SJed Brown   if (vrtol) *vrtol = ts->vrtol;
52273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5228c5033834SJed Brown }
5229c5033834SJed Brown 
52309c6b16b5SShri Abhyankar /*@
52318a175baeSEmil Constantinescu   TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
52321c3436cfSJed Brown 
5233c3339decSBarry Smith   Collective
52341c3436cfSJed Brown 
52354165533cSJose E. Roman   Input Parameters:
52361c3436cfSJed Brown + ts        - time stepping context
5237a4868fbcSLisandro Dalcin . U         - state vector, usually ts->vec_sol
5238a4868fbcSLisandro Dalcin . Y         - state vector to be compared to U
5239bcf0153eSBarry Smith - wnormtype - norm type, either `NORM_2` or `NORM_INFINITY`
52407619abb3SShri 
52414165533cSJose E. Roman   Output Parameters:
5242a2b725a8SWilliam Gropp + norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
52438a175baeSEmil Constantinescu . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5244a2b725a8SWilliam Gropp - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
5245a4868fbcSLisandro Dalcin 
5246bcf0153eSBarry Smith   Options Database Key:
5247a4868fbcSLisandro Dalcin . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
5248a4868fbcSLisandro Dalcin 
52491c3436cfSJed Brown   Level: developer
52501c3436cfSJed Brown 
52518c38e02aSSatish Balay .seealso: [](ch_ts), `TS`, `VecErrorWeightedNorms()`, `TSErrorWeightedENorm()`
52521c3436cfSJed Brown @*/
5253d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedNorm(TS ts, Vec U, Vec Y, NormType wnormtype, PetscReal *norm, PetscReal *norma, PetscReal *normr)
5254d71ae5a4SJacob Faibussowitsch {
5255037d63e4SStefano Zampini   PetscInt norma_loc, norm_loc, normr_loc;
52568a175baeSEmil Constantinescu 
52578a175baeSEmil Constantinescu   PetscFunctionBegin;
52588a175baeSEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5259dabfcb17SStefano Zampini   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
5260dabfcb17SStefano Zampini   PetscValidHeaderSpecific(Y, VEC_CLASSID, 3);
5261dabfcb17SStefano Zampini   PetscValidLogicalCollectiveEnum(ts, wnormtype, 4);
5262dabfcb17SStefano Zampini   PetscAssertPointer(norm, 5);
5263dabfcb17SStefano Zampini   PetscAssertPointer(norma, 6);
5264dabfcb17SStefano Zampini   PetscAssertPointer(normr, 7);
5265037d63e4SStefano Zampini   PetscCall(VecErrorWeightedNorms(U, Y, NULL, wnormtype, ts->atol, ts->vatol, ts->rtol, ts->vrtol, ts->adapt->ignore_max, norm, &norm_loc, norma, &norma_loc, normr, &normr_loc));
5266037d63e4SStefano Zampini   if (wnormtype == NORM_2) {
5267037d63e4SStefano Zampini     if (norm_loc) *norm = PetscSqrtReal(PetscSqr(*norm) / norm_loc);
5268037d63e4SStefano Zampini     if (norma_loc) *norma = PetscSqrtReal(PetscSqr(*norma) / norma_loc);
5269037d63e4SStefano Zampini     if (normr_loc) *normr = PetscSqrtReal(PetscSqr(*normr) / normr_loc);
52708a175baeSEmil Constantinescu   }
52713c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
52723c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
52733c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
52743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
52758a175baeSEmil Constantinescu }
52768a175baeSEmil Constantinescu 
52778a175baeSEmil Constantinescu /*@
52788a175baeSEmil Constantinescu   TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
52798a175baeSEmil Constantinescu 
5280c3339decSBarry Smith   Collective
52818a175baeSEmil Constantinescu 
52824165533cSJose E. Roman   Input Parameters:
52838a175baeSEmil Constantinescu + ts        - time stepping context
52848a175baeSEmil Constantinescu . E         - error vector
52858a175baeSEmil Constantinescu . U         - state vector, usually ts->vec_sol
52868a175baeSEmil Constantinescu . Y         - state vector, previous time step
5287bcf0153eSBarry Smith - wnormtype - norm type, either `NORM_2` or `NORM_INFINITY`
52888a175baeSEmil Constantinescu 
52894165533cSJose E. Roman   Output Parameters:
5290a2b725a8SWilliam Gropp + norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
52918a175baeSEmil Constantinescu . norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5292a2b725a8SWilliam Gropp - normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
52938a175baeSEmil Constantinescu 
5294bcf0153eSBarry Smith   Options Database Key:
52958a175baeSEmil Constantinescu . -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
52968a175baeSEmil Constantinescu 
52978a175baeSEmil Constantinescu   Level: developer
52988a175baeSEmil Constantinescu 
52998c38e02aSSatish Balay .seealso: [](ch_ts), `TS`, `VecErrorWeightedNorms()`, `TSErrorWeightedNorm()`
53008a175baeSEmil Constantinescu @*/
5301d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedENorm(TS ts, Vec E, Vec U, Vec Y, NormType wnormtype, PetscReal *norm, PetscReal *norma, PetscReal *normr)
5302d71ae5a4SJacob Faibussowitsch {
5303037d63e4SStefano Zampini   PetscInt norma_loc, norm_loc, normr_loc;
5304037d63e4SStefano Zampini 
53058a175baeSEmil Constantinescu   PetscFunctionBegin;
5306037d63e4SStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5307037d63e4SStefano Zampini   PetscCall(VecErrorWeightedNorms(U, Y, E, wnormtype, ts->atol, ts->vatol, ts->rtol, ts->vrtol, ts->adapt->ignore_max, norm, &norm_loc, norma, &norma_loc, normr, &normr_loc));
5308037d63e4SStefano Zampini   if (wnormtype == NORM_2) {
5309037d63e4SStefano Zampini     if (norm_loc) *norm = PetscSqrtReal(PetscSqr(*norm) / norm_loc);
5310037d63e4SStefano Zampini     if (norma_loc) *norma = PetscSqrtReal(PetscSqr(*norma) / norma_loc);
5311037d63e4SStefano Zampini     if (normr_loc) *normr = PetscSqrtReal(PetscSqr(*normr) / normr_loc);
5312037d63e4SStefano Zampini   }
5313037d63e4SStefano Zampini   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
5314037d63e4SStefano Zampini   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
5315037d63e4SStefano Zampini   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
53163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
53178a175baeSEmil Constantinescu }
53188a175baeSEmil Constantinescu 
53198d59e960SJed Brown /*@
53208d59e960SJed Brown   TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
53218d59e960SJed Brown 
5322c3339decSBarry Smith   Logically Collective
53238d59e960SJed Brown 
53244165533cSJose E. Roman   Input Parameters:
53258d59e960SJed Brown + ts      - time stepping context
53268d59e960SJed Brown - cfltime - maximum stable time step if using forward Euler (value can be different on each process)
53278d59e960SJed Brown 
53288d59e960SJed Brown   Note:
53298d59e960SJed Brown   After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
53308d59e960SJed Brown 
53318d59e960SJed Brown   Level: intermediate
53328d59e960SJed Brown 
53331cc06b55SBarry Smith .seealso: [](ch_ts), `TSGetCFLTime()`, `TSADAPTCFL`
53348d59e960SJed Brown @*/
5335d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetCFLTimeLocal(TS ts, PetscReal cfltime)
5336d71ae5a4SJacob Faibussowitsch {
53378d59e960SJed Brown   PetscFunctionBegin;
53388d59e960SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
53398d59e960SJed Brown   ts->cfltime_local = cfltime;
53408d59e960SJed Brown   ts->cfltime       = -1.;
53413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
53428d59e960SJed Brown }
53438d59e960SJed Brown 
53448d59e960SJed Brown /*@
53458d59e960SJed Brown   TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
53468d59e960SJed Brown 
5347c3339decSBarry Smith   Collective
53488d59e960SJed Brown 
53494165533cSJose E. Roman   Input Parameter:
53508d59e960SJed Brown . ts - time stepping context
53518d59e960SJed Brown 
53524165533cSJose E. Roman   Output Parameter:
53538d59e960SJed Brown . cfltime - maximum stable time step for forward Euler
53548d59e960SJed Brown 
53558d59e960SJed Brown   Level: advanced
53568d59e960SJed Brown 
53571cc06b55SBarry Smith .seealso: [](ch_ts), `TSSetCFLTimeLocal()`
53588d59e960SJed Brown @*/
5359d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetCFLTime(TS ts, PetscReal *cfltime)
5360d71ae5a4SJacob Faibussowitsch {
53618d59e960SJed Brown   PetscFunctionBegin;
5362462c564dSBarry Smith   if (ts->cfltime < 0) PetscCallMPI(MPIU_Allreduce(&ts->cfltime_local, &ts->cfltime, 1, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject)ts)));
53638d59e960SJed Brown   *cfltime = ts->cfltime;
53643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
53658d59e960SJed Brown }
53668d59e960SJed Brown 
5367d6ebe24aSShri Abhyankar /*@
5368d6ebe24aSShri Abhyankar   TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
5369d6ebe24aSShri Abhyankar 
5370d6ebe24aSShri Abhyankar   Input Parameters:
5371bcf0153eSBarry Smith + ts - the `TS` context.
5372d6ebe24aSShri Abhyankar . xl - lower bound.
5373a2b725a8SWilliam Gropp - xu - upper bound.
5374d6ebe24aSShri Abhyankar 
53752bd2b0e6SSatish Balay   Level: advanced
53762bd2b0e6SSatish Balay 
5377bcf0153eSBarry Smith   Note:
5378bcf0153eSBarry Smith   If this routine is not called then the lower and upper bounds are set to
5379bcf0153eSBarry Smith   `PETSC_NINFINITY` and `PETSC_INFINITY` respectively during `SNESSetUp()`.
5380bcf0153eSBarry Smith 
53811cc06b55SBarry Smith .seealso: [](ch_ts), `TS`
5382d6ebe24aSShri Abhyankar @*/
5383d71ae5a4SJacob Faibussowitsch PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
5384d71ae5a4SJacob Faibussowitsch {
5385d6ebe24aSShri Abhyankar   SNES snes;
5386d6ebe24aSShri Abhyankar 
5387d6ebe24aSShri Abhyankar   PetscFunctionBegin;
53889566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
53899566063dSJacob Faibussowitsch   PetscCall(SNESVISetVariableBounds(snes, xl, xu));
53903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5391d6ebe24aSShri Abhyankar }
5392d6ebe24aSShri Abhyankar 
5393f9c1d6abSBarry Smith /*@
5394f9c1d6abSBarry Smith   TSComputeLinearStability - computes the linear stability function at a point
5395f9c1d6abSBarry Smith 
5396c3339decSBarry Smith   Collective
5397f9c1d6abSBarry Smith 
5398f9c1d6abSBarry Smith   Input Parameters:
5399bcf0153eSBarry Smith + ts - the `TS` context
54002fe279fdSBarry Smith . xr - real part of input argument
54012fe279fdSBarry Smith - xi - imaginary part of input argument
5402f9c1d6abSBarry Smith 
5403f9c1d6abSBarry Smith   Output Parameters:
54042fe279fdSBarry Smith + yr - real part of function value
54052fe279fdSBarry Smith - yi - imaginary part of function value
5406f9c1d6abSBarry Smith 
5407f9c1d6abSBarry Smith   Level: developer
5408f9c1d6abSBarry Smith 
54091cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetRHSFunction()`, `TSComputeIFunction()`
5410f9c1d6abSBarry Smith @*/
5411d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeLinearStability(TS ts, PetscReal xr, PetscReal xi, PetscReal *yr, PetscReal *yi)
5412d71ae5a4SJacob Faibussowitsch {
5413f9c1d6abSBarry Smith   PetscFunctionBegin;
5414f9c1d6abSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5415dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, linearstability, xr, xi, yr, yi);
54163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5417f9c1d6abSBarry Smith }
541824655328SShri 
541924655328SShri /*@
5420dcb233daSLisandro Dalcin   TSRestartStep - Flags the solver to restart the next step
5421dcb233daSLisandro Dalcin 
5422c3339decSBarry Smith   Collective
5423dcb233daSLisandro Dalcin 
5424dcb233daSLisandro Dalcin   Input Parameter:
5425bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
5426dcb233daSLisandro Dalcin 
5427dcb233daSLisandro Dalcin   Level: advanced
5428dcb233daSLisandro Dalcin 
5429dcb233daSLisandro Dalcin   Notes:
5430bcf0153eSBarry Smith   Multistep methods like `TSBDF` or Runge-Kutta methods with FSAL property require restarting the solver in the event of
5431dcb233daSLisandro Dalcin   discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution
5432dcb233daSLisandro Dalcin   vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For
5433bcf0153eSBarry Smith   the sake of correctness and maximum safety, users are expected to call `TSRestart()` whenever they introduce
5434dcb233daSLisandro Dalcin   discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with
5435dcb233daSLisandro Dalcin   discontinuous source terms).
5436dcb233daSLisandro Dalcin 
54371cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSBDF`, `TSSolve()`, `TSSetPreStep()`, `TSSetPostStep()`
5438dcb233daSLisandro Dalcin @*/
5439d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRestartStep(TS ts)
5440d71ae5a4SJacob Faibussowitsch {
5441dcb233daSLisandro Dalcin   PetscFunctionBegin;
5442dcb233daSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5443dcb233daSLisandro Dalcin   ts->steprestart = PETSC_TRUE;
54443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5445dcb233daSLisandro Dalcin }
5446dcb233daSLisandro Dalcin 
5447dcb233daSLisandro Dalcin /*@
544824655328SShri   TSRollBack - Rolls back one time step
544924655328SShri 
5450c3339decSBarry Smith   Collective
545124655328SShri 
545224655328SShri   Input Parameter:
5453bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
545424655328SShri 
545524655328SShri   Level: advanced
545624655328SShri 
54579dc50cb5SStefano Zampini .seealso: [](ch_ts), `TS`, `TSGetStepRollBack()`, `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSInterpolate()`
545824655328SShri @*/
5459d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRollBack(TS ts)
5460d71ae5a4SJacob Faibussowitsch {
546124655328SShri   PetscFunctionBegin;
546224655328SShri   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
54633c633725SBarry Smith   PetscCheck(!ts->steprollback, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "TSRollBack already called");
5464c61711c8SStefano Zampini   PetscTryTypeMethod(ts, rollback);
5465c61711c8SStefano Zampini   PetscCall(VecCopy(ts->vec_sol0, ts->vec_sol));
546624655328SShri   ts->time_step  = ts->ptime - ts->ptime_prev;
546724655328SShri   ts->ptime      = ts->ptime_prev;
5468be5899b3SLisandro Dalcin   ts->ptime_prev = ts->ptime_prev_rollback;
54692808aa04SLisandro Dalcin   ts->steps--;
5470b3de5cdeSLisandro Dalcin   ts->steprollback = PETSC_TRUE;
54713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
547224655328SShri }
5473aeb4809dSShri Abhyankar 
5474ff22ae23SHong Zhang /*@
54759dc50cb5SStefano Zampini   TSGetStepRollBack - Get the internal flag indicating if you are rolling back a step
54769dc50cb5SStefano Zampini 
54779dc50cb5SStefano Zampini   Not collective
54789dc50cb5SStefano Zampini 
54799dc50cb5SStefano Zampini   Input Parameter:
54809dc50cb5SStefano Zampini . ts - the `TS` context obtained from `TSCreate()`
54819dc50cb5SStefano Zampini 
54829dc50cb5SStefano Zampini   Output Parameter:
54839dc50cb5SStefano Zampini . flg - the rollback flag
54849dc50cb5SStefano Zampini 
54859dc50cb5SStefano Zampini   Level: advanced
54869dc50cb5SStefano Zampini 
54879dc50cb5SStefano Zampini .seealso: [](ch_ts), `TS`, `TSCreate()`, `TSRollBack()`
54889dc50cb5SStefano Zampini @*/
54899dc50cb5SStefano Zampini PetscErrorCode TSGetStepRollBack(TS ts, PetscBool *flg)
54909dc50cb5SStefano Zampini {
54919dc50cb5SStefano Zampini   PetscFunctionBegin;
54929dc50cb5SStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
54939dc50cb5SStefano Zampini   PetscAssertPointer(flg, 2);
54949dc50cb5SStefano Zampini   *flg = ts->steprollback;
54959dc50cb5SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
54969dc50cb5SStefano Zampini }
54979dc50cb5SStefano Zampini 
54989dc50cb5SStefano Zampini /*@
5499c6bf8827SStefano Zampini   TSGetStepResize - Get the internal flag indicating if the current step is after a resize.
5500c6bf8827SStefano Zampini 
5501c6bf8827SStefano Zampini   Not collective
5502c6bf8827SStefano Zampini 
5503c6bf8827SStefano Zampini   Input Parameter:
5504c6bf8827SStefano Zampini . ts - the `TS` context obtained from `TSCreate()`
5505c6bf8827SStefano Zampini 
5506c6bf8827SStefano Zampini   Output Parameter:
5507c6bf8827SStefano Zampini . flg - the resize flag
5508c6bf8827SStefano Zampini 
5509c6bf8827SStefano Zampini   Level: advanced
5510c6bf8827SStefano Zampini 
5511c6bf8827SStefano Zampini .seealso: [](ch_ts), `TS`, `TSCreate()`, `TSSetResize()`
5512c6bf8827SStefano Zampini @*/
5513c6bf8827SStefano Zampini PetscErrorCode TSGetStepResize(TS ts, PetscBool *flg)
5514c6bf8827SStefano Zampini {
5515c6bf8827SStefano Zampini   PetscFunctionBegin;
5516c6bf8827SStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5517c6bf8827SStefano Zampini   PetscAssertPointer(flg, 2);
5518c6bf8827SStefano Zampini   *flg = ts->stepresize;
5519c6bf8827SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
5520c6bf8827SStefano Zampini }
5521c6bf8827SStefano Zampini 
5522c6bf8827SStefano Zampini /*@
5523ff22ae23SHong Zhang   TSGetStages - Get the number of stages and stage values
5524ff22ae23SHong Zhang 
5525ff22ae23SHong Zhang   Input Parameter:
5526bcf0153eSBarry Smith . ts - the `TS` context obtained from `TSCreate()`
5527ff22ae23SHong Zhang 
55280429704eSStefano Zampini   Output Parameters:
55290429704eSStefano Zampini + ns - the number of stages
55300429704eSStefano Zampini - Y  - the current stage vectors
55310429704eSStefano Zampini 
5532ff22ae23SHong Zhang   Level: advanced
5533ff22ae23SHong Zhang 
5534bcf0153eSBarry Smith   Note:
5535195e9b02SBarry Smith   Both `ns` and `Y` can be `NULL`.
55360429704eSStefano Zampini 
55371cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSCreate()`
5538ff22ae23SHong Zhang @*/
5539d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetStages(TS ts, PetscInt *ns, Vec **Y)
5540d71ae5a4SJacob Faibussowitsch {
5541ff22ae23SHong Zhang   PetscFunctionBegin;
5542ff22ae23SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
55434f572ea9SToby Isaac   if (ns) PetscAssertPointer(ns, 2);
55444f572ea9SToby Isaac   if (Y) PetscAssertPointer(Y, 3);
55450429704eSStefano Zampini   if (!ts->ops->getstages) {
55460429704eSStefano Zampini     if (ns) *ns = 0;
55470429704eSStefano Zampini     if (Y) *Y = NULL;
5548dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(ts, getstages, ns, Y);
55493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5550ff22ae23SHong Zhang }
5551ff22ae23SHong Zhang 
5552847ff0e1SMatthew G. Knepley /*@C
5553847ff0e1SMatthew G. Knepley   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
5554847ff0e1SMatthew G. Knepley 
5555c3339decSBarry Smith   Collective
5556847ff0e1SMatthew G. Knepley 
5557847ff0e1SMatthew G. Knepley   Input Parameters:
5558bcf0153eSBarry Smith + ts    - the `TS` context
5559847ff0e1SMatthew G. Knepley . t     - current timestep
5560847ff0e1SMatthew G. Knepley . U     - state vector
5561847ff0e1SMatthew G. Knepley . Udot  - time derivative of state vector
5562847ff0e1SMatthew G. Knepley . shift - shift to apply, see note below
5563847ff0e1SMatthew G. Knepley - ctx   - an optional user context
5564847ff0e1SMatthew G. Knepley 
5565847ff0e1SMatthew G. Knepley   Output Parameters:
5566847ff0e1SMatthew G. Knepley + J - Jacobian matrix (not altered in this routine)
5567195e9b02SBarry Smith - B - newly computed Jacobian matrix to use with preconditioner (generally the same as `J`)
5568847ff0e1SMatthew G. Knepley 
5569847ff0e1SMatthew G. Knepley   Level: intermediate
5570847ff0e1SMatthew G. Knepley 
5571847ff0e1SMatthew G. Knepley   Notes:
5572847ff0e1SMatthew G. Knepley   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
5573847ff0e1SMatthew G. Knepley 
5574847ff0e1SMatthew G. Knepley   dF/dU + shift*dF/dUdot
5575847ff0e1SMatthew G. Knepley 
5576847ff0e1SMatthew G. Knepley   Most users should not need to explicitly call this routine, as it
5577847ff0e1SMatthew G. Knepley   is used internally within the nonlinear solvers.
5578847ff0e1SMatthew G. Knepley 
5579bcf0153eSBarry Smith   This will first try to get the coloring from the `DM`.  If the `DM` type has no coloring
5580847ff0e1SMatthew G. Knepley   routine, then it will try to get the coloring from the matrix.  This requires that the
5581847ff0e1SMatthew G. Knepley   matrix have nonzero entries precomputed.
5582847ff0e1SMatthew G. Knepley 
55831cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetIJacobian()`, `MatFDColoringCreate()`, `MatFDColoringSetFunction()`
5584847ff0e1SMatthew G. Knepley @*/
5585d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIJacobianDefaultColor(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat J, Mat B, void *ctx)
5586d71ae5a4SJacob Faibussowitsch {
5587847ff0e1SMatthew G. Knepley   SNES          snes;
5588847ff0e1SMatthew G. Knepley   MatFDColoring color;
5589847ff0e1SMatthew G. Knepley   PetscBool     hascolor, matcolor = PETSC_FALSE;
5590847ff0e1SMatthew G. Knepley 
5591847ff0e1SMatthew G. Knepley   PetscFunctionBegin;
55929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL));
55939566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)B, "TSMatFDColoring", (PetscObject *)&color));
5594847ff0e1SMatthew G. Knepley   if (!color) {
5595847ff0e1SMatthew G. Knepley     DM         dm;
5596847ff0e1SMatthew G. Knepley     ISColoring iscoloring;
5597847ff0e1SMatthew G. Knepley 
55989566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
55999566063dSJacob Faibussowitsch     PetscCall(DMHasColoring(dm, &hascolor));
5600847ff0e1SMatthew G. Knepley     if (hascolor && !matcolor) {
56019566063dSJacob Faibussowitsch       PetscCall(DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring));
56029566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
56032ba42892SBarry Smith       PetscCall(MatFDColoringSetFunction(color, (MatFDColoringFn *)SNESTSFormFunction, (void *)ts));
56049566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
56059566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
56069566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5607847ff0e1SMatthew G. Knepley     } else {
5608847ff0e1SMatthew G. Knepley       MatColoring mc;
5609847ff0e1SMatthew G. Knepley 
56109566063dSJacob Faibussowitsch       PetscCall(MatColoringCreate(B, &mc));
56119566063dSJacob Faibussowitsch       PetscCall(MatColoringSetDistance(mc, 2));
56129566063dSJacob Faibussowitsch       PetscCall(MatColoringSetType(mc, MATCOLORINGSL));
56139566063dSJacob Faibussowitsch       PetscCall(MatColoringSetFromOptions(mc));
56149566063dSJacob Faibussowitsch       PetscCall(MatColoringApply(mc, &iscoloring));
56159566063dSJacob Faibussowitsch       PetscCall(MatColoringDestroy(&mc));
56169566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
56172ba42892SBarry Smith       PetscCall(MatFDColoringSetFunction(color, (MatFDColoringFn *)SNESTSFormFunction, (void *)ts));
56189566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
56199566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
56209566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5621847ff0e1SMatthew G. Knepley     }
56229566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject)B, "TSMatFDColoring", (PetscObject)color));
56239566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)color));
5624847ff0e1SMatthew G. Knepley   }
56259566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
56269566063dSJacob Faibussowitsch   PetscCall(MatFDColoringApply(B, color, U, snes));
5627847ff0e1SMatthew G. Knepley   if (J != B) {
56289566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
56299566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
5630847ff0e1SMatthew G. Knepley   }
56313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5632847ff0e1SMatthew G. Knepley }
563393b34091SDebojyoti Ghosh 
5634b43aa488SJacob Faibussowitsch /*@C
56356bc98fa9SBarry Smith   TSSetFunctionDomainError - Set a function that tests if the current state vector is valid
5636cb9d8021SPierre Barbier de Reuille 
563752f13ae7SStefano Zampini   Logically collective
563852f13ae7SStefano Zampini 
5639cb9d8021SPierre Barbier de Reuille   Input Parameters:
5640bcf0153eSBarry Smith + ts   - the `TS` context
5641bcf0153eSBarry Smith - func - function called within `TSFunctionDomainError()`
56426bc98fa9SBarry Smith 
564320f4b53cSBarry Smith   Calling sequence of `func`:
56448847d985SBarry Smith + ts     - the `TS` context
56456bc98fa9SBarry Smith . time   - the current time (of the stage)
56466bc98fa9SBarry Smith . state  - the state to check if it is valid
5647a144a63fSStefano Zampini - accept - (output parameter) `PETSC_FALSE` if the state is not acceptable, `PETSC_TRUE` if acceptable
5648cb9d8021SPierre Barbier de Reuille 
5649cb9d8021SPierre Barbier de Reuille   Level: intermediate
5650cb9d8021SPierre Barbier de Reuille 
56516bc98fa9SBarry Smith   Notes:
565252f13ae7SStefano Zampini   `accept` must be collectively specified.
56536bc98fa9SBarry Smith   If an implicit ODE solver is being used then, in addition to providing this routine, the
5654bcf0153eSBarry Smith   user's code should call `SNESSetFunctionDomainError()` when domain errors occur during
5655bcf0153eSBarry Smith   function evaluations where the functions are provided by `TSSetIFunction()` or `TSSetRHSFunction()`.
5656bcf0153eSBarry Smith   Use `TSGetSNES()` to obtain the `SNES` object
56576bc98fa9SBarry Smith 
5658b43aa488SJacob Faibussowitsch   Developer Notes:
5659bcf0153eSBarry Smith   The naming of this function is inconsistent with the `SNESSetFunctionDomainError()`
56606bc98fa9SBarry Smith   since one takes a function pointer and the other does not.
56616bc98fa9SBarry Smith 
56621cc06b55SBarry Smith .seealso: [](ch_ts), `TSAdaptCheckStage()`, `TSFunctionDomainError()`, `SNESSetFunctionDomainError()`, `TSGetSNES()`
5663cb9d8021SPierre Barbier de Reuille @*/
5664a144a63fSStefano Zampini PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS ts, PetscReal time, Vec state, PetscBool *accept))
5665d71ae5a4SJacob Faibussowitsch {
5666cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5667cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5668cb9d8021SPierre Barbier de Reuille   ts->functiondomainerror = func;
56693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5670cb9d8021SPierre Barbier de Reuille }
5671cb9d8021SPierre Barbier de Reuille 
5672cb9d8021SPierre Barbier de Reuille /*@
56736bc98fa9SBarry Smith   TSFunctionDomainError - Checks if the current state is valid
5674cb9d8021SPierre Barbier de Reuille 
567552f13ae7SStefano Zampini   Collective
567652f13ae7SStefano Zampini 
5677cb9d8021SPierre Barbier de Reuille   Input Parameters:
5678bcf0153eSBarry Smith + ts        - the `TS` context
56796bc98fa9SBarry Smith . stagetime - time of the simulation
56806bc98fa9SBarry Smith - Y         - state vector to check.
5681cb9d8021SPierre Barbier de Reuille 
5682cb9d8021SPierre Barbier de Reuille   Output Parameter:
5683bcf0153eSBarry Smith . accept - Set to `PETSC_FALSE` if the current state vector is valid.
568496a0c994SBarry Smith 
56856bc98fa9SBarry Smith   Level: developer
56866bc98fa9SBarry Smith 
5687bcf0153eSBarry Smith   Note:
5688bcf0153eSBarry Smith   This function is called by the `TS` integration routines and calls the user provided function (set with `TSSetFunctionDomainError()`)
5689bcf0153eSBarry Smith   to check if the current state is valid.
5690bcf0153eSBarry Smith 
56911cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetFunctionDomainError()`
5692cb9d8021SPierre Barbier de Reuille @*/
5693d71ae5a4SJacob Faibussowitsch PetscErrorCode TSFunctionDomainError(TS ts, PetscReal stagetime, Vec Y, PetscBool *accept)
5694d71ae5a4SJacob Faibussowitsch {
5695cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5696cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
569752f13ae7SStefano Zampini   PetscValidLogicalCollectiveReal(ts, stagetime, 2);
569852f13ae7SStefano Zampini   PetscValidHeaderSpecific(Y, VEC_CLASSID, 3);
569952f13ae7SStefano Zampini   PetscAssertPointer(accept, 4);
5700cb9d8021SPierre Barbier de Reuille   *accept = PETSC_TRUE;
57011e66621cSBarry Smith   if (ts->functiondomainerror) PetscCall((*ts->functiondomainerror)(ts, stagetime, Y, accept));
57023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5703cb9d8021SPierre Barbier de Reuille }
57041ceb14c0SBarry Smith 
5705cc4c1da9SBarry Smith /*@
5706195e9b02SBarry Smith   TSClone - This function clones a time step `TS` object.
570793b34091SDebojyoti Ghosh 
5708d083f849SBarry Smith   Collective
570993b34091SDebojyoti Ghosh 
571093b34091SDebojyoti Ghosh   Input Parameter:
5711bcf0153eSBarry Smith . tsin - The input `TS`
571293b34091SDebojyoti Ghosh 
571393b34091SDebojyoti Ghosh   Output Parameter:
5714bcf0153eSBarry Smith . tsout - The output `TS` (cloned)
57155eca1a21SEmil Constantinescu 
57165eca1a21SEmil Constantinescu   Level: developer
571793b34091SDebojyoti Ghosh 
5718bcf0153eSBarry Smith   Notes:
5719bcf0153eSBarry Smith   This function is used to create a clone of a `TS` object. It is used in `TSARKIMEX` for initializing the slope for first stage explicit methods.
5720bcf0153eSBarry Smith   It will likely be replaced in the future with a mechanism of switching methods on the fly.
5721bcf0153eSBarry Smith 
5722195e9b02SBarry Smith   When using `TSDestroy()` on a clone the user has to first reset the correct `TS` reference in the embedded `SNES` object: e.g., by running
5723195e9b02SBarry Smith .vb
5724195e9b02SBarry Smith  SNES snes_dup = NULL;
5725195e9b02SBarry Smith  TSGetSNES(ts,&snes_dup);
5726195e9b02SBarry Smith  TSSetSNES(ts,snes_dup);
5727195e9b02SBarry Smith .ve
5728bcf0153eSBarry Smith 
57291cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `SNES`, `TSCreate()`, `TSSetType()`, `TSSetUp()`, `TSDestroy()`, `TSSetProblemType()`
573093b34091SDebojyoti Ghosh @*/
5731d71ae5a4SJacob Faibussowitsch PetscErrorCode TSClone(TS tsin, TS *tsout)
5732d71ae5a4SJacob Faibussowitsch {
573393b34091SDebojyoti Ghosh   TS     t;
5734dc846ba4SSatish Balay   SNES   snes_start;
5735dc846ba4SSatish Balay   DM     dm;
5736dc846ba4SSatish Balay   TSType type;
573793b34091SDebojyoti Ghosh 
573893b34091SDebojyoti Ghosh   PetscFunctionBegin;
57394f572ea9SToby Isaac   PetscAssertPointer(tsin, 1);
574093b34091SDebojyoti Ghosh   *tsout = NULL;
574193b34091SDebojyoti Ghosh 
57429566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView));
574393b34091SDebojyoti Ghosh 
574493b34091SDebojyoti Ghosh   /* General TS description */
574593b34091SDebojyoti Ghosh   t->numbermonitors    = 0;
5746371d2eb7SMartin Diehl   t->setupcalled       = PETSC_FALSE;
574793b34091SDebojyoti Ghosh   t->ksp_its           = 0;
574893b34091SDebojyoti Ghosh   t->snes_its          = 0;
574993b34091SDebojyoti Ghosh   t->nwork             = 0;
57507d51462cSStefano Zampini   t->rhsjacobian.time  = PETSC_MIN_REAL;
575193b34091SDebojyoti Ghosh   t->rhsjacobian.scale = 1.;
575293b34091SDebojyoti Ghosh   t->ijacobian.shift   = 1.;
575393b34091SDebojyoti Ghosh 
57549566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(tsin, &snes_start));
57559566063dSJacob Faibussowitsch   PetscCall(TSSetSNES(t, snes_start));
5756d15a3a53SEmil Constantinescu 
57579566063dSJacob Faibussowitsch   PetscCall(TSGetDM(tsin, &dm));
57589566063dSJacob Faibussowitsch   PetscCall(TSSetDM(t, dm));
575993b34091SDebojyoti Ghosh 
576093b34091SDebojyoti Ghosh   t->adapt = tsin->adapt;
57619566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->adapt));
576293b34091SDebojyoti Ghosh 
5763e7069c78SShri   t->trajectory = tsin->trajectory;
57649566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->trajectory));
5765e7069c78SShri 
5766e7069c78SShri   t->event = tsin->event;
57676b10a48eSSatish Balay   if (t->event) t->event->refct++;
5768e7069c78SShri 
576993b34091SDebojyoti Ghosh   t->problem_type      = tsin->problem_type;
577093b34091SDebojyoti Ghosh   t->ptime             = tsin->ptime;
5771e7069c78SShri   t->ptime_prev        = tsin->ptime_prev;
577293b34091SDebojyoti Ghosh   t->time_step         = tsin->time_step;
577393b34091SDebojyoti Ghosh   t->max_time          = tsin->max_time;
577493b34091SDebojyoti Ghosh   t->steps             = tsin->steps;
577593b34091SDebojyoti Ghosh   t->max_steps         = tsin->max_steps;
577693b34091SDebojyoti Ghosh   t->equation_type     = tsin->equation_type;
577793b34091SDebojyoti Ghosh   t->atol              = tsin->atol;
577893b34091SDebojyoti Ghosh   t->rtol              = tsin->rtol;
577993b34091SDebojyoti Ghosh   t->max_snes_failures = tsin->max_snes_failures;
578093b34091SDebojyoti Ghosh   t->max_reject        = tsin->max_reject;
578193b34091SDebojyoti Ghosh   t->errorifstepfailed = tsin->errorifstepfailed;
578293b34091SDebojyoti Ghosh 
57839566063dSJacob Faibussowitsch   PetscCall(TSGetType(tsin, &type));
57849566063dSJacob Faibussowitsch   PetscCall(TSSetType(t, type));
578593b34091SDebojyoti Ghosh 
578693b34091SDebojyoti Ghosh   t->vec_sol = NULL;
578793b34091SDebojyoti Ghosh 
578893b34091SDebojyoti Ghosh   t->cfltime          = tsin->cfltime;
578993b34091SDebojyoti Ghosh   t->cfltime_local    = tsin->cfltime_local;
579093b34091SDebojyoti Ghosh   t->exact_final_time = tsin->exact_final_time;
579193b34091SDebojyoti Ghosh 
5792aea10558SJacob Faibussowitsch   t->ops[0] = tsin->ops[0];
579393b34091SDebojyoti Ghosh 
57940d4fed19SBarry Smith   if (((PetscObject)tsin)->fortran_func_pointers) {
57950d4fed19SBarry Smith     PetscInt i;
57965ebfa9e9SBarry Smith     PetscCall(PetscMalloc((10) * sizeof(PetscFortranCallbackFn *), &((PetscObject)t)->fortran_func_pointers));
5797ad540459SPierre Jolivet     for (i = 0; i < 10; i++) ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
57980d4fed19SBarry Smith   }
579993b34091SDebojyoti Ghosh   *tsout = t;
58003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
580193b34091SDebojyoti Ghosh }
5802f3b1f45cSBarry Smith 
5803d71ae5a4SJacob Faibussowitsch static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void *ctx, Vec x, Vec y)
5804d71ae5a4SJacob Faibussowitsch {
5805f3b1f45cSBarry Smith   TS ts = (TS)ctx;
5806f3b1f45cSBarry Smith 
5807f3b1f45cSBarry Smith   PetscFunctionBegin;
58089566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSFunction(ts, 0, x, y));
58093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5810f3b1f45cSBarry Smith }
5811f3b1f45cSBarry Smith 
5812f3b1f45cSBarry Smith /*@
5813bcf0153eSBarry Smith   TSRHSJacobianTest - Compares the multiply routine provided to the `MATSHELL` with differencing on the `TS` given RHS function.
5814f3b1f45cSBarry Smith 
5815c3339decSBarry Smith   Logically Collective
5816f3b1f45cSBarry Smith 
58172fe279fdSBarry Smith   Input Parameter:
5818b43aa488SJacob Faibussowitsch . ts - the time stepping routine
5819f3b1f45cSBarry Smith 
5820f3b1f45cSBarry Smith   Output Parameter:
5821bcf0153eSBarry Smith . flg - `PETSC_TRUE` if the multiply is likely correct
5822f3b1f45cSBarry Smith 
5823bcf0153eSBarry Smith   Options Database Key:
5824f3b1f45cSBarry Smith . -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator
5825f3b1f45cSBarry Smith 
5826f3b1f45cSBarry Smith   Level: advanced
5827f3b1f45cSBarry Smith 
5828bcf0153eSBarry Smith   Note:
5829195e9b02SBarry Smith   This only works for problems defined using `TSSetRHSFunction()` and Jacobian NOT `TSSetIFunction()` and Jacobian
5830f3b1f45cSBarry Smith 
58311cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `Mat`, `MATSHELL`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTestTranspose()`
5832f3b1f45cSBarry Smith @*/
5833d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSJacobianTest(TS ts, PetscBool *flg)
5834d71ae5a4SJacob Faibussowitsch {
5835f3b1f45cSBarry Smith   Mat              J, B;
58368434afd1SBarry Smith   TSRHSJacobianFn *func;
5837f3b1f45cSBarry Smith   void            *ctx;
5838f3b1f45cSBarry Smith 
5839f3b1f45cSBarry Smith   PetscFunctionBegin;
58409566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, &J, &B, &func, &ctx));
58419566063dSJacob Faibussowitsch   PetscCall((*func)(ts, 0.0, ts->vec_sol, J, B, ctx));
58429566063dSJacob Faibussowitsch   PetscCall(MatShellTestMult(J, RHSWrapperFunction_TSRHSJacobianTest, ts->vec_sol, ts, flg));
58433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5844f3b1f45cSBarry Smith }
5845f3b1f45cSBarry Smith 
5846cc4c1da9SBarry Smith /*@
5847bcf0153eSBarry Smith   TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the `MATSHELL` with differencing on the `TS` given RHS function.
5848f3b1f45cSBarry Smith 
5849c3339decSBarry Smith   Logically Collective
5850f3b1f45cSBarry Smith 
58512fe279fdSBarry Smith   Input Parameter:
5852b43aa488SJacob Faibussowitsch . ts - the time stepping routine
5853f3b1f45cSBarry Smith 
5854f3b1f45cSBarry Smith   Output Parameter:
5855bcf0153eSBarry Smith . flg - `PETSC_TRUE` if the multiply is likely correct
5856f3b1f45cSBarry Smith 
5857bcf0153eSBarry Smith   Options Database Key:
5858f3b1f45cSBarry Smith . -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator
5859f3b1f45cSBarry Smith 
5860bcf0153eSBarry Smith   Level: advanced
5861bcf0153eSBarry Smith 
586295452b02SPatrick Sanan   Notes:
5863195e9b02SBarry Smith   This only works for problems defined using `TSSetRHSFunction()` and Jacobian NOT `TSSetIFunction()` and Jacobian
5864f3b1f45cSBarry Smith 
58651cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `Mat`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTest()`
5866f3b1f45cSBarry Smith @*/
5867d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSJacobianTestTranspose(TS ts, PetscBool *flg)
5868d71ae5a4SJacob Faibussowitsch {
5869f3b1f45cSBarry Smith   Mat              J, B;
5870f3b1f45cSBarry Smith   void            *ctx;
58718434afd1SBarry Smith   TSRHSJacobianFn *func;
5872f3b1f45cSBarry Smith 
5873f3b1f45cSBarry Smith   PetscFunctionBegin;
58749566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, &J, &B, &func, &ctx));
58759566063dSJacob Faibussowitsch   PetscCall((*func)(ts, 0.0, ts->vec_sol, J, B, ctx));
58769566063dSJacob Faibussowitsch   PetscCall(MatShellTestMultTranspose(J, RHSWrapperFunction_TSRHSJacobianTest, ts->vec_sol, ts, flg));
58773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5878f3b1f45cSBarry Smith }
58790fe4d17eSHong Zhang 
58800fe4d17eSHong Zhang /*@
58810fe4d17eSHong Zhang   TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used.
58820fe4d17eSHong Zhang 
588320f4b53cSBarry Smith   Logically Collective
58840fe4d17eSHong Zhang 
5885d8d19677SJose E. Roman   Input Parameters:
58860fe4d17eSHong Zhang + ts                   - timestepping context
5887bcf0153eSBarry Smith - use_splitrhsfunction - `PETSC_TRUE` indicates that the split RHSFunction will be used
58880fe4d17eSHong Zhang 
5889bcf0153eSBarry Smith   Options Database Key:
58900fe4d17eSHong Zhang . -ts_use_splitrhsfunction - <true,false>
58910fe4d17eSHong Zhang 
58920fe4d17eSHong Zhang   Level: intermediate
58930fe4d17eSHong Zhang 
5894bcf0153eSBarry Smith   Note:
5895195e9b02SBarry Smith   This is only for multirate methods
5896bcf0153eSBarry Smith 
58971cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSGetUseSplitRHSFunction()`
58980fe4d17eSHong Zhang @*/
5899d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction)
5900d71ae5a4SJacob Faibussowitsch {
59010fe4d17eSHong Zhang   PetscFunctionBegin;
59020fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
59030fe4d17eSHong Zhang   ts->use_splitrhsfunction = use_splitrhsfunction;
59043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
59050fe4d17eSHong Zhang }
59060fe4d17eSHong Zhang 
59070fe4d17eSHong Zhang /*@
59080fe4d17eSHong Zhang   TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used.
59090fe4d17eSHong Zhang 
591020f4b53cSBarry Smith   Not Collective
59110fe4d17eSHong Zhang 
59120fe4d17eSHong Zhang   Input Parameter:
59130fe4d17eSHong Zhang . ts - timestepping context
59140fe4d17eSHong Zhang 
59150fe4d17eSHong Zhang   Output Parameter:
5916bcf0153eSBarry Smith . use_splitrhsfunction - `PETSC_TRUE` indicates that the split RHSFunction will be used
59170fe4d17eSHong Zhang 
59180fe4d17eSHong Zhang   Level: intermediate
59190fe4d17eSHong Zhang 
59201cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `TSSetUseSplitRHSFunction()`
59210fe4d17eSHong Zhang @*/
5922d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction)
5923d71ae5a4SJacob Faibussowitsch {
59240fe4d17eSHong Zhang   PetscFunctionBegin;
59250fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
59260fe4d17eSHong Zhang   *use_splitrhsfunction = ts->use_splitrhsfunction;
59273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
59280fe4d17eSHong Zhang }
5929d60b7d5cSBarry Smith 
5930d60b7d5cSBarry Smith /*@
5931d60b7d5cSBarry Smith   TSSetMatStructure - sets the relationship between the nonzero structure of the RHS Jacobian matrix to the IJacobian matrix.
5932d60b7d5cSBarry Smith 
5933c3339decSBarry Smith   Logically  Collective
5934d60b7d5cSBarry Smith 
5935d60b7d5cSBarry Smith   Input Parameters:
5936d60b7d5cSBarry Smith + ts  - the time-stepper
5937bcf0153eSBarry Smith - str - the structure (the default is `UNKNOWN_NONZERO_PATTERN`)
5938d60b7d5cSBarry Smith 
5939d60b7d5cSBarry Smith   Level: intermediate
5940d60b7d5cSBarry Smith 
5941bcf0153eSBarry Smith   Note:
5942d60b7d5cSBarry Smith   When the relationship between the nonzero structures is known and supplied the solution process can be much faster
5943d60b7d5cSBarry Smith 
59441cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `MatAXPY()`, `MatStructure`
5945d60b7d5cSBarry Smith  @*/
5946d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMatStructure(TS ts, MatStructure str)
5947d71ae5a4SJacob Faibussowitsch {
5948d60b7d5cSBarry Smith   PetscFunctionBegin;
5949d60b7d5cSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5950d60b7d5cSBarry Smith   ts->axpy_pattern = str;
59513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5952d60b7d5cSBarry Smith }
59534a658b32SHong Zhang 
59544a658b32SHong Zhang /*@
59558343f784SJames Wright   TSSetEvaluationTimes - sets the evaluation points. The solution will be computed and stored for each time requested
59564a658b32SHong Zhang 
5957c3339decSBarry Smith   Collective
59584a658b32SHong Zhang 
59594a658b32SHong Zhang   Input Parameters:
59604a658b32SHong Zhang + ts          - the time-stepper
59618343f784SJames Wright . n           - number of the time points
5962264c38b7SJames Wright - time_points - array of the time points, must be increasing
59634a658b32SHong Zhang 
5964bcf0153eSBarry Smith   Options Database Key:
59658343f784SJames Wright . -ts_eval_times <t0,...tn> - Sets the evaluation times
59664a658b32SHong Zhang 
5967bcf0153eSBarry Smith   Level: intermediate
59684a658b32SHong Zhang 
59694a658b32SHong Zhang   Notes:
5970264c38b7SJames Wright   The elements in `time_points` must be all increasing. They correspond to the intermediate points to be saved.
59714a658b32SHong Zhang 
59728343f784SJames Wright   `TS_EXACTFINALTIME_MATCHSTEP` must be used to make the last time step in each sub-interval match the intermediate points specified.
59738343f784SJames Wright 
5974c80d56d9SJames Wright   The intermediate solutions are saved in a vector array that can be accessed with `TSGetEvaluationSolutions()`. Thus using evaluation times may
59758343f784SJames Wright   pressure the memory system when using a large number of time points.
59768343f784SJames Wright 
5977c80d56d9SJames Wright .seealso: [](ch_ts), `TS`, `TSGetEvaluationTimes()`, `TSGetEvaluationSolutions()`, `TSSetTimeSpan()`
59784a658b32SHong Zhang  @*/
59790fc7ecceSBarry Smith PetscErrorCode TSSetEvaluationTimes(TS ts, PetscInt n, PetscReal time_points[])
5980d71ae5a4SJacob Faibussowitsch {
59818343f784SJames Wright   PetscBool is_sorted;
59828343f784SJames Wright 
59834a658b32SHong Zhang   PetscFunctionBegin;
59844a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5985264c38b7SJames Wright   if (ts->eval_times) { // Reset eval_times
5986264c38b7SJames Wright     ts->eval_times->sol_idx        = 0;
5987264c38b7SJames Wright     ts->eval_times->time_point_idx = 0;
5988264c38b7SJames Wright     if (n != ts->eval_times->num_time_points) {
5989136cf249SJames Wright       PetscCall(PetscFree(ts->eval_times->time_points));
5990264c38b7SJames Wright       PetscCall(PetscFree(ts->eval_times->sol_times));
5991136cf249SJames Wright       PetscCall(VecDestroyVecs(ts->eval_times->num_time_points, &ts->eval_times->sol_vecs));
5992264c38b7SJames Wright     } else {
5993264c38b7SJames Wright       PetscCall(PetscArrayzero(ts->eval_times->sol_times, n));
5994264c38b7SJames Wright       for (PetscInt i = 0; i < n; i++) PetscCall(VecZeroEntries(ts->eval_times->sol_vecs[i]));
59954a658b32SHong Zhang     }
5996264c38b7SJames Wright   } else { // Create/initialize eval_times
5997136cf249SJames Wright     TSEvaluationTimes eval_times;
5998136cf249SJames Wright     PetscCall(PetscNew(&eval_times));
5999136cf249SJames Wright     PetscCall(PetscMalloc1(n, &eval_times->time_points));
6000264c38b7SJames Wright     PetscCall(PetscMalloc1(n, &eval_times->sol_times));
6001136cf249SJames Wright     eval_times->reltol  = 1e-6;
6002136cf249SJames Wright     eval_times->abstol  = 10 * PETSC_MACHINE_EPSILON;
6003136cf249SJames Wright     eval_times->worktol = 0;
6004136cf249SJames Wright     ts->eval_times      = eval_times;
60054a658b32SHong Zhang   }
6006136cf249SJames Wright   ts->eval_times->num_time_points = n;
60078343f784SJames Wright   PetscCall(PetscSortedReal(n, time_points, &is_sorted));
60088343f784SJames Wright   PetscCheck(is_sorted, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "time_points array must be sorted");
6009136cf249SJames Wright   PetscCall(PetscArraycpy(ts->eval_times->time_points, time_points, n));
6010264c38b7SJames Wright   // Note: ts->vec_sol not guaranteed to exist, so ts->eval_times->sol_vecs allocated at TSSolve time
60118343f784SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
60128343f784SJames Wright }
60138343f784SJames Wright 
60148343f784SJames Wright /*@C
60158343f784SJames Wright   TSGetEvaluationTimes - gets the evaluation times set with `TSSetEvaluationTimes()`
60168343f784SJames Wright 
60178343f784SJames Wright   Not Collective
60188343f784SJames Wright 
60198343f784SJames Wright   Input Parameter:
60208343f784SJames Wright . ts - the time-stepper
60218343f784SJames Wright 
60228343f784SJames Wright   Output Parameters:
60238343f784SJames Wright + n           - number of the time points
60248343f784SJames Wright - time_points - array of the time points
60258343f784SJames Wright 
60268343f784SJames Wright   Level: beginner
60278343f784SJames Wright 
60288343f784SJames Wright   Note:
60298343f784SJames Wright   The values obtained are valid until the `TS` object is destroyed.
60308343f784SJames Wright 
60318343f784SJames Wright   Both `n` and `time_points` can be `NULL`.
60328343f784SJames Wright 
60338343f784SJames Wright   Also used to see time points set by `TSSetTimeSpan()`.
60348343f784SJames Wright 
6035c80d56d9SJames Wright .seealso: [](ch_ts), `TS`, `TSSetEvaluationTimes()`, `TSGetEvaluationSolutions()`
60368343f784SJames Wright  @*/
60378343f784SJames Wright PetscErrorCode TSGetEvaluationTimes(TS ts, PetscInt *n, const PetscReal *time_points[])
60388343f784SJames Wright {
60398343f784SJames Wright   PetscFunctionBegin;
60408343f784SJames Wright   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
60418343f784SJames Wright   if (n) PetscAssertPointer(n, 2);
60428343f784SJames Wright   if (time_points) PetscAssertPointer(time_points, 3);
6043136cf249SJames Wright   if (!ts->eval_times) {
60448343f784SJames Wright     if (n) *n = 0;
60458343f784SJames Wright     if (time_points) *time_points = NULL;
60468343f784SJames Wright   } else {
6047136cf249SJames Wright     if (n) *n = ts->eval_times->num_time_points;
6048136cf249SJames Wright     if (time_points) *time_points = ts->eval_times->time_points;
60498343f784SJames Wright   }
60508343f784SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
60518343f784SJames Wright }
60528343f784SJames Wright 
60538343f784SJames Wright /*@C
6054c80d56d9SJames Wright   TSGetEvaluationSolutions - Get the number of solutions and the solutions at the evaluation time points specified
60558343f784SJames Wright 
60568343f784SJames Wright   Input Parameter:
60578343f784SJames Wright . ts - the `TS` context obtained from `TSCreate()`
60588343f784SJames Wright 
60598343f784SJames Wright   Output Parameters:
60608343f784SJames Wright + nsol      - the number of solutions
60618343f784SJames Wright . sol_times - array of solution times corresponding to the solution vectors. See note below
60628343f784SJames Wright - Sols      - the solution vectors
60638343f784SJames Wright 
60648343f784SJames Wright   Level: intermediate
60658343f784SJames Wright 
60668343f784SJames Wright   Notes:
60678343f784SJames Wright   Both `nsol` and `Sols` can be `NULL`.
60688343f784SJames Wright 
60698343f784SJames Wright   Some time points in the evaluation points may be skipped by `TS` so that `nsol` is less than the number of points specified by `TSSetEvaluationTimes()`.
60708343f784SJames Wright   For example, manipulating the step size, especially with a reduced precision, may cause `TS` to step over certain evaluation times.
60718343f784SJames Wright 
60728343f784SJames Wright   Also used to see view solutions requested by `TSSetTimeSpan()`.
60738343f784SJames Wright 
60748343f784SJames Wright .seealso: [](ch_ts), `TS`, `TSSetEvaluationTimes()`, `TSGetEvaluationTimes()`
60758343f784SJames Wright @*/
60760fc7ecceSBarry Smith PetscErrorCode TSGetEvaluationSolutions(TS ts, PetscInt *nsol, const PetscReal *sol_times[], Vec *Sols[])
60778343f784SJames Wright {
60788343f784SJames Wright   PetscFunctionBegin;
60798343f784SJames Wright   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
60808343f784SJames Wright   if (nsol) PetscAssertPointer(nsol, 2);
60818343f784SJames Wright   if (sol_times) PetscAssertPointer(sol_times, 3);
60828343f784SJames Wright   if (Sols) PetscAssertPointer(Sols, 4);
6083136cf249SJames Wright   if (!ts->eval_times) {
60848343f784SJames Wright     if (nsol) *nsol = 0;
60858343f784SJames Wright     if (sol_times) *sol_times = NULL;
60868343f784SJames Wright     if (Sols) *Sols = NULL;
60878343f784SJames Wright   } else {
6088264c38b7SJames Wright     if (nsol) *nsol = ts->eval_times->sol_idx;
6089136cf249SJames Wright     if (sol_times) *sol_times = ts->eval_times->sol_times;
6090136cf249SJames Wright     if (Sols) *Sols = ts->eval_times->sol_vecs;
60918343f784SJames Wright   }
60928343f784SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
60938343f784SJames Wright }
60948343f784SJames Wright 
60958343f784SJames Wright /*@
60968343f784SJames Wright   TSSetTimeSpan - sets the time span. The solution will be computed and stored for each time requested in the span
60978343f784SJames Wright 
60988343f784SJames Wright   Collective
60998343f784SJames Wright 
61008343f784SJames Wright   Input Parameters:
61018343f784SJames Wright + ts         - the time-stepper
61028343f784SJames Wright . n          - number of the time points (>=2)
6103264c38b7SJames Wright - span_times - array of the time points, must be increasing. The first element and the last element are the initial time and the final time respectively.
61048343f784SJames Wright 
61058343f784SJames Wright   Options Database Key:
61068343f784SJames Wright . -ts_time_span <t0,...tf> - Sets the time span
61078343f784SJames Wright 
61088343f784SJames Wright   Level: intermediate
61098343f784SJames Wright 
61108343f784SJames Wright   Notes:
6111c80d56d9SJames Wright   This function is identical to `TSSetEvaluationTimes()`, except that it also sets the initial time and final time for the `ts` to the first and last `span_times` entries.
61128343f784SJames Wright 
6113264c38b7SJames Wright   The elements in `span_times` must be all increasing. They correspond to the intermediate points to be saved.
61148343f784SJames Wright 
61158343f784SJames Wright   `TS_EXACTFINALTIME_MATCHSTEP` must be used to make the last time step in each sub-interval match the intermediate points specified.
61168343f784SJames Wright 
6117c80d56d9SJames Wright   The intermediate solutions are saved in a vector array that can be accessed with `TSGetEvaluationSolutions()`. Thus using time span may
61188343f784SJames Wright   pressure the memory system when using a large number of span points.
61198343f784SJames Wright 
6120c80d56d9SJames Wright .seealso: [](ch_ts), `TS`, `TSSetEvaluationTimes()`, `TSGetEvaluationTimes()`, `TSGetEvaluationSolutions()`
61218343f784SJames Wright  @*/
61220fc7ecceSBarry Smith PetscErrorCode TSSetTimeSpan(TS ts, PetscInt n, PetscReal span_times[])
61238343f784SJames Wright {
61248343f784SJames Wright   PetscFunctionBegin;
61258343f784SJames Wright   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
61268343f784SJames Wright   PetscCheck(n >= 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Minimum time span size is 2 but %" PetscInt_FMT " is provided", n);
61278343f784SJames Wright   PetscCall(TSSetEvaluationTimes(ts, n, span_times));
61288343f784SJames Wright   PetscCall(TSSetTime(ts, span_times[0]));
61298343f784SJames Wright   PetscCall(TSSetMaxTime(ts, span_times[n - 1]));
61303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
61314a658b32SHong Zhang }
61324a658b32SHong Zhang 
6133cc4c1da9SBarry Smith /*@
61347b2dc123SHong Zhang   TSPruneIJacobianColor - Remove nondiagonal zeros in the Jacobian matrix and update the `MatMFFD` coloring information.
6135d7cfae9bSHong Zhang 
6136195e9b02SBarry Smith   Collective
6137d7cfae9bSHong Zhang 
6138d7cfae9bSHong Zhang   Input Parameters:
6139195e9b02SBarry Smith + ts - the `TS` context
6140d7cfae9bSHong Zhang . J  - Jacobian matrix (not altered in this routine)
6141195e9b02SBarry Smith - B  - newly computed Jacobian matrix to use with preconditioner
6142d7cfae9bSHong Zhang 
6143d7cfae9bSHong Zhang   Level: intermediate
6144d7cfae9bSHong Zhang 
6145d7cfae9bSHong Zhang   Notes:
6146195e9b02SBarry Smith   This function improves the `MatFDColoring` performance when the Jacobian matrix was over-allocated or contains
6147195e9b02SBarry Smith   many constant zeros entries, which is typically the case when the matrix is generated by a `DM`
6148d7cfae9bSHong Zhang   and multiple fields are involved.
6149d7cfae9bSHong Zhang 
6150d7cfae9bSHong Zhang   Users need to make sure that the Jacobian matrix is properly filled to reflect the sparsity
6151195e9b02SBarry Smith   structure. For `MatFDColoring`, the values of nonzero entries are not important. So one can
61527b2dc123SHong Zhang   usually call `TSComputeIJacobian()` with randomized input vectors to generate a dummy Jacobian.
61537b2dc123SHong Zhang   `TSComputeIJacobian()` should be called before `TSSolve()` but after `TSSetUp()`.
6154d7cfae9bSHong Zhang 
61551cc06b55SBarry Smith .seealso: [](ch_ts), `TS`, `MatFDColoring`, `TSComputeIJacobianDefaultColor()`, `MatEliminateZeros()`, `MatFDColoringCreate()`, `MatFDColoringSetFunction()`
6156d7cfae9bSHong Zhang @*/
6157d7cfae9bSHong Zhang PetscErrorCode TSPruneIJacobianColor(TS ts, Mat J, Mat B)
6158d7cfae9bSHong Zhang {
6159d7cfae9bSHong Zhang   MatColoring   mc            = NULL;
6160d7cfae9bSHong Zhang   ISColoring    iscoloring    = NULL;
6161d7cfae9bSHong Zhang   MatFDColoring matfdcoloring = NULL;
6162d7cfae9bSHong Zhang 
6163d7cfae9bSHong Zhang   PetscFunctionBegin;
6164d7cfae9bSHong Zhang   /* Generate new coloring after eliminating zeros in the matrix */
616558c11ad4SPierre Jolivet   PetscCall(MatEliminateZeros(B, PETSC_TRUE));
6166d7cfae9bSHong Zhang   PetscCall(MatColoringCreate(B, &mc));
6167d7cfae9bSHong Zhang   PetscCall(MatColoringSetDistance(mc, 2));
6168d7cfae9bSHong Zhang   PetscCall(MatColoringSetType(mc, MATCOLORINGSL));
6169d7cfae9bSHong Zhang   PetscCall(MatColoringSetFromOptions(mc));
6170d7cfae9bSHong Zhang   PetscCall(MatColoringApply(mc, &iscoloring));
6171d7cfae9bSHong Zhang   PetscCall(MatColoringDestroy(&mc));
6172d7cfae9bSHong Zhang   /* Replace the old coloring with the new one */
6173d7cfae9bSHong Zhang   PetscCall(MatFDColoringCreate(B, iscoloring, &matfdcoloring));
61742ba42892SBarry Smith   PetscCall(MatFDColoringSetFunction(matfdcoloring, (MatFDColoringFn *)SNESTSFormFunction, (void *)ts));
6175d7cfae9bSHong Zhang   PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
6176d7cfae9bSHong Zhang   PetscCall(MatFDColoringSetUp(B, iscoloring, matfdcoloring));
6177d7cfae9bSHong Zhang   PetscCall(PetscObjectCompose((PetscObject)B, "TSMatFDColoring", (PetscObject)matfdcoloring));
6178d7cfae9bSHong Zhang   PetscCall(PetscObjectDereference((PetscObject)matfdcoloring));
6179d7cfae9bSHong Zhang   PetscCall(ISColoringDestroy(&iscoloring));
61803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6181d7cfae9bSHong Zhang }
6182