xref: /petsc/src/ts/interface/ts.c (revision 60e16b1b373f0d7eb06432ae904f4dc6ff882c7e)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h"  I*/
21e25c274SJed Brown #include <petscdmda.h>
3*60e16b1bSMatthew G. Knepley #include <petscdmshell.h>
4*60e16b1bSMatthew G. Knepley #include <petscdmplex.h>  // For TSSetFromOptions()
5*60e16b1bSMatthew 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 
109371c9d4SSatish Balay #define SkipSmallValue(a, b, tol) \
119371c9d4SSatish Balay   if (PetscAbsScalar(a) < tol || PetscAbsScalar(b) < tol) continue;
121c167fc2SEmil Constantinescu 
13d5ba7fb7SMatthew Knepley /* Logging support */
14d74926cbSBarry Smith PetscClassId  TS_CLASSID, DMTS_CLASSID;
15a05bf03eSHong Zhang PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
16d405a339SMatthew Knepley 
17c793f718SLisandro Dalcin const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED", "STEPOVER", "INTERPOLATE", "MATCHSTEP", "TSExactFinalTimeOption", "TS_EXACTFINALTIME_", NULL};
1849354f04SShri Abhyankar 
19d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSAdaptSetDefaultType(TSAdapt adapt, TSAdaptType default_type)
20d71ae5a4SJacob Faibussowitsch {
212ffb9264SLisandro Dalcin   PetscFunctionBegin;
22b92453a8SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
23b92453a8SLisandro Dalcin   PetscValidCharPointer(default_type, 2);
241e66621cSBarry Smith   if (!((PetscObject)adapt)->type_name) PetscCall(TSAdaptSetType(adapt, default_type));
253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
262ffb9264SLisandro Dalcin }
272ffb9264SLisandro Dalcin 
28bdad233fSMatthew Knepley /*@
29bcf0153eSBarry Smith    TSSetFromOptions - Sets various `TS` parameters from user options.
30bdad233fSMatthew Knepley 
31c3339decSBarry Smith    Collective
32bdad233fSMatthew Knepley 
33bdad233fSMatthew Knepley    Input Parameter:
34bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
35bdad233fSMatthew Knepley 
36bdad233fSMatthew Knepley    Options Database Keys:
37bcf0153eSBarry Smith +  -ts_type <type> - EULER, BEULER, SUNDIALS, PSEUDO, CN, RK, THETA, ALPHA, GLLE,  SSP, GLEE, BSYMP, IRK
38ef222394SBarry Smith .  -ts_save_trajectory - checkpoint the solution at each time-step
39ef85077eSLisandro Dalcin .  -ts_max_time <time> - maximum time to compute to
404a658b32SHong Zhang .  -ts_time_span <t0,...tf> - sets the time span, solutions are computed and stored for each indicated time
41ef85077eSLisandro Dalcin .  -ts_max_steps <steps> - maximum number of time-steps to take
42ef85077eSLisandro Dalcin .  -ts_init_time <time> - initial time to start computation
434dc72f7fSBarry Smith .  -ts_final_time <time> - final time to compute to (deprecated: use -ts_max_time)
443e4cdcaaSBarry Smith .  -ts_dt <dt> - initial time step
451628793fSSatish 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
46a3cdaa26SBarry Smith .  -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed
47a3cdaa26SBarry Smith .  -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails
48a3cdaa26SBarry Smith .  -ts_error_if_step_fails <true,false> - Error if no step succeeds
49a3cdaa26SBarry Smith .  -ts_rtol <rtol> - relative tolerance for local truncation error
5067b8a455SSatish Balay .  -ts_atol <atol> - Absolute tolerance for local truncation error
51f3b1f45cSBarry Smith .  -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - test the Jacobian at each iteration against finite difference with RHS function
52f3b1f45cSBarry Smith .  -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - test the Jacobian at each iteration against finite difference with RHS function
5367b8a455SSatish Balay .  -ts_adjoint_solve <yes,no> - After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory)
54847ff0e1SMatthew G. Knepley .  -ts_fd_color - Use finite differences with coloring to compute IJacobian
55bdad233fSMatthew Knepley .  -ts_monitor - print information at each timestep
56aee7a9fbSMatthew G. Knepley .  -ts_monitor_cancel - Cancel all monitors
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
699812b6beSJed Brown    -ts_monitor_solution_interval <interval> - output once every interval (default=1) time steps; used with -ts_monitor_solution
7063a3b9bcSJacob 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)
719e336e28SPatrick Sanan -  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
7253ea634cSHong Zhang 
73bcf0153eSBarry Smith    Level: beginner
743d5a8a6aSBarry Smith 
75bcf0153eSBarry Smith    Notes:
76bcf0153eSBarry Smith      See `SNESSetFromOptions()` and `KSPSetFromOptions()` for how to control the nonlinear and linear solves used by the time-stepper.
77bcf0153eSBarry Smith 
78bcf0153eSBarry Smith      Certain `SNES` options get reset for each new nonlinear solver, for example -snes_lag_jacobian <its> and -snes_lag_preconditioner <its>, in order
793d5a8a6aSBarry Smith      to retain them over the multiple nonlinear solves that TS uses you mush also provide -snes_lag_jacobian_persists true and
803d5a8a6aSBarry Smith      -snes_lag_preconditioner_persists true
813d5a8a6aSBarry Smith 
829e336e28SPatrick Sanan    Developer Note:
839e336e28SPatrick Sanan      We should unify all the -ts_monitor options in the way that -xxx_view has been unified
84bdad233fSMatthew Knepley 
85bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetType()`
86bdad233fSMatthew Knepley @*/
87d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetFromOptions(TS ts)
88d71ae5a4SJacob Faibussowitsch {
89bc952696SBarry Smith   PetscBool              opt, flg, tflg;
90eabae89aSBarry Smith   char                   monfilename[PETSC_MAX_PATH_LEN];
914a658b32SHong Zhang   PetscReal              time_step, tspan[100];
924a658b32SHong Zhang   PetscInt               nt = PETSC_STATIC_ARRAY_LENGTH(tspan);
9349354f04SShri Abhyankar   TSExactFinalTimeOption eftopt;
94d1212d36SBarry Smith   char                   dir[16];
95cd11d68dSLisandro Dalcin   TSIFunction            ifun;
966991f827SBarry Smith   const char            *defaultType;
976991f827SBarry Smith   char                   typeName[256];
98bdad233fSMatthew Knepley 
99bdad233fSMatthew Knepley   PetscFunctionBegin;
1000700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1016991f827SBarry Smith 
1029566063dSJacob Faibussowitsch   PetscCall(TSRegisterAll());
1039566063dSJacob Faibussowitsch   PetscCall(TSGetIFunction(ts, NULL, &ifun, NULL));
104cd11d68dSLisandro Dalcin 
105d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)ts);
1061ef27442SStefano Zampini   if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name;
1071ef27442SStefano Zampini   else defaultType = ifun ? TSBEULER : TSEULER;
1089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-ts_type", "TS method", "TSSetType", TSList, defaultType, typeName, 256, &opt));
1091e66621cSBarry Smith   if (opt) PetscCall(TSSetType(ts, typeName));
1101e66621cSBarry Smith   else PetscCall(TSSetType(ts, defaultType));
111bdad233fSMatthew Knepley 
112bdad233fSMatthew Knepley   /* Handle generic TS options */
1139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDeprecated("-ts_final_time", "-ts_max_time", "3.10", NULL));
1149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_max_time", "Maximum time to run to", "TSSetMaxTime", ts->max_time, &ts->max_time, NULL));
1154a658b32SHong Zhang   PetscCall(PetscOptionsRealArray("-ts_time_span", "Time span", "TSSetTimeSpan", tspan, &nt, &flg));
1164a658b32SHong Zhang   if (flg) PetscCall(TSSetTimeSpan(ts, nt, tspan));
1179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_steps", "Maximum number of time steps", "TSSetMaxSteps", ts->max_steps, &ts->max_steps, NULL));
1189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_init_time", "Initial time", "TSSetTime", ts->ptime, &ts->ptime, NULL));
1199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_dt", "Initial time step", "TSSetTimeStep", ts->time_step, &time_step, &flg));
1209566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetTimeStep(ts, time_step));
1219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-ts_exact_final_time", "Option for handling of final time step", "TSSetExactFinalTime", TSExactFinalTimeOptions, (PetscEnum)ts->exact_final_time, (PetscEnum *)&eftopt, &flg));
1229566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetExactFinalTime(ts, eftopt));
1239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_snes_failures", "Maximum number of nonlinear solve failures", "TSSetMaxSNESFailures", ts->max_snes_failures, &ts->max_snes_failures, NULL));
1249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_reject", "Maximum number of step rejections before step fails", "TSSetMaxStepRejections", ts->max_reject, &ts->max_reject, NULL));
1259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_error_if_step_fails", "Error if no step succeeds", "TSSetErrorIfStepFails", ts->errorifstepfailed, &ts->errorifstepfailed, NULL));
1269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_rtol", "Relative tolerance for local truncation error", "TSSetTolerances", ts->rtol, &ts->rtol, NULL));
1279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_atol", "Absolute tolerance for local truncation error", "TSSetTolerances", ts->atol, &ts->atol, NULL));
128bdad233fSMatthew Knepley 
1299566063dSJacob 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));
1309566063dSJacob 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));
1319566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_use_splitrhsfunction", "Use the split RHS function for multirate solvers ", "TSSetUseSplitRHSFunction", ts->use_splitrhsfunction, &ts->use_splitrhsfunction, NULL));
13256f85f32SBarry Smith #if defined(PETSC_HAVE_SAWS)
13356f85f32SBarry Smith   {
13456f85f32SBarry Smith     PetscBool set;
13556f85f32SBarry Smith     flg = PETSC_FALSE;
1369566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-ts_saws_block", "Block for SAWs memory snooper at end of TSSolve", "PetscObjectSAWsBlock", ((PetscObject)ts)->amspublishblock, &flg, &set));
1371baa6e33SBarry Smith     if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)ts, flg));
13856f85f32SBarry Smith   }
13956f85f32SBarry Smith #endif
14056f85f32SBarry Smith 
141bdad233fSMatthew Knepley   /* Monitor options */
1429566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_monitor_frequency", "Number of time steps between monitor output", "TSMonitorSetFrequency", ts->monitorFrequency, &ts->monitorFrequency, NULL));
1439566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor", "Monitor time and timestep size", "TSMonitorDefault", TSMonitorDefault, NULL));
1449566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_extreme", "Monitor extreme values of the solution", "TSMonitorExtreme", TSMonitorExtreme, NULL));
1459566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_solution", "View the solution at each timestep", "TSMonitorSolution", TSMonitorSolution, NULL));
1469566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_dmswarm_monitor_moments", "Monitor moments of particle distribution", "TSDMSwarmMonitorMoments", TSDMSwarmMonitorMoments, NULL));
147fde5950dSBarry Smith 
1489566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_python", "Use Python function", "TSMonitorSet", NULL, monfilename, sizeof(monfilename), &flg));
1499566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)ts, monfilename));
1505180491cSLisandro Dalcin 
1519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_solution", "Monitor solution graphically", "TSMonitorLGSolution", &opt));
152b3603a34SBarry Smith   if (opt) {
1533923b477SBarry Smith     PetscInt  howoften = 1;
154e669de00SBarry Smith     DM        dm;
155e669de00SBarry Smith     PetscBool net;
156b3603a34SBarry Smith 
1579566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_solution", "Monitor solution graphically", "TSMonitorLGSolution", howoften, &howoften, NULL));
1589566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
1599566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMNETWORK, &net));
160e669de00SBarry Smith     if (net) {
161e669de00SBarry Smith       TSMonitorLGCtxNetwork ctx;
1629566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxNetworkCreate(ts, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 600, 400, howoften, &ctx));
1639566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts, TSMonitorLGCtxNetworkSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxNetworkDestroy));
1649566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_lg_solution_semilogy", "Plot the solution with a semi-log axis", "", ctx->semilogy, &ctx->semilogy, NULL));
165e669de00SBarry Smith     } else {
166e669de00SBarry Smith       TSMonitorLGCtx ctx;
1679566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1689566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts, TSMonitorLGSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
169bdad233fSMatthew Knepley     }
170e669de00SBarry Smith   }
1716ba87a44SLisandro Dalcin 
1729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_error", "Monitor error graphically", "TSMonitorLGError", &opt));
173ef20d060SBarry Smith   if (opt) {
1740b039ecaSBarry Smith     TSMonitorLGCtx ctx;
1753923b477SBarry Smith     PetscInt       howoften = 1;
176ef20d060SBarry Smith 
1779566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_error", "Monitor error graphically", "TSMonitorLGError", howoften, &howoften, NULL));
1789566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1799566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGError, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
180ef20d060SBarry Smith   }
1819566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_error", "View the error at each timestep", "TSMonitorError", TSMonitorError, NULL));
1827cf37e64SBarry Smith 
1839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep", "Monitor timestep size graphically", "TSMonitorLGTimeStep", &opt));
1846934998bSLisandro Dalcin   if (opt) {
1856934998bSLisandro Dalcin     TSMonitorLGCtx ctx;
1866934998bSLisandro Dalcin     PetscInt       howoften = 1;
1876934998bSLisandro Dalcin 
1889566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep", "Monitor timestep size graphically", "TSMonitorLGTimeStep", howoften, &howoften, NULL));
1899566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1909566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGTimeStep, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
1916934998bSLisandro Dalcin   }
1929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep_log", "Monitor log timestep size graphically", "TSMonitorLGTimeStep", &opt));
1938b668821SLisandro Dalcin   if (opt) {
1948b668821SLisandro Dalcin     TSMonitorLGCtx ctx;
1958b668821SLisandro Dalcin     PetscInt       howoften = 1;
1968b668821SLisandro Dalcin 
1979566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep_log", "Monitor log timestep size graphically", "TSMonitorLGTimeStep", howoften, &howoften, NULL));
1989566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1999566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGTimeStep, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
2008b668821SLisandro Dalcin     ctx->semilogy = PETSC_TRUE;
2018b668821SLisandro Dalcin   }
2028b668821SLisandro Dalcin 
2039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_snes_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGSNESIterations", &opt));
204201da799SBarry Smith   if (opt) {
205201da799SBarry Smith     TSMonitorLGCtx ctx;
206201da799SBarry Smith     PetscInt       howoften = 1;
207201da799SBarry Smith 
2089566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_snes_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGSNESIterations", howoften, &howoften, NULL));
2099566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
2109566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGSNESIterations, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
211201da799SBarry Smith   }
2129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_ksp_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGKSPIterations", &opt));
213201da799SBarry Smith   if (opt) {
214201da799SBarry Smith     TSMonitorLGCtx ctx;
215201da799SBarry Smith     PetscInt       howoften = 1;
216201da799SBarry Smith 
2179566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_ksp_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGKSPIterations", howoften, &howoften, NULL));
2189566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
2199566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGKSPIterations, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
220201da799SBarry Smith   }
2219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_sp_eig", "Monitor eigenvalues of linearized operator graphically", "TSMonitorSPEig", &opt));
2228189c53fSBarry Smith   if (opt) {
2238189c53fSBarry Smith     TSMonitorSPEigCtx ctx;
2248189c53fSBarry Smith     PetscInt          howoften = 1;
2258189c53fSBarry Smith 
2269566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_sp_eig", "Monitor eigenvalues of linearized operator graphically", "TSMonitorSPEig", howoften, &howoften, NULL));
2279566063dSJacob Faibussowitsch     PetscCall(TSMonitorSPEigCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
2289566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorSPEig, ctx, (PetscErrorCode(*)(void **))TSMonitorSPEigCtxDestroy));
2298189c53fSBarry Smith   }
230*60e16b1bSMatthew G. Knepley   PetscCall(PetscOptionsName("-ts_monitor_sp_swarm", "Display particle phase space from the DMSwarm", "TSMonitorSPSwarm", &opt));
2311b575b74SJoseph Pusztay   if (opt) {
2321b575b74SJoseph Pusztay     TSMonitorSPCtx ctx;
233d7462660SMatthew Knepley     PetscInt       howoften = 1, retain = 0;
234*60e16b1bSMatthew G. Knepley     PetscBool      phase = PETSC_TRUE, create = PETSC_TRUE, multispecies = PETSC_FALSE;
235d7462660SMatthew Knepley 
2369371c9d4SSatish Balay     for (PetscInt i = 0; i < ts->numbermonitors; ++i)
2379371c9d4SSatish Balay       if (ts->monitor[i] == TSMonitorSPSwarmSolution) {
2389371c9d4SSatish Balay         create = PETSC_FALSE;
2399371c9d4SSatish Balay         break;
2409371c9d4SSatish Balay       }
2416a5217c0SMatthew G. Knepley     if (create) {
242*60e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm", "Display particles phase space from the DMSwarm", "TSMonitorSPSwarm", howoften, &howoften, NULL));
2439566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm_retain", "Retain n points plotted to show trajectory, -1 for all points", "TSMonitorSPSwarm", retain, &retain, NULL));
2449566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_sp_swarm_phase", "Plot in phase space rather than coordinate space", "TSMonitorSPSwarm", phase, &phase, NULL));
245*60e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsBool("-ts_monitor_sp_swarm_multi_species", "Color particles by particle species", "TSMonitorSPSwarm", multispecies, &multispecies, NULL));
246*60e16b1bSMatthew G. Knepley       PetscCall(TSMonitorSPCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, retain, phase, multispecies, &ctx));
2479566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts, TSMonitorSPSwarmSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorSPCtxDestroy));
2481b575b74SJoseph Pusztay     }
2496a5217c0SMatthew G. Knepley   }
250*60e16b1bSMatthew G. Knepley   PetscCall(PetscOptionsName("-ts_monitor_hg_swarm", "Display particle histogram from the DMSwarm", "TSMonitorHGSwarm", &opt));
251*60e16b1bSMatthew G. Knepley   if (opt) {
252*60e16b1bSMatthew G. Knepley     TSMonitorHGCtx ctx;
253*60e16b1bSMatthew G. Knepley     PetscInt       howoften = 1, Ns = 1;
254*60e16b1bSMatthew G. Knepley     PetscBool      velocity = PETSC_FALSE, create = PETSC_TRUE;
255*60e16b1bSMatthew G. Knepley 
256*60e16b1bSMatthew G. Knepley     for (PetscInt i = 0; i < ts->numbermonitors; ++i)
257*60e16b1bSMatthew G. Knepley       if (ts->monitor[i] == TSMonitorHGSwarmSolution) {
258*60e16b1bSMatthew G. Knepley         create = PETSC_FALSE;
259*60e16b1bSMatthew G. Knepley         break;
260*60e16b1bSMatthew G. Knepley       }
261*60e16b1bSMatthew G. Knepley     if (create) {
262*60e16b1bSMatthew G. Knepley       DM       sw, dm;
263*60e16b1bSMatthew G. Knepley       PetscInt Nc, Nb;
264*60e16b1bSMatthew G. Knepley 
265*60e16b1bSMatthew G. Knepley       PetscCall(TSGetDM(ts, &sw));
266*60e16b1bSMatthew G. Knepley       PetscCall(DMSwarmGetCellDM(sw, &dm));
267*60e16b1bSMatthew G. Knepley       PetscCall(DMPlexGetHeightStratum(dm, 0, NULL, &Nc));
268*60e16b1bSMatthew G. Knepley       Nb = PetscMin(20, PetscMax(10, Nc));
269*60e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_hg_swarm", "Display particles histogram from the DMSwarm", "TSMonitorHGSwarm", howoften, &howoften, NULL));
270*60e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsBool("-ts_monitor_hg_swarm_velocity", "Plot in velocity space rather than coordinate space", "TSMonitorHGSwarm", velocity, &velocity, NULL));
271*60e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_hg_swarm_species", "Number of species to histogram", "TSMonitorHGSwarm", Ns, &Ns, NULL));
272*60e16b1bSMatthew G. Knepley       PetscCall(PetscOptionsInt("-ts_monitor_hg_swarm_bins", "Number of histogram bins", "TSMonitorHGSwarm", Nb, &Nb, NULL));
273*60e16b1bSMatthew G. Knepley       PetscCall(TSMonitorHGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, Ns, Nb, velocity, &ctx));
274*60e16b1bSMatthew G. Knepley       PetscCall(TSMonitorSet(ts, TSMonitorHGSwarmSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorHGCtxDestroy));
275*60e16b1bSMatthew G. Knepley     }
276*60e16b1bSMatthew G. Knepley   }
277ef20d060SBarry Smith   opt = PETSC_FALSE;
2789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution", "Monitor solution graphically", "TSMonitorDrawSolution", &opt));
279a7cc72afSBarry Smith   if (opt) {
28083a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
28183a4ac43SBarry Smith     PetscInt         howoften = 1;
282a80ad3e0SBarry Smith 
2839566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution", "Monitor solution graphically", "TSMonitorDrawSolution", howoften, &howoften, NULL));
2849566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Computed Solution", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
2859566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
286bdad233fSMatthew Knepley   }
287fb1732b5SBarry Smith   opt = PETSC_FALSE;
2889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_phase", "Monitor solution graphically", "TSMonitorDrawSolutionPhase", &opt));
2892d5ee99bSBarry Smith   if (opt) {
2902d5ee99bSBarry Smith     TSMonitorDrawCtx ctx;
2912d5ee99bSBarry Smith     PetscReal        bounds[4];
2922d5ee99bSBarry Smith     PetscInt         n = 4;
2932d5ee99bSBarry Smith     PetscDraw        draw;
2946934998bSLisandro Dalcin     PetscDrawAxis    axis;
2952d5ee99bSBarry Smith 
2969566063dSJacob Faibussowitsch     PetscCall(PetscOptionsRealArray("-ts_monitor_draw_solution_phase", "Monitor solution graphically", "TSMonitorDrawSolutionPhase", bounds, &n, NULL));
2973c633725SBarry Smith     PetscCheck(n == 4, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Must provide bounding box of phase field");
2989566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, 1, &ctx));
2999566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ctx->viewer, 0, &draw));
3009566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDrawAxis(ctx->viewer, 0, &axis));
3019566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLimits(axis, bounds[0], bounds[2], bounds[1], bounds[3]));
3029566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Phase Diagram", "Variable 1", "Variable 2"));
3039566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolutionPhase, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
3042d5ee99bSBarry Smith   }
3052d5ee99bSBarry Smith   opt = PETSC_FALSE;
3069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_error", "Monitor error graphically", "TSMonitorDrawError", &opt));
3073a471f94SBarry Smith   if (opt) {
30883a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
30983a4ac43SBarry Smith     PetscInt         howoften = 1;
3103a471f94SBarry Smith 
3119566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_error", "Monitor error graphically", "TSMonitorDrawError", howoften, &howoften, NULL));
3129566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Error", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
3139566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawError, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
3143a471f94SBarry Smith   }
3150ed3bfb6SBarry Smith   opt = PETSC_FALSE;
3169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_function", "Monitor solution provided by TSMonitorSetSolutionFunction() graphically", "TSMonitorDrawSolutionFunction", &opt));
3170ed3bfb6SBarry Smith   if (opt) {
3180ed3bfb6SBarry Smith     TSMonitorDrawCtx ctx;
3190ed3bfb6SBarry Smith     PetscInt         howoften = 1;
3200ed3bfb6SBarry Smith 
3219566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution_function", "Monitor solution provided by TSMonitorSetSolutionFunction() graphically", "TSMonitorDrawSolutionFunction", howoften, &howoften, NULL));
3229566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Solution provided by user function", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
3239566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolutionFunction, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
3240ed3bfb6SBarry Smith   }
325fde5950dSBarry Smith 
326ed81e22dSJed Brown   opt = PETSC_FALSE;
32763a3b9bcSJacob 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));
328ed81e22dSJed Brown   if (flg) {
329ed81e22dSJed Brown     const char *ptr, *ptr2;
330ed81e22dSJed Brown     char       *filetemplate;
33163a3b9bcSJacob Faibussowitsch     PetscCheck(monfilename[0], PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03" PetscInt_FMT ".vts");
332ed81e22dSJed Brown     /* Do some cursory validation of the input. */
3339566063dSJacob Faibussowitsch     PetscCall(PetscStrstr(monfilename, "%", (char **)&ptr));
33463a3b9bcSJacob Faibussowitsch     PetscCheck(ptr, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03" PetscInt_FMT ".vts");
335ed81e22dSJed Brown     for (ptr++; ptr && *ptr; ptr++) {
3369566063dSJacob Faibussowitsch       PetscCall(PetscStrchr("DdiouxX", *ptr, (char **)&ptr2));
33763a3b9bcSJacob Faibussowitsch       PetscCheck(ptr2 || (*ptr >= '0' && *ptr <= '9'), PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Invalid file template argument to -ts_monitor_solution_vtk, should look like filename-%%03" PetscInt_FMT ".vts");
338ed81e22dSJed Brown       if (ptr2) break;
339ed81e22dSJed Brown     }
3409566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(monfilename, &filetemplate));
3419566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorSolutionVTK, filetemplate, (PetscErrorCode(*)(void **))TSMonitorSolutionVTKDestroy));
342ed81e22dSJed Brown   }
343bdad233fSMatthew Knepley 
3449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_dmda_ray", "Display a ray of the solution", "None", "y=0", dir, sizeof(dir), &flg));
345d1212d36SBarry Smith   if (flg) {
346d1212d36SBarry Smith     TSMonitorDMDARayCtx *rayctx;
347d1212d36SBarry Smith     int                  ray = 0;
3483ee9839eSMatthew G. Knepley     DMDirection          ddir;
349d1212d36SBarry Smith     DM                   da;
350d1212d36SBarry Smith     PetscMPIInt          rank;
351d1212d36SBarry Smith 
3523c633725SBarry Smith     PetscCheck(dir[1] == '=', PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray %s", dir);
3533ee9839eSMatthew G. Knepley     if (dir[0] == 'x') ddir = DM_X;
3543ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
35598921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray %s", dir);
356d1212d36SBarry Smith     sscanf(dir + 2, "%d", &ray);
357d1212d36SBarry Smith 
3589566063dSJacob Faibussowitsch     PetscCall(PetscInfo(((PetscObject)ts), "Displaying DMDA ray %c = %d\n", dir[0], ray));
3599566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3609566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &da));
3619566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter));
3629566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)ts), &rank));
3631e66621cSBarry Smith     if (rank == 0) PetscCall(PetscViewerDrawOpen(PETSC_COMM_SELF, NULL, NULL, 0, 0, 600, 300, &rayctx->viewer));
36451b4a12fSMatthew G. Knepley     rayctx->lgctx = NULL;
3659566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDMDARay, rayctx, TSMonitorDMDARayDestroy));
366d1212d36SBarry Smith   }
3679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_lg_dmda_ray", "Display a ray of the solution", "None", "x=0", dir, sizeof(dir), &flg));
36851b4a12fSMatthew G. Knepley   if (flg) {
36951b4a12fSMatthew G. Knepley     TSMonitorDMDARayCtx *rayctx;
37051b4a12fSMatthew G. Knepley     int                  ray = 0;
3713ee9839eSMatthew G. Knepley     DMDirection          ddir;
37251b4a12fSMatthew G. Knepley     DM                   da;
37351b4a12fSMatthew G. Knepley     PetscInt             howoften = 1;
374d1212d36SBarry Smith 
3753c633725SBarry Smith     PetscCheck(dir[1] == '=', PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir);
3763ee9839eSMatthew G. Knepley     if (dir[0] == 'x') ddir = DM_X;
3773ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
37898921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir);
37951b4a12fSMatthew G. Knepley     sscanf(dir + 2, "%d", &ray);
3801c3436cfSJed Brown 
3819566063dSJacob Faibussowitsch     PetscCall(PetscInfo(((PetscObject)ts), "Displaying LG DMDA ray %c = %d\n", dir[0], ray));
3829566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3839566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &da));
3849566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter));
3859566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 600, 400, howoften, &rayctx->lgctx));
3869566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy));
38751b4a12fSMatthew G. Knepley   }
388a7a1495cSBarry Smith 
3899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_envelope", "Monitor maximum and minimum value of each component of the solution", "TSMonitorEnvelope", &opt));
390b3d3934dSBarry Smith   if (opt) {
391b3d3934dSBarry Smith     TSMonitorEnvelopeCtx ctx;
392b3d3934dSBarry Smith 
3939566063dSJacob Faibussowitsch     PetscCall(TSMonitorEnvelopeCtxCreate(ts, &ctx));
3949566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorEnvelope, ctx, (PetscErrorCode(*)(void **))TSMonitorEnvelopeCtxDestroy));
395b3d3934dSBarry Smith   }
396aee7a9fbSMatthew G. Knepley   flg = PETSC_FALSE;
3979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_monitor_cancel", "Remove all monitors", "TSMonitorCancel", flg, &flg, &opt));
3989566063dSJacob Faibussowitsch   if (opt && flg) PetscCall(TSMonitorCancel(ts));
399b3d3934dSBarry Smith 
400847ff0e1SMatthew G. Knepley   flg = PETSC_FALSE;
401d7cfae9bSHong Zhang   PetscCall(PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeIJacobianDefaultColor", flg, &flg, NULL));
402847ff0e1SMatthew G. Knepley   if (flg) {
403847ff0e1SMatthew G. Knepley     DM dm;
404847ff0e1SMatthew G. Knepley 
4059371c9d4SSatish Balay     PetscCall(TSGetDM(ts, &dm));
4069371c9d4SSatish Balay     PetscCall(DMTSUnsetIJacobianContext_Internal(dm));
4079566063dSJacob Faibussowitsch     PetscCall(TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, NULL));
4089566063dSJacob Faibussowitsch     PetscCall(PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n"));
409847ff0e1SMatthew G. Knepley   }
410847ff0e1SMatthew G. Knepley 
411d763cef2SBarry Smith   /* Handle specific TS options */
412dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, setfromoptions, PetscOptionsObject);
413fbc52257SHong Zhang 
414a7bdc993SLisandro Dalcin   /* Handle TSAdapt options */
4159566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
4169566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
417dbbe0bcdSBarry Smith   PetscCall(TSAdaptSetFromOptions(ts->adapt, PetscOptionsObject));
418a7bdc993SLisandro Dalcin 
41968bece0bSHong Zhang   /* TS trajectory must be set after TS, since it may use some TS options above */
4204f122a70SLisandro Dalcin   tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE;
4219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_save_trajectory", "Save the solution at each timestep", "TSSetSaveTrajectory", tflg, &tflg, NULL));
4221baa6e33SBarry Smith   if (tflg) PetscCall(TSSetSaveTrajectory(ts));
423a05bf03eSHong Zhang 
424dbbe0bcdSBarry Smith   PetscCall(TSAdjointSetFromOptions(ts, PetscOptionsObject));
425d763cef2SBarry Smith 
426d763cef2SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
427dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)ts, PetscOptionsObject));
428d0609cedSBarry Smith   PetscOptionsEnd();
429d763cef2SBarry Smith 
4301baa6e33SBarry Smith   if (ts->trajectory) PetscCall(TSTrajectorySetFromOptions(ts->trajectory, ts));
43168bece0bSHong Zhang 
4321ef27442SStefano Zampini   /* why do we have to do this here and not during TSSetUp? */
4339566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &ts->snes));
4341ef27442SStefano Zampini   if (ts->problem_type == TS_LINEAR) {
4359566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes, &flg, SNESKSPONLY, SNESKSPTRANSPOSEONLY, ""));
4369566063dSJacob Faibussowitsch     if (!flg) PetscCall(SNESSetType(ts->snes, SNESKSPONLY));
4371ef27442SStefano Zampini   }
4389566063dSJacob Faibussowitsch   PetscCall(SNESSetFromOptions(ts->snes));
4393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
440d763cef2SBarry Smith }
441d763cef2SBarry Smith 
442d2daff3dSHong Zhang /*@
443bcf0153eSBarry Smith    TSGetTrajectory - Gets the trajectory from a `TS` if it exists
44478fbdcc8SBarry Smith 
445c3339decSBarry Smith    Collective
44678fbdcc8SBarry Smith 
44778fbdcc8SBarry Smith    Input Parameters:
448bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
44978fbdcc8SBarry Smith 
4507a7aea1fSJed Brown    Output Parameters:
451bcf0153eSBarry Smith .  tr - the `TSTrajectory` object, if it exists
45278fbdcc8SBarry Smith 
45378fbdcc8SBarry Smith    Level: advanced
45478fbdcc8SBarry Smith 
455bcf0153eSBarry Smith    Note:
456bcf0153eSBarry Smith    This routine should be called after all `TS` options have been set
45778fbdcc8SBarry Smith 
458bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSTrajectory`, `TSAdjointSolve()`, `TSTrajectory`, `TSTrajectoryCreate()`
45978fbdcc8SBarry Smith @*/
460d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTrajectory(TS ts, TSTrajectory *tr)
461d71ae5a4SJacob Faibussowitsch {
46278fbdcc8SBarry Smith   PetscFunctionBegin;
46378fbdcc8SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
46478fbdcc8SBarry Smith   *tr = ts->trajectory;
4653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
46678fbdcc8SBarry Smith }
46778fbdcc8SBarry Smith 
46878fbdcc8SBarry Smith /*@
469bcf0153eSBarry Smith    TSSetSaveTrajectory - Causes the `TS` to save its solutions as it iterates forward in time in a `TSTrajectory` object
470d2daff3dSHong Zhang 
471c3339decSBarry Smith    Collective
472d2daff3dSHong Zhang 
473f899ff85SJose E. Roman    Input Parameter:
474bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
475bc952696SBarry Smith 
476bcf0153eSBarry Smith    Options Database Keys:
47778fbdcc8SBarry Smith +  -ts_save_trajectory - saves the trajectory to a file
47867b8a455SSatish Balay -  -ts_trajectory_type type - set trajectory type
47978fbdcc8SBarry Smith 
480d2daff3dSHong Zhang    Level: intermediate
481d2daff3dSHong Zhang 
482bcf0153eSBarry Smith    Notes:
483bcf0153eSBarry Smith    This routine should be called after all `TS` options have been set
484d2daff3dSHong Zhang 
485bcf0153eSBarry Smith    The `TSTRAJECTORYVISUALIZATION` files can be loaded into Python with $PETSC_DIR/lib/petsc/bin/PetscBinaryIOTrajectory.py and
486bcf0153eSBarry Smith    MATLAB with $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m
487bcf0153eSBarry Smith 
488bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSTrajectory`, `TSGetTrajectory()`, `TSAdjointSolve()`
489d2daff3dSHong Zhang @*/
490d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetSaveTrajectory(TS ts)
491d71ae5a4SJacob Faibussowitsch {
492d2daff3dSHong Zhang   PetscFunctionBegin;
493d2daff3dSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
49463a3b9bcSJacob Faibussowitsch   if (!ts->trajectory) PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts), &ts->trajectory));
4953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
496d2daff3dSHong Zhang }
497d2daff3dSHong Zhang 
498a7a1495cSBarry Smith /*@
499bcf0153eSBarry Smith    TSResetTrajectory - Destroys and recreates the internal `TSTrajectory` object
5002d29f1f2SStefano Zampini 
501c3339decSBarry Smith    Collective
5022d29f1f2SStefano Zampini 
5032d29f1f2SStefano Zampini    Input Parameters:
504bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
5052d29f1f2SStefano Zampini 
5062d29f1f2SStefano Zampini    Level: intermediate
5072d29f1f2SStefano Zampini 
508bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSTrajectory`, `TSGetTrajectory()`, `TSAdjointSolve()`, `TSRemoveTrajectory()`
5092d29f1f2SStefano Zampini @*/
510d71ae5a4SJacob Faibussowitsch PetscErrorCode TSResetTrajectory(TS ts)
511d71ae5a4SJacob Faibussowitsch {
5122d29f1f2SStefano Zampini   PetscFunctionBegin;
5132d29f1f2SStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5142d29f1f2SStefano Zampini   if (ts->trajectory) {
5159566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryDestroy(&ts->trajectory));
5169566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts), &ts->trajectory));
5172d29f1f2SStefano Zampini   }
5183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5192d29f1f2SStefano Zampini }
5202d29f1f2SStefano Zampini 
5212d29f1f2SStefano Zampini /*@
522bcf0153eSBarry Smith    TSRemoveTrajectory - Destroys and removes the internal `TSTrajectory` object from TS
52367a3cfb0SHong Zhang 
524c3339decSBarry Smith    Collective
52567a3cfb0SHong Zhang 
52667a3cfb0SHong Zhang    Input Parameters:
527bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
52867a3cfb0SHong Zhang 
52967a3cfb0SHong Zhang    Level: intermediate
53067a3cfb0SHong Zhang 
531bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSTrajectory`, `TSResetTrajectory()`, `TSAdjointSolve()`
53267a3cfb0SHong Zhang @*/
533d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRemoveTrajectory(TS ts)
534d71ae5a4SJacob Faibussowitsch {
53567a3cfb0SHong Zhang   PetscFunctionBegin;
53667a3cfb0SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5371e66621cSBarry Smith   if (ts->trajectory) PetscCall(TSTrajectoryDestroy(&ts->trajectory));
5383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
53967a3cfb0SHong Zhang }
54067a3cfb0SHong Zhang 
54167a3cfb0SHong Zhang /*@
542a7a1495cSBarry Smith    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
543bcf0153eSBarry Smith       set with `TSSetRHSJacobian()`.
544a7a1495cSBarry Smith 
545c3339decSBarry Smith    Collective
546a7a1495cSBarry Smith 
547a7a1495cSBarry Smith    Input Parameters:
548bcf0153eSBarry Smith +  ts - the `TS` context
549a7a1495cSBarry Smith .  t - current timestep
5500910c330SBarry Smith -  U - input vector
551a7a1495cSBarry Smith 
552a7a1495cSBarry Smith    Output Parameters:
553a7a1495cSBarry Smith +  A - Jacobian matrix
5546b867d5aSJose E. Roman -  B - optional preconditioning matrix
555a7a1495cSBarry Smith 
556bcf0153eSBarry Smith    Level: developer
557bcf0153eSBarry Smith 
558bcf0153eSBarry Smith    Note:
559a7a1495cSBarry Smith    Most users should not need to explicitly call this routine, as it
560a7a1495cSBarry Smith    is used internally within the nonlinear solvers.
561a7a1495cSBarry Smith 
562bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSJacobian()`, `KSPSetOperators()`
563a7a1495cSBarry Smith @*/
564d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSJacobian(TS ts, PetscReal t, Vec U, Mat A, Mat B)
565d71ae5a4SJacob Faibussowitsch {
566270bf2e7SJed Brown   PetscObjectState Ustate;
5676c1e1eecSBarry Smith   PetscObjectId    Uid;
56824989b8cSPeter Brune   DM               dm;
569942e3340SBarry Smith   DMTS             tsdm;
57024989b8cSPeter Brune   TSRHSJacobian    rhsjacobianfunc;
57124989b8cSPeter Brune   void            *ctx;
572b2df71adSDebojyoti Ghosh   TSRHSFunction    rhsfunction;
573a7a1495cSBarry Smith 
574a7a1495cSBarry Smith   PetscFunctionBegin;
5750700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5760910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
5770910c330SBarry Smith   PetscCheckSameComm(ts, 1, U, 3);
5789566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
5799566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
5809566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
5819566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobianfunc, &ctx));
5829566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U, &Ustate));
5839566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U, &Uid));
584971015bcSStefano Zampini 
5853ba16761SJacob Faibussowitsch   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) PetscFunctionReturn(PETSC_SUCCESS);
586d90be118SSean Farley 
58763a3b9bcSJacob 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);
58824989b8cSPeter Brune   if (rhsjacobianfunc) {
5899566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TS_JacobianEval, ts, U, A, B));
590792fecdfSBarry Smith     PetscCallBack("TS callback Jacobian", (*rhsjacobianfunc)(ts, t, U, A, B, ctx));
591a6ab3590SBarry Smith     ts->rhsjacs++;
5929566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TS_JacobianEval, ts, U, A, B));
593ef66eb69SBarry Smith   } else {
5949566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(A));
5959566063dSJacob Faibussowitsch     if (B && A != B) PetscCall(MatZeroEntries(B));
596ef66eb69SBarry Smith   }
5970e4ef248SJed Brown   ts->rhsjacobian.time  = t;
598971015bcSStefano Zampini   ts->rhsjacobian.shift = 0;
599971015bcSStefano Zampini   ts->rhsjacobian.scale = 1.;
6009566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U, &ts->rhsjacobian.Xid));
6019566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U, &ts->rhsjacobian.Xstate));
6023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
603a7a1495cSBarry Smith }
604a7a1495cSBarry Smith 
605316643e7SJed Brown /*@
606bcf0153eSBarry Smith    TSComputeRHSFunction - Evaluates the right-hand-side function for a `TS`
607d763cef2SBarry Smith 
608c3339decSBarry Smith    Collective
609316643e7SJed Brown 
610316643e7SJed Brown    Input Parameters:
611bcf0153eSBarry Smith +  ts - the `TS` context
612316643e7SJed Brown .  t - current time
6130910c330SBarry Smith -  U - state vector
614316643e7SJed Brown 
615316643e7SJed Brown    Output Parameter:
616316643e7SJed Brown .  y - right hand side
617316643e7SJed Brown 
618bcf0153eSBarry Smith    Level: developer
619bcf0153eSBarry Smith 
620316643e7SJed Brown    Note:
621316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
622316643e7SJed Brown    is used internally within the nonlinear solvers.
623316643e7SJed Brown 
624bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSFunction()`, `TSComputeIFunction()`
625316643e7SJed Brown @*/
626d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSFunction(TS ts, PetscReal t, Vec U, Vec y)
627d71ae5a4SJacob Faibussowitsch {
62824989b8cSPeter Brune   TSRHSFunction rhsfunction;
62924989b8cSPeter Brune   TSIFunction   ifunction;
63024989b8cSPeter Brune   void         *ctx;
63124989b8cSPeter Brune   DM            dm;
63224989b8cSPeter Brune 
633d763cef2SBarry Smith   PetscFunctionBegin;
6340700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
6350910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
6360700a824SBarry Smith   PetscValidHeaderSpecific(y, VEC_CLASSID, 4);
6379566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
6389566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, &ctx));
6399566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, &ifunction, NULL));
640d763cef2SBarry Smith 
6413c633725SBarry Smith   PetscCheck(rhsfunction || ifunction, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSFunction() and / or TSSetIFunction()");
642d763cef2SBarry Smith 
64324989b8cSPeter Brune   if (rhsfunction) {
6449566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TS_FunctionEval, ts, U, y, 0));
6459566063dSJacob Faibussowitsch     PetscCall(VecLockReadPush(U));
646792fecdfSBarry Smith     PetscCallBack("TS callback right-hand-side", (*rhsfunction)(ts, t, U, y, ctx));
6479566063dSJacob Faibussowitsch     PetscCall(VecLockReadPop(U));
648a6ab3590SBarry Smith     ts->rhsfuncs++;
6499566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TS_FunctionEval, ts, U, y, 0));
6501e66621cSBarry Smith   } else PetscCall(VecZeroEntries(y));
6513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
652d763cef2SBarry Smith }
653d763cef2SBarry Smith 
654ef20d060SBarry Smith /*@
655ef20d060SBarry Smith    TSComputeSolutionFunction - Evaluates the solution function.
656ef20d060SBarry Smith 
657c3339decSBarry Smith    Collective
658ef20d060SBarry Smith 
659ef20d060SBarry Smith    Input Parameters:
660bcf0153eSBarry Smith +  ts - the `TS` context
661ef20d060SBarry Smith -  t - current time
662ef20d060SBarry Smith 
663ef20d060SBarry Smith    Output Parameter:
6640910c330SBarry Smith .  U - the solution
665ef20d060SBarry Smith 
666ef20d060SBarry Smith    Level: developer
667ef20d060SBarry Smith 
668bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
669ef20d060SBarry Smith @*/
670d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeSolutionFunction(TS ts, PetscReal t, Vec U)
671d71ae5a4SJacob Faibussowitsch {
672ef20d060SBarry Smith   TSSolutionFunction solutionfunction;
673ef20d060SBarry Smith   void              *ctx;
674ef20d060SBarry Smith   DM                 dm;
675ef20d060SBarry Smith 
676ef20d060SBarry Smith   PetscFunctionBegin;
677ef20d060SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
6780910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
6799566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
6809566063dSJacob Faibussowitsch   PetscCall(DMTSGetSolutionFunction(dm, &solutionfunction, &ctx));
681792fecdfSBarry Smith   if (solutionfunction) PetscCallBack("TS callback solution", (*solutionfunction)(ts, t, U, ctx));
6823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
683ef20d060SBarry Smith }
6849b7cd975SBarry Smith /*@
6859b7cd975SBarry Smith    TSComputeForcingFunction - Evaluates the forcing function.
6869b7cd975SBarry Smith 
687c3339decSBarry Smith    Collective
6889b7cd975SBarry Smith 
6899b7cd975SBarry Smith    Input Parameters:
690bcf0153eSBarry Smith +  ts - the `TS` context
6919b7cd975SBarry Smith -  t - current time
6929b7cd975SBarry Smith 
6939b7cd975SBarry Smith    Output Parameter:
6949b7cd975SBarry Smith .  U - the function value
6959b7cd975SBarry Smith 
6969b7cd975SBarry Smith    Level: developer
6979b7cd975SBarry Smith 
698bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
6999b7cd975SBarry Smith @*/
700d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeForcingFunction(TS ts, PetscReal t, Vec U)
701d71ae5a4SJacob Faibussowitsch {
7029b7cd975SBarry Smith   void             *ctx;
7039b7cd975SBarry Smith   DM                dm;
7045f80ce2aSJacob Faibussowitsch   TSForcingFunction forcing;
7059b7cd975SBarry Smith 
7069b7cd975SBarry Smith   PetscFunctionBegin;
7079b7cd975SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
7089b7cd975SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
7099566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
7109566063dSJacob Faibussowitsch   PetscCall(DMTSGetForcingFunction(dm, &forcing, &ctx));
7119b7cd975SBarry Smith 
712792fecdfSBarry Smith   if (forcing) PetscCallBack("TS callback forcing function", (*forcing)(ts, t, U, ctx));
7133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7149b7cd975SBarry Smith }
715ef20d060SBarry Smith 
716d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSGetRHSVec_Private(TS ts, Vec *Frhs)
717d71ae5a4SJacob Faibussowitsch {
7182dd45cf8SJed Brown   Vec F;
719214bc6a2SJed Brown 
720214bc6a2SJed Brown   PetscFunctionBegin;
7210298fd71SBarry Smith   *Frhs = NULL;
7229566063dSJacob Faibussowitsch   PetscCall(TSGetIFunction(ts, &F, NULL, NULL));
7231e66621cSBarry Smith   if (!ts->Frhs) PetscCall(VecDuplicate(F, &ts->Frhs));
724214bc6a2SJed Brown   *Frhs = ts->Frhs;
7253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
726214bc6a2SJed Brown }
727214bc6a2SJed Brown 
728d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetRHSMats_Private(TS ts, Mat *Arhs, Mat *Brhs)
729d71ae5a4SJacob Faibussowitsch {
730214bc6a2SJed Brown   Mat         A, B;
73141a1d4d2SBarry Smith   TSIJacobian ijacobian;
732214bc6a2SJed Brown 
733214bc6a2SJed Brown   PetscFunctionBegin;
734c0cd0301SJed Brown   if (Arhs) *Arhs = NULL;
735c0cd0301SJed Brown   if (Brhs) *Brhs = NULL;
7369566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts, &A, &B, &ijacobian, NULL));
737214bc6a2SJed Brown   if (Arhs) {
738214bc6a2SJed Brown     if (!ts->Arhs) {
73941a1d4d2SBarry Smith       if (ijacobian) {
7409566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &ts->Arhs));
7419566063dSJacob Faibussowitsch         PetscCall(TSSetMatStructure(ts, SAME_NONZERO_PATTERN));
74241a1d4d2SBarry Smith       } else {
74341a1d4d2SBarry Smith         ts->Arhs = A;
7449566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
74541a1d4d2SBarry Smith       }
7463565c898SBarry Smith     } else {
7473565c898SBarry Smith       PetscBool flg;
7489566063dSJacob Faibussowitsch       PetscCall(SNESGetUseMatrixFree(ts->snes, NULL, &flg));
7493565c898SBarry Smith       /* Handle case where user provided only RHSJacobian and used -snes_mf_operator */
7503565c898SBarry Smith       if (flg && !ijacobian && ts->Arhs == ts->Brhs) {
7519566063dSJacob Faibussowitsch         PetscCall(PetscObjectDereference((PetscObject)ts->Arhs));
7523565c898SBarry Smith         ts->Arhs = A;
7539566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
7543565c898SBarry Smith       }
755214bc6a2SJed Brown     }
756214bc6a2SJed Brown     *Arhs = ts->Arhs;
757214bc6a2SJed Brown   }
758214bc6a2SJed Brown   if (Brhs) {
759214bc6a2SJed Brown     if (!ts->Brhs) {
760bdb70873SJed Brown       if (A != B) {
76141a1d4d2SBarry Smith         if (ijacobian) {
7629566063dSJacob Faibussowitsch           PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &ts->Brhs));
763bdb70873SJed Brown         } else {
76441a1d4d2SBarry Smith           ts->Brhs = B;
7659566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)B));
76641a1d4d2SBarry Smith         }
76741a1d4d2SBarry Smith       } else {
7689566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)ts->Arhs));
76951699248SLisandro Dalcin         ts->Brhs = ts->Arhs;
770bdb70873SJed Brown       }
771214bc6a2SJed Brown     }
772214bc6a2SJed Brown     *Brhs = ts->Brhs;
773214bc6a2SJed Brown   }
7743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
775214bc6a2SJed Brown }
776214bc6a2SJed Brown 
777316643e7SJed Brown /*@
7780910c330SBarry Smith    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0
779316643e7SJed Brown 
780c3339decSBarry Smith    Collective
781316643e7SJed Brown 
782316643e7SJed Brown    Input Parameters:
783bcf0153eSBarry Smith +  ts - the `TS` context
784316643e7SJed Brown .  t - current time
7850910c330SBarry Smith .  U - state vector
7860910c330SBarry Smith .  Udot - time derivative of state vector
787bcf0153eSBarry Smith -  imex - flag indicates if the method is `TSIMEX` so that the RHSFunction should be kept separate
788316643e7SJed Brown 
789316643e7SJed Brown    Output Parameter:
790316643e7SJed Brown .  Y - right hand side
791316643e7SJed Brown 
792bcf0153eSBarry Smith    Level: developer
793bcf0153eSBarry Smith 
794316643e7SJed Brown    Note:
795316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
796316643e7SJed Brown    is used internally within the nonlinear solvers.
797316643e7SJed Brown 
798316643e7SJed Brown    If the user did did not write their equations in implicit form, this
799316643e7SJed Brown    function recasts them in implicit form.
800316643e7SJed Brown 
801bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetIFunction()`, `TSComputeRHSFunction()`
802316643e7SJed Brown @*/
803d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIFunction(TS ts, PetscReal t, Vec U, Vec Udot, Vec Y, PetscBool imex)
804d71ae5a4SJacob Faibussowitsch {
80524989b8cSPeter Brune   TSIFunction   ifunction;
80624989b8cSPeter Brune   TSRHSFunction rhsfunction;
80724989b8cSPeter Brune   void         *ctx;
80824989b8cSPeter Brune   DM            dm;
809316643e7SJed Brown 
810316643e7SJed Brown   PetscFunctionBegin;
8110700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
8120910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
8130910c330SBarry Smith   PetscValidHeaderSpecific(Udot, VEC_CLASSID, 4);
8140700a824SBarry Smith   PetscValidHeaderSpecific(Y, VEC_CLASSID, 5);
815316643e7SJed Brown 
8169566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
8179566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, &ifunction, &ctx));
8189566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
81924989b8cSPeter Brune 
8203c633725SBarry Smith   PetscCheck(rhsfunction || ifunction, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSFunction() and / or TSSetIFunction()");
821d90be118SSean Farley 
8229566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_FunctionEval, ts, U, Udot, Y));
82324989b8cSPeter Brune   if (ifunction) {
824792fecdfSBarry Smith     PetscCallBack("TS callback implicit function", (*ifunction)(ts, t, U, Udot, Y, ctx));
825a6ab3590SBarry Smith     ts->ifuncs++;
826214bc6a2SJed Brown   }
827214bc6a2SJed Brown   if (imex) {
8281e66621cSBarry Smith     if (!ifunction) PetscCall(VecCopy(Udot, Y));
82924989b8cSPeter Brune   } else if (rhsfunction) {
83024989b8cSPeter Brune     if (ifunction) {
831214bc6a2SJed Brown       Vec Frhs;
8329566063dSJacob Faibussowitsch       PetscCall(TSGetRHSVec_Private(ts, &Frhs));
8339566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts, t, U, Frhs));
8349566063dSJacob Faibussowitsch       PetscCall(VecAXPY(Y, -1, Frhs));
8352dd45cf8SJed Brown     } else {
8369566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts, t, U, Y));
8379566063dSJacob Faibussowitsch       PetscCall(VecAYPX(Y, -1, Udot));
838316643e7SJed Brown     }
8394a6899ffSJed Brown   }
8409566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_FunctionEval, ts, U, Udot, Y));
8413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
842316643e7SJed Brown }
843316643e7SJed Brown 
844cfa8a9a2SHong Zhang /*
845cfa8a9a2SHong Zhang    TSRecoverRHSJacobian - Recover the Jacobian matrix so that one can call TSComputeRHSJacobian() on it.
846cfa8a9a2SHong Zhang 
847cfa8a9a2SHong Zhang    Note:
848cfa8a9a2SHong Zhang    This routine is needed when one switches from TSComputeIJacobian() to TSComputeRHSJacobian() because the Jacobian matrix may be shifted or scaled in TSComputeIJacobian().
849cfa8a9a2SHong Zhang 
850cfa8a9a2SHong Zhang */
851d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSRecoverRHSJacobian(TS ts, Mat A, Mat B)
852d71ae5a4SJacob Faibussowitsch {
853cfa8a9a2SHong Zhang   PetscFunctionBegin;
854cfa8a9a2SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
8553c633725SBarry Smith   PetscCheck(A == ts->Arhs, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Invalid Amat");
8563c633725SBarry Smith   PetscCheck(B == ts->Brhs, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Invalid Bmat");
857cfa8a9a2SHong Zhang 
8581baa6e33SBarry Smith   if (ts->rhsjacobian.shift) PetscCall(MatShift(A, -ts->rhsjacobian.shift));
85948a46eb9SPierre Jolivet   if (ts->rhsjacobian.scale == -1.) PetscCall(MatScale(A, -1));
860cfa8a9a2SHong Zhang   if (B && B == ts->Brhs && A != B) {
8611baa6e33SBarry Smith     if (ts->rhsjacobian.shift) PetscCall(MatShift(B, -ts->rhsjacobian.shift));
8621e66621cSBarry Smith     if (ts->rhsjacobian.scale == -1.) PetscCall(MatScale(B, -1));
863cfa8a9a2SHong Zhang   }
864cfa8a9a2SHong Zhang   ts->rhsjacobian.shift = 0;
865cfa8a9a2SHong Zhang   ts->rhsjacobian.scale = 1.;
8663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
867cfa8a9a2SHong Zhang }
868cfa8a9a2SHong Zhang 
869316643e7SJed Brown /*@
870316643e7SJed Brown    TSComputeIJacobian - Evaluates the Jacobian of the DAE
871316643e7SJed Brown 
872c3339decSBarry Smith    Collective
873316643e7SJed Brown 
874316643e7SJed Brown    Input
875316643e7SJed Brown       Input Parameters:
876bcf0153eSBarry Smith +  ts - the `TS` context
877316643e7SJed Brown .  t - current timestep
8780910c330SBarry Smith .  U - state vector
8790910c330SBarry Smith .  Udot - time derivative of state vector
880214bc6a2SJed Brown .  shift - shift to apply, see note below
881bcf0153eSBarry Smith -  imex - flag indicates if the method is `TSIMEX` so that the RHSJacobian should be kept separate
882316643e7SJed Brown 
883316643e7SJed Brown    Output Parameters:
884316643e7SJed Brown +  A - Jacobian matrix
8853565c898SBarry Smith -  B - matrix from which the preconditioner is constructed; often the same as A
886316643e7SJed Brown 
887bcf0153eSBarry Smith    Level: developer
888bcf0153eSBarry Smith 
889316643e7SJed Brown    Notes:
8900910c330SBarry Smith    If F(t,U,Udot)=0 is the DAE, the required Jacobian is
891316643e7SJed Brown 
8920910c330SBarry Smith    dF/dU + shift*dF/dUdot
893316643e7SJed Brown 
894316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
895316643e7SJed Brown    is used internally within the nonlinear solvers.
896316643e7SJed Brown 
897bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetIJacobian()`
89863495f91SJed Brown @*/
899d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIJacobian(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat A, Mat B, PetscBool imex)
900d71ae5a4SJacob Faibussowitsch {
90124989b8cSPeter Brune   TSIJacobian   ijacobian;
90224989b8cSPeter Brune   TSRHSJacobian rhsjacobian;
90324989b8cSPeter Brune   DM            dm;
90424989b8cSPeter Brune   void         *ctx;
905316643e7SJed Brown 
906316643e7SJed Brown   PetscFunctionBegin;
9070700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
9080910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
9090910c330SBarry Smith   PetscValidHeaderSpecific(Udot, VEC_CLASSID, 4);
910316643e7SJed Brown   PetscValidPointer(A, 6);
91194ab13aaSBarry Smith   PetscValidHeaderSpecific(A, MAT_CLASSID, 6);
912316643e7SJed Brown   PetscValidPointer(B, 7);
91394ab13aaSBarry Smith   PetscValidHeaderSpecific(B, MAT_CLASSID, 7);
91424989b8cSPeter Brune 
9159566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
9169566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijacobian, &ctx));
9179566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL));
91824989b8cSPeter Brune 
9193c633725SBarry Smith   PetscCheck(rhsjacobian || ijacobian, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
920316643e7SJed Brown 
9219566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_JacobianEval, ts, U, A, B));
92224989b8cSPeter Brune   if (ijacobian) {
923792fecdfSBarry Smith     PetscCallBack("TS callback implicit Jacobian", (*ijacobian)(ts, t, U, Udot, shift, A, B, ctx));
924a6ab3590SBarry Smith     ts->ijacs++;
9254a6899ffSJed Brown   }
926214bc6a2SJed Brown   if (imex) {
927b5abc632SBarry Smith     if (!ijacobian) { /* system was written as Udot = G(t,U) */
9284c26be97Sstefano_zampini       PetscBool assembled;
929971015bcSStefano Zampini       if (rhsjacobian) {
930971015bcSStefano Zampini         Mat Arhs = NULL;
9319566063dSJacob Faibussowitsch         PetscCall(TSGetRHSMats_Private(ts, &Arhs, NULL));
932971015bcSStefano Zampini         if (A == Arhs) {
9333c633725SBarry 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 */
934971015bcSStefano Zampini           ts->rhsjacobian.time = PETSC_MIN_REAL;
935971015bcSStefano Zampini         }
936971015bcSStefano Zampini       }
9379566063dSJacob Faibussowitsch       PetscCall(MatZeroEntries(A));
9389566063dSJacob Faibussowitsch       PetscCall(MatAssembled(A, &assembled));
9394c26be97Sstefano_zampini       if (!assembled) {
9409566063dSJacob Faibussowitsch         PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
9419566063dSJacob Faibussowitsch         PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
9424c26be97Sstefano_zampini       }
9439566063dSJacob Faibussowitsch       PetscCall(MatShift(A, shift));
94494ab13aaSBarry Smith       if (A != B) {
9459566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(B));
9469566063dSJacob Faibussowitsch         PetscCall(MatAssembled(B, &assembled));
9474c26be97Sstefano_zampini         if (!assembled) {
9489566063dSJacob Faibussowitsch           PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
9499566063dSJacob Faibussowitsch           PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
9504c26be97Sstefano_zampini         }
9519566063dSJacob Faibussowitsch         PetscCall(MatShift(B, shift));
952214bc6a2SJed Brown       }
953214bc6a2SJed Brown     }
954214bc6a2SJed Brown   } else {
955e1244c69SJed Brown     Mat Arhs = NULL, Brhs = NULL;
9561e66621cSBarry Smith 
9571e66621cSBarry Smith     /* RHSJacobian needs to be converted to part of IJacobian if exists */
9581e66621cSBarry Smith     if (rhsjacobian) PetscCall(TSGetRHSMats_Private(ts, &Arhs, &Brhs));
959e8b1e424SHong Zhang     if (Arhs == A) { /* No IJacobian matrix, so we only have the RHS matrix */
960e8b1e424SHong Zhang       PetscObjectState Ustate;
961e8b1e424SHong Zhang       PetscObjectId    Uid;
962e8b1e424SHong Zhang       TSRHSFunction    rhsfunction;
963e8b1e424SHong Zhang 
9649566063dSJacob Faibussowitsch       PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
9659566063dSJacob Faibussowitsch       PetscCall(PetscObjectStateGet((PetscObject)U, &Ustate));
9669566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetId((PetscObject)U, &Uid));
9679371c9d4SSatish Balay       if ((rhsjacobian == TSComputeRHSJacobianConstant || (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && rhsfunction != TSComputeRHSFunctionLinear)) &&
9689371c9d4SSatish Balay           ts->rhsjacobian.scale == -1.) {                      /* No need to recompute RHSJacobian */
9699566063dSJacob Faibussowitsch         PetscCall(MatShift(A, shift - ts->rhsjacobian.shift)); /* revert the old shift and add the new shift with a single call to MatShift */
9701e66621cSBarry Smith         if (A != B) PetscCall(MatShift(B, shift - ts->rhsjacobian.shift));
971e8b1e424SHong Zhang       } else {
9723565c898SBarry Smith         PetscBool flg;
973e8b1e424SHong Zhang 
974e8b1e424SHong Zhang         if (ts->rhsjacobian.reuse) { /* Undo the damage */
975e8b1e424SHong Zhang           /* MatScale has a short path for this case.
976e8b1e424SHong Zhang              However, this code path is taken the first time TSComputeRHSJacobian is called
977e8b1e424SHong Zhang              and the matrices have not been assembled yet */
9789566063dSJacob Faibussowitsch           PetscCall(TSRecoverRHSJacobian(ts, A, B));
979e8b1e424SHong Zhang         }
9809566063dSJacob Faibussowitsch         PetscCall(TSComputeRHSJacobian(ts, t, U, A, B));
9819566063dSJacob Faibussowitsch         PetscCall(SNESGetUseMatrixFree(ts->snes, NULL, &flg));
9823565c898SBarry Smith         /* since -snes_mf_operator uses the full SNES function it does not need to be shifted or scaled here */
9833565c898SBarry Smith         if (!flg) {
9849566063dSJacob Faibussowitsch           PetscCall(MatScale(A, -1));
9859566063dSJacob Faibussowitsch           PetscCall(MatShift(A, shift));
9863565c898SBarry Smith         }
98794ab13aaSBarry Smith         if (A != B) {
9889566063dSJacob Faibussowitsch           PetscCall(MatScale(B, -1));
9899566063dSJacob Faibussowitsch           PetscCall(MatShift(B, shift));
990316643e7SJed Brown         }
991e8b1e424SHong Zhang       }
992e8b1e424SHong Zhang       ts->rhsjacobian.scale = -1;
993e8b1e424SHong Zhang       ts->rhsjacobian.shift = shift;
994d60b7d5cSBarry Smith     } else if (Arhs) {  /* Both IJacobian and RHSJacobian */
995e1244c69SJed Brown       if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */
9969566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(A));
9979566063dSJacob Faibussowitsch         PetscCall(MatShift(A, shift));
99894ab13aaSBarry Smith         if (A != B) {
9999566063dSJacob Faibussowitsch           PetscCall(MatZeroEntries(B));
10009566063dSJacob Faibussowitsch           PetscCall(MatShift(B, shift));
1001214bc6a2SJed Brown         }
1002316643e7SJed Brown       }
10039566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSJacobian(ts, t, U, Arhs, Brhs));
10049566063dSJacob Faibussowitsch       PetscCall(MatAXPY(A, -1, Arhs, ts->axpy_pattern));
10051e66621cSBarry Smith       if (A != B) PetscCall(MatAXPY(B, -1, Brhs, ts->axpy_pattern));
1006316643e7SJed Brown     }
1007316643e7SJed Brown   }
10089566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_JacobianEval, ts, U, A, B));
10093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1010316643e7SJed Brown }
1011316643e7SJed Brown 
1012d763cef2SBarry Smith /*@C
1013d763cef2SBarry Smith     TSSetRHSFunction - Sets the routine for evaluating the function,
1014b5abc632SBarry Smith     where U_t = G(t,u).
1015d763cef2SBarry Smith 
1016c3339decSBarry Smith     Logically Collective
1017d763cef2SBarry Smith 
1018d763cef2SBarry Smith     Input Parameters:
1019bcf0153eSBarry Smith +   ts - the `TS` context obtained from `TSCreate()`
10200298fd71SBarry Smith .   r - vector to put the computed right hand side (or NULL to have it created)
1021d763cef2SBarry Smith .   f - routine for evaluating the right-hand-side function
1022d763cef2SBarry Smith -   ctx - [optional] user-defined context for private data for the
10230298fd71SBarry Smith           function evaluation routine (may be NULL)
1024d763cef2SBarry Smith 
1025a96d6ef6SBarry Smith     Calling sequence of f:
1026a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
1027d763cef2SBarry Smith 
1028a96d6ef6SBarry Smith +   ts - timestep context
1029a96d6ef6SBarry Smith .   t - current timestep
1030d763cef2SBarry Smith .   u - input vector
1031d763cef2SBarry Smith .   F - function vector
1032d763cef2SBarry Smith -   ctx - [optional] user-defined function context
1033d763cef2SBarry Smith 
1034d763cef2SBarry Smith     Level: beginner
1035d763cef2SBarry Smith 
1036bcf0153eSBarry Smith     Note:
1037bcf0153eSBarry Smith     You must call this function or `TSSetIFunction()` to define your ODE. You cannot use this function when solving a DAE.
10382bbac0d3SBarry Smith 
1039bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
1040d763cef2SBarry Smith @*/
1041d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetRHSFunction(TS ts, Vec r, PetscErrorCode (*f)(TS, PetscReal, Vec, Vec, void *), void *ctx)
1042d71ae5a4SJacob Faibussowitsch {
1043089b2837SJed Brown   SNES snes;
10440298fd71SBarry Smith   Vec  ralloc = NULL;
104524989b8cSPeter Brune   DM   dm;
1046d763cef2SBarry Smith 
1047089b2837SJed Brown   PetscFunctionBegin;
10480700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1049ca94891dSJed Brown   if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
105024989b8cSPeter Brune 
10519566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
10529566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSFunction(dm, f, ctx));
10539566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
1054e856ceecSJed Brown   if (!r && !ts->dm && ts->vec_sol) {
10559566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol, &ralloc));
1056e856ceecSJed Brown     r = ralloc;
1057e856ceecSJed Brown   }
10589566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, r, SNESTSFormFunction, ts));
10599566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
10603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1061d763cef2SBarry Smith }
1062d763cef2SBarry Smith 
1063ef20d060SBarry Smith /*@C
1064abd5a294SJed Brown     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
1065ef20d060SBarry Smith 
1066c3339decSBarry Smith     Logically Collective
1067ef20d060SBarry Smith 
1068ef20d060SBarry Smith     Input Parameters:
1069bcf0153eSBarry Smith +   ts - the `TS` context obtained from `TSCreate()`
1070ef20d060SBarry Smith .   f - routine for evaluating the solution
1071ef20d060SBarry Smith -   ctx - [optional] user-defined context for private data for the
10720298fd71SBarry Smith           function evaluation routine (may be NULL)
1073ef20d060SBarry Smith 
1074a96d6ef6SBarry Smith     Calling sequence of f:
1075a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
1076ef20d060SBarry Smith 
1077ef20d060SBarry Smith +   t - current timestep
1078ef20d060SBarry Smith .   u - output vector
1079ef20d060SBarry Smith -   ctx - [optional] user-defined function context
1080ef20d060SBarry Smith 
1081bcf0153eSBarry Smith     Options Database Keys:
1082bcf0153eSBarry Smith +  -ts_monitor_lg_error - create a graphical monitor of error history, requires user to have provided `TSSetSolutionFunction()`
1083bcf0153eSBarry Smith -  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided `TSSetSolutionFunction()`
1084bcf0153eSBarry Smith 
1085bcf0153eSBarry Smith     Level: intermediate
10860ed3bfb6SBarry Smith 
1087abd5a294SJed Brown     Notes:
1088abd5a294SJed Brown     This routine is used for testing accuracy of time integration schemes when you already know the solution.
1089abd5a294SJed Brown     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
1090abd5a294SJed Brown     create closed-form solutions with non-physical forcing terms.
1091abd5a294SJed Brown 
1092bcf0153eSBarry Smith     For low-dimensional problems solved in serial, such as small discrete systems, `TSMonitorLGError()` can be used to monitor the error history.
1093abd5a294SJed Brown 
1094bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSComputeSolutionFunction()`, `TSSetForcingFunction()`, `TSSetSolution()`, `TSGetSolution()`, `TSMonitorLGError()`, `TSMonitorDrawError()`
1095ef20d060SBarry Smith @*/
1096d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetSolutionFunction(TS ts, PetscErrorCode (*f)(TS, PetscReal, Vec, void *), void *ctx)
1097d71ae5a4SJacob Faibussowitsch {
1098ef20d060SBarry Smith   DM dm;
1099ef20d060SBarry Smith 
1100ef20d060SBarry Smith   PetscFunctionBegin;
1101ef20d060SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
11029566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
11039566063dSJacob Faibussowitsch   PetscCall(DMTSSetSolutionFunction(dm, f, ctx));
11043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1105ef20d060SBarry Smith }
1106ef20d060SBarry Smith 
11079b7cd975SBarry Smith /*@C
11089b7cd975SBarry Smith     TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE
11099b7cd975SBarry Smith 
1110c3339decSBarry Smith     Logically Collective
11119b7cd975SBarry Smith 
11129b7cd975SBarry Smith     Input Parameters:
1113bcf0153eSBarry Smith +   ts - the `TS` context obtained from `TSCreate()`
1114e162b725SBarry Smith .   func - routine for evaluating the forcing function
11159b7cd975SBarry Smith -   ctx - [optional] user-defined context for private data for the
11160298fd71SBarry Smith           function evaluation routine (may be NULL)
11179b7cd975SBarry Smith 
11189b7cd975SBarry Smith     Calling sequence of func:
11196bc98fa9SBarry Smith $     PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
11209b7cd975SBarry Smith 
11219b7cd975SBarry Smith +   t - current timestep
1122e162b725SBarry Smith .   f - output vector
11239b7cd975SBarry Smith -   ctx - [optional] user-defined function context
11249b7cd975SBarry Smith 
1125bcf0153eSBarry Smith     Level: intermediate
1126bcf0153eSBarry Smith 
11279b7cd975SBarry Smith     Notes:
11289b7cd975SBarry Smith     This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to
1129e162b725SBarry 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
1130e162b725SBarry Smith     definition of the problem you are solving and hence possibly introducing bugs.
1131e162b725SBarry Smith 
1132e162b725SBarry Smith     This replaces the ODE F(u,u_t,t) = 0 the TS is solving with F(u,u_t,t) - func(t) = 0
1133e162b725SBarry Smith 
1134e162b725SBarry 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
1135e162b725SBarry Smith     parameters can be passed in the ctx variable.
11369b7cd975SBarry Smith 
1137bcf0153eSBarry Smith     For low-dimensional problems solved in serial, such as small discrete systems, `TSMonitorLGError()` can be used to monitor the error history.
11389b7cd975SBarry Smith 
1139bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSComputeSolutionFunction()`, `TSSetSolutionFunction()`
11409b7cd975SBarry Smith @*/
1141d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetForcingFunction(TS ts, TSForcingFunction func, void *ctx)
1142d71ae5a4SJacob Faibussowitsch {
11439b7cd975SBarry Smith   DM dm;
11449b7cd975SBarry Smith 
11459b7cd975SBarry Smith   PetscFunctionBegin;
11469b7cd975SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
11479566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
11489566063dSJacob Faibussowitsch   PetscCall(DMTSSetForcingFunction(dm, func, ctx));
11493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11509b7cd975SBarry Smith }
11519b7cd975SBarry Smith 
1152d763cef2SBarry Smith /*@C
1153f7ab8db6SBarry Smith    TSSetRHSJacobian - Sets the function to compute the Jacobian of G,
1154b5abc632SBarry Smith    where U_t = G(U,t), as well as the location to store the matrix.
1155d763cef2SBarry Smith 
1156c3339decSBarry Smith    Logically Collective
1157d763cef2SBarry Smith 
1158d763cef2SBarry Smith    Input Parameters:
1159bcf0153eSBarry Smith +  ts  - the `TS` context obtained from `TSCreate()`
1160e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1161e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1162d763cef2SBarry Smith .  f   - the Jacobian evaluation routine
1163d763cef2SBarry Smith -  ctx - [optional] user-defined context for private data for the
11640298fd71SBarry Smith          Jacobian evaluation routine (may be NULL)
1165d763cef2SBarry Smith 
1166f7ab8db6SBarry Smith    Calling sequence of f:
1167a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
1168d763cef2SBarry Smith 
1169d763cef2SBarry Smith +  t - current timestep
1170d763cef2SBarry Smith .  u - input vector
1171e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1172e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1173d763cef2SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
1174d763cef2SBarry Smith 
1175bcf0153eSBarry Smith    Level: beginner
1176bcf0153eSBarry Smith 
11776cd88445SBarry Smith    Notes:
11786cd88445SBarry Smith    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
11796cd88445SBarry Smith 
1180bcf0153eSBarry Smith    The `TS` solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1181ca5f011dSBarry Smith    You should not assume the values are the same in the next call to f() as you set them in the previous call.
1182d763cef2SBarry Smith 
1183bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `SNESComputeJacobianDefaultColor()`, `TSSetRHSFunction()`, `TSRHSJacobianSetReuse()`, `TSSetIJacobian()`
1184d763cef2SBarry Smith @*/
1185d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetRHSJacobian(TS ts, Mat Amat, Mat Pmat, TSRHSJacobian f, void *ctx)
1186d71ae5a4SJacob Faibussowitsch {
1187089b2837SJed Brown   SNES        snes;
118824989b8cSPeter Brune   DM          dm;
118924989b8cSPeter Brune   TSIJacobian ijacobian;
1190277b19d0SLisandro Dalcin 
1191d763cef2SBarry Smith   PetscFunctionBegin;
11920700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1193e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
1194e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
1195e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts, 1, Amat, 2);
1196e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts, 1, Pmat, 3);
1197d763cef2SBarry Smith 
11989566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
11999566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSJacobian(dm, f, ctx));
12009566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijacobian, NULL));
12019566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
12021e66621cSBarry Smith   if (!ijacobian) PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESTSFormJacobian, ts));
1203e5d3d808SBarry Smith   if (Amat) {
12049566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Amat));
12059566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Arhs));
1206e5d3d808SBarry Smith     ts->Arhs = Amat;
12070e4ef248SJed Brown   }
1208e5d3d808SBarry Smith   if (Pmat) {
12099566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Pmat));
12109566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Brhs));
1211e5d3d808SBarry Smith     ts->Brhs = Pmat;
12120e4ef248SJed Brown   }
12133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1214d763cef2SBarry Smith }
1215d763cef2SBarry Smith 
1216316643e7SJed Brown /*@C
1217b5abc632SBarry Smith    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
1218316643e7SJed Brown 
1219c3339decSBarry Smith    Logically Collective
1220316643e7SJed Brown 
1221316643e7SJed Brown    Input Parameters:
1222bcf0153eSBarry Smith +  ts  - the `TS` context obtained from `TSCreate()`
12230298fd71SBarry Smith .  r   - vector to hold the residual (or NULL to have it created internally)
1224316643e7SJed Brown .  f   - the function evaluation routine
12250298fd71SBarry Smith -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1226316643e7SJed Brown 
1227316643e7SJed Brown    Calling sequence of f:
12286bc98fa9SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
1229316643e7SJed Brown 
1230316643e7SJed Brown +  t   - time at step/stage being solved
1231316643e7SJed Brown .  u   - state vector
1232316643e7SJed Brown .  u_t - time derivative of state vector
1233316643e7SJed Brown .  F   - function vector
1234316643e7SJed Brown -  ctx - [optional] user-defined context for matrix evaluation routine
1235316643e7SJed Brown 
1236316643e7SJed Brown    Level: beginner
1237316643e7SJed Brown 
1238bcf0153eSBarry Smith    Note:
1239bcf0153eSBarry Smith    The user MUST call either this routine or `TSSetRHSFunction()` to define the ODE.  When solving DAEs you must use this function.
1240bcf0153eSBarry Smith 
1241bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSJacobian()`, `TSSetRHSFunction()`, `TSSetIJacobian()`
1242316643e7SJed Brown @*/
1243d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetIFunction(TS ts, Vec r, TSIFunction f, void *ctx)
1244d71ae5a4SJacob Faibussowitsch {
1245089b2837SJed Brown   SNES snes;
124651699248SLisandro Dalcin   Vec  ralloc = NULL;
124724989b8cSPeter Brune   DM   dm;
1248316643e7SJed Brown 
1249316643e7SJed Brown   PetscFunctionBegin;
12500700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
125151699248SLisandro Dalcin   if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
125224989b8cSPeter Brune 
12539566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12549566063dSJacob Faibussowitsch   PetscCall(DMTSSetIFunction(dm, f, ctx));
125524989b8cSPeter Brune 
12569566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
125751699248SLisandro Dalcin   if (!r && !ts->dm && ts->vec_sol) {
12589566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol, &ralloc));
125951699248SLisandro Dalcin     r = ralloc;
1260e856ceecSJed Brown   }
12619566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, r, SNESTSFormFunction, ts));
12629566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
12633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1264089b2837SJed Brown }
1265089b2837SJed Brown 
1266089b2837SJed Brown /*@C
1267a5b23f4aSJose E. Roman    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/context to compute it.
1268089b2837SJed Brown 
1269089b2837SJed Brown    Not Collective
1270089b2837SJed Brown 
1271089b2837SJed Brown    Input Parameter:
1272bcf0153eSBarry Smith .  ts - the `TS` context
1273089b2837SJed Brown 
1274d8d19677SJose E. Roman    Output Parameters:
12750298fd71SBarry Smith +  r - vector to hold residual (or NULL)
12760298fd71SBarry Smith .  func - the function to compute residual (or NULL)
12770298fd71SBarry Smith -  ctx - the function context (or NULL)
1278089b2837SJed Brown 
1279089b2837SJed Brown    Level: advanced
1280089b2837SJed Brown 
1281bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetIFunction()`, `SNESGetFunction()`
1282089b2837SJed Brown @*/
1283d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetIFunction(TS ts, Vec *r, TSIFunction *func, void **ctx)
1284d71ae5a4SJacob Faibussowitsch {
1285089b2837SJed Brown   SNES snes;
128624989b8cSPeter Brune   DM   dm;
1287089b2837SJed Brown 
1288089b2837SJed Brown   PetscFunctionBegin;
1289089b2837SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
12909566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
12919566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
12929566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12939566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, func, ctx));
12943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1295089b2837SJed Brown }
1296089b2837SJed Brown 
1297089b2837SJed Brown /*@C
1298089b2837SJed Brown    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.
1299089b2837SJed Brown 
1300089b2837SJed Brown    Not Collective
1301089b2837SJed Brown 
1302089b2837SJed Brown    Input Parameter:
1303bcf0153eSBarry Smith .  ts - the `TS` context
1304089b2837SJed Brown 
1305d8d19677SJose E. Roman    Output Parameters:
13060298fd71SBarry Smith +  r - vector to hold computed right hand side (or NULL)
13070298fd71SBarry Smith .  func - the function to compute right hand side (or NULL)
13080298fd71SBarry Smith -  ctx - the function context (or NULL)
1309089b2837SJed Brown 
1310089b2837SJed Brown    Level: advanced
1311089b2837SJed Brown 
1312bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSFunction()`, `SNESGetFunction()`
1313089b2837SJed Brown @*/
1314d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetRHSFunction(TS ts, Vec *r, TSRHSFunction *func, void **ctx)
1315d71ae5a4SJacob Faibussowitsch {
1316089b2837SJed Brown   SNES snes;
131724989b8cSPeter Brune   DM   dm;
1318089b2837SJed Brown 
1319089b2837SJed Brown   PetscFunctionBegin;
1320089b2837SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
13219566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
13229566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
13239566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
13249566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, func, ctx));
13253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1326316643e7SJed Brown }
1327316643e7SJed Brown 
1328316643e7SJed Brown /*@C
1329a4f0a591SBarry Smith    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
1330bcf0153eSBarry Smith         provided with `TSSetIFunction()`.
1331316643e7SJed Brown 
1332c3339decSBarry Smith    Logically Collective
1333316643e7SJed Brown 
1334316643e7SJed Brown    Input Parameters:
1335bcf0153eSBarry Smith +  ts  - the `TS` context obtained from `TSCreate()`
1336e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1337e5d3d808SBarry Smith .  Pmat - matrix used to compute preconditioner (usually the same as Amat)
1338316643e7SJed Brown .  f   - the Jacobian evaluation routine
13390298fd71SBarry Smith -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1340316643e7SJed Brown 
1341316643e7SJed Brown    Calling sequence of f:
13426bc98fa9SBarry Smith $    PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
1343316643e7SJed Brown 
1344316643e7SJed Brown +  t    - time at step/stage being solved
13451b4a444bSJed Brown .  U    - state vector
13461b4a444bSJed Brown .  U_t  - time derivative of state vector
1347316643e7SJed Brown .  a    - shift
1348e5d3d808SBarry Smith .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1349e5d3d808SBarry Smith .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1350316643e7SJed Brown -  ctx  - [optional] user-defined context for matrix evaluation routine
1351316643e7SJed Brown 
1352bcf0153eSBarry Smith    Level: beginner
1353316643e7SJed Brown 
1354bcf0153eSBarry Smith    Notes:
1355bcf0153eSBarry Smith    The matrices Amat and Pmat are exactly the matrices that are used by `SNES` for the nonlinear solve.
1356bcf0153eSBarry Smith 
1357bcf0153eSBarry Smith    If you know the operator Amat has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null
1358bcf0153eSBarry Smith    space to Amat and the `KSP` solvers will automatically use that null space as needed during the solution process.
1359895c21f2SBarry Smith 
1360a4f0a591SBarry Smith    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1361b5abc632SBarry Smith    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1362a4f0a591SBarry Smith    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1363a4f0a591SBarry Smith    a and vector W depend on the integration method, step size, and past states. For example with
1364a4f0a591SBarry Smith    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1365a4f0a591SBarry Smith    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1366a4f0a591SBarry Smith 
13676cd88445SBarry Smith    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
13686cd88445SBarry Smith 
13696cd88445SBarry Smith    The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1370ca5f011dSBarry Smith    You should not assume the values are the same in the next call to f() as you set them in the previous call.
1371ca5f011dSBarry Smith 
1372bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetIFunction()`, `TSSetRHSJacobian()`, `SNESComputeJacobianDefaultColor()`, `SNESComputeJacobianDefault()`, `TSSetRHSFunction()`
1373316643e7SJed Brown @*/
1374d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetIJacobian(TS ts, Mat Amat, Mat Pmat, TSIJacobian f, void *ctx)
1375d71ae5a4SJacob Faibussowitsch {
1376089b2837SJed Brown   SNES snes;
137724989b8cSPeter Brune   DM   dm;
1378316643e7SJed Brown 
1379316643e7SJed Brown   PetscFunctionBegin;
13800700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1381e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
1382e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
1383e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts, 1, Amat, 2);
1384e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts, 1, Pmat, 3);
138524989b8cSPeter Brune 
13869566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
13879566063dSJacob Faibussowitsch   PetscCall(DMTSSetIJacobian(dm, f, ctx));
138824989b8cSPeter Brune 
13899566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
13909566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESTSFormJacobian, ts));
13913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1392316643e7SJed Brown }
1393316643e7SJed Brown 
1394e1244c69SJed Brown /*@
1395bcf0153eSBarry Smith    TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating.  Without this flag, `TS` will change the sign and
1396e1244c69SJed Brown    shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute
1397e1244c69SJed Brown    the entire Jacobian.  The reuse flag must be set if the evaluation function will assume that the matrix entries have
1398e1244c69SJed Brown    not been changed by the TS.
1399e1244c69SJed Brown 
1400e1244c69SJed Brown    Logically Collective
1401e1244c69SJed Brown 
14024165533cSJose E. Roman    Input Parameters:
1403bcf0153eSBarry Smith +  ts - `TS` context obtained from `TSCreate()`
1404bcf0153eSBarry Smith -  reuse - `PETSC_TRUE` if the RHS Jacobian
1405e1244c69SJed Brown 
1406e1244c69SJed Brown    Level: intermediate
1407e1244c69SJed Brown 
1408bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
1409e1244c69SJed Brown @*/
1410d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSJacobianSetReuse(TS ts, PetscBool reuse)
1411d71ae5a4SJacob Faibussowitsch {
1412e1244c69SJed Brown   PetscFunctionBegin;
1413e1244c69SJed Brown   ts->rhsjacobian.reuse = reuse;
14143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1415e1244c69SJed Brown }
1416e1244c69SJed Brown 
1417efe9872eSLisandro Dalcin /*@C
1418efe9872eSLisandro Dalcin    TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved.
1419efe9872eSLisandro Dalcin 
1420c3339decSBarry Smith    Logically Collective
1421efe9872eSLisandro Dalcin 
1422efe9872eSLisandro Dalcin    Input Parameters:
1423bcf0153eSBarry Smith +  ts  - the `TS` context obtained from `TSCreate()`
1424efe9872eSLisandro Dalcin .  F   - vector to hold the residual (or NULL to have it created internally)
1425efe9872eSLisandro Dalcin .  fun - the function evaluation routine
1426efe9872eSLisandro Dalcin -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1427efe9872eSLisandro Dalcin 
1428efe9872eSLisandro Dalcin    Calling sequence of fun:
14296bc98fa9SBarry Smith $     PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
1430efe9872eSLisandro Dalcin 
1431efe9872eSLisandro Dalcin +  t    - time at step/stage being solved
1432efe9872eSLisandro Dalcin .  U    - state vector
1433efe9872eSLisandro Dalcin .  U_t  - time derivative of state vector
1434efe9872eSLisandro Dalcin .  U_tt - second time derivative of state vector
1435efe9872eSLisandro Dalcin .  F    - function vector
1436efe9872eSLisandro Dalcin -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)
1437efe9872eSLisandro Dalcin 
1438efe9872eSLisandro Dalcin    Level: beginner
1439efe9872eSLisandro Dalcin 
1440bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetI2Jacobian()`, `TSSetIFunction()`, `TSCreate()`, `TSSetRHSFunction()`
1441efe9872eSLisandro Dalcin @*/
1442d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetI2Function(TS ts, Vec F, TSI2Function fun, void *ctx)
1443d71ae5a4SJacob Faibussowitsch {
1444efe9872eSLisandro Dalcin   DM dm;
1445efe9872eSLisandro Dalcin 
1446efe9872eSLisandro Dalcin   PetscFunctionBegin;
1447efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1448efe9872eSLisandro Dalcin   if (F) PetscValidHeaderSpecific(F, VEC_CLASSID, 2);
14499566063dSJacob Faibussowitsch   PetscCall(TSSetIFunction(ts, F, NULL, NULL));
14509566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14519566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Function(dm, fun, ctx));
14523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1453efe9872eSLisandro Dalcin }
1454efe9872eSLisandro Dalcin 
1455efe9872eSLisandro Dalcin /*@C
1456a5b23f4aSJose E. Roman   TSGetI2Function - Returns the vector where the implicit residual is stored and the function/context to compute it.
1457efe9872eSLisandro Dalcin 
1458efe9872eSLisandro Dalcin   Not Collective
1459efe9872eSLisandro Dalcin 
1460efe9872eSLisandro Dalcin   Input Parameter:
1461bcf0153eSBarry Smith . ts - the `TS` context
1462efe9872eSLisandro Dalcin 
1463d8d19677SJose E. Roman   Output Parameters:
1464efe9872eSLisandro Dalcin + r - vector to hold residual (or NULL)
1465efe9872eSLisandro Dalcin . fun - the function to compute residual (or NULL)
1466efe9872eSLisandro Dalcin - ctx - the function context (or NULL)
1467efe9872eSLisandro Dalcin 
1468efe9872eSLisandro Dalcin   Level: advanced
1469efe9872eSLisandro Dalcin 
1470bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetIFunction()`, `SNESGetFunction()`, `TSCreate()`
1471efe9872eSLisandro Dalcin @*/
1472d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetI2Function(TS ts, Vec *r, TSI2Function *fun, void **ctx)
1473d71ae5a4SJacob Faibussowitsch {
1474efe9872eSLisandro Dalcin   SNES snes;
1475efe9872eSLisandro Dalcin   DM   dm;
1476efe9872eSLisandro Dalcin 
1477efe9872eSLisandro Dalcin   PetscFunctionBegin;
1478efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
14799566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
14809566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
14819566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14829566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm, fun, ctx));
14833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1484efe9872eSLisandro Dalcin }
1485efe9872eSLisandro Dalcin 
1486efe9872eSLisandro Dalcin /*@C
1487bc77d74cSLisandro Dalcin    TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t  + a*dF/dU_tt
1488bcf0153eSBarry Smith         where F(t,U,U_t,U_tt) is the function you provided with `TSSetI2Function()`.
1489efe9872eSLisandro Dalcin 
1490c3339decSBarry Smith    Logically Collective
1491efe9872eSLisandro Dalcin 
1492efe9872eSLisandro Dalcin    Input Parameters:
1493bcf0153eSBarry Smith +  ts  - the `TS` context obtained from `TSCreate()`
1494efe9872eSLisandro Dalcin .  J   - Jacobian matrix
1495efe9872eSLisandro Dalcin .  P   - preconditioning matrix for J (may be same as J)
1496efe9872eSLisandro Dalcin .  jac - the Jacobian evaluation routine
1497efe9872eSLisandro Dalcin -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1498efe9872eSLisandro Dalcin 
1499efe9872eSLisandro Dalcin    Calling sequence of jac:
15006bc98fa9SBarry Smith $    PetscErrorCode jac(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,PetscReal v,PetscReal a,Mat J,Mat P,void *ctx);
1501efe9872eSLisandro Dalcin 
1502efe9872eSLisandro Dalcin +  t    - time at step/stage being solved
1503efe9872eSLisandro Dalcin .  U    - state vector
1504efe9872eSLisandro Dalcin .  U_t  - time derivative of state vector
1505efe9872eSLisandro Dalcin .  U_tt - second time derivative of state vector
1506efe9872eSLisandro Dalcin .  v    - shift for U_t
1507efe9872eSLisandro Dalcin .  a    - shift for U_tt
1508efe9872eSLisandro Dalcin .  J    - Jacobian of G(U) = F(t,U,W+v*U,W'+a*U), equivalent to dF/dU + v*dF/dU_t  + a*dF/dU_tt
1509efe9872eSLisandro Dalcin .  P    - preconditioning matrix for J, may be same as J
1510efe9872eSLisandro Dalcin -  ctx  - [optional] user-defined context for matrix evaluation routine
1511efe9872eSLisandro Dalcin 
1512bcf0153eSBarry Smith    Level: beginner
1513bcf0153eSBarry Smith 
1514efe9872eSLisandro Dalcin    Notes:
1515bcf0153eSBarry Smith    The matrices J and P are exactly the matrices that are used by `SNES` for the nonlinear solve.
1516efe9872eSLisandro Dalcin 
1517efe9872eSLisandro Dalcin    The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be
1518efe9872eSLisandro 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.
1519efe9872eSLisandro Dalcin    The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U  where the positive "shift"
1520bc77d74cSLisandro Dalcin    parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states.
1521efe9872eSLisandro Dalcin 
1522bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetI2Function()`, `TSGetI2Jacobian()`
1523efe9872eSLisandro Dalcin @*/
1524d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetI2Jacobian(TS ts, Mat J, Mat P, TSI2Jacobian jac, void *ctx)
1525d71ae5a4SJacob Faibussowitsch {
1526efe9872eSLisandro Dalcin   DM dm;
1527efe9872eSLisandro Dalcin 
1528efe9872eSLisandro Dalcin   PetscFunctionBegin;
1529efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1530efe9872eSLisandro Dalcin   if (J) PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
1531efe9872eSLisandro Dalcin   if (P) PetscValidHeaderSpecific(P, MAT_CLASSID, 3);
15329566063dSJacob Faibussowitsch   PetscCall(TSSetIJacobian(ts, J, P, NULL, NULL));
15339566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
15349566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Jacobian(dm, jac, ctx));
15353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1536efe9872eSLisandro Dalcin }
1537efe9872eSLisandro Dalcin 
1538efe9872eSLisandro Dalcin /*@C
1539efe9872eSLisandro Dalcin   TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep.
1540efe9872eSLisandro Dalcin 
1541bcf0153eSBarry Smith   Not Collective, but parallel objects are returned if `TS` is parallel
1542efe9872eSLisandro Dalcin 
1543efe9872eSLisandro Dalcin   Input Parameter:
1544bcf0153eSBarry Smith . ts  - The `TS` context obtained from `TSCreate()`
1545efe9872eSLisandro Dalcin 
1546efe9872eSLisandro Dalcin   Output Parameters:
1547efe9872eSLisandro Dalcin + J  - The (approximate) Jacobian of F(t,U,U_t,U_tt)
1548efe9872eSLisandro Dalcin . P - The matrix from which the preconditioner is constructed, often the same as J
1549efe9872eSLisandro Dalcin . jac - The function to compute the Jacobian matrices
1550efe9872eSLisandro Dalcin - ctx - User-defined context for Jacobian evaluation routine
1551efe9872eSLisandro Dalcin 
1552bcf0153eSBarry Smith   Level: advanced
1553bcf0153eSBarry Smith 
155495452b02SPatrick Sanan   Notes:
155595452b02SPatrick Sanan     You can pass in NULL for any return argument you do not need.
1556efe9872eSLisandro Dalcin 
1557bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`, `TSSetI2Jacobian()`, `TSGetI2Function()`, `TSCreate()`
1558efe9872eSLisandro Dalcin @*/
1559d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetI2Jacobian(TS ts, Mat *J, Mat *P, TSI2Jacobian *jac, void **ctx)
1560d71ae5a4SJacob Faibussowitsch {
1561efe9872eSLisandro Dalcin   SNES snes;
1562efe9872eSLisandro Dalcin   DM   dm;
1563efe9872eSLisandro Dalcin 
1564efe9872eSLisandro Dalcin   PetscFunctionBegin;
15659566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
15669566063dSJacob Faibussowitsch   PetscCall(SNESSetUpMatrices(snes));
15679566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, J, P, NULL, NULL));
15689566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
15699566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, jac, ctx));
15703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1571efe9872eSLisandro Dalcin }
1572efe9872eSLisandro Dalcin 
1573efe9872eSLisandro Dalcin /*@
1574efe9872eSLisandro Dalcin   TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0
1575efe9872eSLisandro Dalcin 
1576c3339decSBarry Smith   Collective
1577efe9872eSLisandro Dalcin 
1578efe9872eSLisandro Dalcin   Input Parameters:
1579bcf0153eSBarry Smith + ts - the `TS` context
1580efe9872eSLisandro Dalcin . t - current time
1581efe9872eSLisandro Dalcin . U - state vector
1582efe9872eSLisandro Dalcin . V - time derivative of state vector (U_t)
1583efe9872eSLisandro Dalcin - A - second time derivative of state vector (U_tt)
1584efe9872eSLisandro Dalcin 
1585efe9872eSLisandro Dalcin   Output Parameter:
1586efe9872eSLisandro Dalcin . F - the residual vector
1587efe9872eSLisandro Dalcin 
1588bcf0153eSBarry Smith   Level: developer
1589bcf0153eSBarry Smith 
1590efe9872eSLisandro Dalcin   Note:
1591efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
1592efe9872eSLisandro Dalcin   is used internally within the nonlinear solvers.
1593efe9872eSLisandro Dalcin 
1594bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetI2Function()`, `TSGetI2Function()`
1595efe9872eSLisandro Dalcin @*/
1596d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeI2Function(TS ts, PetscReal t, Vec U, Vec V, Vec A, Vec F)
1597d71ae5a4SJacob Faibussowitsch {
1598efe9872eSLisandro Dalcin   DM            dm;
1599efe9872eSLisandro Dalcin   TSI2Function  I2Function;
1600efe9872eSLisandro Dalcin   void         *ctx;
1601efe9872eSLisandro Dalcin   TSRHSFunction rhsfunction;
1602efe9872eSLisandro Dalcin 
1603efe9872eSLisandro Dalcin   PetscFunctionBegin;
1604efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1605efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
1606efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V, VEC_CLASSID, 4);
1607efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A, VEC_CLASSID, 5);
1608efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(F, VEC_CLASSID, 6);
1609efe9872eSLisandro Dalcin 
16109566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
16119566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm, &I2Function, &ctx));
16129566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
1613efe9872eSLisandro Dalcin 
1614efe9872eSLisandro Dalcin   if (!I2Function) {
16159566063dSJacob Faibussowitsch     PetscCall(TSComputeIFunction(ts, t, U, A, F, PETSC_FALSE));
16163ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
1617efe9872eSLisandro Dalcin   }
1618efe9872eSLisandro Dalcin 
16199566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_FunctionEval, ts, U, V, F));
1620efe9872eSLisandro Dalcin 
1621792fecdfSBarry Smith   PetscCallBack("TS callback implicit function", I2Function(ts, t, U, V, A, F, ctx));
1622efe9872eSLisandro Dalcin 
1623efe9872eSLisandro Dalcin   if (rhsfunction) {
1624efe9872eSLisandro Dalcin     Vec Frhs;
16259566063dSJacob Faibussowitsch     PetscCall(TSGetRHSVec_Private(ts, &Frhs));
16269566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSFunction(ts, t, U, Frhs));
16279566063dSJacob Faibussowitsch     PetscCall(VecAXPY(F, -1, Frhs));
1628efe9872eSLisandro Dalcin   }
1629efe9872eSLisandro Dalcin 
16309566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_FunctionEval, ts, U, V, F));
16313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1632efe9872eSLisandro Dalcin }
1633efe9872eSLisandro Dalcin 
1634efe9872eSLisandro Dalcin /*@
1635efe9872eSLisandro Dalcin   TSComputeI2Jacobian - Evaluates the Jacobian of the DAE
1636efe9872eSLisandro Dalcin 
1637c3339decSBarry Smith   Collective
1638efe9872eSLisandro Dalcin 
1639efe9872eSLisandro Dalcin   Input Parameters:
1640bcf0153eSBarry Smith + ts - the `TS` context
1641efe9872eSLisandro Dalcin . t - current timestep
1642efe9872eSLisandro Dalcin . U - state vector
1643efe9872eSLisandro Dalcin . V - time derivative of state vector
1644efe9872eSLisandro Dalcin . A - second time derivative of state vector
1645efe9872eSLisandro Dalcin . shiftV - shift to apply, see note below
1646efe9872eSLisandro Dalcin - shiftA - shift to apply, see note below
1647efe9872eSLisandro Dalcin 
1648efe9872eSLisandro Dalcin   Output Parameters:
1649efe9872eSLisandro Dalcin + J - Jacobian matrix
1650efe9872eSLisandro Dalcin - P - optional preconditioning matrix
1651efe9872eSLisandro Dalcin 
1652bcf0153eSBarry Smith   Level: developer
1653bcf0153eSBarry Smith 
1654efe9872eSLisandro Dalcin   Notes:
1655efe9872eSLisandro Dalcin   If F(t,U,V,A)=0 is the DAE, the required Jacobian is
1656efe9872eSLisandro Dalcin 
1657efe9872eSLisandro Dalcin   dF/dU + shiftV*dF/dV + shiftA*dF/dA
1658efe9872eSLisandro Dalcin 
1659efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
1660efe9872eSLisandro Dalcin   is used internally within the nonlinear solvers.
1661efe9872eSLisandro Dalcin 
1662bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetI2Jacobian()`
1663efe9872eSLisandro Dalcin @*/
1664d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeI2Jacobian(TS ts, PetscReal t, Vec U, Vec V, Vec A, PetscReal shiftV, PetscReal shiftA, Mat J, Mat P)
1665d71ae5a4SJacob Faibussowitsch {
1666efe9872eSLisandro Dalcin   DM            dm;
1667efe9872eSLisandro Dalcin   TSI2Jacobian  I2Jacobian;
1668efe9872eSLisandro Dalcin   void         *ctx;
1669efe9872eSLisandro Dalcin   TSRHSJacobian rhsjacobian;
1670efe9872eSLisandro Dalcin 
1671efe9872eSLisandro Dalcin   PetscFunctionBegin;
1672efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1673efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
1674efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V, VEC_CLASSID, 4);
1675efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A, VEC_CLASSID, 5);
1676efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(J, MAT_CLASSID, 8);
1677efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(P, MAT_CLASSID, 9);
1678efe9872eSLisandro Dalcin 
16799566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
16809566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, &I2Jacobian, &ctx));
16819566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL));
1682efe9872eSLisandro Dalcin 
1683efe9872eSLisandro Dalcin   if (!I2Jacobian) {
16849566063dSJacob Faibussowitsch     PetscCall(TSComputeIJacobian(ts, t, U, A, shiftA, J, P, PETSC_FALSE));
16853ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
1686efe9872eSLisandro Dalcin   }
1687efe9872eSLisandro Dalcin 
16889566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_JacobianEval, ts, U, J, P));
1689792fecdfSBarry Smith   PetscCallBack("TS callback implicit Jacobian", I2Jacobian(ts, t, U, V, A, shiftV, shiftA, J, P, ctx));
1690efe9872eSLisandro Dalcin   if (rhsjacobian) {
1691d60b7d5cSBarry Smith     Mat Jrhs, Prhs;
16929566063dSJacob Faibussowitsch     PetscCall(TSGetRHSMats_Private(ts, &Jrhs, &Prhs));
16939566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSJacobian(ts, t, U, Jrhs, Prhs));
16949566063dSJacob Faibussowitsch     PetscCall(MatAXPY(J, -1, Jrhs, ts->axpy_pattern));
16959566063dSJacob Faibussowitsch     if (P != J) PetscCall(MatAXPY(P, -1, Prhs, ts->axpy_pattern));
1696efe9872eSLisandro Dalcin   }
1697efe9872eSLisandro Dalcin 
16989566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_JacobianEval, ts, U, J, P));
16993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1700efe9872eSLisandro Dalcin }
1701efe9872eSLisandro Dalcin 
1702438f35afSJed Brown /*@C
1703438f35afSJed Brown    TSSetTransientVariable - sets function to transform from state to transient variables
1704438f35afSJed Brown 
1705438f35afSJed Brown    Logically Collective
1706438f35afSJed Brown 
17074165533cSJose E. Roman    Input Parameters:
1708438f35afSJed Brown +  ts - time stepping context on which to change the transient variable
1709a96d6ef6SBarry Smith .  tvar - a function that transforms to transient variables
1710438f35afSJed Brown -  ctx - a context for tvar
1711438f35afSJed Brown 
1712a96d6ef6SBarry Smith     Calling sequence of tvar:
1713a96d6ef6SBarry Smith $     PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
1714a96d6ef6SBarry Smith 
1715a96d6ef6SBarry Smith +   ts - timestep context
17166aad120cSJose E. Roman .   p - input vector (primitive form)
1717a96d6ef6SBarry Smith .   c - output vector, transient variables (conservative form)
1718a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
1719a96d6ef6SBarry Smith 
1720438f35afSJed Brown    Level: advanced
1721438f35afSJed Brown 
1722438f35afSJed Brown    Notes:
1723bcf0153eSBarry Smith    This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., `TSBDF`)
1724438f35afSJed Brown    can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
1725438f35afSJed Brown    well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
1726438f35afSJed Brown    C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
1727438f35afSJed Brown    evaluated via the chain rule, as in
1728438f35afSJed Brown 
1729438f35afSJed Brown      dF/dP + shift * dF/dCdot dC/dP.
1730438f35afSJed Brown 
1731bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSBDF`, `DMTSSetTransientVariable()`, `DMTSGetTransientVariable()`, `TSSetIFunction()`, `TSSetIJacobian()`
1732438f35afSJed Brown @*/
1733d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTransientVariable(TS ts, TSTransientVariable tvar, void *ctx)
1734d71ae5a4SJacob Faibussowitsch {
1735438f35afSJed Brown   DM dm;
1736438f35afSJed Brown 
1737438f35afSJed Brown   PetscFunctionBegin;
1738438f35afSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
17399566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
17409566063dSJacob Faibussowitsch   PetscCall(DMTSSetTransientVariable(dm, tvar, ctx));
17413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1742438f35afSJed Brown }
1743438f35afSJed Brown 
1744efe9872eSLisandro Dalcin /*@
1745e3c11fc1SJed Brown    TSComputeTransientVariable - transforms state (primitive) variables to transient (conservative) variables
1746e3c11fc1SJed Brown 
1747e3c11fc1SJed Brown    Logically Collective
1748e3c11fc1SJed Brown 
1749e3c11fc1SJed Brown    Input Parameters:
1750e3c11fc1SJed Brown +  ts - TS on which to compute
1751e3c11fc1SJed Brown -  U - state vector to be transformed to transient variables
1752e3c11fc1SJed Brown 
1753e3c11fc1SJed Brown    Output Parameters:
1754e3c11fc1SJed Brown .  C - transient (conservative) variable
1755e3c11fc1SJed Brown 
1756e3c11fc1SJed Brown    Level: developer
1757e3c11fc1SJed Brown 
1758bcf0153eSBarry Smith    Developer Note:
1759bcf0153eSBarry Smith    If `DMTSSetTransientVariable()` has not been called, then C is not modified in this routine and C = NULL is allowed.
1760bcf0153eSBarry Smith    This makes it safe to call without a guard.  One can use `TSHasTransientVariable()` to check if transient variables are
1761bcf0153eSBarry Smith    being used.
1762bcf0153eSBarry Smith 
1763bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSBDF`, `DMTSSetTransientVariable()`, `TSComputeIFunction()`, `TSComputeIJacobian()`
1764e3c11fc1SJed Brown @*/
1765d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeTransientVariable(TS ts, Vec U, Vec C)
1766d71ae5a4SJacob Faibussowitsch {
1767e3c11fc1SJed Brown   DM   dm;
1768e3c11fc1SJed Brown   DMTS dmts;
1769e3c11fc1SJed Brown 
1770e3c11fc1SJed Brown   PetscFunctionBegin;
1771e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1772e3c11fc1SJed Brown   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
17739566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
17749566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
1775e3c11fc1SJed Brown   if (dmts->ops->transientvar) {
1776e3c11fc1SJed Brown     PetscValidHeaderSpecific(C, VEC_CLASSID, 3);
17779566063dSJacob Faibussowitsch     PetscCall((*dmts->ops->transientvar)(ts, U, C, dmts->transientvarctx));
1778e3c11fc1SJed Brown   }
17793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1780e3c11fc1SJed Brown }
1781e3c11fc1SJed Brown 
1782e3c11fc1SJed Brown /*@
1783e3c11fc1SJed Brown    TSHasTransientVariable - determine whether transient variables have been set
1784e3c11fc1SJed Brown 
1785e3c11fc1SJed Brown    Logically Collective
1786e3c11fc1SJed Brown 
1787e3c11fc1SJed Brown    Input Parameters:
1788e3c11fc1SJed Brown .  ts - TS on which to compute
1789e3c11fc1SJed Brown 
1790e3c11fc1SJed Brown    Output Parameters:
1791bcf0153eSBarry Smith .  has - `PETSC_TRUE` if transient variables have been set
1792e3c11fc1SJed Brown 
1793e3c11fc1SJed Brown    Level: developer
1794e3c11fc1SJed Brown 
1795bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSBDF`, `DMTSSetTransientVariable()`, `TSComputeTransientVariable()`
1796e3c11fc1SJed Brown @*/
1797d71ae5a4SJacob Faibussowitsch PetscErrorCode TSHasTransientVariable(TS ts, PetscBool *has)
1798d71ae5a4SJacob Faibussowitsch {
1799e3c11fc1SJed Brown   DM   dm;
1800e3c11fc1SJed Brown   DMTS dmts;
1801e3c11fc1SJed Brown 
1802e3c11fc1SJed Brown   PetscFunctionBegin;
1803e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
18049566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
18059566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
1806e3c11fc1SJed Brown   *has = dmts->ops->transientvar ? PETSC_TRUE : PETSC_FALSE;
18073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1808e3c11fc1SJed Brown }
1809e3c11fc1SJed Brown 
1810e3c11fc1SJed Brown /*@
1811efe9872eSLisandro Dalcin    TS2SetSolution - Sets the initial solution and time derivative vectors
1812bcf0153eSBarry Smith    for use by the `TS` routines handling second order equations.
1813efe9872eSLisandro Dalcin 
1814c3339decSBarry Smith    Logically Collective
1815efe9872eSLisandro Dalcin 
1816efe9872eSLisandro Dalcin    Input Parameters:
1817bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
1818efe9872eSLisandro Dalcin .  u - the solution vector
1819efe9872eSLisandro Dalcin -  v - the time derivative vector
1820efe9872eSLisandro Dalcin 
1821efe9872eSLisandro Dalcin    Level: beginner
1822efe9872eSLisandro Dalcin 
1823bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`
1824efe9872eSLisandro Dalcin @*/
1825d71ae5a4SJacob Faibussowitsch PetscErrorCode TS2SetSolution(TS ts, Vec u, Vec v)
1826d71ae5a4SJacob Faibussowitsch {
1827efe9872eSLisandro Dalcin   PetscFunctionBegin;
1828efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1829efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
1830efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(v, VEC_CLASSID, 3);
18319566063dSJacob Faibussowitsch   PetscCall(TSSetSolution(ts, u));
18329566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)v));
18339566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
1834efe9872eSLisandro Dalcin   ts->vec_dot = v;
18353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1836efe9872eSLisandro Dalcin }
1837efe9872eSLisandro Dalcin 
1838efe9872eSLisandro Dalcin /*@
1839efe9872eSLisandro Dalcin    TS2GetSolution - Returns the solution and time derivative at the present timestep
1840efe9872eSLisandro Dalcin    for second order equations. It is valid to call this routine inside the function
1841efe9872eSLisandro Dalcin    that you are evaluating in order to move to the new timestep. This vector not
1842efe9872eSLisandro Dalcin    changed until the solution at the next timestep has been calculated.
1843efe9872eSLisandro Dalcin 
1844bcf0153eSBarry Smith    Not Collective, but Vec returned is parallel if `TS` is parallel
1845efe9872eSLisandro Dalcin 
1846efe9872eSLisandro Dalcin    Input Parameter:
1847bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
1848efe9872eSLisandro Dalcin 
1849d8d19677SJose E. Roman    Output Parameters:
1850efe9872eSLisandro Dalcin +  u - the vector containing the solution
1851efe9872eSLisandro Dalcin -  v - the vector containing the time derivative
1852efe9872eSLisandro Dalcin 
1853efe9872eSLisandro Dalcin    Level: intermediate
1854efe9872eSLisandro Dalcin 
1855bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TS2SetSolution()`, `TSGetTimeStep()`, `TSGetTime()`
1856efe9872eSLisandro Dalcin @*/
1857d71ae5a4SJacob Faibussowitsch PetscErrorCode TS2GetSolution(TS ts, Vec *u, Vec *v)
1858d71ae5a4SJacob Faibussowitsch {
1859efe9872eSLisandro Dalcin   PetscFunctionBegin;
1860efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1861efe9872eSLisandro Dalcin   if (u) PetscValidPointer(u, 2);
1862efe9872eSLisandro Dalcin   if (v) PetscValidPointer(v, 3);
1863efe9872eSLisandro Dalcin   if (u) *u = ts->vec_sol;
1864efe9872eSLisandro Dalcin   if (v) *v = ts->vec_dot;
18653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1866efe9872eSLisandro Dalcin }
1867efe9872eSLisandro Dalcin 
186855849f57SBarry Smith /*@C
1869bcf0153eSBarry Smith   TSLoad - Loads a `TS` that has been stored in binary  with `TSView()`.
187055849f57SBarry Smith 
1871c3339decSBarry Smith   Collective
187255849f57SBarry Smith 
187355849f57SBarry Smith   Input Parameters:
1874bcf0153eSBarry Smith + newdm - the newly loaded `TS`, this needs to have been created with `TSCreate()` or
1875bcf0153eSBarry Smith            some related function before a call to `TSLoad()`.
1876bcf0153eSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()`
187755849f57SBarry Smith 
187855849f57SBarry Smith    Level: intermediate
187955849f57SBarry Smith 
1880bcf0153eSBarry Smith   Note:
1881bcf0153eSBarry Smith  The type is determined by the data in the file, any type set into the `TS` before this call is ignored.
188255849f57SBarry Smith 
1883bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `PetscViewer`, `PetscViewerBinaryOpen()`, `TSView()`, `MatLoad()`, `VecLoad()`
188455849f57SBarry Smith @*/
1885d71ae5a4SJacob Faibussowitsch PetscErrorCode TSLoad(TS ts, PetscViewer viewer)
1886d71ae5a4SJacob Faibussowitsch {
188755849f57SBarry Smith   PetscBool isbinary;
188855849f57SBarry Smith   PetscInt  classid;
188955849f57SBarry Smith   char      type[256];
18902d53ad75SBarry Smith   DMTS      sdm;
1891ad6bc421SBarry Smith   DM        dm;
189255849f57SBarry Smith 
189355849f57SBarry Smith   PetscFunctionBegin;
1894f2c2a1b9SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
189555849f57SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
18969566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
18973c633725SBarry Smith   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
189855849f57SBarry Smith 
18999566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT));
19003c633725SBarry Smith   PetscCheck(classid == TS_FILE_CLASSID, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Not TS next in file");
19019566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR));
19029566063dSJacob Faibussowitsch   PetscCall(TSSetType(ts, type));
1903dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, load, viewer);
19049566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)ts), &dm));
19059566063dSJacob Faibussowitsch   PetscCall(DMLoad(dm, viewer));
19069566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts, dm));
19079566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(ts->dm, &ts->vec_sol));
19089566063dSJacob Faibussowitsch   PetscCall(VecLoad(ts->vec_sol, viewer));
19099566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm, &sdm));
19109566063dSJacob Faibussowitsch   PetscCall(DMTSLoad(sdm, viewer));
19113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
191255849f57SBarry Smith }
191355849f57SBarry Smith 
19149804daf3SBarry Smith #include <petscdraw.h>
1915e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1916e04113cfSBarry Smith   #include <petscviewersaws.h>
1917f05ece33SBarry Smith #endif
1918fe2efc57SMark 
1919fe2efc57SMark /*@C
1920bcf0153eSBarry Smith    TSViewFromOptions - View a `TS` based on values in the options database
1921fe2efc57SMark 
1922c3339decSBarry Smith    Collective
1923fe2efc57SMark 
1924fe2efc57SMark    Input Parameters:
1925bcf0153eSBarry Smith +  ts - the `TS` context
1926bcf0153eSBarry Smith .  obj - Optional object that provides the prefix for the options database keys
1927bcf0153eSBarry Smith -  name - command line option string to be passed by user
1928fe2efc57SMark 
1929fe2efc57SMark    Level: intermediate
1930bcf0153eSBarry Smith 
1931bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSView`, `PetscObjectViewFromOptions()`, `TSCreate()`
1932fe2efc57SMark @*/
1933bcf0153eSBarry Smith PetscErrorCode TSViewFromOptions(TS ts, PetscObject obj, const char name[])
1934d71ae5a4SJacob Faibussowitsch {
1935fe2efc57SMark   PetscFunctionBegin;
1936bcf0153eSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1937bcf0153eSBarry Smith   PetscCall(PetscObjectViewFromOptions((PetscObject)ts, obj, name));
19383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1939fe2efc57SMark }
1940fe2efc57SMark 
19417e2c5f70SBarry Smith /*@C
1942bcf0153eSBarry Smith     TSView - Prints the `TS` data structure.
1943d763cef2SBarry Smith 
1944c3339decSBarry Smith     Collective
1945d763cef2SBarry Smith 
1946d763cef2SBarry Smith     Input Parameters:
1947bcf0153eSBarry Smith +   ts - the `TS` context obtained from `TSCreate()`
1948d763cef2SBarry Smith -   viewer - visualization context
1949d763cef2SBarry Smith 
1950d763cef2SBarry Smith     Options Database Key:
1951bcf0153eSBarry Smith .   -ts_view - calls `TSView()` at end of `TSStep()`
1952bcf0153eSBarry Smith 
1953bcf0153eSBarry Smith     Level: beginner
1954d763cef2SBarry Smith 
1955d763cef2SBarry Smith     Notes:
1956d763cef2SBarry Smith     The available visualization contexts include
1957bcf0153eSBarry Smith +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
1958bcf0153eSBarry Smith -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
1959d763cef2SBarry Smith          output where only the first processor opens
1960d763cef2SBarry Smith          the file.  All other processors send their
1961d763cef2SBarry Smith          data to the first processor to print.
1962d763cef2SBarry Smith 
1963d763cef2SBarry Smith     The user can open an alternative visualization context with
1964bcf0153eSBarry Smith     `PetscViewerASCIIOpen()` - output to a specified file.
1965d763cef2SBarry Smith 
1966bcf0153eSBarry Smith     In the debugger you can do call `TSView`(ts,0) to display the `TS` solver. (The same holds for any PETSc object viewer).
1967595c91d4SBarry Smith 
1968bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `PetscViewer`, `PetscViewerASCIIOpen()`
1969d763cef2SBarry Smith @*/
1970d71ae5a4SJacob Faibussowitsch PetscErrorCode TSView(TS ts, PetscViewer viewer)
1971d71ae5a4SJacob Faibussowitsch {
197219fd82e9SBarry Smith   TSType    type;
19732b0a91c0SBarry Smith   PetscBool iascii, isstring, isundials, isbinary, isdraw;
19742d53ad75SBarry Smith   DMTS      sdm;
1975e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1976536b137fSBarry Smith   PetscBool issaws;
1977f05ece33SBarry Smith #endif
1978d763cef2SBarry Smith 
1979d763cef2SBarry Smith   PetscFunctionBegin;
19800700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
19811e66621cSBarry Smith   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts), &viewer));
19820700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1983c9780b6fSBarry Smith   PetscCheckSameComm(ts, 1, viewer, 2);
1984fd16b177SBarry Smith 
19859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
19869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
19879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
19889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
1989e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
19909566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
1991f05ece33SBarry Smith #endif
199232077d6dSBarry Smith   if (iascii) {
19939566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ts, viewer));
1994efd4aadfSBarry Smith     if (ts->ops->view) {
19959566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1996dbbe0bcdSBarry Smith       PetscUseTypeMethod(ts, view, viewer);
19979566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
1998efd4aadfSBarry Smith     }
19991e66621cSBarry Smith     if (ts->max_steps < PETSC_MAX_INT) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum steps=%" PetscInt_FMT "\n", ts->max_steps));
20001e66621cSBarry Smith     if (ts->max_time < PETSC_MAX_REAL) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum time=%g\n", (double)ts->max_time));
20011e66621cSBarry Smith     if (ts->ifuncs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of I function evaluations=%" PetscInt_FMT "\n", ts->ifuncs));
20021e66621cSBarry Smith     if (ts->ijacs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of I Jacobian evaluations=%" PetscInt_FMT "\n", ts->ijacs));
20031e66621cSBarry Smith     if (ts->rhsfuncs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of RHS function evaluations=%" PetscInt_FMT "\n", ts->rhsfuncs));
20041e66621cSBarry Smith     if (ts->rhsjacs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of RHS Jacobian evaluations=%" PetscInt_FMT "\n", ts->rhsjacs));
2005efd4aadfSBarry Smith     if (ts->usessnes) {
2006efd4aadfSBarry Smith       PetscBool lin;
20071e66621cSBarry Smith       if (ts->problem_type == TS_NONLINEAR) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of nonlinear solver iterations=%" PetscInt_FMT "\n", ts->snes_its));
200863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of linear solver iterations=%" PetscInt_FMT "\n", ts->ksp_its));
20099566063dSJacob Faibussowitsch       PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes, &lin, SNESKSPONLY, SNESKSPTRANSPOSEONLY, ""));
201063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of %slinear solve failures=%" PetscInt_FMT "\n", lin ? "" : "non", ts->num_snes_failures));
2011efd4aadfSBarry Smith     }
201263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of rejected steps=%" PetscInt_FMT "\n", ts->reject));
20131e66621cSBarry Smith     if (ts->vrtol) PetscCall(PetscViewerASCIIPrintf(viewer, "  using vector of relative error tolerances, "));
20141e66621cSBarry Smith     else PetscCall(PetscViewerASCIIPrintf(viewer, "  using relative error tolerance of %g, ", (double)ts->rtol));
20151e66621cSBarry Smith     if (ts->vatol) PetscCall(PetscViewerASCIIPrintf(viewer, "  using vector of absolute error tolerances\n"));
20161e66621cSBarry Smith     else PetscCall(PetscViewerASCIIPrintf(viewer, "  using absolute error tolerance of %g\n", (double)ts->atol));
20179566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
20189566063dSJacob Faibussowitsch     PetscCall(TSAdaptView(ts->adapt, viewer));
20199566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
20200f5bd95cSBarry Smith   } else if (isstring) {
20219566063dSJacob Faibussowitsch     PetscCall(TSGetType(ts, &type));
20229566063dSJacob Faibussowitsch     PetscCall(PetscViewerStringSPrintf(viewer, " TSType: %-7.7s", type));
2023dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
202455849f57SBarry Smith   } else if (isbinary) {
202555849f57SBarry Smith     PetscInt    classid = TS_FILE_CLASSID;
202655849f57SBarry Smith     MPI_Comm    comm;
202755849f57SBarry Smith     PetscMPIInt rank;
202855849f57SBarry Smith     char        type[256];
202955849f57SBarry Smith 
20309566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
20319566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
2032dd400576SPatrick Sanan     if (rank == 0) {
20339566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
20349566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(type, ((PetscObject)ts)->type_name, 256));
20359566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, type, 256, PETSC_CHAR));
203655849f57SBarry Smith     }
2037dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
20389566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt, viewer));
20399566063dSJacob Faibussowitsch     PetscCall(DMView(ts->dm, viewer));
20409566063dSJacob Faibussowitsch     PetscCall(VecView(ts->vec_sol, viewer));
20419566063dSJacob Faibussowitsch     PetscCall(DMGetDMTS(ts->dm, &sdm));
20429566063dSJacob Faibussowitsch     PetscCall(DMTSView(sdm, viewer));
20432b0a91c0SBarry Smith   } else if (isdraw) {
20442b0a91c0SBarry Smith     PetscDraw draw;
20452b0a91c0SBarry Smith     char      str[36];
204689fd9fafSBarry Smith     PetscReal x, y, bottom, h;
20472b0a91c0SBarry Smith 
20489566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
20499566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y));
20509566063dSJacob Faibussowitsch     PetscCall(PetscStrcpy(str, "TS: "));
20519566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(str, ((PetscObject)ts)->type_name));
20529566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLACK, PETSC_DRAW_BLACK, str, NULL, &h));
205389fd9fafSBarry Smith     bottom = y - h;
20549566063dSJacob Faibussowitsch     PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom));
2055dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
20569566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt, viewer));
20579566063dSJacob Faibussowitsch     if (ts->snes) PetscCall(SNESView(ts->snes, viewer));
20589566063dSJacob Faibussowitsch     PetscCall(PetscDrawPopCurrentPoint(draw));
2059e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
2060536b137fSBarry Smith   } else if (issaws) {
2061d45a07a7SBarry Smith     PetscMPIInt rank;
20622657e9d9SBarry Smith     const char *name;
20632657e9d9SBarry Smith 
20649566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)ts, &name));
20659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
2066dd400576SPatrick Sanan     if (!((PetscObject)ts)->amsmem && rank == 0) {
2067d45a07a7SBarry Smith       char dir[1024];
2068d45a07a7SBarry Smith 
20699566063dSJacob Faibussowitsch       PetscCall(PetscObjectViewSAWs((PetscObject)ts, viewer));
20709566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/time_step", name));
2071792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, &ts->steps, 1, SAWs_READ, SAWs_INT));
20729566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/time", name));
2073792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, &ts->ptime, 1, SAWs_READ, SAWs_DOUBLE));
2074d763cef2SBarry Smith     }
2075dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
2076f05ece33SBarry Smith #endif
2077f05ece33SBarry Smith   }
207836a9e3b9SBarry Smith   if (ts->snes && ts->usessnes) {
20799566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
20809566063dSJacob Faibussowitsch     PetscCall(SNESView(ts->snes, viewer));
20819566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
208236a9e3b9SBarry Smith   }
20839566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm, &sdm));
20849566063dSJacob Faibussowitsch   PetscCall(DMTSView(sdm, viewer));
2085f05ece33SBarry Smith 
20869566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
20879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ts, TSSUNDIALS, &isundials));
20889566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
20893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2090d763cef2SBarry Smith }
2091d763cef2SBarry Smith 
2092b07ff414SBarry Smith /*@
2093d763cef2SBarry Smith    TSSetApplicationContext - Sets an optional user-defined context for
2094d763cef2SBarry Smith    the timesteppers.
2095d763cef2SBarry Smith 
2096c3339decSBarry Smith    Logically Collective
2097d763cef2SBarry Smith 
2098d763cef2SBarry Smith    Input Parameters:
2099bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
2100bcf0153eSBarry Smith -  usrP -  user context
2101daf670e6SBarry Smith 
2102d763cef2SBarry Smith    Level: intermediate
2103d763cef2SBarry Smith 
2104bcf0153eSBarry Smith    Fortran Note:
2105bcf0153eSBarry Smith     To use this from Fortran you must write a Fortran interface definition for this
2106bcf0153eSBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2107bcf0153eSBarry Smith 
2108bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetApplicationContext()`
2109d763cef2SBarry Smith @*/
2110d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetApplicationContext(TS ts, void *usrP)
2111d71ae5a4SJacob Faibussowitsch {
2112d763cef2SBarry Smith   PetscFunctionBegin;
21130700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2114d763cef2SBarry Smith   ts->user = usrP;
21153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2116d763cef2SBarry Smith }
2117d763cef2SBarry Smith 
2118b07ff414SBarry Smith /*@
2119d763cef2SBarry Smith     TSGetApplicationContext - Gets the user-defined context for the
2120bcf0153eSBarry Smith     timestepper that was set with `TSSetApplicationContext()`
2121d763cef2SBarry Smith 
2122d763cef2SBarry Smith     Not Collective
2123d763cef2SBarry Smith 
2124d763cef2SBarry Smith     Input Parameter:
2125bcf0153eSBarry Smith .   ts - the `TS` context obtained from `TSCreate()`
2126d763cef2SBarry Smith 
2127d763cef2SBarry Smith     Output Parameter:
2128d763cef2SBarry Smith .   usrP - user context
2129d763cef2SBarry Smith 
2130bcf0153eSBarry Smith     Level: intermediate
2131bcf0153eSBarry Smith 
2132bcf0153eSBarry Smith     Fortran Note:
213395452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
2134daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2135daf670e6SBarry Smith 
2136bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetApplicationContext()`
2137d763cef2SBarry Smith @*/
2138d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetApplicationContext(TS ts, void *usrP)
2139d71ae5a4SJacob Faibussowitsch {
2140d763cef2SBarry Smith   PetscFunctionBegin;
21410700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2142e71120c6SJed Brown   *(void **)usrP = ts->user;
21433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2144d763cef2SBarry Smith }
2145d763cef2SBarry Smith 
2146d763cef2SBarry Smith /*@
2147bcf0153eSBarry Smith    TSGetStepNumber - Gets the number of time steps completed.
2148d763cef2SBarry Smith 
2149d763cef2SBarry Smith    Not Collective
2150d763cef2SBarry Smith 
2151d763cef2SBarry Smith    Input Parameter:
2152bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2153d763cef2SBarry Smith 
2154d763cef2SBarry Smith    Output Parameter:
215580275a0aSLisandro Dalcin .  steps - number of steps completed so far
2156d763cef2SBarry Smith 
2157d763cef2SBarry Smith    Level: intermediate
2158d763cef2SBarry Smith 
2159bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetTime()`, `TSGetTimeStep()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`
2160d763cef2SBarry Smith @*/
2161d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetStepNumber(TS ts, PetscInt *steps)
2162d71ae5a4SJacob Faibussowitsch {
2163d763cef2SBarry Smith   PetscFunctionBegin;
21640700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
216580275a0aSLisandro Dalcin   PetscValidIntPointer(steps, 2);
216680275a0aSLisandro Dalcin   *steps = ts->steps;
21673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
216880275a0aSLisandro Dalcin }
216980275a0aSLisandro Dalcin 
217080275a0aSLisandro Dalcin /*@
217180275a0aSLisandro Dalcin    TSSetStepNumber - Sets the number of steps completed.
217280275a0aSLisandro Dalcin 
2173c3339decSBarry Smith    Logically Collective
217480275a0aSLisandro Dalcin 
217580275a0aSLisandro Dalcin    Input Parameters:
2176bcf0153eSBarry Smith +  ts - the `TS` context
217780275a0aSLisandro Dalcin -  steps - number of steps completed so far
217880275a0aSLisandro Dalcin 
2179bcf0153eSBarry Smith    Level: developer
2180bcf0153eSBarry Smith 
2181bcf0153eSBarry Smith    Note:
2182bcf0153eSBarry Smith    For most uses of the `TS` solvers the user need not explicitly call
2183bcf0153eSBarry Smith    `TSSetStepNumber()`, as the step counter is appropriately updated in
2184bcf0153eSBarry Smith    `TSSolve()`/`TSStep()`/`TSRollBack()`. Power users may call this routine to
218580275a0aSLisandro Dalcin    reinitialize timestepping by setting the step counter to zero (and time
218680275a0aSLisandro Dalcin    to the initial time) to solve a similar problem with different initial
218780275a0aSLisandro Dalcin    conditions or parameters. Other possible use case is to continue
218880275a0aSLisandro Dalcin    timestepping from a previously interrupted run in such a way that TS
218980275a0aSLisandro Dalcin    monitors will be called with a initial nonzero step counter.
219080275a0aSLisandro Dalcin 
2191bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetStepNumber()`, `TSSetTime()`, `TSSetTimeStep()`, `TSSetSolution()`
219280275a0aSLisandro Dalcin @*/
2193d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetStepNumber(TS ts, PetscInt steps)
2194d71ae5a4SJacob Faibussowitsch {
219580275a0aSLisandro Dalcin   PetscFunctionBegin;
219680275a0aSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
219780275a0aSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts, steps, 2);
21983c633725SBarry Smith   PetscCheck(steps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Step number must be non-negative");
219980275a0aSLisandro Dalcin   ts->steps = steps;
22003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2201d763cef2SBarry Smith }
2202d763cef2SBarry Smith 
2203d763cef2SBarry Smith /*@
2204d763cef2SBarry Smith    TSSetTimeStep - Allows one to reset the timestep at any time,
2205d763cef2SBarry Smith    useful for simple pseudo-timestepping codes.
2206d763cef2SBarry Smith 
2207c3339decSBarry Smith    Logically Collective
2208d763cef2SBarry Smith 
2209d763cef2SBarry Smith    Input Parameters:
2210bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
2211d763cef2SBarry Smith -  time_step - the size of the timestep
2212d763cef2SBarry Smith 
2213d763cef2SBarry Smith    Level: intermediate
2214d763cef2SBarry Smith 
2215bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSPSEUDO`, `TSGetTimeStep()`, `TSSetTime()`
2216d763cef2SBarry Smith @*/
2217d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTimeStep(TS ts, PetscReal time_step)
2218d71ae5a4SJacob Faibussowitsch {
2219d763cef2SBarry Smith   PetscFunctionBegin;
22200700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2221c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts, time_step, 2);
2222d763cef2SBarry Smith   ts->time_step = time_step;
22233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2224d763cef2SBarry Smith }
2225d763cef2SBarry Smith 
2226a43b19c4SJed Brown /*@
222749354f04SShri Abhyankar    TSSetExactFinalTime - Determines whether to adapt the final time step to
222849354f04SShri Abhyankar      match the exact final time, interpolate solution to the exact final time,
2229bcf0153eSBarry Smith      or just return at the final time `TS` computed.
2230a43b19c4SJed Brown 
2231c3339decSBarry Smith   Logically Collective
2232a43b19c4SJed Brown 
2233d8d19677SJose E. Roman    Input Parameters:
2234a43b19c4SJed Brown +   ts - the time-step context
223549354f04SShri Abhyankar -   eftopt - exact final time option
2236bcf0153eSBarry Smith .vb
2237bcf0153eSBarry Smith   TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded
2238bcf0153eSBarry Smith   TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time
2239bcf0153eSBarry Smith   TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time
2240bcf0153eSBarry Smith .ve
2241a43b19c4SJed Brown 
2242bcf0153eSBarry Smith    Options Database Key:
2243feed9e9dSBarry Smith .   -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime
2244feed9e9dSBarry Smith 
2245a43b19c4SJed Brown    Level: beginner
2246a43b19c4SJed Brown 
2247bcf0153eSBarry Smith    Note:
2248bcf0153eSBarry Smith    If you use the option `TS_EXACTFINALTIME_STEPOVER` the solution may be at a very different time
2249bcf0153eSBarry Smith    then the final time you selected.
2250bcf0153eSBarry Smith 
2251bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSExactFinalTimeOption`, `TSGetExactFinalTime()`
2252a43b19c4SJed Brown @*/
2253d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetExactFinalTime(TS ts, TSExactFinalTimeOption eftopt)
2254d71ae5a4SJacob Faibussowitsch {
2255a43b19c4SJed Brown   PetscFunctionBegin;
2256a43b19c4SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
225749354f04SShri Abhyankar   PetscValidLogicalCollectiveEnum(ts, eftopt, 2);
225849354f04SShri Abhyankar   ts->exact_final_time = eftopt;
22593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2260a43b19c4SJed Brown }
2261a43b19c4SJed Brown 
2262d763cef2SBarry Smith /*@
2263bcf0153eSBarry Smith    TSGetExactFinalTime - Gets the exact final time option set with `TSSetExactFinalTime()`
2264f6953c82SLisandro Dalcin 
2265f6953c82SLisandro Dalcin    Not Collective
2266f6953c82SLisandro Dalcin 
2267f6953c82SLisandro Dalcin    Input Parameter:
2268bcf0153eSBarry Smith .  ts - the `TS` context
2269f6953c82SLisandro Dalcin 
2270f6953c82SLisandro Dalcin    Output Parameter:
2271f6953c82SLisandro Dalcin .  eftopt - exact final time option
2272f6953c82SLisandro Dalcin 
2273f6953c82SLisandro Dalcin    Level: beginner
2274f6953c82SLisandro Dalcin 
2275bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSExactFinalTimeOption`, `TSSetExactFinalTime()`
2276f6953c82SLisandro Dalcin @*/
2277d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetExactFinalTime(TS ts, TSExactFinalTimeOption *eftopt)
2278d71ae5a4SJacob Faibussowitsch {
2279f6953c82SLisandro Dalcin   PetscFunctionBegin;
2280f6953c82SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2281f6953c82SLisandro Dalcin   PetscValidPointer(eftopt, 2);
2282f6953c82SLisandro Dalcin   *eftopt = ts->exact_final_time;
22833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2284f6953c82SLisandro Dalcin }
2285f6953c82SLisandro Dalcin 
2286f6953c82SLisandro Dalcin /*@
2287d763cef2SBarry Smith    TSGetTimeStep - Gets the current timestep size.
2288d763cef2SBarry Smith 
2289d763cef2SBarry Smith    Not Collective
2290d763cef2SBarry Smith 
2291d763cef2SBarry Smith    Input Parameter:
2292bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2293d763cef2SBarry Smith 
2294d763cef2SBarry Smith    Output Parameter:
2295d763cef2SBarry Smith .  dt - the current timestep size
2296d763cef2SBarry Smith 
2297d763cef2SBarry Smith    Level: intermediate
2298d763cef2SBarry Smith 
2299bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetTimeStep()`, `TSGetTime()`
2300d763cef2SBarry Smith @*/
2301d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeStep(TS ts, PetscReal *dt)
2302d71ae5a4SJacob Faibussowitsch {
2303d763cef2SBarry Smith   PetscFunctionBegin;
23040700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2305f7cf8827SBarry Smith   PetscValidRealPointer(dt, 2);
2306d763cef2SBarry Smith   *dt = ts->time_step;
23073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2308d763cef2SBarry Smith }
2309d763cef2SBarry Smith 
2310d8e5e3e6SSatish Balay /*@
2311d763cef2SBarry Smith    TSGetSolution - Returns the solution at the present timestep. It
2312d763cef2SBarry Smith    is valid to call this routine inside the function that you are evaluating
2313d763cef2SBarry Smith    in order to move to the new timestep. This vector not changed until
2314d763cef2SBarry Smith    the solution at the next timestep has been calculated.
2315d763cef2SBarry Smith 
2316bcf0153eSBarry Smith    Not Collective, but v returned is parallel if ts is parallel
2317d763cef2SBarry Smith 
2318d763cef2SBarry Smith    Input Parameter:
2319bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2320d763cef2SBarry Smith 
2321d763cef2SBarry Smith    Output Parameter:
2322d763cef2SBarry Smith .  v - the vector containing the solution
2323d763cef2SBarry Smith 
2324d763cef2SBarry Smith    Level: intermediate
2325d763cef2SBarry Smith 
2326bcf0153eSBarry Smith    Note:
2327bcf0153eSBarry Smith    If you used `TSSetExactFinalTime`(ts,`TS_EXACTFINALTIME_MATCHSTEP`); this does not return the solution at the requested
2328bcf0153eSBarry Smith    final time. It returns the solution at the next timestep.
2329d763cef2SBarry Smith 
2330bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetTimeStep()`, `TSGetTime()`, `TSGetSolveTime()`, `TSGetSolutionComponents()`, `TSSetSolutionFunction()`
2331d763cef2SBarry Smith @*/
2332d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSolution(TS ts, Vec *v)
2333d71ae5a4SJacob Faibussowitsch {
2334d763cef2SBarry Smith   PetscFunctionBegin;
23350700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
23364482741eSBarry Smith   PetscValidPointer(v, 2);
23378737fe31SLisandro Dalcin   *v = ts->vec_sol;
23383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2339d763cef2SBarry Smith }
2340d763cef2SBarry Smith 
234103fe5f5eSDebojyoti Ghosh /*@
2342b2bf4f3aSDebojyoti Ghosh    TSGetSolutionComponents - Returns any solution components at the present
234303fe5f5eSDebojyoti Ghosh    timestep, if available for the time integration method being used.
2344b2bf4f3aSDebojyoti Ghosh    Solution components are quantities that share the same size and
234503fe5f5eSDebojyoti Ghosh    structure as the solution vector.
234603fe5f5eSDebojyoti Ghosh 
2347bcf0153eSBarry Smith    Not Collective, but v returned is parallel if ts is parallel
234803fe5f5eSDebojyoti Ghosh 
234903fe5f5eSDebojyoti Ghosh    Parameters :
2350bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()` (input parameter).
2351f3fa974cSJacob Faibussowitsch .  n - If v is NULL, then the number of solution components is
2352b2bf4f3aSDebojyoti Ghosh        returned through n, else the n-th solution component is
235303fe5f5eSDebojyoti Ghosh        returned in v.
2354a2b725a8SWilliam Gropp -  v - the vector containing the n-th solution component
2355f3fa974cSJacob Faibussowitsch        (may be NULL to use this function to find out
2356b2bf4f3aSDebojyoti Ghosh         the number of solutions components).
235703fe5f5eSDebojyoti Ghosh 
23584cdd57e5SDebojyoti Ghosh    Level: advanced
235903fe5f5eSDebojyoti Ghosh 
2360bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetSolution()`
236103fe5f5eSDebojyoti Ghosh @*/
2362d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSolutionComponents(TS ts, PetscInt *n, Vec *v)
2363d71ae5a4SJacob Faibussowitsch {
236403fe5f5eSDebojyoti Ghosh   PetscFunctionBegin;
236503fe5f5eSDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2366b2bf4f3aSDebojyoti Ghosh   if (!ts->ops->getsolutioncomponents) *n = 0;
2367dbbe0bcdSBarry Smith   else PetscUseTypeMethod(ts, getsolutioncomponents, n, v);
23683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
236903fe5f5eSDebojyoti Ghosh }
237003fe5f5eSDebojyoti Ghosh 
23714cdd57e5SDebojyoti Ghosh /*@
23724cdd57e5SDebojyoti Ghosh    TSGetAuxSolution - Returns an auxiliary solution at the present
23734cdd57e5SDebojyoti Ghosh    timestep, if available for the time integration method being used.
23744cdd57e5SDebojyoti Ghosh 
2375bcf0153eSBarry Smith    Not Collective, but v returned is parallel if ts is parallel
23764cdd57e5SDebojyoti Ghosh 
23774cdd57e5SDebojyoti Ghosh    Parameters :
2378bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()` (input parameter).
2379a2b725a8SWilliam Gropp -  v - the vector containing the auxiliary solution
23804cdd57e5SDebojyoti Ghosh 
23814cdd57e5SDebojyoti Ghosh    Level: intermediate
23824cdd57e5SDebojyoti Ghosh 
2383bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetSolution()`
23844cdd57e5SDebojyoti Ghosh @*/
2385d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetAuxSolution(TS ts, Vec *v)
2386d71ae5a4SJacob Faibussowitsch {
23874cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
23884cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2389dbbe0bcdSBarry Smith   if (ts->ops->getauxsolution) PetscUseTypeMethod(ts, getauxsolution, v);
23901e66621cSBarry Smith   else PetscCall(VecZeroEntries(*v));
23913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23924cdd57e5SDebojyoti Ghosh }
23934cdd57e5SDebojyoti Ghosh 
23944cdd57e5SDebojyoti Ghosh /*@
23954cdd57e5SDebojyoti Ghosh    TSGetTimeError - Returns the estimated error vector, if the chosen
2396bcf0153eSBarry Smith    `TSType` has an error estimation functionality and `TSSetTimeError()` was called
23974cdd57e5SDebojyoti Ghosh 
2398bcf0153eSBarry Smith    Not Collective, but v returned is parallel if ts is parallel
23999657682dSDebojyoti Ghosh 
24004cdd57e5SDebojyoti Ghosh    Parameters :
2401bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()` (input parameter).
2402657c1e31SEmil Constantinescu .  n - current estimate (n=0) or previous one (n=-1)
2403a2b725a8SWilliam Gropp -  v - the vector containing the error (same size as the solution).
24044cdd57e5SDebojyoti Ghosh 
24054cdd57e5SDebojyoti Ghosh    Level: intermediate
24064cdd57e5SDebojyoti Ghosh 
2407bcf0153eSBarry Smith    Note:
2408bcf0153eSBarry Smith    MUST call after `TSSetUp()`
24094cdd57e5SDebojyoti Ghosh 
2410bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSGetSolution()`, `TSSetTimeError()`
24114cdd57e5SDebojyoti Ghosh @*/
2412d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeError(TS ts, PetscInt n, Vec *v)
2413d71ae5a4SJacob Faibussowitsch {
24144cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
24154cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2416dbbe0bcdSBarry Smith   if (ts->ops->gettimeerror) PetscUseTypeMethod(ts, gettimeerror, n, v);
24171e66621cSBarry Smith   else PetscCall(VecZeroEntries(*v));
24183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24194cdd57e5SDebojyoti Ghosh }
24204cdd57e5SDebojyoti Ghosh 
242157df6a1bSDebojyoti Ghosh /*@
242257df6a1bSDebojyoti Ghosh    TSSetTimeError - Sets the estimated error vector, if the chosen
2423bcf0153eSBarry Smith    `TSType` has an error estimation functionality. This can be used
242457df6a1bSDebojyoti Ghosh    to restart such a time integrator with a given error vector.
242557df6a1bSDebojyoti Ghosh 
2426bcf0153eSBarry Smith    Not Collective, but v returned is parallel if ts is parallel
242757df6a1bSDebojyoti Ghosh 
242857df6a1bSDebojyoti Ghosh    Parameters :
2429bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()` (input parameter).
2430a2b725a8SWilliam Gropp -  v - the vector containing the error (same size as the solution).
243157df6a1bSDebojyoti Ghosh 
243257df6a1bSDebojyoti Ghosh    Level: intermediate
243357df6a1bSDebojyoti Ghosh 
2434bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetSolution()`, `TSGetTimeError)`
243557df6a1bSDebojyoti Ghosh @*/
2436d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTimeError(TS ts, Vec v)
2437d71ae5a4SJacob Faibussowitsch {
243857df6a1bSDebojyoti Ghosh   PetscFunctionBegin;
243957df6a1bSDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
24403c633725SBarry Smith   PetscCheck(ts->setupcalled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetUp() first");
2441dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, settimeerror, v);
24423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
244357df6a1bSDebojyoti Ghosh }
244457df6a1bSDebojyoti Ghosh 
2445bdad233fSMatthew Knepley /* ----- Routines to initialize and destroy a timestepper ---- */
2446d8e5e3e6SSatish Balay /*@
2447bdad233fSMatthew Knepley   TSSetProblemType - Sets the type of problem to be solved.
2448d763cef2SBarry Smith 
2449bdad233fSMatthew Knepley   Not collective
2450d763cef2SBarry Smith 
2451bdad233fSMatthew Knepley   Input Parameters:
2452bcf0153eSBarry Smith + ts   - The `TS`
2453bcf0153eSBarry Smith - type - One of `TS_LINEAR`, `TS_NONLINEAR` where these types refer to problems of the forms
2454d763cef2SBarry Smith .vb
24550910c330SBarry Smith          U_t - A U = 0      (linear)
24560910c330SBarry Smith          U_t - A(t) U = 0   (linear)
24570910c330SBarry Smith          F(t,U,U_t) = 0     (nonlinear)
2458d763cef2SBarry Smith .ve
2459d763cef2SBarry Smith 
2460d763cef2SBarry Smith    Level: beginner
2461d763cef2SBarry Smith 
2462bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSetUp()`, `TSProblemType`, `TS`
2463d763cef2SBarry Smith @*/
2464d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetProblemType(TS ts, TSProblemType type)
2465d71ae5a4SJacob Faibussowitsch {
2466d763cef2SBarry Smith   PetscFunctionBegin;
24670700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2468bdad233fSMatthew Knepley   ts->problem_type = type;
24699e2a6581SJed Brown   if (type == TS_LINEAR) {
24709e2a6581SJed Brown     SNES snes;
24719566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
24729566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes, SNESKSPONLY));
24739e2a6581SJed Brown   }
24743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2475d763cef2SBarry Smith }
2476d763cef2SBarry Smith 
2477bdad233fSMatthew Knepley /*@C
2478bdad233fSMatthew Knepley   TSGetProblemType - Gets the type of problem to be solved.
2479bdad233fSMatthew Knepley 
2480bdad233fSMatthew Knepley   Not collective
2481bdad233fSMatthew Knepley 
2482bdad233fSMatthew Knepley   Input Parameter:
2483bcf0153eSBarry Smith . ts   - The `TS`
2484bdad233fSMatthew Knepley 
2485bdad233fSMatthew Knepley   Output Parameter:
2486bcf0153eSBarry Smith . type - One of `TS_LINEAR`, `TS_NONLINEAR` where these types refer to problems of the forms
2487bdad233fSMatthew Knepley .vb
2488089b2837SJed Brown          M U_t = A U
2489089b2837SJed Brown          M(t) U_t = A(t) U
2490b5abc632SBarry Smith          F(t,U,U_t)
2491bdad233fSMatthew Knepley .ve
2492bdad233fSMatthew Knepley 
2493bdad233fSMatthew Knepley    Level: beginner
2494bdad233fSMatthew Knepley 
2495bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSetUp()`, `TSProblemType`, `TS`
2496bdad233fSMatthew Knepley @*/
2497d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type)
2498d71ae5a4SJacob Faibussowitsch {
2499bdad233fSMatthew Knepley   PetscFunctionBegin;
25000700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
25014482741eSBarry Smith   PetscValidIntPointer(type, 2);
2502bdad233fSMatthew Knepley   *type = ts->problem_type;
25033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2504bdad233fSMatthew Knepley }
2505d763cef2SBarry Smith 
2506303a5415SBarry Smith /*
2507303a5415SBarry 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()
2508303a5415SBarry Smith */
2509d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSSetExactFinalTimeDefault(TS ts)
2510d71ae5a4SJacob Faibussowitsch {
2511303a5415SBarry Smith   PetscBool isnone;
2512303a5415SBarry Smith 
2513303a5415SBarry Smith   PetscFunctionBegin;
25149566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
25159566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
2516303a5415SBarry Smith 
25179566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ts->adapt, TSADAPTNONE, &isnone));
25181e66621cSBarry Smith   if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP;
25191e66621cSBarry Smith   else if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) ts->exact_final_time = TS_EXACTFINALTIME_INTERPOLATE;
25203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2521303a5415SBarry Smith }
2522303a5415SBarry Smith 
2523d763cef2SBarry Smith /*@
2524303a5415SBarry Smith    TSSetUp - Sets up the internal data structures for the later use of a timestepper.
2525d763cef2SBarry Smith 
2526c3339decSBarry Smith    Collective
2527d763cef2SBarry Smith 
2528d763cef2SBarry Smith    Input Parameter:
2529bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2530d763cef2SBarry Smith 
2531d763cef2SBarry Smith    Level: advanced
2532d763cef2SBarry Smith 
2533bcf0153eSBarry Smith    Note:
2534bcf0153eSBarry Smith    For basic use of the `TS` solvers the user need not explicitly call
2535bcf0153eSBarry Smith    `TSSetUp()`, since these actions will automatically occur during
2536bcf0153eSBarry Smith    the call to `TSStep()` or `TSSolve()`.  However, if one wishes to control this
2537bcf0153eSBarry Smith    phase separately, `TSSetUp()` should be called after `TSCreate()`
2538bcf0153eSBarry Smith    and optional routines of the form TSSetXXX(), but before `TSStep()` and `TSSolve()`.
2539bcf0153eSBarry Smith 
2540bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSCreate()`, `TS`, `TSStep()`, `TSDestroy()`, `TSSolve()`
2541d763cef2SBarry Smith @*/
2542d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetUp(TS ts)
2543d71ae5a4SJacob Faibussowitsch {
25446c6b9e74SPeter Brune   DM dm;
25456c6b9e74SPeter Brune   PetscErrorCode (*func)(SNES, Vec, Vec, void *);
2546d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *);
2547cd11d68dSLisandro Dalcin   TSIFunction   ifun;
25486c6b9e74SPeter Brune   TSIJacobian   ijac;
2549efe9872eSLisandro Dalcin   TSI2Jacobian  i2jac;
25506c6b9e74SPeter Brune   TSRHSJacobian rhsjac;
2551d763cef2SBarry Smith 
2552d763cef2SBarry Smith   PetscFunctionBegin;
25530700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
25543ba16761SJacob Faibussowitsch   if (ts->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
2555277b19d0SLisandro Dalcin 
25567adad957SLisandro Dalcin   if (!((PetscObject)ts)->type_name) {
25579566063dSJacob Faibussowitsch     PetscCall(TSGetIFunction(ts, NULL, &ifun, NULL));
25589566063dSJacob Faibussowitsch     PetscCall(TSSetType(ts, ifun ? TSBEULER : TSEULER));
2559d763cef2SBarry Smith   }
2560277b19d0SLisandro Dalcin 
25611a638600SStefano Zampini   if (!ts->vec_sol) {
25621e66621cSBarry Smith     PetscCheck(ts->dm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetSolution() first");
25639566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(ts->dm, &ts->vec_sol));
25641a638600SStefano Zampini   }
2565277b19d0SLisandro Dalcin 
25664a658b32SHong Zhang   if (ts->tspan) {
25671e66621cSBarry Smith     if (!ts->tspan->vecs_sol) PetscCall(VecDuplicateVecs(ts->vec_sol, ts->tspan->num_span_times, &ts->tspan->vecs_sol));
25684a658b32SHong Zhang   }
2569298bade4SHong Zhang   if (!ts->Jacp && ts->Jacprhs) { /* IJacobianP shares the same matrix with RHSJacobianP if only RHSJacobianP is provided */
25709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)ts->Jacprhs));
2571298bade4SHong Zhang     ts->Jacp = ts->Jacprhs;
2572298bade4SHong Zhang   }
2573298bade4SHong Zhang 
2574cd4cee2dSHong Zhang   if (ts->quadraturets) {
25759566063dSJacob Faibussowitsch     PetscCall(TSSetUp(ts->quadraturets));
25769566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
25779566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->quadraturets->vec_sol, &ts->vec_costintegrand));
2578cd4cee2dSHong Zhang   }
2579cd4cee2dSHong Zhang 
25809566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, NULL, NULL, &rhsjac, NULL));
2581f23ba4b3SHong Zhang   if (rhsjac == TSComputeRHSJacobianConstant) {
2582e1244c69SJed Brown     Mat  Amat, Pmat;
2583e1244c69SJed Brown     SNES snes;
25849566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
25859566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, &Amat, &Pmat, NULL, NULL));
2586e1244c69SJed Brown     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2587e1244c69SJed Brown      * have displaced the RHS matrix */
2588971015bcSStefano Zampini     if (Amat && Amat == ts->Arhs) {
2589abc0d4abSBarry 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 */
25909566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat));
25919566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes, Amat, NULL, NULL, NULL));
25929566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Amat));
2593e1244c69SJed Brown     }
2594971015bcSStefano Zampini     if (Pmat && Pmat == ts->Brhs) {
25959566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Brhs, MAT_COPY_VALUES, &Pmat));
25969566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes, NULL, Pmat, NULL, NULL));
25979566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Pmat));
2598e1244c69SJed Brown     }
2599e1244c69SJed Brown   }
26002ffb9264SLisandro Dalcin 
26019566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
26029566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
26032ffb9264SLisandro Dalcin 
2604dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, setup);
2605277b19d0SLisandro Dalcin 
26069566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
26072ffb9264SLisandro Dalcin 
2608a6772fa2SLisandro Dalcin   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
26096c6b9e74SPeter Brune      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
26106c6b9e74SPeter Brune    */
26119566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
26129566063dSJacob Faibussowitsch   PetscCall(DMSNESGetFunction(dm, &func, NULL));
26131e66621cSBarry Smith   if (!func) PetscCall(DMSNESSetFunction(dm, SNESTSFormFunction, ts));
26141e66621cSBarry Smith 
2615a6772fa2SLisandro 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.
26166c6b9e74SPeter Brune      Otherwise, the SNES will use coloring internally to form the Jacobian.
26176c6b9e74SPeter Brune    */
26189566063dSJacob Faibussowitsch   PetscCall(DMSNESGetJacobian(dm, &jac, NULL));
26199566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijac, NULL));
26209566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, &i2jac, NULL));
26219566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjac, NULL));
26221e66621cSBarry Smith   if (!jac && (ijac || i2jac || rhsjac)) PetscCall(DMSNESSetJacobian(dm, SNESTSFormJacobian, ts));
2623c0517034SDebojyoti Ghosh 
2624c0517034SDebojyoti Ghosh   /* if time integration scheme has a starting method, call it */
2625dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, startingmethod);
2626c0517034SDebojyoti Ghosh 
2627277b19d0SLisandro Dalcin   ts->setupcalled = PETSC_TRUE;
26283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2629277b19d0SLisandro Dalcin }
2630277b19d0SLisandro Dalcin 
2631f6a906c0SBarry Smith /*@
2632bcf0153eSBarry Smith    TSReset - Resets a `TS` context and removes any allocated `Vec`s and `Mat`s.
2633277b19d0SLisandro Dalcin 
2634c3339decSBarry Smith    Collective
2635277b19d0SLisandro Dalcin 
2636277b19d0SLisandro Dalcin    Input Parameter:
2637bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2638277b19d0SLisandro Dalcin 
2639277b19d0SLisandro Dalcin    Level: beginner
2640277b19d0SLisandro Dalcin 
2641bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSCreate()`, `TSSetup()`, `TSDestroy()`
2642277b19d0SLisandro Dalcin @*/
2643d71ae5a4SJacob Faibussowitsch PetscErrorCode TSReset(TS ts)
2644d71ae5a4SJacob Faibussowitsch {
26451d06f6b3SHong Zhang   TS_RHSSplitLink ilink = ts->tsrhssplit, next;
2646277b19d0SLisandro Dalcin 
2647277b19d0SLisandro Dalcin   PetscFunctionBegin;
2648277b19d0SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2649b18ea86cSHong Zhang 
2650dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, reset);
26519566063dSJacob Faibussowitsch   if (ts->snes) PetscCall(SNESReset(ts->snes));
26529566063dSJacob Faibussowitsch   if (ts->adapt) PetscCall(TSAdaptReset(ts->adapt));
2653bbd56ea5SKarl Rupp 
26549566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Arhs));
26559566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Brhs));
26569566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->Frhs));
26579566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
26589566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
26599566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vatol));
26609566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vrtol));
26619566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(ts->nwork, &ts->work));
2662bbd56ea5SKarl Rupp 
26639566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacprhs));
26649566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacp));
26651baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardReset(ts));
2666cd4cee2dSHong Zhang   if (ts->quadraturets) {
26679566063dSJacob Faibussowitsch     PetscCall(TSReset(ts->quadraturets));
26689566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
2669cd4cee2dSHong Zhang   }
26701d06f6b3SHong Zhang   while (ilink) {
26711d06f6b3SHong Zhang     next = ilink->next;
26729566063dSJacob Faibussowitsch     PetscCall(TSDestroy(&ilink->ts));
26739566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink->splitname));
26749566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ilink->is));
26759566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink));
26761d06f6b3SHong Zhang     ilink = next;
267787f4e208SHong Zhang   }
26786bf673ebSJoe Pusztay   ts->tsrhssplit     = NULL;
2679545aaa6fSHong Zhang   ts->num_rhs_splits = 0;
26804a658b32SHong Zhang   if (ts->tspan) {
26814a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan->span_times));
26824a658b32SHong Zhang     PetscCall(VecDestroyVecs(ts->tspan->num_span_times, &ts->tspan->vecs_sol));
26834a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan));
26844a658b32SHong Zhang   }
2685277b19d0SLisandro Dalcin   ts->setupcalled = PETSC_FALSE;
26863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2687d763cef2SBarry Smith }
2688d763cef2SBarry Smith 
26891fb7b255SJunchao Zhang /*@C
2690d763cef2SBarry Smith    TSDestroy - Destroys the timestepper context that was created
2691bcf0153eSBarry Smith    with `TSCreate()`.
2692d763cef2SBarry Smith 
2693c3339decSBarry Smith    Collective
2694d763cef2SBarry Smith 
2695d763cef2SBarry Smith    Input Parameter:
2696bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2697d763cef2SBarry Smith 
2698d763cef2SBarry Smith    Level: beginner
2699d763cef2SBarry Smith 
2700bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSCreate()`, `TSSetUp()`, `TSSolve()`
2701d763cef2SBarry Smith @*/
2702d71ae5a4SJacob Faibussowitsch PetscErrorCode TSDestroy(TS *ts)
2703d71ae5a4SJacob Faibussowitsch {
2704d763cef2SBarry Smith   PetscFunctionBegin;
27053ba16761SJacob Faibussowitsch   if (!*ts) PetscFunctionReturn(PETSC_SUCCESS);
2706ecf68647SHong Zhang   PetscValidHeaderSpecific(*ts, TS_CLASSID, 1);
27079371c9d4SSatish Balay   if (--((PetscObject)(*ts))->refct > 0) {
27089371c9d4SSatish Balay     *ts = NULL;
27093ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
27109371c9d4SSatish Balay   }
2711d763cef2SBarry Smith 
27129566063dSJacob Faibussowitsch   PetscCall(TSReset(*ts));
27139566063dSJacob Faibussowitsch   PetscCall(TSAdjointReset(*ts));
27141e66621cSBarry Smith   if ((*ts)->forward_solve) PetscCall(TSForwardReset(*ts));
27151e66621cSBarry Smith 
2716e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
27179566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*ts));
2718dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ts), destroy);
27196d4c513bSLisandro Dalcin 
27209566063dSJacob Faibussowitsch   PetscCall(TSTrajectoryDestroy(&(*ts)->trajectory));
2721bc952696SBarry Smith 
27229566063dSJacob Faibussowitsch   PetscCall(TSAdaptDestroy(&(*ts)->adapt));
27239566063dSJacob Faibussowitsch   PetscCall(TSEventDestroy(&(*ts)->event));
27246427ac75SLisandro Dalcin 
27259566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&(*ts)->snes));
27269566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&(*ts)->dm));
27279566063dSJacob Faibussowitsch   PetscCall(TSMonitorCancel((*ts)));
27289566063dSJacob Faibussowitsch   PetscCall(TSAdjointMonitorCancel((*ts)));
27296d4c513bSLisandro Dalcin 
27309566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&(*ts)->quadraturets));
27319566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ts));
27323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2733d763cef2SBarry Smith }
2734d763cef2SBarry Smith 
2735d8e5e3e6SSatish Balay /*@
2736bcf0153eSBarry Smith    TSGetSNES - Returns the `SNES` (nonlinear solver) associated with
2737bcf0153eSBarry Smith    a `TS` (timestepper) context. Valid only for nonlinear problems.
2738d763cef2SBarry Smith 
2739bcf0153eSBarry Smith    Not Collective, but snes is parallel if ts is parallel
2740d763cef2SBarry Smith 
2741d763cef2SBarry Smith    Input Parameter:
2742bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2743d763cef2SBarry Smith 
2744d763cef2SBarry Smith    Output Parameter:
2745d763cef2SBarry Smith .  snes - the nonlinear solver context
2746d763cef2SBarry Smith 
2747d763cef2SBarry Smith    Level: beginner
2748d763cef2SBarry Smith 
2749bcf0153eSBarry Smith    Notes:
2750bcf0153eSBarry Smith    The user can then directly manipulate the `SNES` context to set various
2751bcf0153eSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
2752bcf0153eSBarry Smith    `KSP`, and `PC` contexts as well.
2753bcf0153eSBarry Smith 
2754bcf0153eSBarry Smith    `TSGetSNES()` does not work for integrators that do not use `SNES`; in
2755bcf0153eSBarry Smith    this case `TSGetSNES()` returns NULL in snes.
2756bcf0153eSBarry Smith 
2757bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `SNES`, `TSCreate()`, `TSSetUp()`, `TSSolve()`
2758d763cef2SBarry Smith @*/
2759d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSNES(TS ts, SNES *snes)
2760d71ae5a4SJacob Faibussowitsch {
2761d763cef2SBarry Smith   PetscFunctionBegin;
27620700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
27634482741eSBarry Smith   PetscValidPointer(snes, 2);
2764d372ba47SLisandro Dalcin   if (!ts->snes) {
27659566063dSJacob Faibussowitsch     PetscCall(SNESCreate(PetscObjectComm((PetscObject)ts), &ts->snes));
27669566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)ts->snes, ((PetscObject)ts)->options));
27679566063dSJacob Faibussowitsch     PetscCall(SNESSetFunction(ts->snes, NULL, SNESTSFormFunction, ts));
27689566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->snes, (PetscObject)ts, 1));
27699566063dSJacob Faibussowitsch     if (ts->dm) PetscCall(SNESSetDM(ts->snes, ts->dm));
27701e66621cSBarry Smith     if (ts->problem_type == TS_LINEAR) PetscCall(SNESSetType(ts->snes, SNESKSPONLY));
2771d372ba47SLisandro Dalcin   }
2772d763cef2SBarry Smith   *snes = ts->snes;
27733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2774d763cef2SBarry Smith }
2775d763cef2SBarry Smith 
2776deb2cd25SJed Brown /*@
2777bcf0153eSBarry Smith    TSSetSNES - Set the `SNES` (nonlinear solver) to be used by the timestepping context
2778deb2cd25SJed Brown 
2779deb2cd25SJed Brown    Collective
2780deb2cd25SJed Brown 
2781d8d19677SJose E. Roman    Input Parameters:
2782bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
2783deb2cd25SJed Brown -  snes - the nonlinear solver context
2784deb2cd25SJed Brown 
2785deb2cd25SJed Brown    Level: developer
2786deb2cd25SJed Brown 
2787bcf0153eSBarry Smith    Note:
2788bcf0153eSBarry Smith    Most users should have the `TS` created by calling `TSGetSNES()`
2789bcf0153eSBarry Smith 
2790bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `SNES`, `TSCreate()`, `TSSetUp()`, `TSSolve()`, `TSGetSNES()`
2791deb2cd25SJed Brown @*/
2792d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetSNES(TS ts, SNES snes)
2793d71ae5a4SJacob Faibussowitsch {
2794d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
2795deb2cd25SJed Brown 
2796deb2cd25SJed Brown   PetscFunctionBegin;
2797deb2cd25SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2798deb2cd25SJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 2);
27999566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)snes));
28009566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&ts->snes));
2801bbd56ea5SKarl Rupp 
2802deb2cd25SJed Brown   ts->snes = snes;
2803bbd56ea5SKarl Rupp 
28049566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(ts->snes, NULL, SNESTSFormFunction, ts));
28059566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(ts->snes, NULL, NULL, &func, NULL));
28061e66621cSBarry Smith   if (func == SNESTSFormJacobian) PetscCall(SNESSetJacobian(ts->snes, NULL, NULL, SNESTSFormJacobian, ts));
28073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2808deb2cd25SJed Brown }
2809deb2cd25SJed Brown 
2810d8e5e3e6SSatish Balay /*@
2811bcf0153eSBarry Smith    TSGetKSP - Returns the `KSP` (linear solver) associated with
2812bcf0153eSBarry Smith    a `TS` (timestepper) context.
2813d763cef2SBarry Smith 
2814bcf0153eSBarry Smith    Not Collective, but ksp is parallel if ts is parallel
2815d763cef2SBarry Smith 
2816d763cef2SBarry Smith    Input Parameter:
2817bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2818d763cef2SBarry Smith 
2819d763cef2SBarry Smith    Output Parameter:
282094b7f48cSBarry Smith .  ksp - the nonlinear solver context
2821d763cef2SBarry Smith 
2822d763cef2SBarry Smith    Level: beginner
2823d763cef2SBarry Smith 
2824bcf0153eSBarry Smith    Notes:
2825bcf0153eSBarry Smith    The user can then directly manipulate the `KSP` context to set various
2826bcf0153eSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
2827bcf0153eSBarry Smith    `PC` context as well.
2828bcf0153eSBarry Smith 
2829bcf0153eSBarry Smith    `TSGetKSP()` does not work for integrators that do not use `KSP`;
2830bcf0153eSBarry Smith    in this case `TSGetKSP()` returns NULL in ksp.
2831bcf0153eSBarry Smith 
2832bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `SNES`, `KSP`, `TSCreate()`, `TSSetUp()`, `TSSolve()`, `TSGetSNES()`
2833d763cef2SBarry Smith @*/
2834d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetKSP(TS ts, KSP *ksp)
2835d71ae5a4SJacob Faibussowitsch {
2836089b2837SJed Brown   SNES snes;
2837d372ba47SLisandro Dalcin 
2838d763cef2SBarry Smith   PetscFunctionBegin;
28390700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
28404482741eSBarry Smith   PetscValidPointer(ksp, 2);
28413c633725SBarry Smith   PetscCheck(((PetscObject)ts)->type_name, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "KSP is not created yet. Call TSSetType() first");
28423c633725SBarry Smith   PetscCheck(ts->problem_type == TS_LINEAR, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Linear only; use TSGetSNES()");
28439566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
28449566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, ksp));
28453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2846d763cef2SBarry Smith }
2847d763cef2SBarry Smith 
2848d763cef2SBarry Smith /* ----------- Routines to set solver parameters ---------- */
2849d763cef2SBarry Smith 
2850adb62b0dSMatthew Knepley /*@
2851618ce8baSLisandro Dalcin    TSSetMaxSteps - Sets the maximum number of steps to use.
2852618ce8baSLisandro Dalcin 
2853c3339decSBarry Smith    Logically Collective
2854618ce8baSLisandro Dalcin 
2855618ce8baSLisandro Dalcin    Input Parameters:
2856bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
2857618ce8baSLisandro Dalcin -  maxsteps - maximum number of steps to use
2858618ce8baSLisandro Dalcin 
2859bcf0153eSBarry Smith    Options Database Key:
2860618ce8baSLisandro Dalcin .  -ts_max_steps <maxsteps> - Sets maxsteps
2861618ce8baSLisandro Dalcin 
2862618ce8baSLisandro Dalcin    Level: intermediate
2863618ce8baSLisandro Dalcin 
2864bcf0153eSBarry Smith    Note:
2865bcf0153eSBarry Smith    The default maximum number of steps is 5000
2866bcf0153eSBarry Smith 
2867bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetMaxSteps()`, `TSSetMaxTime()`, `TSSetExactFinalTime()`
2868618ce8baSLisandro Dalcin @*/
2869d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxSteps(TS ts, PetscInt maxsteps)
2870d71ae5a4SJacob Faibussowitsch {
2871618ce8baSLisandro Dalcin   PetscFunctionBegin;
2872618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2873618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts, maxsteps, 2);
28743c633725SBarry Smith   PetscCheck(maxsteps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of steps must be non-negative");
2875618ce8baSLisandro Dalcin   ts->max_steps = maxsteps;
28763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2877618ce8baSLisandro Dalcin }
2878618ce8baSLisandro Dalcin 
2879618ce8baSLisandro Dalcin /*@
2880618ce8baSLisandro Dalcin    TSGetMaxSteps - Gets the maximum number of steps to use.
2881618ce8baSLisandro Dalcin 
2882618ce8baSLisandro Dalcin    Not Collective
2883618ce8baSLisandro Dalcin 
2884618ce8baSLisandro Dalcin    Input Parameters:
2885bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2886618ce8baSLisandro Dalcin 
2887618ce8baSLisandro Dalcin    Output Parameter:
2888618ce8baSLisandro Dalcin .  maxsteps - maximum number of steps to use
2889618ce8baSLisandro Dalcin 
2890618ce8baSLisandro Dalcin    Level: advanced
2891618ce8baSLisandro Dalcin 
2892bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetMaxSteps()`, `TSGetMaxTime()`, `TSSetMaxTime()`
2893618ce8baSLisandro Dalcin @*/
2894d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetMaxSteps(TS ts, PetscInt *maxsteps)
2895d71ae5a4SJacob Faibussowitsch {
2896618ce8baSLisandro Dalcin   PetscFunctionBegin;
2897618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2898618ce8baSLisandro Dalcin   PetscValidIntPointer(maxsteps, 2);
2899618ce8baSLisandro Dalcin   *maxsteps = ts->max_steps;
29003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2901618ce8baSLisandro Dalcin }
2902618ce8baSLisandro Dalcin 
2903618ce8baSLisandro Dalcin /*@
2904618ce8baSLisandro Dalcin    TSSetMaxTime - Sets the maximum (or final) time for timestepping.
2905618ce8baSLisandro Dalcin 
2906c3339decSBarry Smith    Logically Collective
2907618ce8baSLisandro Dalcin 
2908618ce8baSLisandro Dalcin    Input Parameters:
2909bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
2910618ce8baSLisandro Dalcin -  maxtime - final time to step to
2911618ce8baSLisandro Dalcin 
2912bcf0153eSBarry Smith    Options Database Key:
2913ef85077eSLisandro Dalcin .  -ts_max_time <maxtime> - Sets maxtime
2914618ce8baSLisandro Dalcin 
2915bcf0153eSBarry Smith    Level: intermediate
2916bcf0153eSBarry Smith 
2917618ce8baSLisandro Dalcin    Notes:
2918618ce8baSLisandro Dalcin    The default maximum time is 5.0
2919618ce8baSLisandro Dalcin 
2920bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetMaxTime()`, `TSSetMaxSteps()`, `TSSetExactFinalTime()`
2921618ce8baSLisandro Dalcin @*/
2922d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxTime(TS ts, PetscReal maxtime)
2923d71ae5a4SJacob Faibussowitsch {
2924618ce8baSLisandro Dalcin   PetscFunctionBegin;
2925618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2926618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveReal(ts, maxtime, 2);
2927618ce8baSLisandro Dalcin   ts->max_time = maxtime;
29283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2929618ce8baSLisandro Dalcin }
2930618ce8baSLisandro Dalcin 
2931618ce8baSLisandro Dalcin /*@
2932618ce8baSLisandro Dalcin    TSGetMaxTime - Gets the maximum (or final) time for timestepping.
2933618ce8baSLisandro Dalcin 
2934618ce8baSLisandro Dalcin    Not Collective
2935618ce8baSLisandro Dalcin 
2936618ce8baSLisandro Dalcin    Input Parameters:
2937bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
2938618ce8baSLisandro Dalcin 
2939618ce8baSLisandro Dalcin    Output Parameter:
2940618ce8baSLisandro Dalcin .  maxtime - final time to step to
2941618ce8baSLisandro Dalcin 
2942618ce8baSLisandro Dalcin    Level: advanced
2943618ce8baSLisandro Dalcin 
2944bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetMaxTime()`, `TSGetMaxSteps()`, `TSSetMaxSteps()`
2945618ce8baSLisandro Dalcin @*/
2946d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetMaxTime(TS ts, PetscReal *maxtime)
2947d71ae5a4SJacob Faibussowitsch {
2948618ce8baSLisandro Dalcin   PetscFunctionBegin;
2949618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2950618ce8baSLisandro Dalcin   PetscValidRealPointer(maxtime, 2);
2951618ce8baSLisandro Dalcin   *maxtime = ts->max_time;
29523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2953618ce8baSLisandro Dalcin }
2954618ce8baSLisandro Dalcin 
2955618ce8baSLisandro Dalcin /*@
2956bcf0153eSBarry Smith    TSSetInitialTimeStep - Deprecated, use `TSSetTime()` and `TSSetTimeStep()`.
2957edc382c3SSatish Balay 
2958edc382c3SSatish Balay    Level: deprecated
2959edc382c3SSatish Balay 
2960aaa6c58dSLisandro Dalcin @*/
2961d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetInitialTimeStep(TS ts, PetscReal initial_time, PetscReal time_step)
2962d71ae5a4SJacob Faibussowitsch {
2963aaa6c58dSLisandro Dalcin   PetscFunctionBegin;
2964aaa6c58dSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
29659566063dSJacob Faibussowitsch   PetscCall(TSSetTime(ts, initial_time));
29669566063dSJacob Faibussowitsch   PetscCall(TSSetTimeStep(ts, time_step));
29673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2968aaa6c58dSLisandro Dalcin }
2969aaa6c58dSLisandro Dalcin 
2970aaa6c58dSLisandro Dalcin /*@
2971bcf0153eSBarry Smith    TSGetDuration - Deprecated, use `TSGetMaxSteps()` and `TSGetMaxTime()`.
2972edc382c3SSatish Balay 
2973edc382c3SSatish Balay    Level: deprecated
2974edc382c3SSatish Balay 
2975adb62b0dSMatthew Knepley @*/
2976d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
2977d71ae5a4SJacob Faibussowitsch {
2978adb62b0dSMatthew Knepley   PetscFunctionBegin;
29790700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2980abc0a331SBarry Smith   if (maxsteps) {
29814482741eSBarry Smith     PetscValidIntPointer(maxsteps, 2);
2982adb62b0dSMatthew Knepley     *maxsteps = ts->max_steps;
2983adb62b0dSMatthew Knepley   }
2984abc0a331SBarry Smith   if (maxtime) {
2985064a246eSJacob Faibussowitsch     PetscValidRealPointer(maxtime, 3);
2986adb62b0dSMatthew Knepley     *maxtime = ts->max_time;
2987adb62b0dSMatthew Knepley   }
29883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2989adb62b0dSMatthew Knepley }
2990adb62b0dSMatthew Knepley 
2991d763cef2SBarry Smith /*@
2992bcf0153eSBarry Smith    TSSetDuration - Deprecated, use `TSSetMaxSteps()` and `TSSetMaxTime()`.
2993edc382c3SSatish Balay 
2994edc382c3SSatish Balay    Level: deprecated
2995edc382c3SSatish Balay 
2996d763cef2SBarry Smith @*/
2997d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetDuration(TS ts, PetscInt maxsteps, PetscReal maxtime)
2998d71ae5a4SJacob Faibussowitsch {
2999d763cef2SBarry Smith   PetscFunctionBegin;
30000700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3001c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(ts, maxsteps, 2);
3002064a246eSJacob Faibussowitsch   PetscValidLogicalCollectiveReal(ts, maxtime, 3);
300339b7ec4bSSean Farley   if (maxsteps >= 0) ts->max_steps = maxsteps;
300439b7ec4bSSean Farley   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
30053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3006d763cef2SBarry Smith }
3007d763cef2SBarry Smith 
3008d763cef2SBarry Smith /*@
3009bcf0153eSBarry Smith    TSGetTimeStepNumber - Deprecated, use `TSGetStepNumber()`.
3010edc382c3SSatish Balay 
3011edc382c3SSatish Balay    Level: deprecated
3012edc382c3SSatish Balay 
30135c5f5948SLisandro Dalcin @*/
3014d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeStepNumber(TS ts, PetscInt *steps)
3015d71ae5a4SJacob Faibussowitsch {
30169371c9d4SSatish Balay   return TSGetStepNumber(ts, steps);
30179371c9d4SSatish Balay }
30185c5f5948SLisandro Dalcin 
301919eac22cSLisandro Dalcin /*@
3020bcf0153eSBarry Smith    TSGetTotalSteps - Deprecated, use `TSGetStepNumber()`.
3021edc382c3SSatish Balay 
3022edc382c3SSatish Balay    Level: deprecated
3023edc382c3SSatish Balay 
30244f4e0956SLisandro Dalcin @*/
3025d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTotalSteps(TS ts, PetscInt *steps)
3026d71ae5a4SJacob Faibussowitsch {
30279371c9d4SSatish Balay   return TSGetStepNumber(ts, steps);
30289371c9d4SSatish Balay }
30294f4e0956SLisandro Dalcin 
30304f4e0956SLisandro Dalcin /*@
3031d763cef2SBarry Smith    TSSetSolution - Sets the initial solution vector
3032bcf0153eSBarry Smith    for use by the `TS` routines.
3033d763cef2SBarry Smith 
3034c3339decSBarry Smith    Logically Collective
3035d763cef2SBarry Smith 
3036d763cef2SBarry Smith    Input Parameters:
3037bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
30380910c330SBarry Smith -  u - the solution vector
3039d763cef2SBarry Smith 
3040d763cef2SBarry Smith    Level: beginner
3041d763cef2SBarry Smith 
3042bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetSolutionFunction()`, `TSGetSolution()`, `TSCreate()`
3043d763cef2SBarry Smith @*/
3044d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetSolution(TS ts, Vec u)
3045d71ae5a4SJacob Faibussowitsch {
3046496e6a7aSJed Brown   DM dm;
30478737fe31SLisandro Dalcin 
3048d763cef2SBarry Smith   PetscFunctionBegin;
30490700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
30500910c330SBarry Smith   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
30519566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)u));
30529566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
30530910c330SBarry Smith   ts->vec_sol = u;
3054bbd56ea5SKarl Rupp 
30559566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
30569566063dSJacob Faibussowitsch   PetscCall(DMShellSetGlobalVector(dm, u));
30573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3058d763cef2SBarry Smith }
3059d763cef2SBarry Smith 
3060ac226902SBarry Smith /*@C
3061000e7ae3SMatthew Knepley   TSSetPreStep - Sets the general-purpose function
30623f2090d5SJed Brown   called once at the beginning of each time step.
3063000e7ae3SMatthew Knepley 
3064c3339decSBarry Smith   Logically Collective
3065000e7ae3SMatthew Knepley 
3066000e7ae3SMatthew Knepley   Input Parameters:
3067bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3068000e7ae3SMatthew Knepley - func - The function
3069000e7ae3SMatthew Knepley 
3070000e7ae3SMatthew Knepley   Calling sequence of func:
307167b8a455SSatish Balay .vb
307267b8a455SSatish Balay   PetscErrorCode func (TS ts);
307367b8a455SSatish Balay .ve
3074000e7ae3SMatthew Knepley 
3075000e7ae3SMatthew Knepley   Level: intermediate
3076000e7ae3SMatthew Knepley 
3077bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`, `TSStep()`, `TSRestartStep()`
3078000e7ae3SMatthew Knepley @*/
3079d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
3080d71ae5a4SJacob Faibussowitsch {
3081000e7ae3SMatthew Knepley   PetscFunctionBegin;
30820700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3083ae60f76fSBarry Smith   ts->prestep = func;
30843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3085000e7ae3SMatthew Knepley }
3086000e7ae3SMatthew Knepley 
308709ee8438SJed Brown /*@
3088bcf0153eSBarry Smith   TSPreStep - Runs the user-defined pre-step function provided with `TSSetPreStep()`
30893f2090d5SJed Brown 
3090c3339decSBarry Smith   Collective
30913f2090d5SJed Brown 
30923f2090d5SJed Brown   Input Parameters:
3093bcf0153eSBarry Smith . ts   - The `TS` context obtained from `TSCreate()`
30943f2090d5SJed Brown 
30953f2090d5SJed Brown   Level: developer
30963f2090d5SJed Brown 
3097bcf0153eSBarry Smith   Note:
3098bcf0153eSBarry Smith   `TSPreStep()` is typically used within time stepping implementations,
3099bcf0153eSBarry Smith   so most users would not generally call this routine themselves.
3100bcf0153eSBarry Smith 
3101bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPreStep()`, `TSPreStage()`, `TSPostStage()`, `TSPostStep()`
31023f2090d5SJed Brown @*/
3103d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPreStep(TS ts)
3104d71ae5a4SJacob Faibussowitsch {
31053f2090d5SJed Brown   PetscFunctionBegin;
31060700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3107ae60f76fSBarry Smith   if (ts->prestep) {
31085efd42a4SStefano Zampini     Vec              U;
3109ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3110ef8d1ce0SJohann Rudi     PetscBool        sameObject;
31115efd42a4SStefano Zampini     PetscObjectState sprev, spost;
31125efd42a4SStefano Zampini 
31139566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
31149566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U, &idprev));
31159566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
311625e27a38SBarry Smith     PetscCallBack("TS callback preset", (*ts->prestep)(ts));
31179566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
31189566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U, idprev, &sameObject));
31199566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
31209566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
3121312ce896SJed Brown   }
31223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31233f2090d5SJed Brown }
31243f2090d5SJed Brown 
3125b8123daeSJed Brown /*@C
3126b8123daeSJed Brown   TSSetPreStage - Sets the general-purpose function
3127b8123daeSJed Brown   called once at the beginning of each stage.
3128b8123daeSJed Brown 
3129c3339decSBarry Smith   Logically Collective
3130b8123daeSJed Brown 
3131b8123daeSJed Brown   Input Parameters:
3132bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3133b8123daeSJed Brown - func - The function
3134b8123daeSJed Brown 
3135b8123daeSJed Brown   Calling sequence of func:
313667b8a455SSatish Balay .vb
313767b8a455SSatish Balay   PetscErrorCode func(TS ts, PetscReal stagetime);
313867b8a455SSatish Balay .ve
3139b8123daeSJed Brown 
3140b8123daeSJed Brown   Level: intermediate
3141b8123daeSJed Brown 
3142b8123daeSJed Brown   Note:
3143b8123daeSJed Brown   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3144bcf0153eSBarry Smith   The time step number being computed can be queried using `TSGetStepNumber()` and the total size of the step being
3145bcf0153eSBarry Smith   attempted can be obtained using `TSGetTimeStep()`. The time at the start of the step is available via `TSGetTime()`.
3146b8123daeSJed Brown 
3147bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPostStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3148b8123daeSJed Brown @*/
3149d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS, PetscReal))
3150d71ae5a4SJacob Faibussowitsch {
3151b8123daeSJed Brown   PetscFunctionBegin;
3152b8123daeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3153ae60f76fSBarry Smith   ts->prestage = func;
31543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3155b8123daeSJed Brown }
3156b8123daeSJed Brown 
31579be3e283SDebojyoti Ghosh /*@C
3158bcf0153eSBarry Smith   TSSetPostStage - Sets the general-purpose function, provided with `TSSetPostStep()`,
31599be3e283SDebojyoti Ghosh   called once at the end of each stage.
31609be3e283SDebojyoti Ghosh 
3161c3339decSBarry Smith   Logically Collective
31629be3e283SDebojyoti Ghosh 
31639be3e283SDebojyoti Ghosh   Input Parameters:
3164bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
31659be3e283SDebojyoti Ghosh - func - The function
31669be3e283SDebojyoti Ghosh 
31679be3e283SDebojyoti Ghosh   Calling sequence of func:
316867b8a455SSatish Balay .vb
316967b8a455SSatish Balay   PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
317067b8a455SSatish Balay .ve
31719be3e283SDebojyoti Ghosh 
31729be3e283SDebojyoti Ghosh   Level: intermediate
31739be3e283SDebojyoti Ghosh 
31749be3e283SDebojyoti Ghosh   Note:
31759be3e283SDebojyoti Ghosh   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
3176bcf0153eSBarry Smith   The time step number being computed can be queried using `TSGetStepNumber()` and the total size of the step being
3177bcf0153eSBarry Smith   attempted can be obtained using `TSGetTimeStep()`. The time at the start of the step is available via `TSGetTime()`.
31789be3e283SDebojyoti Ghosh 
3179bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
31809be3e283SDebojyoti Ghosh @*/
3181d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS, PetscReal, PetscInt, Vec *))
3182d71ae5a4SJacob Faibussowitsch {
31839be3e283SDebojyoti Ghosh   PetscFunctionBegin;
31849be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
31859be3e283SDebojyoti Ghosh   ts->poststage = func;
31863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
31879be3e283SDebojyoti Ghosh }
31889be3e283SDebojyoti Ghosh 
3189c688d042SShri Abhyankar /*@C
3190c688d042SShri Abhyankar   TSSetPostEvaluate - Sets the general-purpose function
3191c688d042SShri Abhyankar   called once at the end of each step evaluation.
3192c688d042SShri Abhyankar 
3193c3339decSBarry Smith   Logically Collective
3194c688d042SShri Abhyankar 
3195c688d042SShri Abhyankar   Input Parameters:
3196bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3197c688d042SShri Abhyankar - func - The function
3198c688d042SShri Abhyankar 
3199c688d042SShri Abhyankar   Calling sequence of func:
320067b8a455SSatish Balay .vb
320167b8a455SSatish Balay   PetscErrorCode func(TS ts);
320267b8a455SSatish Balay .ve
3203c688d042SShri Abhyankar 
3204c688d042SShri Abhyankar   Level: intermediate
3205c688d042SShri Abhyankar 
3206c688d042SShri Abhyankar   Note:
3207bcf0153eSBarry Smith   Semantically, `TSSetPostEvaluate()` differs from `TSSetPostStep()` since the function it sets is called before event-handling
3208bcf0153eSBarry Smith   thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, `TSPostStep()`
3209bcf0153eSBarry Smith   may be passed a different solution, possibly changed by the event handler. `TSPostEvaluate()` is called after the next step
3210bcf0153eSBarry Smith   solution is evaluated allowing to modify it, if need be. The solution can be obtained with `TSGetSolution()`, the time step
3211bcf0153eSBarry Smith   with `TSGetTimeStep()`, and the time at the start of the step is available via `TSGetTime()`
3212c688d042SShri Abhyankar 
3213bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3214c688d042SShri Abhyankar @*/
3215d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS))
3216d71ae5a4SJacob Faibussowitsch {
3217c688d042SShri Abhyankar   PetscFunctionBegin;
3218c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3219c688d042SShri Abhyankar   ts->postevaluate = func;
32203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3221c688d042SShri Abhyankar }
3222c688d042SShri Abhyankar 
3223b8123daeSJed Brown /*@
3224bcf0153eSBarry Smith   TSPreStage - Runs the user-defined pre-stage function set using `TSSetPreStage()`
3225b8123daeSJed Brown 
3226c3339decSBarry Smith   Collective
3227b8123daeSJed Brown 
3228b8123daeSJed Brown   Input Parameters:
3229bcf0153eSBarry Smith . ts          - The `TS` context obtained from `TSCreate()`
32309be3e283SDebojyoti Ghosh   stagetime   - The absolute time of the current stage
3231b8123daeSJed Brown 
3232b8123daeSJed Brown   Level: developer
3233b8123daeSJed Brown 
3234bcf0153eSBarry Smith   Note:
3235bcf0153eSBarry Smith   `TSPreStage()` is typically used within time stepping implementations,
3236bcf0153eSBarry Smith   most users would not generally call this routine themselves.
3237bcf0153eSBarry Smith 
3238bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSPostStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3239b8123daeSJed Brown @*/
3240d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPreStage(TS ts, PetscReal stagetime)
3241d71ae5a4SJacob Faibussowitsch {
3242b8123daeSJed Brown   PetscFunctionBegin;
3243b8123daeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
32441e66621cSBarry Smith   if (ts->prestage) PetscCallBack("TS callback prestage", (*ts->prestage)(ts, stagetime));
32453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3246b8123daeSJed Brown }
3247b8123daeSJed Brown 
32489be3e283SDebojyoti Ghosh /*@
3249bcf0153eSBarry Smith   TSPostStage - Runs the user-defined post-stage function set using `TSSetPostStage()`
32509be3e283SDebojyoti Ghosh 
3251c3339decSBarry Smith   Collective
32529be3e283SDebojyoti Ghosh 
32539be3e283SDebojyoti Ghosh   Input Parameters:
3254bcf0153eSBarry Smith . ts          - The `TS` context obtained from `TSCreate()`
32559be3e283SDebojyoti Ghosh   stagetime   - The absolute time of the current stage
32569be3e283SDebojyoti Ghosh   stageindex  - Stage number
32579be3e283SDebojyoti Ghosh   Y           - Array of vectors (of size = total number
32589be3e283SDebojyoti Ghosh                 of stages) with the stage solutions
32599be3e283SDebojyoti Ghosh 
32609be3e283SDebojyoti Ghosh   Level: developer
32619be3e283SDebojyoti Ghosh 
3262bcf0153eSBarry Smith   Note:
3263bcf0153eSBarry Smith   `TSPostStage()` is typically used within time stepping implementations,
3264bcf0153eSBarry Smith   most users would not generally call this routine themselves.
3265bcf0153eSBarry Smith 
3266bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSPreStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
32679be3e283SDebojyoti Ghosh @*/
3268d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
3269d71ae5a4SJacob Faibussowitsch {
32709be3e283SDebojyoti Ghosh   PetscFunctionBegin;
32719be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
32721e66621cSBarry Smith   if (ts->poststage) PetscCallBack("TS callback poststage", (*ts->poststage)(ts, stagetime, stageindex, Y));
32733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32749be3e283SDebojyoti Ghosh }
32759be3e283SDebojyoti Ghosh 
3276c688d042SShri Abhyankar /*@
3277bcf0153eSBarry Smith   TSPostEvaluate - Runs the user-defined post-evaluate function set using `TSSetPostEvaluate()`
3278c688d042SShri Abhyankar 
3279c3339decSBarry Smith   Collective
3280c688d042SShri Abhyankar 
3281c688d042SShri Abhyankar   Input Parameters:
3282bcf0153eSBarry Smith . ts - The `TS` context obtained from `TSCreate()`
3283c688d042SShri Abhyankar 
3284c688d042SShri Abhyankar   Level: developer
3285c688d042SShri Abhyankar 
3286bcf0153eSBarry Smith   Note:
3287bcf0153eSBarry Smith   `TSPostEvaluate()` is typically used within time stepping implementations,
3288bcf0153eSBarry Smith   most users would not generally call this routine themselves.
3289bcf0153eSBarry Smith 
3290bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPostEvaluate()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3291c688d042SShri Abhyankar @*/
3292d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPostEvaluate(TS ts)
3293d71ae5a4SJacob Faibussowitsch {
3294c688d042SShri Abhyankar   PetscFunctionBegin;
3295c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3296c688d042SShri Abhyankar   if (ts->postevaluate) {
3297dcb233daSLisandro Dalcin     Vec              U;
3298dcb233daSLisandro Dalcin     PetscObjectState sprev, spost;
3299dcb233daSLisandro Dalcin 
33009566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
33019566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
330225e27a38SBarry Smith     PetscCallBack("TS callback postevaluate", (*ts->postevaluate)(ts));
33039566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
33049566063dSJacob Faibussowitsch     if (sprev != spost) PetscCall(TSRestartStep(ts));
3305c688d042SShri Abhyankar   }
33063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3307c688d042SShri Abhyankar }
3308c688d042SShri Abhyankar 
3309ac226902SBarry Smith /*@C
3310000e7ae3SMatthew Knepley   TSSetPostStep - Sets the general-purpose function
33113f2090d5SJed Brown   called once at the end of each time step.
3312000e7ae3SMatthew Knepley 
3313c3339decSBarry Smith   Logically Collective
3314000e7ae3SMatthew Knepley 
3315000e7ae3SMatthew Knepley   Input Parameters:
3316bcf0153eSBarry Smith + ts   - The `TS` context obtained from `TSCreate()`
3317000e7ae3SMatthew Knepley - func - The function
3318000e7ae3SMatthew Knepley 
3319000e7ae3SMatthew Knepley   Calling sequence of func:
3320b8123daeSJed Brown $ func (TS ts);
3321000e7ae3SMatthew Knepley 
3322000e7ae3SMatthew Knepley   Level: intermediate
3323000e7ae3SMatthew Knepley 
3324bcf0153eSBarry Smith   Note:
3325bcf0153eSBarry Smith   The function set by `TSSetPostStep()` is called after each successful step. The solution vector X
3326bcf0153eSBarry Smith   obtained by `TSGetSolution()` may be different than that computed at the step end if the event handler
3327bcf0153eSBarry Smith   locates an event and `TSPostEvent()` modifies it. Use `TSSetPostEvaluate()` if an unmodified solution is needed instead.
3328bcf0153eSBarry Smith 
3329bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostEvaluate()`, `TSGetTimeStep()`, `TSGetStepNumber()`, `TSGetTime()`, `TSRestartStep()`
3330000e7ae3SMatthew Knepley @*/
3331d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
3332d71ae5a4SJacob Faibussowitsch {
3333000e7ae3SMatthew Knepley   PetscFunctionBegin;
33340700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3335ae60f76fSBarry Smith   ts->poststep = func;
33363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3337000e7ae3SMatthew Knepley }
3338000e7ae3SMatthew Knepley 
333909ee8438SJed Brown /*@
3340bcf0153eSBarry Smith   TSPostStep - Runs the user-defined post-step function that was set with `TSSetPotsStep()`
33413f2090d5SJed Brown 
3342c3339decSBarry Smith   Collective
33433f2090d5SJed Brown 
33443f2090d5SJed Brown   Input Parameters:
3345bcf0153eSBarry Smith . ts   - The `TS` context obtained from `TSCreate()`
33463f2090d5SJed Brown 
3347bcf0153eSBarry Smith   Note:
3348bcf0153eSBarry Smith   `TSPostStep()` is typically used within time stepping implementations,
33493f2090d5SJed Brown   so most users would not generally call this routine themselves.
33503f2090d5SJed Brown 
33513f2090d5SJed Brown   Level: developer
33523f2090d5SJed Brown 
3353bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostEvaluate()`, `TSGetTimeStep()`, `TSGetStepNumber()`, `TSGetTime()`, `TSSetPotsStep()`
33543f2090d5SJed Brown @*/
3355d71ae5a4SJacob Faibussowitsch PetscErrorCode TSPostStep(TS ts)
3356d71ae5a4SJacob Faibussowitsch {
33573f2090d5SJed Brown   PetscFunctionBegin;
33580700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3359ae60f76fSBarry Smith   if (ts->poststep) {
33605efd42a4SStefano Zampini     Vec              U;
3361ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3362ef8d1ce0SJohann Rudi     PetscBool        sameObject;
33635efd42a4SStefano Zampini     PetscObjectState sprev, spost;
33645efd42a4SStefano Zampini 
33659566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
33669566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U, &idprev));
33679566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
336825e27a38SBarry Smith     PetscCallBack("TS callback poststep", (*ts->poststep)(ts));
33699566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
33709566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U, idprev, &sameObject));
33719566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
33729566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
337372ac3e02SJed Brown   }
33743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33753f2090d5SJed Brown }
33763f2090d5SJed Brown 
3377cd652676SJed Brown /*@
3378cd652676SJed Brown    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3379cd652676SJed Brown 
3380c3339decSBarry Smith    Collective
3381cd652676SJed Brown 
33824165533cSJose E. Roman    Input Parameters:
3383cd652676SJed Brown +  ts - time stepping context
3384cd652676SJed Brown -  t - time to interpolate to
3385cd652676SJed Brown 
33864165533cSJose E. Roman    Output Parameter:
33870910c330SBarry Smith .  U - state at given time
3388cd652676SJed Brown 
3389cd652676SJed Brown    Level: intermediate
3390cd652676SJed Brown 
3391bcf0153eSBarry Smith    Developer Note:
3392bcf0153eSBarry Smith    `TSInterpolate()` and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3393cd652676SJed Brown 
3394bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetExactFinalTime()`, `TSSolve()`
3395cd652676SJed Brown @*/
3396d71ae5a4SJacob Faibussowitsch PetscErrorCode TSInterpolate(TS ts, PetscReal t, Vec U)
3397d71ae5a4SJacob Faibussowitsch {
3398cd652676SJed Brown   PetscFunctionBegin;
3399cd652676SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3400b06615a5SLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
340163a3b9bcSJacob 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);
3402dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, interpolate, t, U);
34033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3404cd652676SJed Brown }
3405cd652676SJed Brown 
3406d763cef2SBarry Smith /*@
34076d9e5789SSean Farley    TSStep - Steps one time step
3408d763cef2SBarry Smith 
3409c3339decSBarry Smith    Collective
3410d763cef2SBarry Smith 
3411d763cef2SBarry Smith    Input Parameter:
3412bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
3413d763cef2SBarry Smith 
341427829d71SBarry Smith    Level: developer
3415d763cef2SBarry Smith 
3416b8123daeSJed Brown    Notes:
3417bcf0153eSBarry Smith    The public interface for the ODE/DAE solvers is `TSSolve()`, you should almost for sure be using that routine and not this routine.
341827829d71SBarry Smith 
3419bcf0153eSBarry Smith    The hook set using `TSSetPreStep()` is called before each attempt to take the step. In general, the time step size may
3420b8123daeSJed Brown    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3421b8123daeSJed Brown 
3422bcf0153eSBarry Smith    This may over-step the final time provided in `TSSetMaxTime()` depending on the time-step used. `TSSolve()` interpolates to exactly the
3423bcf0153eSBarry Smith    time provided in `TSSetMaxTime()`. One can use `TSInterpolate()` to determine an interpolated solution within the final timestep.
342425cb2221SBarry Smith 
3425bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSInterpolate()`
3426d763cef2SBarry Smith @*/
3427d71ae5a4SJacob Faibussowitsch PetscErrorCode TSStep(TS ts)
3428d71ae5a4SJacob Faibussowitsch {
3429fffbeea8SBarry Smith   static PetscBool cite = PETSC_FALSE;
3430be5899b3SLisandro Dalcin   PetscReal        ptime;
3431d763cef2SBarry Smith 
3432d763cef2SBarry Smith   PetscFunctionBegin;
34330700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3434d0609cedSBarry Smith   PetscCall(PetscCitationsRegister("@article{tspaper,\n"
3435fffbeea8SBarry Smith                                    "  title         = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3436f1d62c27SHong Zhang                                    "  author        = {Abhyankar, Shrirang and Brown, Jed and Constantinescu, Emil and Ghosh, Debojyoti and Smith, Barry F. and Zhang, Hong},\n"
3437f1d62c27SHong Zhang                                    "  journal       = {arXiv e-preprints},\n"
3438f1d62c27SHong Zhang                                    "  eprint        = {1806.01437},\n"
3439f1d62c27SHong Zhang                                    "  archivePrefix = {arXiv},\n"
34409371c9d4SSatish Balay                                    "  year          = {2018}\n}\n",
34419371c9d4SSatish Balay                                    &cite));
34429566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
34439566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory, ts));
3444d405a339SMatthew Knepley 
34453c633725SBarry Smith   PetscCheck(ts->max_time < PETSC_MAX_REAL || ts->max_steps != PETSC_MAX_INT, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>");
34463c633725SBarry 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()");
34473c633725SBarry 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");
3448a6772fa2SLisandro Dalcin 
3449be5899b3SLisandro Dalcin   if (!ts->steps) ts->ptime_prev = ts->ptime;
34509371c9d4SSatish Balay   ptime                   = ts->ptime;
34519371c9d4SSatish Balay   ts->ptime_prev_rollback = ts->ptime_prev;
34522808aa04SLisandro Dalcin   ts->reason              = TS_CONVERGED_ITERATING;
3453fc8dbba5SLisandro Dalcin 
34549566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_Step, ts, 0, 0, 0));
3455dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, step);
34569566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_Step, ts, 0, 0, 0));
3457fc8dbba5SLisandro Dalcin 
34589371c9d4SSatish Balay   if (ts->tspan && PetscIsCloseAtTol(ts->ptime, ts->tspan->span_times[ts->tspan->spanctr], ts->tspan->reltol * ts->time_step + ts->tspan->abstol, 0) && ts->tspan->spanctr < ts->tspan->num_span_times)
34599371c9d4SSatish Balay     PetscCall(VecCopy(ts->vec_sol, ts->tspan->vecs_sol[ts->tspan->spanctr++]));
3460fc8dbba5SLisandro Dalcin   if (ts->reason >= 0) {
3461be5899b3SLisandro Dalcin     ts->ptime_prev = ptime;
34622808aa04SLisandro Dalcin     ts->steps++;
3463be5899b3SLisandro Dalcin     ts->steprollback = PETSC_FALSE;
346428d5b5d6SLisandro Dalcin     ts->steprestart  = PETSC_FALSE;
3465d2daff3dSHong Zhang   }
3466fc8dbba5SLisandro Dalcin   if (!ts->reason) {
346708c7845fSBarry Smith     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
346808c7845fSBarry Smith     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
346908c7845fSBarry Smith   }
3470fc8dbba5SLisandro Dalcin 
34715c9bbc89SJed Brown   if (ts->reason < 0 && ts->errorifstepfailed) {
34725c9bbc89SJed Brown     PetscCall(TSMonitorCancel(ts));
34735c9bbc89SJed Brown     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 make negative to attempt recovery", TSConvergedReasons[ts->reason]);
34745c9bbc89SJed Brown     SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_NOT_CONVERGED, "TSStep has failed due to %s", TSConvergedReasons[ts->reason]);
34755c9bbc89SJed Brown   }
34763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
347708c7845fSBarry Smith }
347808c7845fSBarry Smith 
347908c7845fSBarry Smith /*@
34807cbde773SLisandro Dalcin    TSEvaluateWLTE - Evaluate the weighted local truncation error norm
34817cbde773SLisandro Dalcin    at the end of a time step with a given order of accuracy.
34827cbde773SLisandro Dalcin 
3483c3339decSBarry Smith    Collective
34847cbde773SLisandro Dalcin 
34854165533cSJose E. Roman    Input Parameters:
34867cbde773SLisandro Dalcin +  ts - time stepping context
3487bcf0153eSBarry Smith -  wnormtype - norm type, either `NORM_2` or `NORM_INFINITY`
34887cbde773SLisandro Dalcin 
348997bb3fdcSJose E. Roman    Input/Output Parameter:
3490bcf0153eSBarry Smith .  order - optional, desired order for the error evaluation or `PETSC_DECIDE`;
349197bb3fdcSJose E. Roman            on output, the actual order of the error evaluation
349297bb3fdcSJose E. Roman 
349397bb3fdcSJose E. Roman    Output Parameter:
349497bb3fdcSJose E. Roman .  wlte - the weighted local truncation error norm
34957cbde773SLisandro Dalcin 
34967cbde773SLisandro Dalcin    Level: advanced
34977cbde773SLisandro Dalcin 
3498bcf0153eSBarry Smith    Note:
34997cbde773SLisandro Dalcin    If the timestepper cannot evaluate the error in a particular step
35007cbde773SLisandro Dalcin    (eg. in the first step or restart steps after event handling),
35017cbde773SLisandro Dalcin    this routine returns wlte=-1.0 .
35027cbde773SLisandro Dalcin 
3503bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSStep()`, `TSAdapt`, `TSErrorWeightedNorm()`
35047cbde773SLisandro Dalcin @*/
3505d71ae5a4SJacob Faibussowitsch PetscErrorCode TSEvaluateWLTE(TS ts, NormType wnormtype, PetscInt *order, PetscReal *wlte)
3506d71ae5a4SJacob Faibussowitsch {
35077cbde773SLisandro Dalcin   PetscFunctionBegin;
35087cbde773SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
35097cbde773SLisandro Dalcin   PetscValidType(ts, 1);
3510064a246eSJacob Faibussowitsch   PetscValidLogicalCollectiveEnum(ts, wnormtype, 2);
35117cbde773SLisandro Dalcin   if (order) PetscValidIntPointer(order, 3);
35127cbde773SLisandro Dalcin   if (order) PetscValidLogicalCollectiveInt(ts, *order, 3);
35137cbde773SLisandro Dalcin   PetscValidRealPointer(wlte, 4);
35143c633725SBarry Smith   PetscCheck(wnormtype == NORM_2 || wnormtype == NORM_INFINITY, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
3515dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, evaluatewlte, wnormtype, order, wlte);
35163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35177cbde773SLisandro Dalcin }
35187cbde773SLisandro Dalcin 
351905175c85SJed Brown /*@
352005175c85SJed Brown    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
352105175c85SJed Brown 
3522c3339decSBarry Smith    Collective
352305175c85SJed Brown 
35244165533cSJose E. Roman    Input Parameters:
35251c3436cfSJed Brown +  ts - time stepping context
35261c3436cfSJed Brown .  order - desired order of accuracy
35270298fd71SBarry Smith -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
352805175c85SJed Brown 
35294165533cSJose E. Roman    Output Parameter:
35300910c330SBarry Smith .  U - state at the end of the current step
353105175c85SJed Brown 
353205175c85SJed Brown    Level: advanced
353305175c85SJed Brown 
3534108c343cSJed Brown    Notes:
3535108c343cSJed Brown    This function cannot be called until all stages have been evaluated.
3536108c343cSJed Brown 
3537bcf0153eSBarry 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.
3538bcf0153eSBarry Smith 
3539bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSStep()`, `TSAdapt`
354005175c85SJed Brown @*/
3541d71ae5a4SJacob Faibussowitsch PetscErrorCode TSEvaluateStep(TS ts, PetscInt order, Vec U, PetscBool *done)
3542d71ae5a4SJacob Faibussowitsch {
354305175c85SJed Brown   PetscFunctionBegin;
354405175c85SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
354505175c85SJed Brown   PetscValidType(ts, 1);
35460910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
3547dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, evaluatestep, order, U, done);
35483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
354905175c85SJed Brown }
355005175c85SJed Brown 
3551aad739acSMatthew G. Knepley /*@C
35522e61be88SMatthew G. Knepley   TSGetComputeInitialCondition - Get the function used to automatically compute an initial condition for the timestepping.
3553aad739acSMatthew G. Knepley 
3554aad739acSMatthew G. Knepley   Not collective
3555aad739acSMatthew G. Knepley 
35564165533cSJose E. Roman   Input Parameter:
3557aad739acSMatthew G. Knepley . ts - time stepping context
3558aad739acSMatthew G. Knepley 
35594165533cSJose E. Roman   Output Parameter:
35602e61be88SMatthew G. Knepley . initConditions - The function which computes an initial condition
3561aad739acSMatthew G. Knepley 
3562bcf0153eSBarry Smith   The calling sequence for the function is
3563bcf0153eSBarry Smith .vb
3564bcf0153eSBarry Smith  initCondition(TS ts, Vec u)
3565bcf0153eSBarry Smith  ts - The timestepping context
3566bcf0153eSBarry Smith  u  - The input vector in which the initial condition is stored
3567bcf0153eSBarry Smith .ve
3568bcf0153eSBarry Smith 
3569aad739acSMatthew G. Knepley    Level: advanced
3570aad739acSMatthew G. Knepley 
3571bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetComputeInitialCondition()`, `TSComputeInitialCondition()`
3572aad739acSMatthew G. Knepley @*/
3573d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetComputeInitialCondition(TS ts, PetscErrorCode (**initCondition)(TS, Vec))
3574d71ae5a4SJacob Faibussowitsch {
3575aad739acSMatthew G. Knepley   PetscFunctionBegin;
3576aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
35772e61be88SMatthew G. Knepley   PetscValidPointer(initCondition, 2);
35782e61be88SMatthew G. Knepley   *initCondition = ts->ops->initcondition;
35793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3580aad739acSMatthew G. Knepley }
3581aad739acSMatthew G. Knepley 
3582aad739acSMatthew G. Knepley /*@C
35832e61be88SMatthew G. Knepley   TSSetComputeInitialCondition - Set the function used to automatically compute an initial condition for the timestepping.
3584aad739acSMatthew G. Knepley 
3585c3339decSBarry Smith   Logically collective
3586aad739acSMatthew G. Knepley 
35874165533cSJose E. Roman   Input Parameters:
3588aad739acSMatthew G. Knepley + ts  - time stepping context
35892e61be88SMatthew G. Knepley - initCondition - The function which computes an initial condition
3590aad739acSMatthew G. Knepley 
3591a96d6ef6SBarry Smith   Calling sequence for initCondition:
3592a96d6ef6SBarry Smith $ PetscErrorCode initCondition(TS ts, Vec u)
3593a96d6ef6SBarry Smith + ts - The timestepping context
3594a96d6ef6SBarry Smith - u  - The input vector in which the initial condition is to be stored
3595aad739acSMatthew G. Knepley 
3596bcf0153eSBarry Smith   Level: advanced
3597bcf0153eSBarry Smith 
3598bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetComputeInitialCondition()`, `TSComputeInitialCondition()`
3599aad739acSMatthew G. Knepley @*/
3600d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetComputeInitialCondition(TS ts, PetscErrorCode (*initCondition)(TS, Vec))
3601d71ae5a4SJacob Faibussowitsch {
3602aad739acSMatthew G. Knepley   PetscFunctionBegin;
3603aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
36042e61be88SMatthew G. Knepley   PetscValidFunction(initCondition, 2);
36052e61be88SMatthew G. Knepley   ts->ops->initcondition = initCondition;
36063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3607aad739acSMatthew G. Knepley }
3608aad739acSMatthew G. Knepley 
3609aad739acSMatthew G. Knepley /*@
3610bcf0153eSBarry Smith   TSComputeInitialCondition - Compute an initial condition for the timestepping using the function previously set with `TSSetComputeInitialCondition()`
3611aad739acSMatthew G. Knepley 
3612c3339decSBarry Smith   Collective
3613aad739acSMatthew G. Knepley 
36144165533cSJose E. Roman   Input Parameters:
3615aad739acSMatthew G. Knepley + ts - time stepping context
3616bcf0153eSBarry Smith - u  - The `Vec` to store the condition in which will be used in `TSSolve()`
3617aad739acSMatthew G. Knepley 
3618aad739acSMatthew G. Knepley   Level: advanced
3619aad739acSMatthew G. Knepley 
3620bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3621aad739acSMatthew G. Knepley @*/
3622d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeInitialCondition(TS ts, Vec u)
3623d71ae5a4SJacob Faibussowitsch {
3624aad739acSMatthew G. Knepley   PetscFunctionBegin;
3625aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3626aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3627dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, initcondition, u);
36283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3629aad739acSMatthew G. Knepley }
3630aad739acSMatthew G. Knepley 
3631aad739acSMatthew G. Knepley /*@C
3632aad739acSMatthew G. Knepley   TSGetComputeExactError - Get the function used to automatically compute the exact error for the timestepping.
3633aad739acSMatthew G. Knepley 
3634aad739acSMatthew G. Knepley   Not collective
3635aad739acSMatthew G. Knepley 
36364165533cSJose E. Roman   Input Parameter:
3637aad739acSMatthew G. Knepley . ts - time stepping context
3638aad739acSMatthew G. Knepley 
36394165533cSJose E. Roman   Output Parameter:
3640aad739acSMatthew G. Knepley . exactError - The function which computes the solution error
3641aad739acSMatthew G. Knepley 
3642a96d6ef6SBarry Smith   Calling sequence for exactError:
3643a96d6ef6SBarry Smith $ PetscErrorCode exactError(TS ts, Vec u)
3644a96d6ef6SBarry Smith + ts - The timestepping context
3645a96d6ef6SBarry Smith . u  - The approximate solution vector
3646a96d6ef6SBarry Smith - e  - The input vector in which the error is stored
3647aad739acSMatthew G. Knepley 
3648bcf0153eSBarry Smith   Level: advanced
3649bcf0153eSBarry Smith 
3650bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetComputeExactError()`, `TSComputeExactError()`
3651aad739acSMatthew G. Knepley @*/
3652d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetComputeExactError(TS ts, PetscErrorCode (**exactError)(TS, Vec, Vec))
3653d71ae5a4SJacob Faibussowitsch {
3654aad739acSMatthew G. Knepley   PetscFunctionBegin;
3655aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3656aad739acSMatthew G. Knepley   PetscValidPointer(exactError, 2);
3657aad739acSMatthew G. Knepley   *exactError = ts->ops->exacterror;
36583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3659aad739acSMatthew G. Knepley }
3660aad739acSMatthew G. Knepley 
3661aad739acSMatthew G. Knepley /*@C
3662aad739acSMatthew G. Knepley   TSSetComputeExactError - Set the function used to automatically compute the exact error for the timestepping.
3663aad739acSMatthew G. Knepley 
3664c3339decSBarry Smith   Logically collective
3665aad739acSMatthew G. Knepley 
36664165533cSJose E. Roman   Input Parameters:
3667aad739acSMatthew G. Knepley + ts - time stepping context
3668aad739acSMatthew G. Knepley - exactError - The function which computes the solution error
3669aad739acSMatthew G. Knepley 
3670a96d6ef6SBarry Smith   Calling sequence for exactError:
3671a96d6ef6SBarry Smith $ PetscErrorCode exactError(TS ts, Vec u)
3672a96d6ef6SBarry Smith + ts - The timestepping context
3673a96d6ef6SBarry Smith . u  - The approximate solution vector
3674a96d6ef6SBarry Smith - e  - The input vector in which the error is stored
3675aad739acSMatthew G. Knepley 
3676bcf0153eSBarry Smith   Level: advanced
3677bcf0153eSBarry Smith 
3678bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetComputeExactError()`, `TSComputeExactError()`
3679aad739acSMatthew G. Knepley @*/
3680d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetComputeExactError(TS ts, PetscErrorCode (*exactError)(TS, Vec, Vec))
3681d71ae5a4SJacob Faibussowitsch {
3682aad739acSMatthew G. Knepley   PetscFunctionBegin;
3683aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3684f907fdbfSMatthew G. Knepley   PetscValidFunction(exactError, 2);
3685aad739acSMatthew G. Knepley   ts->ops->exacterror = exactError;
36863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3687aad739acSMatthew G. Knepley }
3688aad739acSMatthew G. Knepley 
3689aad739acSMatthew G. Knepley /*@
3690bcf0153eSBarry Smith   TSComputeExactError - Compute the solution error for the timestepping using the function previously set with `TSSetComputeExactError()`
3691aad739acSMatthew G. Knepley 
3692c3339decSBarry Smith   Collective
3693aad739acSMatthew G. Knepley 
36944165533cSJose E. Roman   Input Parameters:
3695aad739acSMatthew G. Knepley + ts - time stepping context
3696aad739acSMatthew G. Knepley . u  - The approximate solution
3697bcf0153eSBarry Smith - e  - The `Vec` used to store the error
3698aad739acSMatthew G. Knepley 
3699aad739acSMatthew G. Knepley   Level: advanced
3700aad739acSMatthew G. Knepley 
3701bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3702aad739acSMatthew G. Knepley @*/
3703d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeExactError(TS ts, Vec u, Vec e)
3704d71ae5a4SJacob Faibussowitsch {
3705aad739acSMatthew G. Knepley   PetscFunctionBegin;
3706aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3707aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3708aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(e, VEC_CLASSID, 3);
3709dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, exacterror, u, e);
37103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3711aad739acSMatthew G. Knepley }
3712aad739acSMatthew G. Knepley 
3713b1cb36f3SHong Zhang /*@
37146a4d4014SLisandro Dalcin    TSSolve - Steps the requested number of timesteps.
37156a4d4014SLisandro Dalcin 
3716c3339decSBarry Smith    Collective
37176a4d4014SLisandro Dalcin 
3718d8d19677SJose E. Roman    Input Parameters:
3719bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
3720bcf0153eSBarry Smith -  u - the solution vector  (can be null if `TSSetSolution()` was used and `TSSetExactFinalTime`(ts,`TS_EXACTFINALTIME_MATCHSTEP`) was not used,
372163e21af5SBarry Smith                              otherwise must contain the initial conditions and will contain the solution at the final requested time
37225a3a76d0SJed Brown 
37236a4d4014SLisandro Dalcin    Level: beginner
37246a4d4014SLisandro Dalcin 
37255a3a76d0SJed Brown    Notes:
37265a3a76d0SJed Brown    The final time returned by this function may be different from the time of the internally
3727bcf0153eSBarry Smith    held state accessible by `TSGetSolution()` and `TSGetTime()` because the method may have
37285a3a76d0SJed Brown    stepped over the final time.
37295a3a76d0SJed Brown 
3730bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSCreate()`, `TSSetSolution()`, `TSStep()`, `TSGetTime()`, `TSGetSolveTime()`
37316a4d4014SLisandro Dalcin @*/
3732d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSolve(TS ts, Vec u)
3733d71ae5a4SJacob Faibussowitsch {
3734b06615a5SLisandro Dalcin   Vec solution;
3735f22f69f0SBarry Smith 
37366a4d4014SLisandro Dalcin   PetscFunctionBegin;
37370700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3738f2c2a1b9SBarry Smith   if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3739303a5415SBarry Smith 
37409566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
3741ee41a567SStefano 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 */
37420910c330SBarry Smith     if (!ts->vec_sol || u == ts->vec_sol) {
37439566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u, &solution));
37449566063dSJacob Faibussowitsch       PetscCall(TSSetSolution(ts, solution));
37459566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&solution)); /* grant ownership */
37465a3a76d0SJed Brown     }
37479566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ts->vec_sol));
37483c633725SBarry Smith     PetscCheck(!ts->forward_solve, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE");
37491baa6e33SBarry Smith   } else if (u) PetscCall(TSSetSolution(ts, u));
37509566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
37519566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory, ts));
3752a6772fa2SLisandro Dalcin 
37533c633725SBarry Smith   PetscCheck(ts->max_time < PETSC_MAX_REAL || ts->max_steps != PETSC_MAX_INT, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "You must call TSSetMaxTime() or TSSetMaxSteps(), or use -ts_max_time <time> or -ts_max_steps <steps>");
37543c633725SBarry 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()");
37553c633725SBarry 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");
37564a658b32SHong Zhang   PetscCheck(!(ts->tspan && ts->exact_final_time != TS_EXACTFINALTIME_MATCHSTEP), PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "You must use TS_EXACTFINALTIME_MATCHSTEP when using time span");
37574a658b32SHong Zhang 
3758e1db57b0SHong Zhang   if (ts->tspan && PetscIsCloseAtTol(ts->ptime, ts->tspan->span_times[0], ts->tspan->reltol * ts->time_step + ts->tspan->abstol, 0)) { /* starting point in time span */
37594a658b32SHong Zhang     PetscCall(VecCopy(ts->vec_sol, ts->tspan->vecs_sol[0]));
37604a658b32SHong Zhang     ts->tspan->spanctr = 1;
37614a658b32SHong Zhang   }
3762a6772fa2SLisandro Dalcin 
37631baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardSetUp(ts));
3764715f1b00SHong Zhang 
3765e7069c78SShri   /* reset number of steps only when the step is not restarted. ARKIMEX
3766715f1b00SHong Zhang      restarts the step after an event. Resetting these counters in such case causes
3767e7069c78SShri      TSTrajectory to incorrectly save the output files
3768e7069c78SShri   */
3769715f1b00SHong Zhang   /* reset time step and iteration counters */
37702808aa04SLisandro Dalcin   if (!ts->steps) {
37715ef26d82SJed Brown     ts->ksp_its           = 0;
37725ef26d82SJed Brown     ts->snes_its          = 0;
3773c610991cSLisandro Dalcin     ts->num_snes_failures = 0;
3774c610991cSLisandro Dalcin     ts->reject            = 0;
37752808aa04SLisandro Dalcin     ts->steprestart       = PETSC_TRUE;
37762808aa04SLisandro Dalcin     ts->steprollback      = PETSC_FALSE;
37777d51462cSStefano Zampini     ts->rhsjacobian.time  = PETSC_MIN_REAL;
37782808aa04SLisandro Dalcin   }
3779e97c63d7SStefano Zampini 
37804a658b32SHong Zhang   /* make sure initial time step does not overshoot final time or the next point in tspan */
3781e97c63d7SStefano Zampini   if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
37824a658b32SHong Zhang     PetscReal maxdt;
3783e97c63d7SStefano Zampini     PetscReal dt = ts->time_step;
3784e97c63d7SStefano Zampini 
37854a658b32SHong Zhang     if (ts->tspan) maxdt = ts->tspan->span_times[ts->tspan->spanctr] - ts->ptime;
37864a658b32SHong Zhang     else maxdt = ts->max_time - ts->ptime;
3787e97c63d7SStefano Zampini     ts->time_step = dt >= maxdt ? maxdt : (PetscIsCloseAtTol(dt, maxdt, 10 * PETSC_MACHINE_EPSILON, 0) ? maxdt : dt);
3788e97c63d7SStefano Zampini   }
3789193ac0bcSJed Brown   ts->reason = TS_CONVERGED_ITERATING;
3790193ac0bcSJed Brown 
3791900f6b5bSMatthew G. Knepley   {
3792900f6b5bSMatthew G. Knepley     PetscViewer       viewer;
3793900f6b5bSMatthew G. Knepley     PetscViewerFormat format;
3794900f6b5bSMatthew G. Knepley     PetscBool         flg;
3795900f6b5bSMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
3796900f6b5bSMatthew G. Knepley 
3797900f6b5bSMatthew G. Knepley     if (!incall) {
3798900f6b5bSMatthew G. Knepley       /* Estimate the convergence rate of the time discretization */
37999566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_convergence_estimate", &viewer, &format, &flg));
3800900f6b5bSMatthew G. Knepley       if (flg) {
3801900f6b5bSMatthew G. Knepley         PetscConvEst conv;
3802900f6b5bSMatthew G. Knepley         DM           dm;
3803900f6b5bSMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
3804900f6b5bSMatthew G. Knepley         PetscInt     Nf;
3805f2ed2dc7SMatthew G. Knepley         PetscBool    checkTemporal = PETSC_TRUE;
3806900f6b5bSMatthew G. Knepley 
3807900f6b5bSMatthew G. Knepley         incall = PETSC_TRUE;
38089566063dSJacob Faibussowitsch         PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_convergence_temporal", &checkTemporal, &flg));
38099566063dSJacob Faibussowitsch         PetscCall(TSGetDM(ts, &dm));
38109566063dSJacob Faibussowitsch         PetscCall(DMGetNumFields(dm, &Nf));
38119566063dSJacob Faibussowitsch         PetscCall(PetscCalloc1(PetscMax(Nf, 1), &alpha));
38129566063dSJacob Faibussowitsch         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)ts), &conv));
38139566063dSJacob Faibussowitsch         PetscCall(PetscConvEstUseTS(conv, checkTemporal));
38149566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetSolver(conv, (PetscObject)ts));
38159566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetFromOptions(conv));
38169566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetUp(conv));
38179566063dSJacob Faibussowitsch         PetscCall(PetscConvEstGetConvRate(conv, alpha));
38189566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(viewer, format));
38199566063dSJacob Faibussowitsch         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
38209566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(viewer));
38219566063dSJacob Faibussowitsch         PetscCall(PetscViewerDestroy(&viewer));
38229566063dSJacob Faibussowitsch         PetscCall(PetscConvEstDestroy(&conv));
38239566063dSJacob Faibussowitsch         PetscCall(PetscFree(alpha));
3824900f6b5bSMatthew G. Knepley         incall = PETSC_FALSE;
3825900f6b5bSMatthew G. Knepley       }
3826900f6b5bSMatthew G. Knepley     }
3827900f6b5bSMatthew G. Knepley   }
3828900f6b5bSMatthew G. Knepley 
38299566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts, NULL, "-ts_view_pre"));
3830f05ece33SBarry Smith 
3831193ac0bcSJed Brown   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
3832dbbe0bcdSBarry Smith     PetscUseTypeMethod(ts, solve);
38339566063dSJacob Faibussowitsch     if (u) PetscCall(VecCopy(ts->vec_sol, u));
3834cc708dedSBarry Smith     ts->solvetime = ts->ptime;
3835a6772fa2SLisandro Dalcin     solution      = ts->vec_sol;
3836be5899b3SLisandro Dalcin   } else { /* Step the requested number of timesteps. */
3837db4deed7SKarl Rupp     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
3838db4deed7SKarl Rupp     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3839e7069c78SShri 
38402808aa04SLisandro Dalcin     if (!ts->steps) {
38419566063dSJacob Faibussowitsch       PetscCall(TSTrajectorySet(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
38429566063dSJacob Faibussowitsch       PetscCall(TSEventInitialize(ts->event, ts, ts->ptime, ts->vec_sol));
38432808aa04SLisandro Dalcin     }
38446427ac75SLisandro Dalcin 
3845e1a7a14fSJed Brown     while (!ts->reason) {
38469566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts, ts->steps, ts->ptime, ts->vec_sol));
38471e66621cSBarry Smith       if (!ts->steprollback) PetscCall(TSPreStep(ts));
38489566063dSJacob Faibussowitsch       PetscCall(TSStep(ts));
38491baa6e33SBarry Smith       if (ts->testjacobian) PetscCall(TSRHSJacobianTest(ts, NULL));
38501baa6e33SBarry Smith       if (ts->testjacobiantranspose) PetscCall(TSRHSJacobianTestTranspose(ts, NULL));
3851cd4cee2dSHong Zhang       if (ts->quadraturets && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
38527b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--;            /* Revert the step number changed by TSStep() */
38539566063dSJacob Faibussowitsch         PetscCall(TSForwardCostIntegral(ts));
38547b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
3855b1cb36f3SHong Zhang       }
385658818c2dSLisandro Dalcin       if (ts->forward_solve) {            /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */
38577b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */
38589566063dSJacob Faibussowitsch         PetscCall(TSForwardStep(ts));
38597b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
3860715f1b00SHong Zhang       }
38619566063dSJacob Faibussowitsch       PetscCall(TSPostEvaluate(ts));
38629566063dSJacob 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. */
38631baa6e33SBarry Smith       if (ts->steprollback) PetscCall(TSPostEvaluate(ts));
3864e783b05fSHong Zhang       if (!ts->steprollback) {
38659566063dSJacob Faibussowitsch         PetscCall(TSTrajectorySet(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
38669566063dSJacob Faibussowitsch         PetscCall(TSPostStep(ts));
3867aeb4809dSShri Abhyankar       }
3868193ac0bcSJed Brown     }
38699566063dSJacob Faibussowitsch     PetscCall(TSMonitor(ts, ts->steps, ts->ptime, ts->vec_sol));
38706427ac75SLisandro Dalcin 
387149354f04SShri Abhyankar     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
38729566063dSJacob Faibussowitsch       PetscCall(TSInterpolate(ts, ts->max_time, u));
3873cc708dedSBarry Smith       ts->solvetime = ts->max_time;
3874b06615a5SLisandro Dalcin       solution      = u;
38759566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts, -1, ts->solvetime, solution));
38760574a7fbSJed Brown     } else {
38779566063dSJacob Faibussowitsch       if (u) PetscCall(VecCopy(ts->vec_sol, u));
3878cc708dedSBarry Smith       ts->solvetime = ts->ptime;
3879b06615a5SLisandro Dalcin       solution      = ts->vec_sol;
38800574a7fbSJed Brown     }
3881193ac0bcSJed Brown   }
3882d2daff3dSHong Zhang 
38839566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts, NULL, "-ts_view"));
38849566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(solution, (PetscObject)ts, "-ts_view_solution"));
38859566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsBlock((PetscObject)ts));
38861baa6e33SBarry Smith   if (ts->adjoint_solve) PetscCall(TSAdjointSolve(ts));
38873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38886a4d4014SLisandro Dalcin }
38896a4d4014SLisandro Dalcin 
3890d763cef2SBarry Smith /*@
3891b8123daeSJed Brown    TSGetTime - Gets the time of the most recently completed step.
3892d763cef2SBarry Smith 
3893d763cef2SBarry Smith    Not Collective
3894d763cef2SBarry Smith 
3895d763cef2SBarry Smith    Input Parameter:
3896bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
3897d763cef2SBarry Smith 
3898d763cef2SBarry Smith    Output Parameter:
3899bcf0153eSBarry Smith .  t  - the current time. This time may not corresponds to the final time set with `TSSetMaxTime()`, use `TSGetSolveTime()`.
3900d763cef2SBarry Smith 
3901d763cef2SBarry Smith    Level: beginner
3902d763cef2SBarry Smith 
3903b8123daeSJed Brown    Note:
3904bcf0153eSBarry Smith    When called during time step evaluation (e.g. during residual evaluation or via hooks set using `TSSetPreStep()`,
3905bcf0153eSBarry Smith    `TSSetPreStage()`, `TSSetPostStage()`, or `TSSetPostStep()`), the time is the time at the start of the step being evaluated.
3906b8123daeSJed Brown 
3907bcf0153eSBarry Smith .seealso: [](chapter_ts), TS`, ``TSGetSolveTime()`, `TSSetTime()`, `TSGetTimeStep()`, `TSGetStepNumber()`
3908d763cef2SBarry Smith @*/
3909d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTime(TS ts, PetscReal *t)
3910d71ae5a4SJacob Faibussowitsch {
3911d763cef2SBarry Smith   PetscFunctionBegin;
39120700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3913f7cf8827SBarry Smith   PetscValidRealPointer(t, 2);
3914d763cef2SBarry Smith   *t = ts->ptime;
39153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3916d763cef2SBarry Smith }
3917d763cef2SBarry Smith 
3918e5e524a1SHong Zhang /*@
3919e5e524a1SHong Zhang    TSGetPrevTime - Gets the starting time of the previously completed step.
3920e5e524a1SHong Zhang 
3921e5e524a1SHong Zhang    Not Collective
3922e5e524a1SHong Zhang 
3923e5e524a1SHong Zhang    Input Parameter:
3924bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
3925e5e524a1SHong Zhang 
3926e5e524a1SHong Zhang    Output Parameter:
3927e5e524a1SHong Zhang .  t  - the previous time
3928e5e524a1SHong Zhang 
3929e5e524a1SHong Zhang    Level: beginner
3930e5e524a1SHong Zhang 
3931bcf0153eSBarry Smith .seealso: [](chapter_ts), TS`, ``TSGetTime()`, `TSGetSolveTime()`, `TSGetTimeStep()`
3932e5e524a1SHong Zhang @*/
3933d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetPrevTime(TS ts, PetscReal *t)
3934d71ae5a4SJacob Faibussowitsch {
3935e5e524a1SHong Zhang   PetscFunctionBegin;
3936e5e524a1SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3937e5e524a1SHong Zhang   PetscValidRealPointer(t, 2);
3938e5e524a1SHong Zhang   *t = ts->ptime_prev;
39393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3940e5e524a1SHong Zhang }
3941e5e524a1SHong Zhang 
39426a4d4014SLisandro Dalcin /*@
39436a4d4014SLisandro Dalcin    TSSetTime - Allows one to reset the time.
39446a4d4014SLisandro Dalcin 
3945c3339decSBarry Smith    Logically Collective
39466a4d4014SLisandro Dalcin 
39476a4d4014SLisandro Dalcin    Input Parameters:
3948bcf0153eSBarry Smith +  ts - the `TS` context obtained from `TSCreate()`
39496a4d4014SLisandro Dalcin -  time - the time
39506a4d4014SLisandro Dalcin 
39516a4d4014SLisandro Dalcin    Level: intermediate
39526a4d4014SLisandro Dalcin 
3953bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetTime()`, `TSSetMaxSteps()`
39546a4d4014SLisandro Dalcin @*/
3955d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTime(TS ts, PetscReal t)
3956d71ae5a4SJacob Faibussowitsch {
39576a4d4014SLisandro Dalcin   PetscFunctionBegin;
39580700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3959c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts, t, 2);
39606a4d4014SLisandro Dalcin   ts->ptime = t;
39613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39626a4d4014SLisandro Dalcin }
39636a4d4014SLisandro Dalcin 
3964d763cef2SBarry Smith /*@C
3965d763cef2SBarry Smith    TSSetOptionsPrefix - Sets the prefix used for searching for all
3966d763cef2SBarry Smith    TS options in the database.
3967d763cef2SBarry Smith 
3968c3339decSBarry Smith    Logically Collective
3969d763cef2SBarry Smith 
3970d8d19677SJose E. Roman    Input Parameters:
3971bcf0153eSBarry Smith +  ts     - The `TS` context
3972d763cef2SBarry Smith -  prefix - The prefix to prepend to all option names
3973d763cef2SBarry Smith 
3974bcf0153eSBarry Smith    Level: advanced
3975bcf0153eSBarry Smith 
3976bcf0153eSBarry Smith    Note:
3977d763cef2SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
3978d763cef2SBarry Smith    The first character of all runtime options is AUTOMATICALLY the
3979d763cef2SBarry Smith    hyphen.
3980d763cef2SBarry Smith 
3981bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetFromOptions()`, `TSAppendOptionsPrefix()`
3982d763cef2SBarry Smith @*/
3983d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetOptionsPrefix(TS ts, const char prefix[])
3984d71ae5a4SJacob Faibussowitsch {
3985089b2837SJed Brown   SNES snes;
3986d763cef2SBarry Smith 
3987d763cef2SBarry Smith   PetscFunctionBegin;
39880700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
39899566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ts, prefix));
39909566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
39919566063dSJacob Faibussowitsch   PetscCall(SNESSetOptionsPrefix(snes, prefix));
39923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3993d763cef2SBarry Smith }
3994d763cef2SBarry Smith 
3995d763cef2SBarry Smith /*@C
3996d763cef2SBarry Smith    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
3997d763cef2SBarry Smith    TS options in the database.
3998d763cef2SBarry Smith 
3999c3339decSBarry Smith    Logically Collective
4000d763cef2SBarry Smith 
4001d8d19677SJose E. Roman    Input Parameters:
4002bcf0153eSBarry Smith +  ts     - The `TS` context
4003d763cef2SBarry Smith -  prefix - The prefix to prepend to all option names
4004d763cef2SBarry Smith 
4005bcf0153eSBarry Smith    Level: advanced
4006bcf0153eSBarry Smith 
4007bcf0153eSBarry Smith    Note:
4008d763cef2SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
4009d763cef2SBarry Smith    The first character of all runtime options is AUTOMATICALLY the
4010d763cef2SBarry Smith    hyphen.
4011d763cef2SBarry Smith 
4012bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetOptionsPrefix()`, `TSSetOptionsPrefix()`, `TSSetFromOptions()`
4013d763cef2SBarry Smith @*/
4014d71ae5a4SJacob Faibussowitsch PetscErrorCode TSAppendOptionsPrefix(TS ts, const char prefix[])
4015d71ae5a4SJacob Faibussowitsch {
4016089b2837SJed Brown   SNES snes;
4017d763cef2SBarry Smith 
4018d763cef2SBarry Smith   PetscFunctionBegin;
40190700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
40209566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)ts, prefix));
40219566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
40229566063dSJacob Faibussowitsch   PetscCall(SNESAppendOptionsPrefix(snes, prefix));
40233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4024d763cef2SBarry Smith }
4025d763cef2SBarry Smith 
4026d763cef2SBarry Smith /*@C
4027d763cef2SBarry Smith    TSGetOptionsPrefix - Sets the prefix used for searching for all
4028bcf0153eSBarry Smith    `TS` options in the database.
4029d763cef2SBarry Smith 
4030d763cef2SBarry Smith    Not Collective
4031d763cef2SBarry Smith 
4032d763cef2SBarry Smith    Input Parameter:
4033bcf0153eSBarry Smith .  ts - The `TS` context
4034d763cef2SBarry Smith 
4035d763cef2SBarry Smith    Output Parameter:
4036d763cef2SBarry Smith .  prefix - A pointer to the prefix string used
4037d763cef2SBarry Smith 
4038d763cef2SBarry Smith    Level: intermediate
4039d763cef2SBarry Smith 
4040bcf0153eSBarry Smith    Fortran Note:
4041bcf0153eSBarry Smith    On the fortran side, the user should pass in a string 'prefix' of
4042bcf0153eSBarry Smith    sufficient length to hold the prefix.
4043bcf0153eSBarry Smith 
4044bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSAppendOptionsPrefix()`, `TSSetFromOptions()`
4045d763cef2SBarry Smith @*/
4046d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetOptionsPrefix(TS ts, const char *prefix[])
4047d71ae5a4SJacob Faibussowitsch {
4048d763cef2SBarry Smith   PetscFunctionBegin;
40490700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
40504482741eSBarry Smith   PetscValidPointer(prefix, 2);
40519566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, prefix));
40523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4053d763cef2SBarry Smith }
4054d763cef2SBarry Smith 
4055d763cef2SBarry Smith /*@C
4056d763cef2SBarry Smith    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4057d763cef2SBarry Smith 
4058bcf0153eSBarry Smith    Not Collective, but parallel objects are returned if ts is parallel
4059d763cef2SBarry Smith 
4060d763cef2SBarry Smith    Input Parameter:
4061bcf0153eSBarry Smith .  ts  - The `TS` context obtained from `TSCreate()`
4062d763cef2SBarry Smith 
4063d763cef2SBarry Smith    Output Parameters:
4064e4357dc4SBarry Smith +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4065e4357dc4SBarry Smith .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4066e4357dc4SBarry Smith .  func - Function to compute the Jacobian of the RHS  (or NULL)
4067e4357dc4SBarry Smith -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4068d763cef2SBarry Smith 
4069d763cef2SBarry Smith    Level: intermediate
4070d763cef2SBarry Smith 
4071bcf0153eSBarry Smith    Note:
4072bcf0153eSBarry Smith     You can pass in NULL for any return argument you do not need.
4073bcf0153eSBarry Smith 
4074bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
4075d763cef2SBarry Smith 
4076d763cef2SBarry Smith @*/
4077d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetRHSJacobian(TS ts, Mat *Amat, Mat *Pmat, TSRHSJacobian *func, void **ctx)
4078d71ae5a4SJacob Faibussowitsch {
407924989b8cSPeter Brune   DM dm;
4080089b2837SJed Brown 
4081d763cef2SBarry Smith   PetscFunctionBegin;
408223a57915SBarry Smith   if (Amat || Pmat) {
408323a57915SBarry Smith     SNES snes;
40849566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
40859566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
40869566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
408723a57915SBarry Smith   }
40889566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
40899566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, func, ctx));
40903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4091d763cef2SBarry Smith }
4092d763cef2SBarry Smith 
40932eca1d9cSJed Brown /*@C
40942eca1d9cSJed Brown    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
40952eca1d9cSJed Brown 
4096bcf0153eSBarry Smith    Not Collective, but parallel objects are returned if ts is parallel
40972eca1d9cSJed Brown 
40982eca1d9cSJed Brown    Input Parameter:
4099bcf0153eSBarry Smith .  ts  - The `TS` context obtained from `TSCreate()`
41002eca1d9cSJed Brown 
41012eca1d9cSJed Brown    Output Parameters:
4102e4357dc4SBarry Smith +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4103e4357dc4SBarry Smith .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
41042eca1d9cSJed Brown .  f   - The function to compute the matrices
41052eca1d9cSJed Brown - ctx - User-defined context for Jacobian evaluation routine
41062eca1d9cSJed Brown 
41072eca1d9cSJed Brown    Level: advanced
41082eca1d9cSJed Brown 
4109bcf0153eSBarry Smith    Note:
4110bcf0153eSBarry Smith     You can pass in NULL for any return argument you do not need.
4111bcf0153eSBarry Smith 
4112bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetTimeStep()`, `TSGetRHSJacobian()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
41132eca1d9cSJed Brown 
41142eca1d9cSJed Brown @*/
4115d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetIJacobian(TS ts, Mat *Amat, Mat *Pmat, TSIJacobian *f, void **ctx)
4116d71ae5a4SJacob Faibussowitsch {
411724989b8cSPeter Brune   DM dm;
41180910c330SBarry Smith 
41192eca1d9cSJed Brown   PetscFunctionBegin;
4120c0aab802Sstefano_zampini   if (Amat || Pmat) {
4121c0aab802Sstefano_zampini     SNES snes;
41229566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
41239566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
41249566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
4125c0aab802Sstefano_zampini   }
41269566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
41279566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, f, ctx));
41283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41292eca1d9cSJed Brown }
41302eca1d9cSJed Brown 
4131af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
41326c699258SBarry Smith /*@
4133bcf0153eSBarry Smith    TSSetDM - Sets the `DM` that may be used by some nonlinear solvers or preconditioners under the `TS`
41346c699258SBarry Smith 
4135c3339decSBarry Smith    Logically Collective
41366c699258SBarry Smith 
41376c699258SBarry Smith    Input Parameters:
4138bcf0153eSBarry Smith +  ts - the `TS` integrator object
41392a808120SBarry Smith -  dm - the dm, cannot be NULL
41406c699258SBarry Smith 
41416c699258SBarry Smith    Level: intermediate
41426c699258SBarry Smith 
4143bcf0153eSBarry Smith    Notes:
4144bcf0153eSBarry Smith    A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`,
4145bcf0153eSBarry Smith    even when not using interfaces like `DMTSSetIFunction()`.  Use `DMClone()` to get a distinct `DM` when solving
4146bcf0153eSBarry Smith    different problems using the same function space.
4147bcf0153eSBarry Smith 
4148bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `DM`, `TSGetDM()`, `SNESSetDM()`, `SNESGetDM()`
41496c699258SBarry Smith @*/
4150d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetDM(TS ts, DM dm)
4151d71ae5a4SJacob Faibussowitsch {
4152089b2837SJed Brown   SNES snes;
4153942e3340SBarry Smith   DMTS tsdm;
41546c699258SBarry Smith 
41556c699258SBarry Smith   PetscFunctionBegin;
41560700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
41572a808120SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
41589566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)dm));
4159942e3340SBarry Smith   if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */
41602a34c10cSBarry Smith     if (ts->dm->dmts && !dm->dmts) {
41619566063dSJacob Faibussowitsch       PetscCall(DMCopyDMTS(ts->dm, dm));
41629566063dSJacob Faibussowitsch       PetscCall(DMGetDMTS(ts->dm, &tsdm));
41631e66621cSBarry Smith       /* Grant write privileges to the replacement DM */
41641e66621cSBarry Smith       if (tsdm->originaldm == ts->dm) tsdm->originaldm = dm;
416524989b8cSPeter Brune     }
41669566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&ts->dm));
416724989b8cSPeter Brune   }
41686c699258SBarry Smith   ts->dm = dm;
4169bbd56ea5SKarl Rupp 
41709566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
41719566063dSJacob Faibussowitsch   PetscCall(SNESSetDM(snes, dm));
41723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41736c699258SBarry Smith }
41746c699258SBarry Smith 
41756c699258SBarry Smith /*@
4176bcf0153eSBarry Smith    TSGetDM - Gets the `DM` that may be used by some preconditioners
41776c699258SBarry Smith 
41783f9fe445SBarry Smith    Not Collective
41796c699258SBarry Smith 
41806c699258SBarry Smith    Input Parameter:
4181bcf0153eSBarry Smith . ts - the `TS`
41826c699258SBarry Smith 
41836c699258SBarry Smith    Output Parameter:
41846c699258SBarry Smith .  dm - the dm
41856c699258SBarry Smith 
41866c699258SBarry Smith    Level: intermediate
41876c699258SBarry Smith 
4188bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `DM`, `TSSetDM()`, `SNESSetDM()`, `SNESGetDM()`
41896c699258SBarry Smith @*/
4190d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetDM(TS ts, DM *dm)
4191d71ae5a4SJacob Faibussowitsch {
41926c699258SBarry Smith   PetscFunctionBegin;
41930700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4194496e6a7aSJed Brown   if (!ts->dm) {
41959566063dSJacob Faibussowitsch     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)ts), &ts->dm));
41969566063dSJacob Faibussowitsch     if (ts->snes) PetscCall(SNESSetDM(ts->snes, ts->dm));
4197496e6a7aSJed Brown   }
41986c699258SBarry Smith   *dm = ts->dm;
41993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42006c699258SBarry Smith }
42011713a123SBarry Smith 
42020f5c6efeSJed Brown /*@
42030f5c6efeSJed Brown    SNESTSFormFunction - Function to evaluate nonlinear residual
42040f5c6efeSJed Brown 
4205c3339decSBarry Smith    Logically Collective
42060f5c6efeSJed Brown 
4207d8d19677SJose E. Roman    Input Parameters:
4208d42a1c89SJed Brown + snes - nonlinear solver
42090910c330SBarry Smith . U - the current state at which to evaluate the residual
4210d42a1c89SJed Brown - ctx - user context, must be a TS
42110f5c6efeSJed Brown 
42120f5c6efeSJed Brown    Output Parameter:
42130f5c6efeSJed Brown . F - the nonlinear residual
42140f5c6efeSJed Brown 
42150f5c6efeSJed Brown    Level: advanced
42160f5c6efeSJed Brown 
4217bcf0153eSBarry Smith    Note:
4218bcf0153eSBarry Smith    This function is not normally called by users and is automatically registered with the `SNES` used by `TS`.
4219bcf0153eSBarry Smith    It is most frequently passed to `MatFDColoringSetFunction()`.
4220bcf0153eSBarry Smith 
4221bcf0153eSBarry Smith .seealso: [](chapter_ts), `SNESSetFunction()`, `MatFDColoringSetFunction()`
42220f5c6efeSJed Brown @*/
4223d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTSFormFunction(SNES snes, Vec U, Vec F, void *ctx)
4224d71ae5a4SJacob Faibussowitsch {
42250f5c6efeSJed Brown   TS ts = (TS)ctx;
42260f5c6efeSJed Brown 
42270f5c6efeSJed Brown   PetscFunctionBegin;
42280f5c6efeSJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
42290910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
42300f5c6efeSJed Brown   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
42310f5c6efeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 4);
42329566063dSJacob Faibussowitsch   PetscCall((ts->ops->snesfunction)(snes, U, F, ts));
42333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42340f5c6efeSJed Brown }
42350f5c6efeSJed Brown 
42360f5c6efeSJed Brown /*@
42370f5c6efeSJed Brown    SNESTSFormJacobian - Function to evaluate the Jacobian
42380f5c6efeSJed Brown 
4239c3339decSBarry Smith    Collective
42400f5c6efeSJed Brown 
4241d8d19677SJose E. Roman    Input Parameters:
42420f5c6efeSJed Brown + snes - nonlinear solver
42430910c330SBarry Smith . U - the current state at which to evaluate the residual
4244bcf0153eSBarry Smith - ctx - user context, must be a `TS`
42450f5c6efeSJed Brown 
4246d8d19677SJose E. Roman    Output Parameters:
42470f5c6efeSJed Brown + A - the Jacobian
42486b867d5aSJose E. Roman - B - the preconditioning matrix (may be the same as A)
42490f5c6efeSJed Brown 
42500f5c6efeSJed Brown    Level: developer
42510f5c6efeSJed Brown 
4252bcf0153eSBarry Smith    Note:
4253bcf0153eSBarry Smith    This function is not normally called by users and is automatically registered with the `SNES` used by `TS`.
4254bcf0153eSBarry Smith 
4255bcf0153eSBarry Smith .seealso: [](chapter_ts), `SNESSetJacobian()`
42560f5c6efeSJed Brown @*/
4257d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTSFormJacobian(SNES snes, Vec U, Mat A, Mat B, void *ctx)
4258d71ae5a4SJacob Faibussowitsch {
42590f5c6efeSJed Brown   TS ts = (TS)ctx;
42600f5c6efeSJed Brown 
42610f5c6efeSJed Brown   PetscFunctionBegin;
42620f5c6efeSJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
42630910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
42640f5c6efeSJed Brown   PetscValidPointer(A, 3);
426594ab13aaSBarry Smith   PetscValidHeaderSpecific(A, MAT_CLASSID, 3);
42660f5c6efeSJed Brown   PetscValidPointer(B, 4);
426794ab13aaSBarry Smith   PetscValidHeaderSpecific(B, MAT_CLASSID, 4);
4268064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(ts, TS_CLASSID, 5);
42699566063dSJacob Faibussowitsch   PetscCall((ts->ops->snesjacobian)(snes, U, A, B, ts));
42703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42710f5c6efeSJed Brown }
4272325fc9f4SBarry Smith 
42730e4ef248SJed Brown /*@C
42749ae8fd06SBarry Smith    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
42750e4ef248SJed Brown 
4276c3339decSBarry Smith    Collective
42770e4ef248SJed Brown 
42784165533cSJose E. Roman    Input Parameters:
42790e4ef248SJed Brown +  ts - time stepping context
42800e4ef248SJed Brown .  t - time at which to evaluate
42810910c330SBarry Smith .  U - state at which to evaluate
42820e4ef248SJed Brown -  ctx - context
42830e4ef248SJed Brown 
42844165533cSJose E. Roman    Output Parameter:
42850e4ef248SJed Brown .  F - right hand side
42860e4ef248SJed Brown 
42870e4ef248SJed Brown    Level: intermediate
42880e4ef248SJed Brown 
4289bcf0153eSBarry Smith    Note:
4290bcf0153eSBarry Smith    This function is intended to be passed to `TSSetRHSFunction()` to evaluate the right hand side for linear problems.
4291bcf0153eSBarry Smith    The matrix (and optionally the evaluation context) should be passed to `TSSetRHSJacobian()`.
42920e4ef248SJed Brown 
4293bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
42940e4ef248SJed Brown @*/
4295d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSFunctionLinear(TS ts, PetscReal t, Vec U, Vec F, void *ctx)
4296d71ae5a4SJacob Faibussowitsch {
42970e4ef248SJed Brown   Mat Arhs, Brhs;
42980e4ef248SJed Brown 
42990e4ef248SJed Brown   PetscFunctionBegin;
43009566063dSJacob Faibussowitsch   PetscCall(TSGetRHSMats_Private(ts, &Arhs, &Brhs));
43012663174eSHong Zhang   /* undo the damage caused by shifting */
43029566063dSJacob Faibussowitsch   PetscCall(TSRecoverRHSJacobian(ts, Arhs, Brhs));
43039566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSJacobian(ts, t, U, Arhs, Brhs));
43049566063dSJacob Faibussowitsch   PetscCall(MatMult(Arhs, U, F));
43053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43060e4ef248SJed Brown }
43070e4ef248SJed Brown 
43080e4ef248SJed Brown /*@C
43090e4ef248SJed Brown    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
43100e4ef248SJed Brown 
4311c3339decSBarry Smith    Collective
43120e4ef248SJed Brown 
43134165533cSJose E. Roman    Input Parameters:
43140e4ef248SJed Brown +  ts - time stepping context
43150e4ef248SJed Brown .  t - time at which to evaluate
43160910c330SBarry Smith .  U - state at which to evaluate
43170e4ef248SJed Brown -  ctx - context
43180e4ef248SJed Brown 
43194165533cSJose E. Roman    Output Parameters:
43200e4ef248SJed Brown +  A - pointer to operator
432197bb3fdcSJose E. Roman -  B - pointer to preconditioning matrix
43220e4ef248SJed Brown 
43230e4ef248SJed Brown    Level: intermediate
43240e4ef248SJed Brown 
4325bcf0153eSBarry Smith    Note:
4326bcf0153eSBarry Smith    This function is intended to be passed to `TSSetRHSJacobian()` to evaluate the Jacobian for linear time-independent problems.
43270e4ef248SJed Brown 
4328bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSFunctionLinear()`
43290e4ef248SJed Brown @*/
4330d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeRHSJacobianConstant(TS ts, PetscReal t, Vec U, Mat A, Mat B, void *ctx)
4331d71ae5a4SJacob Faibussowitsch {
43320e4ef248SJed Brown   PetscFunctionBegin;
43333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43340e4ef248SJed Brown }
43350e4ef248SJed Brown 
43360026cea9SSean Farley /*@C
43370026cea9SSean Farley    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
43380026cea9SSean Farley 
4339c3339decSBarry Smith    Collective
43400026cea9SSean Farley 
43414165533cSJose E. Roman    Input Parameters:
43420026cea9SSean Farley +  ts - time stepping context
43430026cea9SSean Farley .  t - time at which to evaluate
43440910c330SBarry Smith .  U - state at which to evaluate
43450910c330SBarry Smith .  Udot - time derivative of state vector
43460026cea9SSean Farley -  ctx - context
43470026cea9SSean Farley 
43484165533cSJose E. Roman    Output Parameter:
43490026cea9SSean Farley .  F - left hand side
43500026cea9SSean Farley 
43510026cea9SSean Farley    Level: intermediate
43520026cea9SSean Farley 
43530026cea9SSean Farley    Notes:
43540910c330SBarry 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
4355bcf0153eSBarry Smith    user is required to write their own `TSComputeIFunction()`.
4356bcf0153eSBarry Smith    This function is intended to be passed to `TSSetIFunction()` to evaluate the left hand side for linear problems.
4357bcf0153eSBarry Smith    The matrix (and optionally the evaluation context) should be passed to `TSSetIJacobian()`.
43580026cea9SSean Farley 
4359bcf0153eSBarry Smith    Note that using this function is NOT equivalent to using `TSComputeRHSFunctionLinear()` since that solves Udot = A U
43609ae8fd06SBarry Smith 
4361bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIJacobianConstant()`, `TSComputeRHSFunctionLinear()`
43620026cea9SSean Farley @*/
4363d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIFunctionLinear(TS ts, PetscReal t, Vec U, Vec Udot, Vec F, void *ctx)
4364d71ae5a4SJacob Faibussowitsch {
43650026cea9SSean Farley   Mat A, B;
43660026cea9SSean Farley 
43670026cea9SSean Farley   PetscFunctionBegin;
43689566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts, &A, &B, NULL, NULL));
43699566063dSJacob Faibussowitsch   PetscCall(TSComputeIJacobian(ts, t, U, Udot, 1.0, A, B, PETSC_TRUE));
43709566063dSJacob Faibussowitsch   PetscCall(MatMult(A, Udot, F));
43713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43720026cea9SSean Farley }
43730026cea9SSean Farley 
43740026cea9SSean Farley /*@C
4375b41af12eSJed Brown    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
43760026cea9SSean Farley 
4377c3339decSBarry Smith    Collective
43780026cea9SSean Farley 
43794165533cSJose E. Roman    Input Parameters:
43800026cea9SSean Farley +  ts - time stepping context
43810026cea9SSean Farley .  t - time at which to evaluate
43820910c330SBarry Smith .  U - state at which to evaluate
43830910c330SBarry Smith .  Udot - time derivative of state vector
43840026cea9SSean Farley .  shift - shift to apply
43850026cea9SSean Farley -  ctx - context
43860026cea9SSean Farley 
43874165533cSJose E. Roman    Output Parameters:
43880026cea9SSean Farley +  A - pointer to operator
438997bb3fdcSJose E. Roman -  B - pointer to preconditioning matrix
43900026cea9SSean Farley 
4391b41af12eSJed Brown    Level: advanced
43920026cea9SSean Farley 
43930026cea9SSean Farley    Notes:
4394bcf0153eSBarry Smith    This function is intended to be passed to `TSSetIJacobian()` to evaluate the Jacobian for linear time-independent problems.
43950026cea9SSean Farley 
4396b41af12eSJed Brown    It is only appropriate for problems of the form
4397b41af12eSJed Brown 
4398b41af12eSJed Brown $     M Udot = F(U,t)
4399b41af12eSJed Brown 
4400bcf0153eSBarry Smith   where M is constant and F is non-stiff.  The user must pass M to `TSSetIJacobian()`.  The current implementation only
4401bcf0153eSBarry Smith   works with IMEX time integration methods such as `TSROSW` and `TSARKIMEX`, since there is no support for de-constructing
4402b41af12eSJed Brown   an implicit operator of the form
4403b41af12eSJed Brown 
4404b41af12eSJed Brown $    shift*M + J
4405b41af12eSJed Brown 
4406b41af12eSJed 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
4407b41af12eSJed Brown   a copy of M or reassemble it when requested.
4408b41af12eSJed Brown 
4409bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSROSW`, `TSARKIMEX`, `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIFunctionLinear()`
44100026cea9SSean Farley @*/
4411d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIJacobianConstant(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat A, Mat B, void *ctx)
4412d71ae5a4SJacob Faibussowitsch {
44130026cea9SSean Farley   PetscFunctionBegin;
44149566063dSJacob Faibussowitsch   PetscCall(MatScale(A, shift / ts->ijacobian.shift));
4415b41af12eSJed Brown   ts->ijacobian.shift = shift;
44163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44170026cea9SSean Farley }
4418b41af12eSJed Brown 
4419e817cc15SEmil Constantinescu /*@
4420bcf0153eSBarry Smith    TSGetEquationType - Gets the type of the equation that `TS` is solving.
4421e817cc15SEmil Constantinescu 
4422e817cc15SEmil Constantinescu    Not Collective
4423e817cc15SEmil Constantinescu 
4424e817cc15SEmil Constantinescu    Input Parameter:
4425bcf0153eSBarry Smith .  ts - the `TS` context
4426e817cc15SEmil Constantinescu 
4427e817cc15SEmil Constantinescu    Output Parameter:
4428bcf0153eSBarry Smith .  equation_type - see `TSEquationType`
4429e817cc15SEmil Constantinescu 
4430e817cc15SEmil Constantinescu    Level: beginner
4431e817cc15SEmil Constantinescu 
4432bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetEquationType()`, `TSEquationType`
4433e817cc15SEmil Constantinescu @*/
4434d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetEquationType(TS ts, TSEquationType *equation_type)
4435d71ae5a4SJacob Faibussowitsch {
4436e817cc15SEmil Constantinescu   PetscFunctionBegin;
4437e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4438e817cc15SEmil Constantinescu   PetscValidPointer(equation_type, 2);
4439e817cc15SEmil Constantinescu   *equation_type = ts->equation_type;
44403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4441e817cc15SEmil Constantinescu }
4442e817cc15SEmil Constantinescu 
4443e817cc15SEmil Constantinescu /*@
4444bcf0153eSBarry Smith    TSSetEquationType - Sets the type of the equation that `TS` is solving.
4445e817cc15SEmil Constantinescu 
4446e817cc15SEmil Constantinescu    Not Collective
4447e817cc15SEmil Constantinescu 
4448d8d19677SJose E. Roman    Input Parameters:
4449bcf0153eSBarry Smith +  ts - the `TS` context
4450bcf0153eSBarry Smith -  equation_type - see `TSEquationType`
4451e817cc15SEmil Constantinescu 
4452e817cc15SEmil Constantinescu    Level: advanced
4453e817cc15SEmil Constantinescu 
4454bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetEquationType()`, `TSEquationType`
4455e817cc15SEmil Constantinescu @*/
4456d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetEquationType(TS ts, TSEquationType equation_type)
4457d71ae5a4SJacob Faibussowitsch {
4458e817cc15SEmil Constantinescu   PetscFunctionBegin;
4459e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4460e817cc15SEmil Constantinescu   ts->equation_type = equation_type;
44613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4462e817cc15SEmil Constantinescu }
44630026cea9SSean Farley 
44644af1b03aSJed Brown /*@
4465bcf0153eSBarry Smith    TSGetConvergedReason - Gets the reason the `TS` iteration was stopped.
44664af1b03aSJed Brown 
44674af1b03aSJed Brown    Not Collective
44684af1b03aSJed Brown 
44694af1b03aSJed Brown    Input Parameter:
4470bcf0153eSBarry Smith .  ts - the `TS` context
44714af1b03aSJed Brown 
44724af1b03aSJed Brown    Output Parameter:
4473bcf0153eSBarry Smith .  reason - negative value indicates diverged, positive value converged, see `TSConvergedReason` or the
44744af1b03aSJed Brown             manual pages for the individual convergence tests for complete lists
44754af1b03aSJed Brown 
4476487e0bb9SJed Brown    Level: beginner
44774af1b03aSJed Brown 
4478bcf0153eSBarry Smith    Note:
4479bcf0153eSBarry Smith    Can only be called after the call to `TSSolve()` is complete.
44804af1b03aSJed Brown 
4481bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSolve()`, `TSSetConvergenceTest()`, `TSConvergedReason`
44824af1b03aSJed Brown @*/
4483d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetConvergedReason(TS ts, TSConvergedReason *reason)
4484d71ae5a4SJacob Faibussowitsch {
44854af1b03aSJed Brown   PetscFunctionBegin;
44864af1b03aSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
44874af1b03aSJed Brown   PetscValidPointer(reason, 2);
44884af1b03aSJed Brown   *reason = ts->reason;
44893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44904af1b03aSJed Brown }
44914af1b03aSJed Brown 
4492d6ad946cSShri Abhyankar /*@
4493bcf0153eSBarry Smith    TSSetConvergedReason - Sets the reason for handling the convergence of `TSSolve()`.
4494d6ad946cSShri Abhyankar 
44956b221cbeSPatrick Sanan    Logically Collective; reason must contain common value
4496d6ad946cSShri Abhyankar 
44976b221cbeSPatrick Sanan    Input Parameters:
4498bcf0153eSBarry Smith +  ts - the `TS` context
4499bcf0153eSBarry Smith -  reason - negative value indicates diverged, positive value converged, see `TSConvergedReason` or the
4500d6ad946cSShri Abhyankar             manual pages for the individual convergence tests for complete lists
4501d6ad946cSShri Abhyankar 
4502f5abba47SShri Abhyankar    Level: advanced
4503d6ad946cSShri Abhyankar 
4504bcf0153eSBarry Smith    Note:
4505bcf0153eSBarry Smith    Can only be called while `TSSolve()` is active.
4506d6ad946cSShri Abhyankar 
4507bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSolve()`, `TSConvergedReason`
4508d6ad946cSShri Abhyankar @*/
4509d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetConvergedReason(TS ts, TSConvergedReason reason)
4510d71ae5a4SJacob Faibussowitsch {
4511d6ad946cSShri Abhyankar   PetscFunctionBegin;
4512d6ad946cSShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4513d6ad946cSShri Abhyankar   ts->reason = reason;
45143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4515d6ad946cSShri Abhyankar }
4516d6ad946cSShri Abhyankar 
4517cc708dedSBarry Smith /*@
4518bcf0153eSBarry Smith    TSGetSolveTime - Gets the time after a call to `TSSolve()`
4519cc708dedSBarry Smith 
4520cc708dedSBarry Smith    Not Collective
4521cc708dedSBarry Smith 
4522cc708dedSBarry Smith    Input Parameter:
4523bcf0153eSBarry Smith .  ts - the `TS` context
4524cc708dedSBarry Smith 
4525cc708dedSBarry Smith    Output Parameter:
4526bcf0153eSBarry Smith .  ftime - the final time. This time corresponds to the final time set with `TSSetMaxTime()`
4527cc708dedSBarry Smith 
4528487e0bb9SJed Brown    Level: beginner
4529cc708dedSBarry Smith 
4530bcf0153eSBarry Smith    Note:
4531bcf0153eSBarry Smith    Can only be called after the call to `TSSolve()` is complete.
4532cc708dedSBarry Smith 
4533bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSolve()`, `TSSetConvergenceTest()`, `TSConvergedReason`
4534cc708dedSBarry Smith @*/
4535d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSolveTime(TS ts, PetscReal *ftime)
4536d71ae5a4SJacob Faibussowitsch {
4537cc708dedSBarry Smith   PetscFunctionBegin;
4538cc708dedSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4539dadcf809SJacob Faibussowitsch   PetscValidRealPointer(ftime, 2);
4540cc708dedSBarry Smith   *ftime = ts->solvetime;
45413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4542cc708dedSBarry Smith }
4543cc708dedSBarry Smith 
45442c18e0fdSBarry Smith /*@
45455ef26d82SJed Brown    TSGetSNESIterations - Gets the total number of nonlinear iterations
45469f67acb7SJed Brown    used by the time integrator.
45479f67acb7SJed Brown 
45489f67acb7SJed Brown    Not Collective
45499f67acb7SJed Brown 
45509f67acb7SJed Brown    Input Parameter:
4551bcf0153eSBarry Smith .  ts - `TS` context
45529f67acb7SJed Brown 
45539f67acb7SJed Brown    Output Parameter:
45549f67acb7SJed Brown .  nits - number of nonlinear iterations
45559f67acb7SJed Brown 
45569f67acb7SJed Brown    Level: intermediate
45579f67acb7SJed Brown 
4558bcf0153eSBarry Smith    Notes:
4559bcf0153eSBarry Smith    This counter is reset to zero for each successive call to `TSSolve()`.
4560bcf0153eSBarry Smith 
4561bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSolve()`, `TSGetKSPIterations()`
45629f67acb7SJed Brown @*/
4563d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSNESIterations(TS ts, PetscInt *nits)
4564d71ae5a4SJacob Faibussowitsch {
45659f67acb7SJed Brown   PetscFunctionBegin;
45669f67acb7SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
45679f67acb7SJed Brown   PetscValidIntPointer(nits, 2);
45685ef26d82SJed Brown   *nits = ts->snes_its;
45693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45709f67acb7SJed Brown }
45719f67acb7SJed Brown 
45729f67acb7SJed Brown /*@
45735ef26d82SJed Brown    TSGetKSPIterations - Gets the total number of linear iterations
45749f67acb7SJed Brown    used by the time integrator.
45759f67acb7SJed Brown 
45769f67acb7SJed Brown    Not Collective
45779f67acb7SJed Brown 
45789f67acb7SJed Brown    Input Parameter:
4579bcf0153eSBarry Smith .  ts - `TS` context
45809f67acb7SJed Brown 
45819f67acb7SJed Brown    Output Parameter:
45829f67acb7SJed Brown .  lits - number of linear iterations
45839f67acb7SJed Brown 
45849f67acb7SJed Brown    Level: intermediate
45859f67acb7SJed Brown 
4586bcf0153eSBarry Smith    Note:
4587bcf0153eSBarry Smith    This counter is reset to zero for each successive call to `TSSolve()`.
4588bcf0153eSBarry Smith 
4589bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSolve()`, `TSGetSNESIterations()`, `SNESGetKSPIterations()`
45909f67acb7SJed Brown @*/
4591d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetKSPIterations(TS ts, PetscInt *lits)
4592d71ae5a4SJacob Faibussowitsch {
45939f67acb7SJed Brown   PetscFunctionBegin;
45949f67acb7SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
45959f67acb7SJed Brown   PetscValidIntPointer(lits, 2);
45965ef26d82SJed Brown   *lits = ts->ksp_its;
45973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45989f67acb7SJed Brown }
45999f67acb7SJed Brown 
4600cef5090cSJed Brown /*@
4601cef5090cSJed Brown    TSGetStepRejections - Gets the total number of rejected steps.
4602cef5090cSJed Brown 
4603cef5090cSJed Brown    Not Collective
4604cef5090cSJed Brown 
4605cef5090cSJed Brown    Input Parameter:
4606bcf0153eSBarry Smith .  ts - `TS` context
4607cef5090cSJed Brown 
4608cef5090cSJed Brown    Output Parameter:
4609cef5090cSJed Brown .  rejects - number of steps rejected
4610cef5090cSJed Brown 
4611cef5090cSJed Brown    Level: intermediate
4612cef5090cSJed Brown 
4613bcf0153eSBarry Smith    Note:
4614bcf0153eSBarry Smith    This counter is reset to zero for each successive call to `TSSolve()`.
4615bcf0153eSBarry Smith 
4616bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSolve()`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetSNESFailures()`, `TSSetMaxSNESFailures()`, `TSSetErrorIfStepFails()`
4617cef5090cSJed Brown @*/
4618d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetStepRejections(TS ts, PetscInt *rejects)
4619d71ae5a4SJacob Faibussowitsch {
4620cef5090cSJed Brown   PetscFunctionBegin;
4621cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4622cef5090cSJed Brown   PetscValidIntPointer(rejects, 2);
4623cef5090cSJed Brown   *rejects = ts->reject;
46243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4625cef5090cSJed Brown }
4626cef5090cSJed Brown 
4627cef5090cSJed Brown /*@
4628bcf0153eSBarry Smith    TSGetSNESFailures - Gets the total number of failed `SNES` solves in a `TS`
4629cef5090cSJed Brown 
4630cef5090cSJed Brown    Not Collective
4631cef5090cSJed Brown 
4632cef5090cSJed Brown    Input Parameter:
4633bcf0153eSBarry Smith .  ts - `TS` context
4634cef5090cSJed Brown 
4635cef5090cSJed Brown    Output Parameter:
4636cef5090cSJed Brown .  fails - number of failed nonlinear solves
4637cef5090cSJed Brown 
4638cef5090cSJed Brown    Level: intermediate
4639cef5090cSJed Brown 
4640bcf0153eSBarry Smith    Note:
4641bcf0153eSBarry Smith    This counter is reset to zero for each successive call to `TSSolve()`.
4642bcf0153eSBarry Smith 
4643bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSolve()`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSSetMaxSNESFailures()`
4644cef5090cSJed Brown @*/
4645d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetSNESFailures(TS ts, PetscInt *fails)
4646d71ae5a4SJacob Faibussowitsch {
4647cef5090cSJed Brown   PetscFunctionBegin;
4648cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4649cef5090cSJed Brown   PetscValidIntPointer(fails, 2);
4650cef5090cSJed Brown   *fails = ts->num_snes_failures;
46513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4652cef5090cSJed Brown }
4653cef5090cSJed Brown 
4654cef5090cSJed Brown /*@
4655bcf0153eSBarry Smith    TSSetMaxStepRejections - Sets the maximum number of step rejections before a time step fails
4656cef5090cSJed Brown 
4657cef5090cSJed Brown    Not Collective
4658cef5090cSJed Brown 
4659d8d19677SJose E. Roman    Input Parameters:
4660bcf0153eSBarry Smith +  ts - `TS` context
4661cef5090cSJed Brown -  rejects - maximum number of rejected steps, pass -1 for unlimited
4662cef5090cSJed Brown 
4663cef5090cSJed Brown    Options Database Key:
4664cef5090cSJed Brown .  -ts_max_reject - Maximum number of step rejections before a step fails
4665cef5090cSJed Brown 
4666cef5090cSJed Brown    Level: intermediate
4667cef5090cSJed Brown 
4668bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `SNES`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxSNESFailures()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSSetErrorIfStepFails()`, `TSGetConvergedReason()`
4669cef5090cSJed Brown @*/
4670d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxStepRejections(TS ts, PetscInt rejects)
4671d71ae5a4SJacob Faibussowitsch {
4672cef5090cSJed Brown   PetscFunctionBegin;
4673cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4674cef5090cSJed Brown   ts->max_reject = rejects;
46753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4676cef5090cSJed Brown }
4677cef5090cSJed Brown 
4678cef5090cSJed Brown /*@
4679bcf0153eSBarry Smith    TSSetMaxSNESFailures - Sets the maximum number of failed `SNES` solves
4680cef5090cSJed Brown 
4681cef5090cSJed Brown    Not Collective
4682cef5090cSJed Brown 
4683d8d19677SJose E. Roman    Input Parameters:
4684bcf0153eSBarry Smith +  ts - `TS` context
4685cef5090cSJed Brown -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
4686cef5090cSJed Brown 
4687cef5090cSJed Brown    Options Database Key:
4688cef5090cSJed Brown .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
4689cef5090cSJed Brown 
4690cef5090cSJed Brown    Level: intermediate
4691cef5090cSJed Brown 
4692bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `SNES`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `SNESGetConvergedReason()`, `TSGetConvergedReason()`
4693cef5090cSJed Brown @*/
4694d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMaxSNESFailures(TS ts, PetscInt fails)
4695d71ae5a4SJacob Faibussowitsch {
4696cef5090cSJed Brown   PetscFunctionBegin;
4697cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4698cef5090cSJed Brown   ts->max_snes_failures = fails;
46993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4700cef5090cSJed Brown }
4701cef5090cSJed Brown 
4702cef5090cSJed Brown /*@
4703bcf0153eSBarry Smith    TSSetErrorIfStepFails - Immediately error if no step succeeds
4704cef5090cSJed Brown 
4705cef5090cSJed Brown    Not Collective
4706cef5090cSJed Brown 
4707d8d19677SJose E. Roman    Input Parameters:
4708bcf0153eSBarry Smith +  ts - `TS` context
4709bcf0153eSBarry Smith -  err - `PETSC_TRUE` to error if no step succeeds, `PETSC_FALSE` to return without failure
4710cef5090cSJed Brown 
4711cef5090cSJed Brown    Options Database Key:
4712cef5090cSJed Brown .  -ts_error_if_step_fails - Error if no step succeeds
4713cef5090cSJed Brown 
4714cef5090cSJed Brown    Level: intermediate
4715cef5090cSJed Brown 
4716bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSSetErrorIfStepFails()`, `TSGetConvergedReason()`
4717cef5090cSJed Brown @*/
4718d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetErrorIfStepFails(TS ts, PetscBool err)
4719d71ae5a4SJacob Faibussowitsch {
4720cef5090cSJed Brown   PetscFunctionBegin;
4721cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4722cef5090cSJed Brown   ts->errorifstepfailed = err;
47233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4724cef5090cSJed Brown }
4725cef5090cSJed Brown 
472684df9cb4SJed Brown /*@
4727552698daSJed Brown    TSGetAdapt - Get the adaptive controller context for the current method
472884df9cb4SJed Brown 
4729bcf0153eSBarry Smith    Collective on ts if controller has not been created yet
473084df9cb4SJed Brown 
47314165533cSJose E. Roman    Input Parameter:
4732ed81e22dSJed Brown .  ts - time stepping context
473384df9cb4SJed Brown 
47344165533cSJose E. Roman    Output Parameter:
4735ed81e22dSJed Brown .  adapt - adaptive controller
473684df9cb4SJed Brown 
473784df9cb4SJed Brown    Level: intermediate
473884df9cb4SJed Brown 
4739bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSAdapt`, `TSAdaptSetType()`, `TSAdaptChoose()`
474084df9cb4SJed Brown @*/
4741d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetAdapt(TS ts, TSAdapt *adapt)
4742d71ae5a4SJacob Faibussowitsch {
474384df9cb4SJed Brown   PetscFunctionBegin;
474484df9cb4SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4745bec58848SLisandro Dalcin   PetscValidPointer(adapt, 2);
474684df9cb4SJed Brown   if (!ts->adapt) {
47479566063dSJacob Faibussowitsch     PetscCall(TSAdaptCreate(PetscObjectComm((PetscObject)ts), &ts->adapt));
47489566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->adapt, (PetscObject)ts, 1));
474984df9cb4SJed Brown   }
4750bec58848SLisandro Dalcin   *adapt = ts->adapt;
47513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
475284df9cb4SJed Brown }
4753d6ebe24aSShri Abhyankar 
47541c3436cfSJed Brown /*@
47551c3436cfSJed Brown    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
47561c3436cfSJed Brown 
47571c3436cfSJed Brown    Logically Collective
47581c3436cfSJed Brown 
47594165533cSJose E. Roman    Input Parameters:
47601c3436cfSJed Brown +  ts - time integration context
4761bcf0153eSBarry Smith .  atol - scalar absolute tolerances, `PETSC_DECIDE` to leave current value
47620298fd71SBarry Smith .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
4763bcf0153eSBarry Smith .  rtol - scalar relative tolerances, `PETSC_DECIDE` to leave current value
47640298fd71SBarry Smith -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
47651c3436cfSJed Brown 
4766a3cdaa26SBarry Smith    Options Database keys:
4767a3cdaa26SBarry Smith +  -ts_rtol <rtol> - relative tolerance for local truncation error
476867b8a455SSatish Balay -  -ts_atol <atol> - Absolute tolerance for local truncation error
4769a3cdaa26SBarry Smith 
4770bcf0153eSBarry Smith    Level: beginner
4771bcf0153eSBarry Smith 
47723ff766beSShri Abhyankar    Notes:
47733ff766beSShri Abhyankar    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
47743ff766beSShri Abhyankar    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
47753ff766beSShri Abhyankar    computed only for the differential or the algebraic part then this can be done using the vector of
47763ff766beSShri Abhyankar    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
47773ff766beSShri Abhyankar    differential part and infinity for the algebraic part, the LTE calculation will include only the
47783ff766beSShri Abhyankar    differential variables.
47793ff766beSShri Abhyankar 
4780bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSGetTolerances()`
47811c3436cfSJed Brown @*/
4782d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTolerances(TS ts, PetscReal atol, Vec vatol, PetscReal rtol, Vec vrtol)
4783d71ae5a4SJacob Faibussowitsch {
47841c3436cfSJed Brown   PetscFunctionBegin;
4785c5033834SJed Brown   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
47861c3436cfSJed Brown   if (vatol) {
47879566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vatol));
47889566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vatol));
47891c3436cfSJed Brown     ts->vatol = vatol;
47901c3436cfSJed Brown   }
4791c5033834SJed Brown   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
47921c3436cfSJed Brown   if (vrtol) {
47939566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vrtol));
47949566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vrtol));
47951c3436cfSJed Brown     ts->vrtol = vrtol;
47961c3436cfSJed Brown   }
47973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
47981c3436cfSJed Brown }
47991c3436cfSJed Brown 
4800c5033834SJed Brown /*@
4801c5033834SJed Brown    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
4802c5033834SJed Brown 
4803c5033834SJed Brown    Logically Collective
4804c5033834SJed Brown 
48054165533cSJose E. Roman    Input Parameter:
4806c5033834SJed Brown .  ts - time integration context
4807c5033834SJed Brown 
48084165533cSJose E. Roman    Output Parameters:
48090298fd71SBarry Smith +  atol - scalar absolute tolerances, NULL to ignore
48100298fd71SBarry Smith .  vatol - vector of absolute tolerances, NULL to ignore
48110298fd71SBarry Smith .  rtol - scalar relative tolerances, NULL to ignore
48120298fd71SBarry Smith -  vrtol - vector of relative tolerances, NULL to ignore
4813c5033834SJed Brown 
4814c5033834SJed Brown    Level: beginner
4815c5033834SJed Brown 
4816bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSSetTolerances()`
4817c5033834SJed Brown @*/
4818d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTolerances(TS ts, PetscReal *atol, Vec *vatol, PetscReal *rtol, Vec *vrtol)
4819d71ae5a4SJacob Faibussowitsch {
4820c5033834SJed Brown   PetscFunctionBegin;
4821c5033834SJed Brown   if (atol) *atol = ts->atol;
4822c5033834SJed Brown   if (vatol) *vatol = ts->vatol;
4823c5033834SJed Brown   if (rtol) *rtol = ts->rtol;
4824c5033834SJed Brown   if (vrtol) *vrtol = ts->vrtol;
48253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4826c5033834SJed Brown }
4827c5033834SJed Brown 
48289c6b16b5SShri Abhyankar /*@
4829a4868fbcSLisandro Dalcin    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
48309c6b16b5SShri Abhyankar 
4831c3339decSBarry Smith    Collective
48329c6b16b5SShri Abhyankar 
48334165533cSJose E. Roman    Input Parameters:
48349c6b16b5SShri Abhyankar +  ts - time stepping context
4835a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
4836a4868fbcSLisandro Dalcin -  Y - state vector to be compared to U
48379c6b16b5SShri Abhyankar 
48384165533cSJose E. Roman    Output Parameters:
4839a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
48407453f775SEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
4841a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
48429c6b16b5SShri Abhyankar 
48439c6b16b5SShri Abhyankar    Level: developer
48449c6b16b5SShri Abhyankar 
4845bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSErrorWeightedNorm()`, `TSErrorWeightedNormInfinity()`
48469c6b16b5SShri Abhyankar @*/
4847d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedNorm2(TS ts, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr)
4848d71ae5a4SJacob Faibussowitsch {
48499c6b16b5SShri Abhyankar   PetscInt           i, n, N, rstart;
48507453f775SEmil Constantinescu   PetscInt           n_loc, na_loc, nr_loc;
48517453f775SEmil Constantinescu   PetscReal          n_glb, na_glb, nr_glb;
48529c6b16b5SShri Abhyankar   const PetscScalar *u, *y;
48537453f775SEmil Constantinescu   PetscReal          sum, suma, sumr, gsum, gsuma, gsumr, diff;
48547453f775SEmil Constantinescu   PetscReal          tol, tola, tolr;
48557453f775SEmil Constantinescu   PetscReal          err_loc[6], err_glb[6];
48569c6b16b5SShri Abhyankar 
48579c6b16b5SShri Abhyankar   PetscFunctionBegin;
48589c6b16b5SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4859a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
4860a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(Y, VEC_CLASSID, 3);
4861a4868fbcSLisandro Dalcin   PetscValidType(U, 2);
4862a4868fbcSLisandro Dalcin   PetscValidType(Y, 3);
4863a4868fbcSLisandro Dalcin   PetscCheckSameComm(U, 2, Y, 3);
4864dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 4);
4865dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 5);
4866dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 6);
48673c633725SBarry Smith   PetscCheck(U != Y, PetscObjectComm((PetscObject)U), PETSC_ERR_ARG_IDN, "U and Y cannot be the same vector");
48689c6b16b5SShri Abhyankar 
48699566063dSJacob Faibussowitsch   PetscCall(VecGetSize(U, &N));
48709566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &n));
48719566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(U, &rstart, NULL));
48729566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
48739566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
48749371c9d4SSatish Balay   sum    = 0.;
48759371c9d4SSatish Balay   n_loc  = 0;
48769371c9d4SSatish Balay   suma   = 0.;
48779371c9d4SSatish Balay   na_loc = 0;
48789371c9d4SSatish Balay   sumr   = 0.;
48799371c9d4SSatish Balay   nr_loc = 0;
48809c6b16b5SShri Abhyankar   if (ts->vatol && ts->vrtol) {
48819c6b16b5SShri Abhyankar     const PetscScalar *atol, *rtol;
48829566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
48839566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
48849c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
488576cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
48867453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
48877453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
48887453f775SEmil Constantinescu       if (tola > 0.) {
48897453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
48907453f775SEmil Constantinescu         na_loc++;
48917453f775SEmil Constantinescu       }
48927453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
48937453f775SEmil Constantinescu       if (tolr > 0.) {
48947453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
48957453f775SEmil Constantinescu         nr_loc++;
48967453f775SEmil Constantinescu       }
48977453f775SEmil Constantinescu       tol = tola + tolr;
48987453f775SEmil Constantinescu       if (tol > 0.) {
48997453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
49007453f775SEmil Constantinescu         n_loc++;
49017453f775SEmil Constantinescu       }
49029c6b16b5SShri Abhyankar     }
49039566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
49049566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
49059c6b16b5SShri Abhyankar   } else if (ts->vatol) { /* vector atol, scalar rtol */
49069c6b16b5SShri Abhyankar     const PetscScalar *atol;
49079566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
49089c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
490976cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
49107453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49117453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
49127453f775SEmil Constantinescu       if (tola > 0.) {
49137453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
49147453f775SEmil Constantinescu         na_loc++;
49157453f775SEmil Constantinescu       }
49167453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
49177453f775SEmil Constantinescu       if (tolr > 0.) {
49187453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
49197453f775SEmil Constantinescu         nr_loc++;
49207453f775SEmil Constantinescu       }
49217453f775SEmil Constantinescu       tol = tola + tolr;
49227453f775SEmil Constantinescu       if (tol > 0.) {
49237453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
49247453f775SEmil Constantinescu         n_loc++;
49257453f775SEmil Constantinescu       }
49269c6b16b5SShri Abhyankar     }
49279566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
49289c6b16b5SShri Abhyankar   } else if (ts->vrtol) { /* scalar atol, vector rtol */
49299c6b16b5SShri Abhyankar     const PetscScalar *rtol;
49309566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
49319c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
493276cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
49337453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49347453f775SEmil Constantinescu       tola = ts->atol;
49357453f775SEmil Constantinescu       if (tola > 0.) {
49367453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
49377453f775SEmil Constantinescu         na_loc++;
49387453f775SEmil Constantinescu       }
49397453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
49407453f775SEmil Constantinescu       if (tolr > 0.) {
49417453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
49427453f775SEmil Constantinescu         nr_loc++;
49437453f775SEmil Constantinescu       }
49447453f775SEmil Constantinescu       tol = tola + tolr;
49457453f775SEmil Constantinescu       if (tol > 0.) {
49467453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
49477453f775SEmil Constantinescu         n_loc++;
49487453f775SEmil Constantinescu       }
49499c6b16b5SShri Abhyankar     }
49509566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
49519c6b16b5SShri Abhyankar   } else { /* scalar atol, scalar rtol */
49529c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
495376cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
49547453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49557453f775SEmil Constantinescu       tola = ts->atol;
49567453f775SEmil Constantinescu       if (tola > 0.) {
49577453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
49587453f775SEmil Constantinescu         na_loc++;
49597453f775SEmil Constantinescu       }
49607453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
49617453f775SEmil Constantinescu       if (tolr > 0.) {
49627453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
49637453f775SEmil Constantinescu         nr_loc++;
49647453f775SEmil Constantinescu       }
49657453f775SEmil Constantinescu       tol = tola + tolr;
49667453f775SEmil Constantinescu       if (tol > 0.) {
49677453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
49687453f775SEmil Constantinescu         n_loc++;
49697453f775SEmil Constantinescu       }
49709c6b16b5SShri Abhyankar     }
49719c6b16b5SShri Abhyankar   }
49729566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
49739566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
49749c6b16b5SShri Abhyankar 
49757453f775SEmil Constantinescu   err_loc[0] = sum;
49767453f775SEmil Constantinescu   err_loc[1] = suma;
49777453f775SEmil Constantinescu   err_loc[2] = sumr;
49787453f775SEmil Constantinescu   err_loc[3] = (PetscReal)n_loc;
49797453f775SEmil Constantinescu   err_loc[4] = (PetscReal)na_loc;
49807453f775SEmil Constantinescu   err_loc[5] = (PetscReal)nr_loc;
49817453f775SEmil Constantinescu 
49821c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 6, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ts)));
49837453f775SEmil Constantinescu 
49847453f775SEmil Constantinescu   gsum   = err_glb[0];
49857453f775SEmil Constantinescu   gsuma  = err_glb[1];
49867453f775SEmil Constantinescu   gsumr  = err_glb[2];
49877453f775SEmil Constantinescu   n_glb  = err_glb[3];
49887453f775SEmil Constantinescu   na_glb = err_glb[4];
49897453f775SEmil Constantinescu   nr_glb = err_glb[5];
49907453f775SEmil Constantinescu 
4991b1316ef9SEmil Constantinescu   *norm = 0.;
49921e66621cSBarry Smith   if (n_glb > 0.) *norm = PetscSqrtReal(gsum / n_glb);
4993b1316ef9SEmil Constantinescu   *norma = 0.;
49941e66621cSBarry Smith   if (na_glb > 0.) *norma = PetscSqrtReal(gsuma / na_glb);
4995b1316ef9SEmil Constantinescu   *normr = 0.;
49961e66621cSBarry Smith   if (nr_glb > 0.) *normr = PetscSqrtReal(gsumr / nr_glb);
49979c6b16b5SShri Abhyankar 
49983c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
49993c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
50003c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
50013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50029c6b16b5SShri Abhyankar }
50039c6b16b5SShri Abhyankar 
50049c6b16b5SShri Abhyankar /*@
5005a4868fbcSLisandro Dalcin    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
50069c6b16b5SShri Abhyankar 
5007c3339decSBarry Smith    Collective
50089c6b16b5SShri Abhyankar 
50094165533cSJose E. Roman    Input Parameters:
50109c6b16b5SShri Abhyankar +  ts - time stepping context
5011a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
5012a4868fbcSLisandro Dalcin -  Y - state vector to be compared to U
50139c6b16b5SShri Abhyankar 
50144165533cSJose E. Roman    Output Parameters:
5015a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
50167453f775SEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5017a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
50189c6b16b5SShri Abhyankar 
50199c6b16b5SShri Abhyankar    Level: developer
50209c6b16b5SShri Abhyankar 
5021bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSErrorWeightedNorm()`, `TSErrorWeightedNorm2()`
50229c6b16b5SShri Abhyankar @*/
5023d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedNormInfinity(TS ts, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr)
5024d71ae5a4SJacob Faibussowitsch {
50257453f775SEmil Constantinescu   PetscInt           i, n, N, rstart;
50269c6b16b5SShri Abhyankar   const PetscScalar *u, *y;
50277453f775SEmil Constantinescu   PetscReal          max, gmax, maxa, gmaxa, maxr, gmaxr;
50287453f775SEmil Constantinescu   PetscReal          tol, tola, tolr, diff;
50297453f775SEmil Constantinescu   PetscReal          err_loc[3], err_glb[3];
50309c6b16b5SShri Abhyankar 
50319c6b16b5SShri Abhyankar   PetscFunctionBegin;
50329c6b16b5SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5033a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
5034a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(Y, VEC_CLASSID, 3);
5035a4868fbcSLisandro Dalcin   PetscValidType(U, 2);
5036a4868fbcSLisandro Dalcin   PetscValidType(Y, 3);
5037a4868fbcSLisandro Dalcin   PetscCheckSameComm(U, 2, Y, 3);
5038dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 4);
5039dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 5);
5040dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 6);
50413c633725SBarry Smith   PetscCheck(U != Y, PetscObjectComm((PetscObject)U), PETSC_ERR_ARG_IDN, "U and Y cannot be the same vector");
50429c6b16b5SShri Abhyankar 
50439566063dSJacob Faibussowitsch   PetscCall(VecGetSize(U, &N));
50449566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &n));
50459566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(U, &rstart, NULL));
50469566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
50479566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
50487453f775SEmil Constantinescu 
50497453f775SEmil Constantinescu   max  = 0.;
50507453f775SEmil Constantinescu   maxa = 0.;
50517453f775SEmil Constantinescu   maxr = 0.;
50527453f775SEmil Constantinescu 
50537453f775SEmil Constantinescu   if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */
50549c6b16b5SShri Abhyankar     const PetscScalar *atol, *rtol;
50559566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
50569566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
50577453f775SEmil Constantinescu 
50587453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
505976cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
50607453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
50617453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
50627453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
50637453f775SEmil Constantinescu       tol  = tola + tolr;
50641e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
50651e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
50661e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
50679c6b16b5SShri Abhyankar     }
50689566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
50699566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
50709c6b16b5SShri Abhyankar   } else if (ts->vatol) { /* vector atol, scalar rtol */
50719c6b16b5SShri Abhyankar     const PetscScalar *atol;
50729566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
50737453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
507476cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
50757453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
50767453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
50777453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
50787453f775SEmil Constantinescu       tol  = tola + tolr;
50791e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
50801e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
50811e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
50829c6b16b5SShri Abhyankar     }
50839566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
50849c6b16b5SShri Abhyankar   } else if (ts->vrtol) { /* scalar atol, vector rtol */
50859c6b16b5SShri Abhyankar     const PetscScalar *rtol;
50869566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
50877453f775SEmil Constantinescu 
50887453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
508976cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
50907453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
50917453f775SEmil Constantinescu       tola = ts->atol;
50927453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
50937453f775SEmil Constantinescu       tol  = tola + tolr;
50941e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
50951e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
50961e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
50979c6b16b5SShri Abhyankar     }
50989566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
50999c6b16b5SShri Abhyankar   } else { /* scalar atol, scalar rtol */
51007453f775SEmil Constantinescu 
51017453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
510276cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
51037453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
51047453f775SEmil Constantinescu       tola = ts->atol;
51057453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
51067453f775SEmil Constantinescu       tol  = tola + tolr;
51071e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
51081e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
51091e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
51109c6b16b5SShri Abhyankar     }
51119c6b16b5SShri Abhyankar   }
51129566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
51139566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
51147453f775SEmil Constantinescu   err_loc[0] = max;
51157453f775SEmil Constantinescu   err_loc[1] = maxa;
51167453f775SEmil Constantinescu   err_loc[2] = maxr;
51171c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)ts)));
51187453f775SEmil Constantinescu   gmax  = err_glb[0];
51197453f775SEmil Constantinescu   gmaxa = err_glb[1];
51207453f775SEmil Constantinescu   gmaxr = err_glb[2];
51219c6b16b5SShri Abhyankar 
51229c6b16b5SShri Abhyankar   *norm  = gmax;
51237453f775SEmil Constantinescu   *norma = gmaxa;
51247453f775SEmil Constantinescu   *normr = gmaxr;
51253c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
51263c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
51273c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
51283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
51299c6b16b5SShri Abhyankar }
51309c6b16b5SShri Abhyankar 
51311c3436cfSJed Brown /*@
51328a175baeSEmil Constantinescu    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
51331c3436cfSJed Brown 
5134c3339decSBarry Smith    Collective
51351c3436cfSJed Brown 
51364165533cSJose E. Roman    Input Parameters:
51371c3436cfSJed Brown +  ts - time stepping context
5138a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
5139a4868fbcSLisandro Dalcin .  Y - state vector to be compared to U
5140bcf0153eSBarry Smith -  wnormtype - norm type, either `NORM_2` or `NORM_INFINITY`
51417619abb3SShri 
51424165533cSJose E. Roman    Output Parameters:
5143a2b725a8SWilliam Gropp +  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
51448a175baeSEmil Constantinescu .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5145a2b725a8SWilliam Gropp -  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
5146a4868fbcSLisandro Dalcin 
5147bcf0153eSBarry Smith    Options Database Key:
5148a4868fbcSLisandro Dalcin .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
5149a4868fbcSLisandro Dalcin 
51501c3436cfSJed Brown    Level: developer
51511c3436cfSJed Brown 
5152bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSErrorWeightedNormInfinity()`, `TSErrorWeightedNorm2()`, `TSErrorWeightedENorm`
51531c3436cfSJed Brown @*/
5154d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedNorm(TS ts, Vec U, Vec Y, NormType wnormtype, PetscReal *norm, PetscReal *norma, PetscReal *normr)
5155d71ae5a4SJacob Faibussowitsch {
51561c3436cfSJed Brown   PetscFunctionBegin;
51571e66621cSBarry Smith   if (wnormtype == NORM_2) PetscCall(TSErrorWeightedNorm2(ts, U, Y, norm, norma, normr));
51581e66621cSBarry Smith   else if (wnormtype == NORM_INFINITY) PetscCall(TSErrorWeightedNormInfinity(ts, U, Y, norm, norma, normr));
51591e66621cSBarry Smith   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
51603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
51611c3436cfSJed Brown }
51621c3436cfSJed Brown 
51638a175baeSEmil Constantinescu /*@
51648a175baeSEmil Constantinescu    TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances
51658a175baeSEmil Constantinescu 
5166c3339decSBarry Smith    Collective
51678a175baeSEmil Constantinescu 
51684165533cSJose E. Roman    Input Parameters:
51698a175baeSEmil Constantinescu +  ts - time stepping context
51708a175baeSEmil Constantinescu .  E - error vector
51718a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
51728a175baeSEmil Constantinescu -  Y - state vector, previous time step
51738a175baeSEmil Constantinescu 
51744165533cSJose E. Roman    Output Parameters:
5175a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
51768a175baeSEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5177a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
51788a175baeSEmil Constantinescu 
51798a175baeSEmil Constantinescu    Level: developer
51808a175baeSEmil Constantinescu 
5181bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSErrorWeightedENorm()`, `TSErrorWeightedENormInfinity()`
51828a175baeSEmil Constantinescu @*/
5183d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedENorm2(TS ts, Vec E, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr)
5184d71ae5a4SJacob Faibussowitsch {
51858a175baeSEmil Constantinescu   PetscInt           i, n, N, rstart;
51868a175baeSEmil Constantinescu   PetscInt           n_loc, na_loc, nr_loc;
51878a175baeSEmil Constantinescu   PetscReal          n_glb, na_glb, nr_glb;
51888a175baeSEmil Constantinescu   const PetscScalar *e, *u, *y;
51898a175baeSEmil Constantinescu   PetscReal          err, sum, suma, sumr, gsum, gsuma, gsumr;
51908a175baeSEmil Constantinescu   PetscReal          tol, tola, tolr;
51918a175baeSEmil Constantinescu   PetscReal          err_loc[6], err_glb[6];
51928a175baeSEmil Constantinescu 
51938a175baeSEmil Constantinescu   PetscFunctionBegin;
51948a175baeSEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
51958a175baeSEmil Constantinescu   PetscValidHeaderSpecific(E, VEC_CLASSID, 2);
51968a175baeSEmil Constantinescu   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
51978a175baeSEmil Constantinescu   PetscValidHeaderSpecific(Y, VEC_CLASSID, 4);
51988a175baeSEmil Constantinescu   PetscValidType(E, 2);
51998a175baeSEmil Constantinescu   PetscValidType(U, 3);
52008a175baeSEmil Constantinescu   PetscValidType(Y, 4);
52018a175baeSEmil Constantinescu   PetscCheckSameComm(E, 2, U, 3);
5202064a246eSJacob Faibussowitsch   PetscCheckSameComm(U, 3, Y, 4);
5203dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 5);
5204dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 6);
5205dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 7);
52068a175baeSEmil Constantinescu 
52079566063dSJacob Faibussowitsch   PetscCall(VecGetSize(E, &N));
52089566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(E, &n));
52099566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(E, &rstart, NULL));
52109566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(E, &e));
52119566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
52129566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
52139371c9d4SSatish Balay   sum    = 0.;
52149371c9d4SSatish Balay   n_loc  = 0;
52159371c9d4SSatish Balay   suma   = 0.;
52169371c9d4SSatish Balay   na_loc = 0;
52179371c9d4SSatish Balay   sumr   = 0.;
52189371c9d4SSatish Balay   nr_loc = 0;
52198a175baeSEmil Constantinescu   if (ts->vatol && ts->vrtol) {
52208a175baeSEmil Constantinescu     const PetscScalar *atol, *rtol;
52219566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
52229566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
52238a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
522476cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
52258a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
52268a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
52278a175baeSEmil Constantinescu       if (tola > 0.) {
52288a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
52298a175baeSEmil Constantinescu         na_loc++;
52308a175baeSEmil Constantinescu       }
52318a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
52328a175baeSEmil Constantinescu       if (tolr > 0.) {
52338a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
52348a175baeSEmil Constantinescu         nr_loc++;
52358a175baeSEmil Constantinescu       }
52368a175baeSEmil Constantinescu       tol = tola + tolr;
52378a175baeSEmil Constantinescu       if (tol > 0.) {
52388a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
52398a175baeSEmil Constantinescu         n_loc++;
52408a175baeSEmil Constantinescu       }
52418a175baeSEmil Constantinescu     }
52429566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
52439566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
52448a175baeSEmil Constantinescu   } else if (ts->vatol) { /* vector atol, scalar rtol */
52458a175baeSEmil Constantinescu     const PetscScalar *atol;
52469566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
52478a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
524876cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
52498a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
52508a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
52518a175baeSEmil Constantinescu       if (tola > 0.) {
52528a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
52538a175baeSEmil Constantinescu         na_loc++;
52548a175baeSEmil Constantinescu       }
52558a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
52568a175baeSEmil Constantinescu       if (tolr > 0.) {
52578a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
52588a175baeSEmil Constantinescu         nr_loc++;
52598a175baeSEmil Constantinescu       }
52608a175baeSEmil Constantinescu       tol = tola + tolr;
52618a175baeSEmil Constantinescu       if (tol > 0.) {
52628a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
52638a175baeSEmil Constantinescu         n_loc++;
52648a175baeSEmil Constantinescu       }
52658a175baeSEmil Constantinescu     }
52669566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
52678a175baeSEmil Constantinescu   } else if (ts->vrtol) { /* scalar atol, vector rtol */
52688a175baeSEmil Constantinescu     const PetscScalar *rtol;
52699566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
52708a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
527176cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
52728a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
52738a175baeSEmil Constantinescu       tola = ts->atol;
52748a175baeSEmil Constantinescu       if (tola > 0.) {
52758a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
52768a175baeSEmil Constantinescu         na_loc++;
52778a175baeSEmil Constantinescu       }
52788a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
52798a175baeSEmil Constantinescu       if (tolr > 0.) {
52808a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
52818a175baeSEmil Constantinescu         nr_loc++;
52828a175baeSEmil Constantinescu       }
52838a175baeSEmil Constantinescu       tol = tola + tolr;
52848a175baeSEmil Constantinescu       if (tol > 0.) {
52858a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
52868a175baeSEmil Constantinescu         n_loc++;
52878a175baeSEmil Constantinescu       }
52888a175baeSEmil Constantinescu     }
52899566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
52908a175baeSEmil Constantinescu   } else { /* scalar atol, scalar rtol */
52918a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
529276cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
52938a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
52948a175baeSEmil Constantinescu       tola = ts->atol;
52958a175baeSEmil Constantinescu       if (tola > 0.) {
52968a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
52978a175baeSEmil Constantinescu         na_loc++;
52988a175baeSEmil Constantinescu       }
52998a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
53008a175baeSEmil Constantinescu       if (tolr > 0.) {
53018a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
53028a175baeSEmil Constantinescu         nr_loc++;
53038a175baeSEmil Constantinescu       }
53048a175baeSEmil Constantinescu       tol = tola + tolr;
53058a175baeSEmil Constantinescu       if (tol > 0.) {
53068a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
53078a175baeSEmil Constantinescu         n_loc++;
53088a175baeSEmil Constantinescu       }
53098a175baeSEmil Constantinescu     }
53108a175baeSEmil Constantinescu   }
53119566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(E, &e));
53129566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
53139566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
53148a175baeSEmil Constantinescu 
53158a175baeSEmil Constantinescu   err_loc[0] = sum;
53168a175baeSEmil Constantinescu   err_loc[1] = suma;
53178a175baeSEmil Constantinescu   err_loc[2] = sumr;
53188a175baeSEmil Constantinescu   err_loc[3] = (PetscReal)n_loc;
53198a175baeSEmil Constantinescu   err_loc[4] = (PetscReal)na_loc;
53208a175baeSEmil Constantinescu   err_loc[5] = (PetscReal)nr_loc;
53218a175baeSEmil Constantinescu 
53221c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 6, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ts)));
53238a175baeSEmil Constantinescu 
53248a175baeSEmil Constantinescu   gsum   = err_glb[0];
53258a175baeSEmil Constantinescu   gsuma  = err_glb[1];
53268a175baeSEmil Constantinescu   gsumr  = err_glb[2];
53278a175baeSEmil Constantinescu   n_glb  = err_glb[3];
53288a175baeSEmil Constantinescu   na_glb = err_glb[4];
53298a175baeSEmil Constantinescu   nr_glb = err_glb[5];
53308a175baeSEmil Constantinescu 
53318a175baeSEmil Constantinescu   *norm = 0.;
53321e66621cSBarry Smith   if (n_glb > 0.) *norm = PetscSqrtReal(gsum / n_glb);
53338a175baeSEmil Constantinescu   *norma = 0.;
53341e66621cSBarry Smith   if (na_glb > 0.) *norma = PetscSqrtReal(gsuma / na_glb);
53358a175baeSEmil Constantinescu   *normr = 0.;
53361e66621cSBarry Smith   if (nr_glb > 0.) *normr = PetscSqrtReal(gsumr / nr_glb);
53378a175baeSEmil Constantinescu 
53383c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
53393c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
53403c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
53413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
53428a175baeSEmil Constantinescu }
53438a175baeSEmil Constantinescu 
53448a175baeSEmil Constantinescu /*@
53458a175baeSEmil Constantinescu    TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances
5346bcf0153eSBarry Smith 
5347c3339decSBarry Smith    Collective
53488a175baeSEmil Constantinescu 
53494165533cSJose E. Roman    Input Parameters:
53508a175baeSEmil Constantinescu +  ts - time stepping context
53518a175baeSEmil Constantinescu .  E - error vector
53528a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
53538a175baeSEmil Constantinescu -  Y - state vector, previous time step
53548a175baeSEmil Constantinescu 
53554165533cSJose E. Roman    Output Parameters:
5356a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
53578a175baeSEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5358a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
53598a175baeSEmil Constantinescu 
53608a175baeSEmil Constantinescu    Level: developer
53618a175baeSEmil Constantinescu 
5362bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSErrorWeightedENorm()`, `TSErrorWeightedENorm2()`
53638a175baeSEmil Constantinescu @*/
5364d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedENormInfinity(TS ts, Vec E, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr)
5365d71ae5a4SJacob Faibussowitsch {
53668a175baeSEmil Constantinescu   PetscInt           i, n, N, rstart;
53678a175baeSEmil Constantinescu   const PetscScalar *e, *u, *y;
53688a175baeSEmil Constantinescu   PetscReal          err, max, gmax, maxa, gmaxa, maxr, gmaxr;
53698a175baeSEmil Constantinescu   PetscReal          tol, tola, tolr;
53708a175baeSEmil Constantinescu   PetscReal          err_loc[3], err_glb[3];
53718a175baeSEmil Constantinescu 
53728a175baeSEmil Constantinescu   PetscFunctionBegin;
53738a175baeSEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
53748a175baeSEmil Constantinescu   PetscValidHeaderSpecific(E, VEC_CLASSID, 2);
53758a175baeSEmil Constantinescu   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
53768a175baeSEmil Constantinescu   PetscValidHeaderSpecific(Y, VEC_CLASSID, 4);
53778a175baeSEmil Constantinescu   PetscValidType(E, 2);
53788a175baeSEmil Constantinescu   PetscValidType(U, 3);
53798a175baeSEmil Constantinescu   PetscValidType(Y, 4);
53808a175baeSEmil Constantinescu   PetscCheckSameComm(E, 2, U, 3);
5381064a246eSJacob Faibussowitsch   PetscCheckSameComm(U, 3, Y, 4);
5382dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 5);
5383dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 6);
5384dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 7);
53858a175baeSEmil Constantinescu 
53869566063dSJacob Faibussowitsch   PetscCall(VecGetSize(E, &N));
53879566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(E, &n));
53889566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(E, &rstart, NULL));
53899566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(E, &e));
53909566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
53919566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
53928a175baeSEmil Constantinescu 
53938a175baeSEmil Constantinescu   max  = 0.;
53948a175baeSEmil Constantinescu   maxa = 0.;
53958a175baeSEmil Constantinescu   maxr = 0.;
53968a175baeSEmil Constantinescu 
53978a175baeSEmil Constantinescu   if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */
53988a175baeSEmil Constantinescu     const PetscScalar *atol, *rtol;
53999566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
54009566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
54018a175baeSEmil Constantinescu 
54028a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
540376cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
54048a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
54058a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
54068a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
54078a175baeSEmil Constantinescu       tol  = tola + tolr;
54081e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
54091e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
54101e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
54118a175baeSEmil Constantinescu     }
54129566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
54139566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
54148a175baeSEmil Constantinescu   } else if (ts->vatol) { /* vector atol, scalar rtol */
54158a175baeSEmil Constantinescu     const PetscScalar *atol;
54169566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
54178a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
541876cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
54198a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
54208a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
54218a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
54228a175baeSEmil Constantinescu       tol  = tola + tolr;
54231e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
54241e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
54251e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
54268a175baeSEmil Constantinescu     }
54279566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
54288a175baeSEmil Constantinescu   } else if (ts->vrtol) { /* scalar atol, vector rtol */
54298a175baeSEmil Constantinescu     const PetscScalar *rtol;
54309566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
54318a175baeSEmil Constantinescu 
54328a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
543376cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
54348a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
54358a175baeSEmil Constantinescu       tola = ts->atol;
54368a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
54378a175baeSEmil Constantinescu       tol  = tola + tolr;
54381e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
54391e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
54401e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
54418a175baeSEmil Constantinescu     }
54429566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
54438a175baeSEmil Constantinescu   } else { /* scalar atol, scalar rtol */
54448a175baeSEmil Constantinescu 
54458a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
544676cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
54478a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
54488a175baeSEmil Constantinescu       tola = ts->atol;
54498a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
54508a175baeSEmil Constantinescu       tol  = tola + tolr;
54511e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
54521e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
54531e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
54548a175baeSEmil Constantinescu     }
54558a175baeSEmil Constantinescu   }
54569566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(E, &e));
54579566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
54589566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
54598a175baeSEmil Constantinescu   err_loc[0] = max;
54608a175baeSEmil Constantinescu   err_loc[1] = maxa;
54618a175baeSEmil Constantinescu   err_loc[2] = maxr;
54621c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)ts)));
54638a175baeSEmil Constantinescu   gmax  = err_glb[0];
54648a175baeSEmil Constantinescu   gmaxa = err_glb[1];
54658a175baeSEmil Constantinescu   gmaxr = err_glb[2];
54668a175baeSEmil Constantinescu 
54678a175baeSEmil Constantinescu   *norm  = gmax;
54688a175baeSEmil Constantinescu   *norma = gmaxa;
54698a175baeSEmil Constantinescu   *normr = gmaxr;
54703c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
54713c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
54723c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
54733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
54748a175baeSEmil Constantinescu }
54758a175baeSEmil Constantinescu 
54768a175baeSEmil Constantinescu /*@
54778a175baeSEmil Constantinescu    TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
54788a175baeSEmil Constantinescu 
5479c3339decSBarry Smith    Collective
54808a175baeSEmil Constantinescu 
54814165533cSJose E. Roman    Input Parameters:
54828a175baeSEmil Constantinescu +  ts - time stepping context
54838a175baeSEmil Constantinescu .  E - error vector
54848a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
54858a175baeSEmil Constantinescu .  Y - state vector, previous time step
5486bcf0153eSBarry Smith -  wnormtype - norm type, either `NORM_2` or `NORM_INFINITY`
54878a175baeSEmil Constantinescu 
54884165533cSJose E. Roman    Output Parameters:
5489a2b725a8SWilliam Gropp +  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
54908a175baeSEmil Constantinescu .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5491a2b725a8SWilliam Gropp -  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
54928a175baeSEmil Constantinescu 
5493bcf0153eSBarry Smith    Options Database Key:
54948a175baeSEmil Constantinescu .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
54958a175baeSEmil Constantinescu 
54968a175baeSEmil Constantinescu    Level: developer
54978a175baeSEmil Constantinescu 
5498bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSErrorWeightedENormInfinity()`, `TSErrorWeightedENorm2()`, `TSErrorWeightedNormInfinity()`, `TSErrorWeightedNorm2()`
54998a175baeSEmil Constantinescu @*/
5500d71ae5a4SJacob Faibussowitsch PetscErrorCode TSErrorWeightedENorm(TS ts, Vec E, Vec U, Vec Y, NormType wnormtype, PetscReal *norm, PetscReal *norma, PetscReal *normr)
5501d71ae5a4SJacob Faibussowitsch {
55028a175baeSEmil Constantinescu   PetscFunctionBegin;
55031e66621cSBarry Smith   if (wnormtype == NORM_2) PetscCall(TSErrorWeightedENorm2(ts, E, U, Y, norm, norma, normr));
55041e66621cSBarry Smith   else if (wnormtype == NORM_INFINITY) PetscCall(TSErrorWeightedENormInfinity(ts, E, U, Y, norm, norma, normr));
55051e66621cSBarry Smith   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
55063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
55078a175baeSEmil Constantinescu }
55088a175baeSEmil Constantinescu 
55098d59e960SJed Brown /*@
55108d59e960SJed Brown    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
55118d59e960SJed Brown 
5512c3339decSBarry Smith    Logically Collective
55138d59e960SJed Brown 
55144165533cSJose E. Roman    Input Parameters:
55158d59e960SJed Brown +  ts - time stepping context
55168d59e960SJed Brown -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
55178d59e960SJed Brown 
55188d59e960SJed Brown    Note:
55198d59e960SJed Brown    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
55208d59e960SJed Brown 
55218d59e960SJed Brown    Level: intermediate
55228d59e960SJed Brown 
5523bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSGetCFLTime()`, `TSADAPTCFL`
55248d59e960SJed Brown @*/
5525d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetCFLTimeLocal(TS ts, PetscReal cfltime)
5526d71ae5a4SJacob Faibussowitsch {
55278d59e960SJed Brown   PetscFunctionBegin;
55288d59e960SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
55298d59e960SJed Brown   ts->cfltime_local = cfltime;
55308d59e960SJed Brown   ts->cfltime       = -1.;
55313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
55328d59e960SJed Brown }
55338d59e960SJed Brown 
55348d59e960SJed Brown /*@
55358d59e960SJed Brown    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
55368d59e960SJed Brown 
5537c3339decSBarry Smith    Collective
55388d59e960SJed Brown 
55394165533cSJose E. Roman    Input Parameter:
55408d59e960SJed Brown .  ts - time stepping context
55418d59e960SJed Brown 
55424165533cSJose E. Roman    Output Parameter:
55438d59e960SJed Brown .  cfltime - maximum stable time step for forward Euler
55448d59e960SJed Brown 
55458d59e960SJed Brown    Level: advanced
55468d59e960SJed Brown 
5547bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSSetCFLTimeLocal()`
55488d59e960SJed Brown @*/
5549d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetCFLTime(TS ts, PetscReal *cfltime)
5550d71ae5a4SJacob Faibussowitsch {
55518d59e960SJed Brown   PetscFunctionBegin;
55521e66621cSBarry Smith   if (ts->cfltime < 0) PetscCall(MPIU_Allreduce(&ts->cfltime_local, &ts->cfltime, 1, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject)ts)));
55538d59e960SJed Brown   *cfltime = ts->cfltime;
55543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
55558d59e960SJed Brown }
55568d59e960SJed Brown 
5557d6ebe24aSShri Abhyankar /*@
5558d6ebe24aSShri Abhyankar    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
5559d6ebe24aSShri Abhyankar 
5560d6ebe24aSShri Abhyankar    Input Parameters:
5561bcf0153eSBarry Smith +  ts   - the `TS` context.
5562d6ebe24aSShri Abhyankar .  xl   - lower bound.
5563a2b725a8SWilliam Gropp -  xu   - upper bound.
5564d6ebe24aSShri Abhyankar 
55652bd2b0e6SSatish Balay    Level: advanced
55662bd2b0e6SSatish Balay 
5567bcf0153eSBarry Smith    Note:
5568bcf0153eSBarry Smith    If this routine is not called then the lower and upper bounds are set to
5569bcf0153eSBarry Smith    `PETSC_NINFINITY` and `PETSC_INFINITY` respectively during `SNESSetUp()`.
5570bcf0153eSBarry Smith 
5571bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`
5572d6ebe24aSShri Abhyankar @*/
5573d71ae5a4SJacob Faibussowitsch PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
5574d71ae5a4SJacob Faibussowitsch {
5575d6ebe24aSShri Abhyankar   SNES snes;
5576d6ebe24aSShri Abhyankar 
5577d6ebe24aSShri Abhyankar   PetscFunctionBegin;
55789566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
55799566063dSJacob Faibussowitsch   PetscCall(SNESVISetVariableBounds(snes, xl, xu));
55803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5581d6ebe24aSShri Abhyankar }
5582d6ebe24aSShri Abhyankar 
5583f9c1d6abSBarry Smith /*@
5584f9c1d6abSBarry Smith    TSComputeLinearStability - computes the linear stability function at a point
5585f9c1d6abSBarry Smith 
5586c3339decSBarry Smith    Collective
5587f9c1d6abSBarry Smith 
5588f9c1d6abSBarry Smith    Input Parameters:
5589bcf0153eSBarry Smith +  ts - the `TS` context
5590f9c1d6abSBarry Smith -  xr,xi - real and imaginary part of input arguments
5591f9c1d6abSBarry Smith 
5592f9c1d6abSBarry Smith    Output Parameters:
5593f9c1d6abSBarry Smith .  yr,yi - real and imaginary part of function value
5594f9c1d6abSBarry Smith 
5595f9c1d6abSBarry Smith    Level: developer
5596f9c1d6abSBarry Smith 
5597bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetRHSFunction()`, `TSComputeIFunction()`
5598f9c1d6abSBarry Smith @*/
5599d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeLinearStability(TS ts, PetscReal xr, PetscReal xi, PetscReal *yr, PetscReal *yi)
5600d71ae5a4SJacob Faibussowitsch {
5601f9c1d6abSBarry Smith   PetscFunctionBegin;
5602f9c1d6abSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5603dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, linearstability, xr, xi, yr, yi);
56043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5605f9c1d6abSBarry Smith }
560624655328SShri 
560724655328SShri /*@
5608dcb233daSLisandro Dalcin    TSRestartStep - Flags the solver to restart the next step
5609dcb233daSLisandro Dalcin 
5610c3339decSBarry Smith    Collective
5611dcb233daSLisandro Dalcin 
5612dcb233daSLisandro Dalcin    Input Parameter:
5613bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
5614dcb233daSLisandro Dalcin 
5615dcb233daSLisandro Dalcin    Level: advanced
5616dcb233daSLisandro Dalcin 
5617dcb233daSLisandro Dalcin    Notes:
5618bcf0153eSBarry Smith    Multistep methods like `TSBDF` or Runge-Kutta methods with FSAL property require restarting the solver in the event of
5619dcb233daSLisandro Dalcin    discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution
5620dcb233daSLisandro Dalcin    vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For
5621bcf0153eSBarry Smith    the sake of correctness and maximum safety, users are expected to call `TSRestart()` whenever they introduce
5622dcb233daSLisandro Dalcin    discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with
5623dcb233daSLisandro Dalcin    discontinuous source terms).
5624dcb233daSLisandro Dalcin 
5625bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSBDF`, `TSSolve()`, `TSSetPreStep()`, `TSSetPostStep()`
5626dcb233daSLisandro Dalcin @*/
5627d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRestartStep(TS ts)
5628d71ae5a4SJacob Faibussowitsch {
5629dcb233daSLisandro Dalcin   PetscFunctionBegin;
5630dcb233daSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5631dcb233daSLisandro Dalcin   ts->steprestart = PETSC_TRUE;
56323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5633dcb233daSLisandro Dalcin }
5634dcb233daSLisandro Dalcin 
5635dcb233daSLisandro Dalcin /*@
563624655328SShri    TSRollBack - Rolls back one time step
563724655328SShri 
5638c3339decSBarry Smith    Collective
563924655328SShri 
564024655328SShri    Input Parameter:
5641bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
564224655328SShri 
564324655328SShri    Level: advanced
564424655328SShri 
5645bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSInterpolate()`
564624655328SShri @*/
5647d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRollBack(TS ts)
5648d71ae5a4SJacob Faibussowitsch {
564924655328SShri   PetscFunctionBegin;
565024655328SShri   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
56513c633725SBarry Smith   PetscCheck(!ts->steprollback, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "TSRollBack already called");
5652dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, rollback);
565324655328SShri   ts->time_step  = ts->ptime - ts->ptime_prev;
565424655328SShri   ts->ptime      = ts->ptime_prev;
5655be5899b3SLisandro Dalcin   ts->ptime_prev = ts->ptime_prev_rollback;
56562808aa04SLisandro Dalcin   ts->steps--;
5657b3de5cdeSLisandro Dalcin   ts->steprollback = PETSC_TRUE;
56583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
565924655328SShri }
5660aeb4809dSShri Abhyankar 
5661ff22ae23SHong Zhang /*@
5662ff22ae23SHong Zhang    TSGetStages - Get the number of stages and stage values
5663ff22ae23SHong Zhang 
5664ff22ae23SHong Zhang    Input Parameter:
5665bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
5666ff22ae23SHong Zhang 
56670429704eSStefano Zampini    Output Parameters:
56680429704eSStefano Zampini +  ns - the number of stages
56690429704eSStefano Zampini -  Y - the current stage vectors
56700429704eSStefano Zampini 
5671ff22ae23SHong Zhang    Level: advanced
5672ff22ae23SHong Zhang 
5673bcf0153eSBarry Smith    Note:
5674bcf0153eSBarry Smith    Both ns and Y can be NULL.
56750429704eSStefano Zampini 
5676bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSCreate()`
5677ff22ae23SHong Zhang @*/
5678d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetStages(TS ts, PetscInt *ns, Vec **Y)
5679d71ae5a4SJacob Faibussowitsch {
5680ff22ae23SHong Zhang   PetscFunctionBegin;
5681ff22ae23SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5682dadcf809SJacob Faibussowitsch   if (ns) PetscValidIntPointer(ns, 2);
56830429704eSStefano Zampini   if (Y) PetscValidPointer(Y, 3);
56840429704eSStefano Zampini   if (!ts->ops->getstages) {
56850429704eSStefano Zampini     if (ns) *ns = 0;
56860429704eSStefano Zampini     if (Y) *Y = NULL;
5687dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(ts, getstages, ns, Y);
56883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5689ff22ae23SHong Zhang }
5690ff22ae23SHong Zhang 
5691847ff0e1SMatthew G. Knepley /*@C
5692847ff0e1SMatthew G. Knepley   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
5693847ff0e1SMatthew G. Knepley 
5694c3339decSBarry Smith   Collective
5695847ff0e1SMatthew G. Knepley 
5696847ff0e1SMatthew G. Knepley   Input Parameters:
5697bcf0153eSBarry Smith + ts - the `TS` context
5698847ff0e1SMatthew G. Knepley . t - current timestep
5699847ff0e1SMatthew G. Knepley . U - state vector
5700847ff0e1SMatthew G. Knepley . Udot - time derivative of state vector
5701847ff0e1SMatthew G. Knepley . shift - shift to apply, see note below
5702847ff0e1SMatthew G. Knepley - ctx - an optional user context
5703847ff0e1SMatthew G. Knepley 
5704847ff0e1SMatthew G. Knepley   Output Parameters:
5705847ff0e1SMatthew G. Knepley + J - Jacobian matrix (not altered in this routine)
5706847ff0e1SMatthew G. Knepley - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
5707847ff0e1SMatthew G. Knepley 
5708847ff0e1SMatthew G. Knepley   Level: intermediate
5709847ff0e1SMatthew G. Knepley 
5710847ff0e1SMatthew G. Knepley   Notes:
5711847ff0e1SMatthew G. Knepley   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
5712847ff0e1SMatthew G. Knepley 
5713847ff0e1SMatthew G. Knepley   dF/dU + shift*dF/dUdot
5714847ff0e1SMatthew G. Knepley 
5715847ff0e1SMatthew G. Knepley   Most users should not need to explicitly call this routine, as it
5716847ff0e1SMatthew G. Knepley   is used internally within the nonlinear solvers.
5717847ff0e1SMatthew G. Knepley 
5718bcf0153eSBarry Smith   This will first try to get the coloring from the `DM`.  If the `DM` type has no coloring
5719847ff0e1SMatthew G. Knepley   routine, then it will try to get the coloring from the matrix.  This requires that the
5720847ff0e1SMatthew G. Knepley   matrix have nonzero entries precomputed.
5721847ff0e1SMatthew G. Knepley 
5722bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetIJacobian()`, `MatFDColoringCreate()`, `MatFDColoringSetFunction()`
5723847ff0e1SMatthew G. Knepley @*/
5724d71ae5a4SJacob Faibussowitsch PetscErrorCode TSComputeIJacobianDefaultColor(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat J, Mat B, void *ctx)
5725d71ae5a4SJacob Faibussowitsch {
5726847ff0e1SMatthew G. Knepley   SNES          snes;
5727847ff0e1SMatthew G. Knepley   MatFDColoring color;
5728847ff0e1SMatthew G. Knepley   PetscBool     hascolor, matcolor = PETSC_FALSE;
5729847ff0e1SMatthew G. Knepley 
5730847ff0e1SMatthew G. Knepley   PetscFunctionBegin;
57319566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL));
57329566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)B, "TSMatFDColoring", (PetscObject *)&color));
5733847ff0e1SMatthew G. Knepley   if (!color) {
5734847ff0e1SMatthew G. Knepley     DM         dm;
5735847ff0e1SMatthew G. Knepley     ISColoring iscoloring;
5736847ff0e1SMatthew G. Knepley 
57379566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
57389566063dSJacob Faibussowitsch     PetscCall(DMHasColoring(dm, &hascolor));
5739847ff0e1SMatthew G. Knepley     if (hascolor && !matcolor) {
57409566063dSJacob Faibussowitsch       PetscCall(DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring));
57419566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
57429566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(color, (PetscErrorCode(*)(void))SNESTSFormFunction, (void *)ts));
57439566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
57449566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
57459566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5746847ff0e1SMatthew G. Knepley     } else {
5747847ff0e1SMatthew G. Knepley       MatColoring mc;
5748847ff0e1SMatthew G. Knepley 
57499566063dSJacob Faibussowitsch       PetscCall(MatColoringCreate(B, &mc));
57509566063dSJacob Faibussowitsch       PetscCall(MatColoringSetDistance(mc, 2));
57519566063dSJacob Faibussowitsch       PetscCall(MatColoringSetType(mc, MATCOLORINGSL));
57529566063dSJacob Faibussowitsch       PetscCall(MatColoringSetFromOptions(mc));
57539566063dSJacob Faibussowitsch       PetscCall(MatColoringApply(mc, &iscoloring));
57549566063dSJacob Faibussowitsch       PetscCall(MatColoringDestroy(&mc));
57559566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
57569566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(color, (PetscErrorCode(*)(void))SNESTSFormFunction, (void *)ts));
57579566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
57589566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
57599566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5760847ff0e1SMatthew G. Knepley     }
57619566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject)B, "TSMatFDColoring", (PetscObject)color));
57629566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)color));
5763847ff0e1SMatthew G. Knepley   }
57649566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
57659566063dSJacob Faibussowitsch   PetscCall(MatFDColoringApply(B, color, U, snes));
5766847ff0e1SMatthew G. Knepley   if (J != B) {
57679566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
57689566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
5769847ff0e1SMatthew G. Knepley   }
57703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5771847ff0e1SMatthew G. Knepley }
577293b34091SDebojyoti Ghosh 
5773cb9d8021SPierre Barbier de Reuille /*@
57746bc98fa9SBarry Smith     TSSetFunctionDomainError - Set a function that tests if the current state vector is valid
5775cb9d8021SPierre Barbier de Reuille 
5776cb9d8021SPierre Barbier de Reuille     Input Parameters:
5777bcf0153eSBarry Smith +    ts - the `TS` context
5778bcf0153eSBarry Smith -    func - function called within `TSFunctionDomainError()`
57796bc98fa9SBarry Smith 
57806bc98fa9SBarry Smith     Calling sequence of func:
57816bc98fa9SBarry Smith $     PetscErrorCode func(TS ts,PetscReal time,Vec state,PetscBool reject)
57826bc98fa9SBarry Smith 
57836bc98fa9SBarry Smith +   ts - the TS context
57846bc98fa9SBarry Smith .   time - the current time (of the stage)
57856bc98fa9SBarry Smith .   state - the state to check if it is valid
57866bc98fa9SBarry Smith -   reject - (output parameter) PETSC_FALSE if the state is acceptable, PETSC_TRUE if not acceptable
5787cb9d8021SPierre Barbier de Reuille 
5788cb9d8021SPierre Barbier de Reuille     Level: intermediate
5789cb9d8021SPierre Barbier de Reuille 
57906bc98fa9SBarry Smith     Notes:
57916bc98fa9SBarry Smith       If an implicit ODE solver is being used then, in addition to providing this routine, the
5792bcf0153eSBarry Smith       user's code should call `SNESSetFunctionDomainError()` when domain errors occur during
5793bcf0153eSBarry Smith       function evaluations where the functions are provided by `TSSetIFunction()` or `TSSetRHSFunction()`.
5794bcf0153eSBarry Smith       Use `TSGetSNES()` to obtain the `SNES` object
57956bc98fa9SBarry Smith 
5796bcf0153eSBarry Smith     Developer Note:
5797bcf0153eSBarry Smith       The naming of this function is inconsistent with the `SNESSetFunctionDomainError()`
57986bc98fa9SBarry Smith       since one takes a function pointer and the other does not.
57996bc98fa9SBarry Smith 
5800bcf0153eSBarry Smith .seealso: [](chapter_ts), `TSAdaptCheckStage()`, `TSFunctionDomainError()`, `SNESSetFunctionDomainError()`, `TSGetSNES()`
5801cb9d8021SPierre Barbier de Reuille @*/
5802cb9d8021SPierre Barbier de Reuille 
5803d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS, PetscReal, Vec, PetscBool *))
5804d71ae5a4SJacob Faibussowitsch {
5805cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5806cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5807cb9d8021SPierre Barbier de Reuille   ts->functiondomainerror = func;
58083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5809cb9d8021SPierre Barbier de Reuille }
5810cb9d8021SPierre Barbier de Reuille 
5811cb9d8021SPierre Barbier de Reuille /*@
58126bc98fa9SBarry Smith     TSFunctionDomainError - Checks if the current state is valid
5813cb9d8021SPierre Barbier de Reuille 
5814cb9d8021SPierre Barbier de Reuille     Input Parameters:
5815bcf0153eSBarry Smith +    ts - the `TS` context
58166bc98fa9SBarry Smith .    stagetime - time of the simulation
58176bc98fa9SBarry Smith -    Y - state vector to check.
5818cb9d8021SPierre Barbier de Reuille 
5819cb9d8021SPierre Barbier de Reuille     Output Parameter:
5820bcf0153eSBarry Smith .    accept - Set to `PETSC_FALSE` if the current state vector is valid.
582196a0c994SBarry Smith 
58226bc98fa9SBarry Smith     Level: developer
58236bc98fa9SBarry Smith 
5824bcf0153eSBarry Smith     Note:
5825bcf0153eSBarry Smith     This function is called by the `TS` integration routines and calls the user provided function (set with `TSSetFunctionDomainError()`)
5826bcf0153eSBarry Smith     to check if the current state is valid.
5827bcf0153eSBarry Smith 
5828bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetFunctionDomainError()`
5829cb9d8021SPierre Barbier de Reuille @*/
5830d71ae5a4SJacob Faibussowitsch PetscErrorCode TSFunctionDomainError(TS ts, PetscReal stagetime, Vec Y, PetscBool *accept)
5831d71ae5a4SJacob Faibussowitsch {
5832cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5833cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5834cb9d8021SPierre Barbier de Reuille   *accept = PETSC_TRUE;
58351e66621cSBarry Smith   if (ts->functiondomainerror) PetscCall((*ts->functiondomainerror)(ts, stagetime, Y, accept));
58363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5837cb9d8021SPierre Barbier de Reuille }
58381ceb14c0SBarry Smith 
583993b34091SDebojyoti Ghosh /*@C
5840e5168f73SEmil Constantinescu   TSClone - This function clones a time step object.
584193b34091SDebojyoti Ghosh 
5842d083f849SBarry Smith   Collective
584393b34091SDebojyoti Ghosh 
584493b34091SDebojyoti Ghosh   Input Parameter:
5845bcf0153eSBarry Smith . tsin    - The input `TS`
584693b34091SDebojyoti Ghosh 
584793b34091SDebojyoti Ghosh   Output Parameter:
5848bcf0153eSBarry Smith . tsout   - The output `TS` (cloned)
58495eca1a21SEmil Constantinescu 
58505eca1a21SEmil Constantinescu   Level: developer
585193b34091SDebojyoti Ghosh 
5852bcf0153eSBarry Smith   Notes:
5853bcf0153eSBarry 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.
5854bcf0153eSBarry Smith   It will likely be replaced in the future with a mechanism of switching methods on the fly.
5855bcf0153eSBarry Smith 
5856bcf0153eSBarry 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 `SNES` snes_dup=NULL; `TSGetSNES`(ts,&snes_dup); `TSSetSNES`(ts,snes_dup);
5857bcf0153eSBarry Smith 
5858bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `SNES`, `TSCreate()`, `TSSetType()`, `TSSetUp()`, `TSDestroy()`, `TSSetProblemType()`
585993b34091SDebojyoti Ghosh @*/
5860d71ae5a4SJacob Faibussowitsch PetscErrorCode TSClone(TS tsin, TS *tsout)
5861d71ae5a4SJacob Faibussowitsch {
586293b34091SDebojyoti Ghosh   TS     t;
5863dc846ba4SSatish Balay   SNES   snes_start;
5864dc846ba4SSatish Balay   DM     dm;
5865dc846ba4SSatish Balay   TSType type;
586693b34091SDebojyoti Ghosh 
586793b34091SDebojyoti Ghosh   PetscFunctionBegin;
586893b34091SDebojyoti Ghosh   PetscValidPointer(tsin, 1);
586993b34091SDebojyoti Ghosh   *tsout = NULL;
587093b34091SDebojyoti Ghosh 
58719566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView));
587293b34091SDebojyoti Ghosh 
587393b34091SDebojyoti Ghosh   /* General TS description */
587493b34091SDebojyoti Ghosh   t->numbermonitors    = 0;
5875d0c080abSJoseph Pusztay   t->monitorFrequency  = 1;
587693b34091SDebojyoti Ghosh   t->setupcalled       = 0;
587793b34091SDebojyoti Ghosh   t->ksp_its           = 0;
587893b34091SDebojyoti Ghosh   t->snes_its          = 0;
587993b34091SDebojyoti Ghosh   t->nwork             = 0;
58807d51462cSStefano Zampini   t->rhsjacobian.time  = PETSC_MIN_REAL;
588193b34091SDebojyoti Ghosh   t->rhsjacobian.scale = 1.;
588293b34091SDebojyoti Ghosh   t->ijacobian.shift   = 1.;
588393b34091SDebojyoti Ghosh 
58849566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(tsin, &snes_start));
58859566063dSJacob Faibussowitsch   PetscCall(TSSetSNES(t, snes_start));
5886d15a3a53SEmil Constantinescu 
58879566063dSJacob Faibussowitsch   PetscCall(TSGetDM(tsin, &dm));
58889566063dSJacob Faibussowitsch   PetscCall(TSSetDM(t, dm));
588993b34091SDebojyoti Ghosh 
589093b34091SDebojyoti Ghosh   t->adapt = tsin->adapt;
58919566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->adapt));
589293b34091SDebojyoti Ghosh 
5893e7069c78SShri   t->trajectory = tsin->trajectory;
58949566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->trajectory));
5895e7069c78SShri 
5896e7069c78SShri   t->event = tsin->event;
58976b10a48eSSatish Balay   if (t->event) t->event->refct++;
5898e7069c78SShri 
589993b34091SDebojyoti Ghosh   t->problem_type      = tsin->problem_type;
590093b34091SDebojyoti Ghosh   t->ptime             = tsin->ptime;
5901e7069c78SShri   t->ptime_prev        = tsin->ptime_prev;
590293b34091SDebojyoti Ghosh   t->time_step         = tsin->time_step;
590393b34091SDebojyoti Ghosh   t->max_time          = tsin->max_time;
590493b34091SDebojyoti Ghosh   t->steps             = tsin->steps;
590593b34091SDebojyoti Ghosh   t->max_steps         = tsin->max_steps;
590693b34091SDebojyoti Ghosh   t->equation_type     = tsin->equation_type;
590793b34091SDebojyoti Ghosh   t->atol              = tsin->atol;
590893b34091SDebojyoti Ghosh   t->rtol              = tsin->rtol;
590993b34091SDebojyoti Ghosh   t->max_snes_failures = tsin->max_snes_failures;
591093b34091SDebojyoti Ghosh   t->max_reject        = tsin->max_reject;
591193b34091SDebojyoti Ghosh   t->errorifstepfailed = tsin->errorifstepfailed;
591293b34091SDebojyoti Ghosh 
59139566063dSJacob Faibussowitsch   PetscCall(TSGetType(tsin, &type));
59149566063dSJacob Faibussowitsch   PetscCall(TSSetType(t, type));
591593b34091SDebojyoti Ghosh 
591693b34091SDebojyoti Ghosh   t->vec_sol = NULL;
591793b34091SDebojyoti Ghosh 
591893b34091SDebojyoti Ghosh   t->cfltime          = tsin->cfltime;
591993b34091SDebojyoti Ghosh   t->cfltime_local    = tsin->cfltime_local;
592093b34091SDebojyoti Ghosh   t->exact_final_time = tsin->exact_final_time;
592193b34091SDebojyoti Ghosh 
59229566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(t->ops, tsin->ops, sizeof(struct _TSOps)));
592393b34091SDebojyoti Ghosh 
59240d4fed19SBarry Smith   if (((PetscObject)tsin)->fortran_func_pointers) {
59250d4fed19SBarry Smith     PetscInt i;
59269566063dSJacob Faibussowitsch     PetscCall(PetscMalloc((10) * sizeof(void (*)(void)), &((PetscObject)t)->fortran_func_pointers));
5927ad540459SPierre Jolivet     for (i = 0; i < 10; i++) ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
59280d4fed19SBarry Smith   }
592993b34091SDebojyoti Ghosh   *tsout = t;
59303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
593193b34091SDebojyoti Ghosh }
5932f3b1f45cSBarry Smith 
5933d71ae5a4SJacob Faibussowitsch static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void *ctx, Vec x, Vec y)
5934d71ae5a4SJacob Faibussowitsch {
5935f3b1f45cSBarry Smith   TS ts = (TS)ctx;
5936f3b1f45cSBarry Smith 
5937f3b1f45cSBarry Smith   PetscFunctionBegin;
59389566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSFunction(ts, 0, x, y));
59393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5940f3b1f45cSBarry Smith }
5941f3b1f45cSBarry Smith 
5942f3b1f45cSBarry Smith /*@
5943bcf0153eSBarry Smith     TSRHSJacobianTest - Compares the multiply routine provided to the `MATSHELL` with differencing on the `TS` given RHS function.
5944f3b1f45cSBarry Smith 
5945c3339decSBarry Smith    Logically Collective
5946f3b1f45cSBarry Smith 
5947f3b1f45cSBarry Smith     Input Parameters:
5948f3b1f45cSBarry Smith     TS - the time stepping routine
5949f3b1f45cSBarry Smith 
5950f3b1f45cSBarry Smith    Output Parameter:
5951bcf0153eSBarry Smith .   flg - `PETSC_TRUE` if the multiply is likely correct
5952f3b1f45cSBarry Smith 
5953bcf0153eSBarry Smith    Options Database Key:
5954f3b1f45cSBarry Smith  .   -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator
5955f3b1f45cSBarry Smith 
5956f3b1f45cSBarry Smith    Level: advanced
5957f3b1f45cSBarry Smith 
5958bcf0153eSBarry Smith    Note:
595995452b02SPatrick Sanan     This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
5960f3b1f45cSBarry Smith 
5961bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `Mat`, `MATSHELL`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTestTranspose()`
5962f3b1f45cSBarry Smith @*/
5963d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSJacobianTest(TS ts, PetscBool *flg)
5964d71ae5a4SJacob Faibussowitsch {
5965f3b1f45cSBarry Smith   Mat           J, B;
5966f3b1f45cSBarry Smith   TSRHSJacobian func;
5967f3b1f45cSBarry Smith   void         *ctx;
5968f3b1f45cSBarry Smith 
5969f3b1f45cSBarry Smith   PetscFunctionBegin;
59709566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, &J, &B, &func, &ctx));
59719566063dSJacob Faibussowitsch   PetscCall((*func)(ts, 0.0, ts->vec_sol, J, B, ctx));
59729566063dSJacob Faibussowitsch   PetscCall(MatShellTestMult(J, RHSWrapperFunction_TSRHSJacobianTest, ts->vec_sol, ts, flg));
59733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5974f3b1f45cSBarry Smith }
5975f3b1f45cSBarry Smith 
5976f3b1f45cSBarry Smith /*@C
5977bcf0153eSBarry Smith     TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the `MATSHELL` with differencing on the `TS` given RHS function.
5978f3b1f45cSBarry Smith 
5979c3339decSBarry Smith    Logically Collective
5980f3b1f45cSBarry Smith 
5981f3b1f45cSBarry Smith     Input Parameters:
5982f3b1f45cSBarry Smith     TS - the time stepping routine
5983f3b1f45cSBarry Smith 
5984f3b1f45cSBarry Smith    Output Parameter:
5985bcf0153eSBarry Smith .   flg - `PETSC_TRUE` if the multiply is likely correct
5986f3b1f45cSBarry Smith 
5987bcf0153eSBarry Smith    Options Database Key:
5988f3b1f45cSBarry Smith .   -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator
5989f3b1f45cSBarry Smith 
5990bcf0153eSBarry Smith    Level: advanced
5991bcf0153eSBarry Smith 
599295452b02SPatrick Sanan    Notes:
599395452b02SPatrick Sanan     This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
5994f3b1f45cSBarry Smith 
5995bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `Mat`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTest()`
5996f3b1f45cSBarry Smith @*/
5997d71ae5a4SJacob Faibussowitsch PetscErrorCode TSRHSJacobianTestTranspose(TS ts, PetscBool *flg)
5998d71ae5a4SJacob Faibussowitsch {
5999f3b1f45cSBarry Smith   Mat           J, B;
6000f3b1f45cSBarry Smith   void         *ctx;
6001f3b1f45cSBarry Smith   TSRHSJacobian func;
6002f3b1f45cSBarry Smith 
6003f3b1f45cSBarry Smith   PetscFunctionBegin;
60049566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, &J, &B, &func, &ctx));
60059566063dSJacob Faibussowitsch   PetscCall((*func)(ts, 0.0, ts->vec_sol, J, B, ctx));
60069566063dSJacob Faibussowitsch   PetscCall(MatShellTestMultTranspose(J, RHSWrapperFunction_TSRHSJacobianTest, ts->vec_sol, ts, flg));
60073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6008f3b1f45cSBarry Smith }
60090fe4d17eSHong Zhang 
60100fe4d17eSHong Zhang /*@
60110fe4d17eSHong Zhang   TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used.
60120fe4d17eSHong Zhang 
60130fe4d17eSHong Zhang   Logically collective
60140fe4d17eSHong Zhang 
6015d8d19677SJose E. Roman   Input Parameters:
60160fe4d17eSHong Zhang +  ts - timestepping context
6017bcf0153eSBarry Smith -  use_splitrhsfunction - `PETSC_TRUE` indicates that the split RHSFunction will be used
60180fe4d17eSHong Zhang 
6019bcf0153eSBarry Smith   Options Database Key:
60200fe4d17eSHong Zhang .   -ts_use_splitrhsfunction - <true,false>
60210fe4d17eSHong Zhang 
60220fe4d17eSHong Zhang   Level: intermediate
60230fe4d17eSHong Zhang 
6024bcf0153eSBarry Smith   Note:
6025bcf0153eSBarry Smith     This is only useful for multirate methods
6026bcf0153eSBarry Smith 
6027bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetUseSplitRHSFunction()`
60280fe4d17eSHong Zhang @*/
6029d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction)
6030d71ae5a4SJacob Faibussowitsch {
60310fe4d17eSHong Zhang   PetscFunctionBegin;
60320fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
60330fe4d17eSHong Zhang   ts->use_splitrhsfunction = use_splitrhsfunction;
60343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
60350fe4d17eSHong Zhang }
60360fe4d17eSHong Zhang 
60370fe4d17eSHong Zhang /*@
60380fe4d17eSHong Zhang   TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used.
60390fe4d17eSHong Zhang 
60400fe4d17eSHong Zhang   Not collective
60410fe4d17eSHong Zhang 
60420fe4d17eSHong Zhang   Input Parameter:
60430fe4d17eSHong Zhang .  ts - timestepping context
60440fe4d17eSHong Zhang 
60450fe4d17eSHong Zhang   Output Parameter:
6046bcf0153eSBarry Smith .  use_splitrhsfunction - `PETSC_TRUE` indicates that the split RHSFunction will be used
60470fe4d17eSHong Zhang 
60480fe4d17eSHong Zhang   Level: intermediate
60490fe4d17eSHong Zhang 
6050bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetUseSplitRHSFunction()`
60510fe4d17eSHong Zhang @*/
6052d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction)
6053d71ae5a4SJacob Faibussowitsch {
60540fe4d17eSHong Zhang   PetscFunctionBegin;
60550fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
60560fe4d17eSHong Zhang   *use_splitrhsfunction = ts->use_splitrhsfunction;
60573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
60580fe4d17eSHong Zhang }
6059d60b7d5cSBarry Smith 
6060d60b7d5cSBarry Smith /*@
6061d60b7d5cSBarry Smith     TSSetMatStructure - sets the relationship between the nonzero structure of the RHS Jacobian matrix to the IJacobian matrix.
6062d60b7d5cSBarry Smith 
6063c3339decSBarry Smith    Logically  Collective
6064d60b7d5cSBarry Smith 
6065d60b7d5cSBarry Smith    Input Parameters:
6066d60b7d5cSBarry Smith +  ts - the time-stepper
6067bcf0153eSBarry Smith -  str - the structure (the default is `UNKNOWN_NONZERO_PATTERN`)
6068d60b7d5cSBarry Smith 
6069d60b7d5cSBarry Smith    Level: intermediate
6070d60b7d5cSBarry Smith 
6071bcf0153eSBarry Smith    Note:
6072d60b7d5cSBarry Smith      When the relationship between the nonzero structures is known and supplied the solution process can be much faster
6073d60b7d5cSBarry Smith 
6074bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `MatAXPY()`, `MatStructure`
6075d60b7d5cSBarry Smith  @*/
6076d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetMatStructure(TS ts, MatStructure str)
6077d71ae5a4SJacob Faibussowitsch {
6078d60b7d5cSBarry Smith   PetscFunctionBegin;
6079d60b7d5cSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
6080d60b7d5cSBarry Smith   ts->axpy_pattern = str;
60813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6082d60b7d5cSBarry Smith }
60834a658b32SHong Zhang 
60844a658b32SHong Zhang /*@
6085bcf0153eSBarry Smith   TSSetTimeSpan - sets the time span. The solution will be computed and stored for each time requested in the span
60864a658b32SHong Zhang 
6087c3339decSBarry Smith   Collective
60884a658b32SHong Zhang 
60894a658b32SHong Zhang   Input Parameters:
60904a658b32SHong Zhang + ts - the time-stepper
60914a658b32SHong Zhang . n - number of the time points (>=2)
60924a658b32SHong Zhang - span_times - array of the time points. The first element and the last element are the initial time and the final time respectively.
60934a658b32SHong Zhang 
6094bcf0153eSBarry Smith   Options Database Key:
60954a658b32SHong Zhang . -ts_time_span <t0,...tf> - Sets the time span
60964a658b32SHong Zhang 
6097bcf0153eSBarry Smith   Level: intermediate
60984a658b32SHong Zhang 
60994a658b32SHong Zhang   Notes:
61004a658b32SHong Zhang   The elements in tspan must be all increasing. They correspond to the intermediate points for time integration.
6101bcf0153eSBarry Smith   `TS_EXACTFINALTIME_MATCHSTEP` must be used to make the last time step in each sub-interval match the intermediate points specified.
6102bcf0153eSBarry Smith   The intermediate solutions are saved in a vector array that can be accessed with `TSGetTimeSpanSolutions()`. Thus using time span may
61034a658b32SHong Zhang   pressure the memory system when using a large number of span points.
61044a658b32SHong Zhang 
6105bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSGetTimeSpan()`, `TSGetTimeSpanSolutions()`
61064a658b32SHong Zhang  @*/
6107d71ae5a4SJacob Faibussowitsch PetscErrorCode TSSetTimeSpan(TS ts, PetscInt n, PetscReal *span_times)
6108d71ae5a4SJacob Faibussowitsch {
61094a658b32SHong Zhang   PetscFunctionBegin;
61104a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
611163a3b9bcSJacob Faibussowitsch   PetscCheck(n >= 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Minimum time span size is 2 but %" PetscInt_FMT " is provided", n);
61124a658b32SHong Zhang   if (ts->tspan && n != ts->tspan->num_span_times) {
61134a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan->span_times));
61144a658b32SHong Zhang     PetscCall(VecDestroyVecs(ts->tspan->num_span_times, &ts->tspan->vecs_sol));
61154a658b32SHong Zhang     PetscCall(PetscMalloc1(n, &ts->tspan->span_times));
61164a658b32SHong Zhang   }
61174a658b32SHong Zhang   if (!ts->tspan) {
61184a658b32SHong Zhang     TSTimeSpan tspan;
61194a658b32SHong Zhang     PetscCall(PetscNew(&tspan));
61204a658b32SHong Zhang     PetscCall(PetscMalloc1(n, &tspan->span_times));
6121e1db57b0SHong Zhang     tspan->reltol = 1e-6;
6122e1db57b0SHong Zhang     tspan->abstol = 10 * PETSC_MACHINE_EPSILON;
61234a658b32SHong Zhang     ts->tspan     = tspan;
61244a658b32SHong Zhang   }
61254a658b32SHong Zhang   ts->tspan->num_span_times = n;
61264a658b32SHong Zhang   PetscCall(PetscArraycpy(ts->tspan->span_times, span_times, n));
61274a658b32SHong Zhang   PetscCall(TSSetTime(ts, ts->tspan->span_times[0]));
61284a658b32SHong Zhang   PetscCall(TSSetMaxTime(ts, ts->tspan->span_times[n - 1]));
61293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
61304a658b32SHong Zhang }
61314a658b32SHong Zhang 
61324a658b32SHong Zhang /*@C
61334a658b32SHong Zhang   TSGetTimeSpan - gets the time span.
61344a658b32SHong Zhang 
61354a658b32SHong Zhang   Not Collective
61364a658b32SHong Zhang 
61374a658b32SHong Zhang   Input Parameter:
61384a658b32SHong Zhang . ts - the time-stepper
61394a658b32SHong Zhang 
61404a658b32SHong Zhang   Output Parameters:
61414a658b32SHong Zhang + n - number of the time points (>=2)
6142bcf0153eSBarry Smith - span_times - array of the time points. The first element and the last element are the initial time and the final time respectively.
6143bcf0153eSBarry Smith   The values are valid until the `TS` object is destroyed.
61444a658b32SHong Zhang 
61454a658b32SHong Zhang   Level: beginner
61464a658b32SHong Zhang 
6147bcf0153eSBarry Smith   Note:
6148bcf0153eSBarry Smith   Both n and span_times can be NULL.
6149bcf0153eSBarry Smith 
6150bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetTimeSpan()`, `TSGetTimeSpanSolutions()`
61514a658b32SHong Zhang  @*/
6152d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeSpan(TS ts, PetscInt *n, const PetscReal **span_times)
6153d71ae5a4SJacob Faibussowitsch {
61544a658b32SHong Zhang   PetscFunctionBegin;
61554a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
61564a658b32SHong Zhang   if (n) PetscValidIntPointer(n, 2);
61574a658b32SHong Zhang   if (span_times) PetscValidPointer(span_times, 3);
61584a658b32SHong Zhang   if (!ts->tspan) {
61594a658b32SHong Zhang     if (n) *n = 0;
61604a658b32SHong Zhang     if (span_times) *span_times = NULL;
61614a658b32SHong Zhang   } else {
61624a658b32SHong Zhang     if (n) *n = ts->tspan->num_span_times;
61634a658b32SHong Zhang     if (span_times) *span_times = ts->tspan->span_times;
61644a658b32SHong Zhang   }
61653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
61664a658b32SHong Zhang }
61674a658b32SHong Zhang 
61684a658b32SHong Zhang /*@
61694a658b32SHong Zhang    TSGetTimeSpanSolutions - Get the number of solutions and the solutions at the time points specified by the time span.
61704a658b32SHong Zhang 
61714a658b32SHong Zhang    Input Parameter:
6172bcf0153eSBarry Smith .  ts - the `TS` context obtained from `TSCreate()`
61734a658b32SHong Zhang 
61744a658b32SHong Zhang    Output Parameters:
61754a658b32SHong Zhang +  nsol - the number of solutions
61764a658b32SHong Zhang -  Sols - the solution vectors
61774a658b32SHong Zhang 
6178bcf0153eSBarry Smith    Level: intermediate
61794a658b32SHong Zhang 
618040bd4cedSHong Zhang    Notes:
618140bd4cedSHong Zhang     Both nsol and Sols can be NULL.
61824a658b32SHong Zhang 
6183bcf0153eSBarry Smith     Some time points in the time span may be skipped by TS so that nsol is less than the number of points specified by `TSSetTimeSpan()`.
6184bcf0153eSBarry Smith     For example, manipulating the step size, especially with a reduced precision, may cause `TS` to step over certain points in the span.
6185bcf0153eSBarry Smith 
6186bcf0153eSBarry Smith .seealso: [](chapter_ts), `TS`, `TSSetTimeSpan()`
61874a658b32SHong Zhang @*/
6188d71ae5a4SJacob Faibussowitsch PetscErrorCode TSGetTimeSpanSolutions(TS ts, PetscInt *nsol, Vec **Sols)
6189d71ae5a4SJacob Faibussowitsch {
61904a658b32SHong Zhang   PetscFunctionBegin;
61914a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
61924a658b32SHong Zhang   if (nsol) PetscValidIntPointer(nsol, 2);
61934a658b32SHong Zhang   if (Sols) PetscValidPointer(Sols, 3);
61944a658b32SHong Zhang   if (!ts->tspan) {
61954a658b32SHong Zhang     if (nsol) *nsol = 0;
61964a658b32SHong Zhang     if (Sols) *Sols = NULL;
61974a658b32SHong Zhang   } else {
619840bd4cedSHong Zhang     if (nsol) *nsol = ts->tspan->spanctr;
61994a658b32SHong Zhang     if (Sols) *Sols = ts->tspan->vecs_sol;
62004a658b32SHong Zhang   }
62013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
62024a658b32SHong Zhang }
6203d7cfae9bSHong Zhang 
6204d7cfae9bSHong Zhang /*@C
62057b2dc123SHong Zhang   TSPruneIJacobianColor - Remove nondiagonal zeros in the Jacobian matrix and update the `MatMFFD` coloring information.
6206d7cfae9bSHong Zhang 
6207d7cfae9bSHong Zhang   Collective on TS
6208d7cfae9bSHong Zhang 
6209d7cfae9bSHong Zhang   Input Parameters:
6210d7cfae9bSHong Zhang + ts - the TS context
6211d7cfae9bSHong Zhang . J - Jacobian matrix (not altered in this routine)
6212d7cfae9bSHong Zhang - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
6213d7cfae9bSHong Zhang 
6214d7cfae9bSHong Zhang   Level: intermediate
6215d7cfae9bSHong Zhang 
6216d7cfae9bSHong Zhang   Notes:
62177b2dc123SHong Zhang   This function improves the `MatMFFD` coloring performance when the Jacobian matrix is overallocated or contains
6218d7cfae9bSHong Zhang   many constant zeros entries, which is typically the case when the matrix is generated by a DM
6219d7cfae9bSHong Zhang   and multiple fields are involved.
6220d7cfae9bSHong Zhang 
6221d7cfae9bSHong Zhang   Users need to make sure that the Jacobian matrix is properly filled to reflect the sparsity
62227b2dc123SHong Zhang   structure. For `MatMFFD` coloring, the values of nonzero entries are not important. So one can
62237b2dc123SHong Zhang   usually call `TSComputeIJacobian()` with randomized input vectors to generate a dummy Jacobian.
62247b2dc123SHong Zhang   `TSComputeIJacobian()` should be called before `TSSolve()` but after `TSSetUp()`.
6225d7cfae9bSHong Zhang 
6226d7cfae9bSHong Zhang .seealso: `TSComputeIJacobianDefaultColor()`, `MatEliminateZeros()`, `MatFDColoringCreate()`, `MatFDColoringSetFunction()`
6227d7cfae9bSHong Zhang @*/
6228d7cfae9bSHong Zhang PetscErrorCode TSPruneIJacobianColor(TS ts, Mat J, Mat B)
6229d7cfae9bSHong Zhang {
6230d7cfae9bSHong Zhang   MatColoring   mc            = NULL;
6231d7cfae9bSHong Zhang   ISColoring    iscoloring    = NULL;
6232d7cfae9bSHong Zhang   MatFDColoring matfdcoloring = NULL;
6233d7cfae9bSHong Zhang 
6234d7cfae9bSHong Zhang   PetscFunctionBegin;
6235d7cfae9bSHong Zhang   /* Generate new coloring after eliminating zeros in the matrix */
6236d7cfae9bSHong Zhang   PetscCall(MatEliminateZeros(B));
6237d7cfae9bSHong Zhang   PetscCall(MatColoringCreate(B, &mc));
6238d7cfae9bSHong Zhang   PetscCall(MatColoringSetDistance(mc, 2));
6239d7cfae9bSHong Zhang   PetscCall(MatColoringSetType(mc, MATCOLORINGSL));
6240d7cfae9bSHong Zhang   PetscCall(MatColoringSetFromOptions(mc));
6241d7cfae9bSHong Zhang   PetscCall(MatColoringApply(mc, &iscoloring));
6242d7cfae9bSHong Zhang   PetscCall(MatColoringDestroy(&mc));
6243d7cfae9bSHong Zhang   /* Replace the old coloring with the new one */
6244d7cfae9bSHong Zhang   PetscCall(MatFDColoringCreate(B, iscoloring, &matfdcoloring));
6245d7cfae9bSHong Zhang   PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))SNESTSFormFunction, (void *)ts));
6246d7cfae9bSHong Zhang   PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
6247d7cfae9bSHong Zhang   PetscCall(MatFDColoringSetUp(B, iscoloring, matfdcoloring));
6248d7cfae9bSHong Zhang   PetscCall(PetscObjectCompose((PetscObject)B, "TSMatFDColoring", (PetscObject)matfdcoloring));
6249d7cfae9bSHong Zhang   PetscCall(PetscObjectDereference((PetscObject)matfdcoloring));
6250d7cfae9bSHong Zhang   PetscCall(ISColoringDestroy(&iscoloring));
62513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6252d7cfae9bSHong Zhang }
6253