xref: /petsc/src/ts/interface/ts.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1af0996ceSBarry Smith #include <petsc/private/tsimpl.h> /*I "petscts.h"  I*/
2496e6a7aSJed Brown #include <petscdmshell.h>
31e25c274SJed Brown #include <petscdmda.h>
42d5ee99bSBarry Smith #include <petscviewer.h>
52d5ee99bSBarry Smith #include <petscdraw.h>
6900f6b5bSMatthew G. Knepley #include <petscconvest.h>
7d763cef2SBarry Smith 
89371c9d4SSatish Balay #define SkipSmallValue(a, b, tol) \
99371c9d4SSatish Balay   if (PetscAbsScalar(a) < tol || PetscAbsScalar(b) < tol) continue;
101c167fc2SEmil Constantinescu 
11d5ba7fb7SMatthew Knepley /* Logging support */
12d74926cbSBarry Smith PetscClassId  TS_CLASSID, DMTS_CLASSID;
13a05bf03eSHong Zhang PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
14d405a339SMatthew Knepley 
15c793f718SLisandro Dalcin const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED", "STEPOVER", "INTERPOLATE", "MATCHSTEP", "TSExactFinalTimeOption", "TS_EXACTFINALTIME_", NULL};
1649354f04SShri Abhyankar 
179371c9d4SSatish Balay static PetscErrorCode TSAdaptSetDefaultType(TSAdapt adapt, TSAdaptType default_type) {
182ffb9264SLisandro Dalcin   PetscFunctionBegin;
19b92453a8SLisandro Dalcin   PetscValidHeaderSpecific(adapt, TSADAPT_CLASSID, 1);
20b92453a8SLisandro Dalcin   PetscValidCharPointer(default_type, 2);
211e66621cSBarry Smith   if (!((PetscObject)adapt)->type_name) PetscCall(TSAdaptSetType(adapt, default_type));
222ffb9264SLisandro Dalcin   PetscFunctionReturn(0);
232ffb9264SLisandro Dalcin }
242ffb9264SLisandro Dalcin 
25bdad233fSMatthew Knepley /*@
26bdad233fSMatthew Knepley    TSSetFromOptions - Sets various TS parameters from user options.
27bdad233fSMatthew Knepley 
28bdad233fSMatthew Knepley    Collective on TS
29bdad233fSMatthew Knepley 
30bdad233fSMatthew Knepley    Input Parameter:
31bdad233fSMatthew Knepley .  ts - the TS context obtained from TSCreate()
32bdad233fSMatthew Knepley 
33bdad233fSMatthew Knepley    Options Database Keys:
34d2567f34SHong Zhang +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSALPHA, TSGLLE, TSSSP, TSGLEE, TSBSYMP, TSIRK
35ef222394SBarry Smith .  -ts_save_trajectory - checkpoint the solution at each time-step
36ef85077eSLisandro Dalcin .  -ts_max_time <time> - maximum time to compute to
374a658b32SHong Zhang .  -ts_time_span <t0,...tf> - sets the time span, solutions are computed and stored for each indicated time
38ef85077eSLisandro Dalcin .  -ts_max_steps <steps> - maximum number of time-steps to take
39ef85077eSLisandro Dalcin .  -ts_init_time <time> - initial time to start computation
404dc72f7fSBarry Smith .  -ts_final_time <time> - final time to compute to (deprecated: use -ts_max_time)
413e4cdcaaSBarry Smith .  -ts_dt <dt> - initial time step
421628793fSSatish 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
43a3cdaa26SBarry Smith .  -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed
44a3cdaa26SBarry Smith .  -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails
45a3cdaa26SBarry Smith .  -ts_error_if_step_fails <true,false> - Error if no step succeeds
46a3cdaa26SBarry Smith .  -ts_rtol <rtol> - relative tolerance for local truncation error
4767b8a455SSatish Balay .  -ts_atol <atol> - Absolute tolerance for local truncation error
48f3b1f45cSBarry Smith .  -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - test the Jacobian at each iteration against finite difference with RHS function
49f3b1f45cSBarry 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
5067b8a455SSatish Balay .  -ts_adjoint_solve <yes,no> - After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory)
51847ff0e1SMatthew G. Knepley .  -ts_fd_color - Use finite differences with coloring to compute IJacobian
52bdad233fSMatthew Knepley .  -ts_monitor - print information at each timestep
53aee7a9fbSMatthew G. Knepley .  -ts_monitor_cancel - Cancel all monitors
54de06c3feSJed Brown .  -ts_monitor_lg_solution - Monitor solution graphically
55de06c3feSJed Brown .  -ts_monitor_lg_error - Monitor error graphically
567cf37e64SBarry Smith .  -ts_monitor_error - Monitors norm of error
576934998bSLisandro Dalcin .  -ts_monitor_lg_timestep - Monitor timestep size graphically
588b668821SLisandro Dalcin .  -ts_monitor_lg_timestep_log - Monitor log timestep size graphically
59de06c3feSJed Brown .  -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically
60de06c3feSJed Brown .  -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically
61de06c3feSJed Brown .  -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically
62de06c3feSJed Brown .  -ts_monitor_draw_solution - Monitor solution graphically
633e4cdcaaSBarry Smith .  -ts_monitor_draw_solution_phase  <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom
643e4cdcaaSBarry Smith .  -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction()
65fde5950dSBarry Smith .  -ts_monitor_solution [ascii binary draw][:filename][:viewerformat] - monitors the solution at each timestep
6663a3b9bcSJacob 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)
679e336e28SPatrick Sanan -  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
6853ea634cSHong Zhang 
693d5a8a6aSBarry Smith    Notes:
703d5a8a6aSBarry Smith      See SNESSetFromOptions() and KSPSetFromOptions() for how to control the nonlinear and linear solves used by the time-stepper.
713d5a8a6aSBarry Smith 
723d5a8a6aSBarry Smith      Certain SNES options get reset for each new nonlinear solver, for example -snes_lag_jacobian <its> and -snes_lag_preconditioner <its>, in order
733d5a8a6aSBarry Smith      to retain them over the multiple nonlinear solves that TS uses you mush also provide -snes_lag_jacobian_persists true and
743d5a8a6aSBarry Smith      -snes_lag_preconditioner_persists true
753d5a8a6aSBarry Smith 
769e336e28SPatrick Sanan    Developer Note:
779e336e28SPatrick Sanan      We should unify all the -ts_monitor options in the way that -xxx_view has been unified
78bdad233fSMatthew Knepley 
79bdad233fSMatthew Knepley    Level: beginner
80bdad233fSMatthew Knepley 
81db781477SPatrick Sanan .seealso: `TSGetType()`
82bdad233fSMatthew Knepley @*/
839371c9d4SSatish Balay PetscErrorCode TSSetFromOptions(TS ts) {
84bc952696SBarry Smith   PetscBool              opt, flg, tflg;
85eabae89aSBarry Smith   char                   monfilename[PETSC_MAX_PATH_LEN];
864a658b32SHong Zhang   PetscReal              time_step, tspan[100];
874a658b32SHong Zhang   PetscInt               nt = PETSC_STATIC_ARRAY_LENGTH(tspan);
8849354f04SShri Abhyankar   TSExactFinalTimeOption eftopt;
89d1212d36SBarry Smith   char                   dir[16];
90cd11d68dSLisandro Dalcin   TSIFunction            ifun;
916991f827SBarry Smith   const char            *defaultType;
926991f827SBarry Smith   char                   typeName[256];
93bdad233fSMatthew Knepley 
94bdad233fSMatthew Knepley   PetscFunctionBegin;
950700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
966991f827SBarry Smith 
979566063dSJacob Faibussowitsch   PetscCall(TSRegisterAll());
989566063dSJacob Faibussowitsch   PetscCall(TSGetIFunction(ts, NULL, &ifun, NULL));
99cd11d68dSLisandro Dalcin 
100d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)ts);
1011ef27442SStefano Zampini   if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name;
1021ef27442SStefano Zampini   else defaultType = ifun ? TSBEULER : TSEULER;
1039566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-ts_type", "TS method", "TSSetType", TSList, defaultType, typeName, 256, &opt));
1041e66621cSBarry Smith   if (opt) PetscCall(TSSetType(ts, typeName));
1051e66621cSBarry Smith   else PetscCall(TSSetType(ts, defaultType));
106bdad233fSMatthew Knepley 
107bdad233fSMatthew Knepley   /* Handle generic TS options */
1089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDeprecated("-ts_final_time", "-ts_max_time", "3.10", NULL));
1099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_max_time", "Maximum time to run to", "TSSetMaxTime", ts->max_time, &ts->max_time, NULL));
1104a658b32SHong Zhang   PetscCall(PetscOptionsRealArray("-ts_time_span", "Time span", "TSSetTimeSpan", tspan, &nt, &flg));
1114a658b32SHong Zhang   if (flg) PetscCall(TSSetTimeSpan(ts, nt, tspan));
1129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_steps", "Maximum number of time steps", "TSSetMaxSteps", ts->max_steps, &ts->max_steps, NULL));
1139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_init_time", "Initial time", "TSSetTime", ts->ptime, &ts->ptime, NULL));
1149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_dt", "Initial time step", "TSSetTimeStep", ts->time_step, &time_step, &flg));
1159566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetTimeStep(ts, time_step));
1169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-ts_exact_final_time", "Option for handling of final time step", "TSSetExactFinalTime", TSExactFinalTimeOptions, (PetscEnum)ts->exact_final_time, (PetscEnum *)&eftopt, &flg));
1179566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetExactFinalTime(ts, eftopt));
1189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_snes_failures", "Maximum number of nonlinear solve failures", "TSSetMaxSNESFailures", ts->max_snes_failures, &ts->max_snes_failures, NULL));
1199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_reject", "Maximum number of step rejections before step fails", "TSSetMaxStepRejections", ts->max_reject, &ts->max_reject, NULL));
1209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_error_if_step_fails", "Error if no step succeeds", "TSSetErrorIfStepFails", ts->errorifstepfailed, &ts->errorifstepfailed, NULL));
1219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_rtol", "Relative tolerance for local truncation error", "TSSetTolerances", ts->rtol, &ts->rtol, NULL));
1229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_atol", "Absolute tolerance for local truncation error", "TSSetTolerances", ts->atol, &ts->atol, NULL));
123bdad233fSMatthew Knepley 
1249566063dSJacob 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));
1259566063dSJacob 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));
1269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_use_splitrhsfunction", "Use the split RHS function for multirate solvers ", "TSSetUseSplitRHSFunction", ts->use_splitrhsfunction, &ts->use_splitrhsfunction, NULL));
12756f85f32SBarry Smith #if defined(PETSC_HAVE_SAWS)
12856f85f32SBarry Smith   {
12956f85f32SBarry Smith     PetscBool set;
13056f85f32SBarry Smith     flg = PETSC_FALSE;
1319566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-ts_saws_block", "Block for SAWs memory snooper at end of TSSolve", "PetscObjectSAWsBlock", ((PetscObject)ts)->amspublishblock, &flg, &set));
1321baa6e33SBarry Smith     if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)ts, flg));
13356f85f32SBarry Smith   }
13456f85f32SBarry Smith #endif
13556f85f32SBarry Smith 
136bdad233fSMatthew Knepley   /* Monitor options */
1379566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_monitor_frequency", "Number of time steps between monitor output", "TSMonitorSetFrequency", ts->monitorFrequency, &ts->monitorFrequency, NULL));
1389566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor", "Monitor time and timestep size", "TSMonitorDefault", TSMonitorDefault, NULL));
1399566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_extreme", "Monitor extreme values of the solution", "TSMonitorExtreme", TSMonitorExtreme, NULL));
1409566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_solution", "View the solution at each timestep", "TSMonitorSolution", TSMonitorSolution, NULL));
1419566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_dmswarm_monitor_moments", "Monitor moments of particle distribution", "TSDMSwarmMonitorMoments", TSDMSwarmMonitorMoments, NULL));
142fde5950dSBarry Smith 
1439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_python", "Use Python function", "TSMonitorSet", NULL, monfilename, sizeof(monfilename), &flg));
1449566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)ts, monfilename));
1455180491cSLisandro Dalcin 
1469566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_solution", "Monitor solution graphically", "TSMonitorLGSolution", &opt));
147b3603a34SBarry Smith   if (opt) {
1483923b477SBarry Smith     PetscInt  howoften = 1;
149e669de00SBarry Smith     DM        dm;
150e669de00SBarry Smith     PetscBool net;
151b3603a34SBarry Smith 
1529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_solution", "Monitor solution graphically", "TSMonitorLGSolution", howoften, &howoften, NULL));
1539566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
1549566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dm, DMNETWORK, &net));
155e669de00SBarry Smith     if (net) {
156e669de00SBarry Smith       TSMonitorLGCtxNetwork ctx;
1579566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxNetworkCreate(ts, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 600, 400, howoften, &ctx));
1589566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts, TSMonitorLGCtxNetworkSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxNetworkDestroy));
1599566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_lg_solution_semilogy", "Plot the solution with a semi-log axis", "", ctx->semilogy, &ctx->semilogy, NULL));
160e669de00SBarry Smith     } else {
161e669de00SBarry Smith       TSMonitorLGCtx ctx;
1629566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1639566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts, TSMonitorLGSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
164bdad233fSMatthew Knepley     }
165e669de00SBarry Smith   }
1666ba87a44SLisandro Dalcin 
1679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_error", "Monitor error graphically", "TSMonitorLGError", &opt));
168ef20d060SBarry Smith   if (opt) {
1690b039ecaSBarry Smith     TSMonitorLGCtx ctx;
1703923b477SBarry Smith     PetscInt       howoften = 1;
171ef20d060SBarry Smith 
1729566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_error", "Monitor error graphically", "TSMonitorLGError", howoften, &howoften, NULL));
1739566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1749566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGError, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
175ef20d060SBarry Smith   }
1769566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts, "-ts_monitor_error", "View the error at each timestep", "TSMonitorError", TSMonitorError, NULL));
1777cf37e64SBarry Smith 
1789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep", "Monitor timestep size graphically", "TSMonitorLGTimeStep", &opt));
1796934998bSLisandro Dalcin   if (opt) {
1806934998bSLisandro Dalcin     TSMonitorLGCtx ctx;
1816934998bSLisandro Dalcin     PetscInt       howoften = 1;
1826934998bSLisandro Dalcin 
1839566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep", "Monitor timestep size graphically", "TSMonitorLGTimeStep", howoften, &howoften, NULL));
1849566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1859566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGTimeStep, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
1866934998bSLisandro Dalcin   }
1879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep_log", "Monitor log timestep size graphically", "TSMonitorLGTimeStep", &opt));
1888b668821SLisandro Dalcin   if (opt) {
1898b668821SLisandro Dalcin     TSMonitorLGCtx ctx;
1908b668821SLisandro Dalcin     PetscInt       howoften = 1;
1918b668821SLisandro Dalcin 
1929566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep_log", "Monitor log timestep size graphically", "TSMonitorLGTimeStep", howoften, &howoften, NULL));
1939566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
1949566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGTimeStep, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
1958b668821SLisandro Dalcin     ctx->semilogy = PETSC_TRUE;
1968b668821SLisandro Dalcin   }
1978b668821SLisandro Dalcin 
1989566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_snes_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGSNESIterations", &opt));
199201da799SBarry Smith   if (opt) {
200201da799SBarry Smith     TSMonitorLGCtx ctx;
201201da799SBarry Smith     PetscInt       howoften = 1;
202201da799SBarry Smith 
2039566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_snes_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGSNESIterations", howoften, &howoften, NULL));
2049566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
2059566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGSNESIterations, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
206201da799SBarry Smith   }
2079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_ksp_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGKSPIterations", &opt));
208201da799SBarry Smith   if (opt) {
209201da799SBarry Smith     TSMonitorLGCtx ctx;
210201da799SBarry Smith     PetscInt       howoften = 1;
211201da799SBarry Smith 
2129566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_ksp_iterations", "Monitor number nonlinear iterations for each timestep graphically", "TSMonitorLGKSPIterations", howoften, &howoften, NULL));
2139566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, howoften, &ctx));
2149566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGKSPIterations, ctx, (PetscErrorCode(*)(void **))TSMonitorLGCtxDestroy));
215201da799SBarry Smith   }
2169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_sp_eig", "Monitor eigenvalues of linearized operator graphically", "TSMonitorSPEig", &opt));
2178189c53fSBarry Smith   if (opt) {
2188189c53fSBarry Smith     TSMonitorSPEigCtx ctx;
2198189c53fSBarry Smith     PetscInt          howoften = 1;
2208189c53fSBarry Smith 
2219566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_sp_eig", "Monitor eigenvalues of linearized operator graphically", "TSMonitorSPEig", howoften, &howoften, NULL));
2229566063dSJacob Faibussowitsch     PetscCall(TSMonitorSPEigCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
2239566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorSPEig, ctx, (PetscErrorCode(*)(void **))TSMonitorSPEigCtxDestroy));
2248189c53fSBarry Smith   }
2259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_sp_swarm", "Display particle phase from the DMSwarm", "TSMonitorSPSwarm", &opt));
2261b575b74SJoseph Pusztay   if (opt) {
2271b575b74SJoseph Pusztay     TSMonitorSPCtx ctx;
228d7462660SMatthew Knepley     PetscInt       howoften = 1, retain = 0;
2296a5217c0SMatthew G. Knepley     PetscBool      phase = PETSC_TRUE, create = PETSC_TRUE;
230d7462660SMatthew Knepley 
2319371c9d4SSatish Balay     for (PetscInt i = 0; i < ts->numbermonitors; ++i)
2329371c9d4SSatish Balay       if (ts->monitor[i] == TSMonitorSPSwarmSolution) {
2339371c9d4SSatish Balay         create = PETSC_FALSE;
2349371c9d4SSatish Balay         break;
2359371c9d4SSatish Balay       }
2366a5217c0SMatthew G. Knepley     if (create) {
2379566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm", "Display particles phase from the DMSwarm", "TSMonitorSPSwarm", howoften, &howoften, NULL));
2389566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm_retain", "Retain n points plotted to show trajectory, -1 for all points", "TSMonitorSPSwarm", retain, &retain, NULL));
2399566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_sp_swarm_phase", "Plot in phase space rather than coordinate space", "TSMonitorSPSwarm", phase, &phase, NULL));
2409566063dSJacob Faibussowitsch       PetscCall(TSMonitorSPCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, retain, phase, &ctx));
2419566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts, TSMonitorSPSwarmSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorSPCtxDestroy));
2421b575b74SJoseph Pusztay     }
2436a5217c0SMatthew G. Knepley   }
244ef20d060SBarry Smith   opt = PETSC_FALSE;
2459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution", "Monitor solution graphically", "TSMonitorDrawSolution", &opt));
246a7cc72afSBarry Smith   if (opt) {
24783a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
24883a4ac43SBarry Smith     PetscInt         howoften = 1;
249a80ad3e0SBarry Smith 
2509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution", "Monitor solution graphically", "TSMonitorDrawSolution", howoften, &howoften, NULL));
2519566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Computed Solution", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
2529566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolution, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
253bdad233fSMatthew Knepley   }
254fb1732b5SBarry Smith   opt = PETSC_FALSE;
2559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_phase", "Monitor solution graphically", "TSMonitorDrawSolutionPhase", &opt));
2562d5ee99bSBarry Smith   if (opt) {
2572d5ee99bSBarry Smith     TSMonitorDrawCtx ctx;
2582d5ee99bSBarry Smith     PetscReal        bounds[4];
2592d5ee99bSBarry Smith     PetscInt         n = 4;
2602d5ee99bSBarry Smith     PetscDraw        draw;
2616934998bSLisandro Dalcin     PetscDrawAxis    axis;
2622d5ee99bSBarry Smith 
2639566063dSJacob Faibussowitsch     PetscCall(PetscOptionsRealArray("-ts_monitor_draw_solution_phase", "Monitor solution graphically", "TSMonitorDrawSolutionPhase", bounds, &n, NULL));
2643c633725SBarry Smith     PetscCheck(n == 4, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Must provide bounding box of phase field");
2659566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, 1, &ctx));
2669566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ctx->viewer, 0, &draw));
2679566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDrawAxis(ctx->viewer, 0, &axis));
2689566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLimits(axis, bounds[0], bounds[2], bounds[1], bounds[3]));
2699566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis, "Phase Diagram", "Variable 1", "Variable 2"));
2709566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolutionPhase, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
2712d5ee99bSBarry Smith   }
2722d5ee99bSBarry Smith   opt = PETSC_FALSE;
2739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_error", "Monitor error graphically", "TSMonitorDrawError", &opt));
2743a471f94SBarry Smith   if (opt) {
27583a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
27683a4ac43SBarry Smith     PetscInt         howoften = 1;
2773a471f94SBarry Smith 
2789566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_error", "Monitor error graphically", "TSMonitorDrawError", howoften, &howoften, NULL));
2799566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Error", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
2809566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawError, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
2813a471f94SBarry Smith   }
2820ed3bfb6SBarry Smith   opt = PETSC_FALSE;
2839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_function", "Monitor solution provided by TSMonitorSetSolutionFunction() graphically", "TSMonitorDrawSolutionFunction", &opt));
2840ed3bfb6SBarry Smith   if (opt) {
2850ed3bfb6SBarry Smith     TSMonitorDrawCtx ctx;
2860ed3bfb6SBarry Smith     PetscInt         howoften = 1;
2870ed3bfb6SBarry Smith 
2889566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution_function", "Monitor solution provided by TSMonitorSetSolutionFunction() graphically", "TSMonitorDrawSolutionFunction", howoften, &howoften, NULL));
2899566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts), NULL, "Solution provided by user function", PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, &ctx));
2909566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDrawSolutionFunction, ctx, (PetscErrorCode(*)(void **))TSMonitorDrawCtxDestroy));
2910ed3bfb6SBarry Smith   }
292fde5950dSBarry Smith 
293ed81e22dSJed Brown   opt = PETSC_FALSE;
29463a3b9bcSJacob 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));
295ed81e22dSJed Brown   if (flg) {
296ed81e22dSJed Brown     const char *ptr, *ptr2;
297ed81e22dSJed Brown     char       *filetemplate;
29863a3b9bcSJacob 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");
299ed81e22dSJed Brown     /* Do some cursory validation of the input. */
3009566063dSJacob Faibussowitsch     PetscCall(PetscStrstr(monfilename, "%", (char **)&ptr));
30163a3b9bcSJacob Faibussowitsch     PetscCheck(ptr, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03" PetscInt_FMT ".vts");
302ed81e22dSJed Brown     for (ptr++; ptr && *ptr; ptr++) {
3039566063dSJacob Faibussowitsch       PetscCall(PetscStrchr("DdiouxX", *ptr, (char **)&ptr2));
30463a3b9bcSJacob 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");
305ed81e22dSJed Brown       if (ptr2) break;
306ed81e22dSJed Brown     }
3079566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(monfilename, &filetemplate));
3089566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorSolutionVTK, filetemplate, (PetscErrorCode(*)(void **))TSMonitorSolutionVTKDestroy));
309ed81e22dSJed Brown   }
310bdad233fSMatthew Knepley 
3119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_dmda_ray", "Display a ray of the solution", "None", "y=0", dir, sizeof(dir), &flg));
312d1212d36SBarry Smith   if (flg) {
313d1212d36SBarry Smith     TSMonitorDMDARayCtx *rayctx;
314d1212d36SBarry Smith     int                  ray = 0;
3153ee9839eSMatthew G. Knepley     DMDirection          ddir;
316d1212d36SBarry Smith     DM                   da;
317d1212d36SBarry Smith     PetscMPIInt          rank;
318d1212d36SBarry Smith 
3193c633725SBarry Smith     PetscCheck(dir[1] == '=', PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray %s", dir);
3203ee9839eSMatthew G. Knepley     if (dir[0] == 'x') ddir = DM_X;
3213ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
32298921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray %s", dir);
323d1212d36SBarry Smith     sscanf(dir + 2, "%d", &ray);
324d1212d36SBarry Smith 
3259566063dSJacob Faibussowitsch     PetscCall(PetscInfo(((PetscObject)ts), "Displaying DMDA ray %c = %d\n", dir[0], ray));
3269566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3279566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &da));
3289566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter));
3299566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)ts), &rank));
3301e66621cSBarry Smith     if (rank == 0) PetscCall(PetscViewerDrawOpen(PETSC_COMM_SELF, NULL, NULL, 0, 0, 600, 300, &rayctx->viewer));
33151b4a12fSMatthew G. Knepley     rayctx->lgctx = NULL;
3329566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorDMDARay, rayctx, TSMonitorDMDARayDestroy));
333d1212d36SBarry Smith   }
3349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_lg_dmda_ray", "Display a ray of the solution", "None", "x=0", dir, sizeof(dir), &flg));
33551b4a12fSMatthew G. Knepley   if (flg) {
33651b4a12fSMatthew G. Knepley     TSMonitorDMDARayCtx *rayctx;
33751b4a12fSMatthew G. Knepley     int                  ray = 0;
3383ee9839eSMatthew G. Knepley     DMDirection          ddir;
33951b4a12fSMatthew G. Knepley     DM                   da;
34051b4a12fSMatthew G. Knepley     PetscInt             howoften = 1;
341d1212d36SBarry Smith 
3423c633725SBarry Smith     PetscCheck(dir[1] == '=', PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir);
3433ee9839eSMatthew G. Knepley     if (dir[0] == 'x') ddir = DM_X;
3443ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
34598921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir);
34651b4a12fSMatthew G. Knepley     sscanf(dir + 2, "%d", &ray);
3471c3436cfSJed Brown 
3489566063dSJacob Faibussowitsch     PetscCall(PetscInfo(((PetscObject)ts), "Displaying LG DMDA ray %c = %d\n", dir[0], ray));
3499566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3509566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &da));
3519566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter));
3529566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 600, 400, howoften, &rayctx->lgctx));
3539566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy));
35451b4a12fSMatthew G. Knepley   }
355a7a1495cSBarry Smith 
3569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_envelope", "Monitor maximum and minimum value of each component of the solution", "TSMonitorEnvelope", &opt));
357b3d3934dSBarry Smith   if (opt) {
358b3d3934dSBarry Smith     TSMonitorEnvelopeCtx ctx;
359b3d3934dSBarry Smith 
3609566063dSJacob Faibussowitsch     PetscCall(TSMonitorEnvelopeCtxCreate(ts, &ctx));
3619566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorEnvelope, ctx, (PetscErrorCode(*)(void **))TSMonitorEnvelopeCtxDestroy));
362b3d3934dSBarry Smith   }
363aee7a9fbSMatthew G. Knepley   flg = PETSC_FALSE;
3649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_monitor_cancel", "Remove all monitors", "TSMonitorCancel", flg, &flg, &opt));
3659566063dSJacob Faibussowitsch   if (opt && flg) PetscCall(TSMonitorCancel(ts));
366b3d3934dSBarry Smith 
367847ff0e1SMatthew G. Knepley   flg = PETSC_FALSE;
3689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL));
369847ff0e1SMatthew G. Knepley   if (flg) {
370847ff0e1SMatthew G. Knepley     DM dm;
371847ff0e1SMatthew G. Knepley 
3729371c9d4SSatish Balay     PetscCall(TSGetDM(ts, &dm));
3739371c9d4SSatish Balay     PetscCall(DMTSUnsetIJacobianContext_Internal(dm));
3749566063dSJacob Faibussowitsch     PetscCall(TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, NULL));
3759566063dSJacob Faibussowitsch     PetscCall(PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n"));
376847ff0e1SMatthew G. Knepley   }
377847ff0e1SMatthew G. Knepley 
378d763cef2SBarry Smith   /* Handle specific TS options */
379dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, setfromoptions, PetscOptionsObject);
380fbc52257SHong Zhang 
381a7bdc993SLisandro Dalcin   /* Handle TSAdapt options */
3829566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
3839566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
384dbbe0bcdSBarry Smith   PetscCall(TSAdaptSetFromOptions(ts->adapt, PetscOptionsObject));
385a7bdc993SLisandro Dalcin 
38668bece0bSHong Zhang   /* TS trajectory must be set after TS, since it may use some TS options above */
3874f122a70SLisandro Dalcin   tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE;
3889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_save_trajectory", "Save the solution at each timestep", "TSSetSaveTrajectory", tflg, &tflg, NULL));
3891baa6e33SBarry Smith   if (tflg) PetscCall(TSSetSaveTrajectory(ts));
390a05bf03eSHong Zhang 
391dbbe0bcdSBarry Smith   PetscCall(TSAdjointSetFromOptions(ts, PetscOptionsObject));
392d763cef2SBarry Smith 
393d763cef2SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
394dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)ts, PetscOptionsObject));
395d0609cedSBarry Smith   PetscOptionsEnd();
396d763cef2SBarry Smith 
3971baa6e33SBarry Smith   if (ts->trajectory) PetscCall(TSTrajectorySetFromOptions(ts->trajectory, ts));
39868bece0bSHong Zhang 
3991ef27442SStefano Zampini   /* why do we have to do this here and not during TSSetUp? */
4009566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &ts->snes));
4011ef27442SStefano Zampini   if (ts->problem_type == TS_LINEAR) {
4029566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes, &flg, SNESKSPONLY, SNESKSPTRANSPOSEONLY, ""));
4039566063dSJacob Faibussowitsch     if (!flg) PetscCall(SNESSetType(ts->snes, SNESKSPONLY));
4041ef27442SStefano Zampini   }
4059566063dSJacob Faibussowitsch   PetscCall(SNESSetFromOptions(ts->snes));
406d763cef2SBarry Smith   PetscFunctionReturn(0);
407d763cef2SBarry Smith }
408d763cef2SBarry Smith 
409d2daff3dSHong Zhang /*@
41078fbdcc8SBarry Smith    TSGetTrajectory - Gets the trajectory from a TS if it exists
41178fbdcc8SBarry Smith 
41278fbdcc8SBarry Smith    Collective on TS
41378fbdcc8SBarry Smith 
41478fbdcc8SBarry Smith    Input Parameters:
41578fbdcc8SBarry Smith .  ts - the TS context obtained from TSCreate()
41678fbdcc8SBarry Smith 
4177a7aea1fSJed Brown    Output Parameters:
41878fbdcc8SBarry Smith .  tr - the TSTrajectory object, if it exists
41978fbdcc8SBarry Smith 
42078fbdcc8SBarry Smith    Note: This routine should be called after all TS options have been set
42178fbdcc8SBarry Smith 
42278fbdcc8SBarry Smith    Level: advanced
42378fbdcc8SBarry Smith 
424db781477SPatrick Sanan .seealso: `TSGetTrajectory()`, `TSAdjointSolve()`, `TSTrajectory`, `TSTrajectoryCreate()`
42578fbdcc8SBarry Smith 
42678fbdcc8SBarry Smith @*/
4279371c9d4SSatish Balay PetscErrorCode TSGetTrajectory(TS ts, TSTrajectory *tr) {
42878fbdcc8SBarry Smith   PetscFunctionBegin;
42978fbdcc8SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
43078fbdcc8SBarry Smith   *tr = ts->trajectory;
43178fbdcc8SBarry Smith   PetscFunctionReturn(0);
43278fbdcc8SBarry Smith }
43378fbdcc8SBarry Smith 
43478fbdcc8SBarry Smith /*@
435bc952696SBarry Smith    TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object
436d2daff3dSHong Zhang 
437d2daff3dSHong Zhang    Collective on TS
438d2daff3dSHong Zhang 
439f899ff85SJose E. Roman    Input Parameter:
440bc952696SBarry Smith .  ts - the TS context obtained from TSCreate()
441bc952696SBarry Smith 
44278fbdcc8SBarry Smith    Options Database:
44378fbdcc8SBarry Smith +  -ts_save_trajectory - saves the trajectory to a file
44467b8a455SSatish Balay -  -ts_trajectory_type type - set trajectory type
44578fbdcc8SBarry Smith 
44668bece0bSHong Zhang Note: This routine should be called after all TS options have been set
447d2daff3dSHong Zhang 
448c3a89c15SBarry Smith     The TSTRAJECTORYVISUALIZATION files can be loaded into Python with $PETSC_DIR/lib/petsc/bin/PetscBinaryIOTrajectory.py and
44978fbdcc8SBarry Smith    MATLAB with $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m
45078fbdcc8SBarry Smith 
451d2daff3dSHong Zhang    Level: intermediate
452d2daff3dSHong Zhang 
453db781477SPatrick Sanan .seealso: `TSGetTrajectory()`, `TSAdjointSolve()`
454d2daff3dSHong Zhang 
455d2daff3dSHong Zhang @*/
4569371c9d4SSatish Balay PetscErrorCode TSSetSaveTrajectory(TS ts) {
457d2daff3dSHong Zhang   PetscFunctionBegin;
458d2daff3dSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
45963a3b9bcSJacob Faibussowitsch   if (!ts->trajectory) PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts), &ts->trajectory));
460d2daff3dSHong Zhang   PetscFunctionReturn(0);
461d2daff3dSHong Zhang }
462d2daff3dSHong Zhang 
463a7a1495cSBarry Smith /*@
4642d29f1f2SStefano Zampini    TSResetTrajectory - Destroys and recreates the internal TSTrajectory object
4652d29f1f2SStefano Zampini 
4662d29f1f2SStefano Zampini    Collective on TS
4672d29f1f2SStefano Zampini 
4682d29f1f2SStefano Zampini    Input Parameters:
4692d29f1f2SStefano Zampini .  ts - the TS context obtained from TSCreate()
4702d29f1f2SStefano Zampini 
4712d29f1f2SStefano Zampini    Level: intermediate
4722d29f1f2SStefano Zampini 
473db781477SPatrick Sanan .seealso: `TSGetTrajectory()`, `TSAdjointSolve()`, `TSRemoveTrajectory()`
4742d29f1f2SStefano Zampini 
4752d29f1f2SStefano Zampini @*/
4769371c9d4SSatish Balay PetscErrorCode TSResetTrajectory(TS ts) {
4772d29f1f2SStefano Zampini   PetscFunctionBegin;
4782d29f1f2SStefano Zampini   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4792d29f1f2SStefano Zampini   if (ts->trajectory) {
4809566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryDestroy(&ts->trajectory));
4819566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts), &ts->trajectory));
4822d29f1f2SStefano Zampini   }
4832d29f1f2SStefano Zampini   PetscFunctionReturn(0);
4842d29f1f2SStefano Zampini }
4852d29f1f2SStefano Zampini 
4862d29f1f2SStefano Zampini /*@
48767a3cfb0SHong Zhang    TSRemoveTrajectory - Destroys and removes the internal TSTrajectory object from TS
48867a3cfb0SHong Zhang 
48967a3cfb0SHong Zhang    Collective on TS
49067a3cfb0SHong Zhang 
49167a3cfb0SHong Zhang    Input Parameters:
49267a3cfb0SHong Zhang .  ts - the TS context obtained from TSCreate()
49367a3cfb0SHong Zhang 
49467a3cfb0SHong Zhang    Level: intermediate
49567a3cfb0SHong Zhang 
496db781477SPatrick Sanan .seealso: `TSResetTrajectory()`, `TSAdjointSolve()`
49767a3cfb0SHong Zhang 
49867a3cfb0SHong Zhang @*/
4999371c9d4SSatish Balay PetscErrorCode TSRemoveTrajectory(TS ts) {
50067a3cfb0SHong Zhang   PetscFunctionBegin;
50167a3cfb0SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5021e66621cSBarry Smith   if (ts->trajectory) PetscCall(TSTrajectoryDestroy(&ts->trajectory));
50367a3cfb0SHong Zhang   PetscFunctionReturn(0);
50467a3cfb0SHong Zhang }
50567a3cfb0SHong Zhang 
50667a3cfb0SHong Zhang /*@
507a7a1495cSBarry Smith    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
508a7a1495cSBarry Smith       set with TSSetRHSJacobian().
509a7a1495cSBarry Smith 
510d083f849SBarry Smith    Collective on TS
511a7a1495cSBarry Smith 
512a7a1495cSBarry Smith    Input Parameters:
513316643e7SJed Brown +  ts - the TS context
514a7a1495cSBarry Smith .  t - current timestep
5150910c330SBarry Smith -  U - input vector
516a7a1495cSBarry Smith 
517a7a1495cSBarry Smith    Output Parameters:
518a7a1495cSBarry Smith +  A - Jacobian matrix
5196b867d5aSJose E. Roman -  B - optional preconditioning matrix
520a7a1495cSBarry Smith 
521a7a1495cSBarry Smith    Notes:
522a7a1495cSBarry Smith    Most users should not need to explicitly call this routine, as it
523a7a1495cSBarry Smith    is used internally within the nonlinear solvers.
524a7a1495cSBarry Smith 
525a7a1495cSBarry Smith    Level: developer
526a7a1495cSBarry Smith 
527db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `KSPSetOperators()`
528a7a1495cSBarry Smith @*/
5299371c9d4SSatish Balay PetscErrorCode TSComputeRHSJacobian(TS ts, PetscReal t, Vec U, Mat A, Mat B) {
530270bf2e7SJed Brown   PetscObjectState Ustate;
5316c1e1eecSBarry Smith   PetscObjectId    Uid;
53224989b8cSPeter Brune   DM               dm;
533942e3340SBarry Smith   DMTS             tsdm;
53424989b8cSPeter Brune   TSRHSJacobian    rhsjacobianfunc;
53524989b8cSPeter Brune   void            *ctx;
536b2df71adSDebojyoti Ghosh   TSRHSFunction    rhsfunction;
537a7a1495cSBarry Smith 
538a7a1495cSBarry Smith   PetscFunctionBegin;
5390700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5400910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
5410910c330SBarry Smith   PetscCheckSameComm(ts, 1, U, 3);
5429566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
5439566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &tsdm));
5449566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
5459566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobianfunc, &ctx));
5469566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U, &Ustate));
5479566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U, &Uid));
548971015bcSStefano Zampini 
5492663174eSHong Zhang   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) PetscFunctionReturn(0);
550d90be118SSean Farley 
55163a3b9bcSJacob 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);
55224989b8cSPeter Brune   if (rhsjacobianfunc) {
5539566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TS_JacobianEval, ts, U, A, B));
554792fecdfSBarry Smith     PetscCallBack("TS callback Jacobian", (*rhsjacobianfunc)(ts, t, U, A, B, ctx));
555a6ab3590SBarry Smith     ts->rhsjacs++;
5569566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TS_JacobianEval, ts, U, A, B));
557ef66eb69SBarry Smith   } else {
5589566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(A));
5599566063dSJacob Faibussowitsch     if (B && A != B) PetscCall(MatZeroEntries(B));
560ef66eb69SBarry Smith   }
5610e4ef248SJed Brown   ts->rhsjacobian.time  = t;
562971015bcSStefano Zampini   ts->rhsjacobian.shift = 0;
563971015bcSStefano Zampini   ts->rhsjacobian.scale = 1.;
5649566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U, &ts->rhsjacobian.Xid));
5659566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U, &ts->rhsjacobian.Xstate));
566a7a1495cSBarry Smith   PetscFunctionReturn(0);
567a7a1495cSBarry Smith }
568a7a1495cSBarry Smith 
569316643e7SJed Brown /*@
570d763cef2SBarry Smith    TSComputeRHSFunction - Evaluates the right-hand-side function.
571d763cef2SBarry Smith 
572d083f849SBarry Smith    Collective on TS
573316643e7SJed Brown 
574316643e7SJed Brown    Input Parameters:
575316643e7SJed Brown +  ts - the TS context
576316643e7SJed Brown .  t - current time
5770910c330SBarry Smith -  U - state vector
578316643e7SJed Brown 
579316643e7SJed Brown    Output Parameter:
580316643e7SJed Brown .  y - right hand side
581316643e7SJed Brown 
582316643e7SJed Brown    Note:
583316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
584316643e7SJed Brown    is used internally within the nonlinear solvers.
585316643e7SJed Brown 
586316643e7SJed Brown    Level: developer
587316643e7SJed Brown 
588db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSComputeIFunction()`
589316643e7SJed Brown @*/
5909371c9d4SSatish Balay PetscErrorCode TSComputeRHSFunction(TS ts, PetscReal t, Vec U, Vec y) {
59124989b8cSPeter Brune   TSRHSFunction rhsfunction;
59224989b8cSPeter Brune   TSIFunction   ifunction;
59324989b8cSPeter Brune   void         *ctx;
59424989b8cSPeter Brune   DM            dm;
59524989b8cSPeter Brune 
596d763cef2SBarry Smith   PetscFunctionBegin;
5970700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5980910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
5990700a824SBarry Smith   PetscValidHeaderSpecific(y, VEC_CLASSID, 4);
6009566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
6019566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, &ctx));
6029566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, &ifunction, NULL));
603d763cef2SBarry Smith 
6043c633725SBarry Smith   PetscCheck(rhsfunction || ifunction, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSFunction() and / or TSSetIFunction()");
605d763cef2SBarry Smith 
60624989b8cSPeter Brune   if (rhsfunction) {
6079566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TS_FunctionEval, ts, U, y, 0));
6089566063dSJacob Faibussowitsch     PetscCall(VecLockReadPush(U));
609792fecdfSBarry Smith     PetscCallBack("TS callback right-hand-side", (*rhsfunction)(ts, t, U, y, ctx));
6109566063dSJacob Faibussowitsch     PetscCall(VecLockReadPop(U));
611a6ab3590SBarry Smith     ts->rhsfuncs++;
6129566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TS_FunctionEval, ts, U, y, 0));
6131e66621cSBarry Smith   } else PetscCall(VecZeroEntries(y));
614d763cef2SBarry Smith   PetscFunctionReturn(0);
615d763cef2SBarry Smith }
616d763cef2SBarry Smith 
617ef20d060SBarry Smith /*@
618ef20d060SBarry Smith    TSComputeSolutionFunction - Evaluates the solution function.
619ef20d060SBarry Smith 
620d083f849SBarry Smith    Collective on TS
621ef20d060SBarry Smith 
622ef20d060SBarry Smith    Input Parameters:
623ef20d060SBarry Smith +  ts - the TS context
624ef20d060SBarry Smith -  t - current time
625ef20d060SBarry Smith 
626ef20d060SBarry Smith    Output Parameter:
6270910c330SBarry Smith .  U - the solution
628ef20d060SBarry Smith 
629ef20d060SBarry Smith    Note:
630ef20d060SBarry Smith    Most users should not need to explicitly call this routine, as it
631ef20d060SBarry Smith    is used internally within the nonlinear solvers.
632ef20d060SBarry Smith 
633ef20d060SBarry Smith    Level: developer
634ef20d060SBarry Smith 
635db781477SPatrick Sanan .seealso: `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
636ef20d060SBarry Smith @*/
6379371c9d4SSatish Balay PetscErrorCode TSComputeSolutionFunction(TS ts, PetscReal t, Vec U) {
638ef20d060SBarry Smith   TSSolutionFunction solutionfunction;
639ef20d060SBarry Smith   void              *ctx;
640ef20d060SBarry Smith   DM                 dm;
641ef20d060SBarry Smith 
642ef20d060SBarry Smith   PetscFunctionBegin;
643ef20d060SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
6440910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
6459566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
6469566063dSJacob Faibussowitsch   PetscCall(DMTSGetSolutionFunction(dm, &solutionfunction, &ctx));
647ef20d060SBarry Smith 
648792fecdfSBarry Smith   if (solutionfunction) PetscCallBack("TS callback solution", (*solutionfunction)(ts, t, U, ctx));
649ef20d060SBarry Smith   PetscFunctionReturn(0);
650ef20d060SBarry Smith }
6519b7cd975SBarry Smith /*@
6529b7cd975SBarry Smith    TSComputeForcingFunction - Evaluates the forcing function.
6539b7cd975SBarry Smith 
654d083f849SBarry Smith    Collective on TS
6559b7cd975SBarry Smith 
6569b7cd975SBarry Smith    Input Parameters:
6579b7cd975SBarry Smith +  ts - the TS context
6589b7cd975SBarry Smith -  t - current time
6599b7cd975SBarry Smith 
6609b7cd975SBarry Smith    Output Parameter:
6619b7cd975SBarry Smith .  U - the function value
6629b7cd975SBarry Smith 
6639b7cd975SBarry Smith    Note:
6649b7cd975SBarry Smith    Most users should not need to explicitly call this routine, as it
6659b7cd975SBarry Smith    is used internally within the nonlinear solvers.
6669b7cd975SBarry Smith 
6679b7cd975SBarry Smith    Level: developer
6689b7cd975SBarry Smith 
669db781477SPatrick Sanan .seealso: `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
6709b7cd975SBarry Smith @*/
6719371c9d4SSatish Balay PetscErrorCode TSComputeForcingFunction(TS ts, PetscReal t, Vec U) {
6729b7cd975SBarry Smith   void             *ctx;
6739b7cd975SBarry Smith   DM                dm;
6745f80ce2aSJacob Faibussowitsch   TSForcingFunction forcing;
6759b7cd975SBarry Smith 
6769b7cd975SBarry Smith   PetscFunctionBegin;
6779b7cd975SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
6789b7cd975SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
6799566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
6809566063dSJacob Faibussowitsch   PetscCall(DMTSGetForcingFunction(dm, &forcing, &ctx));
6819b7cd975SBarry Smith 
682792fecdfSBarry Smith   if (forcing) PetscCallBack("TS callback forcing function", (*forcing)(ts, t, U, ctx));
6839b7cd975SBarry Smith   PetscFunctionReturn(0);
6849b7cd975SBarry Smith }
685ef20d060SBarry Smith 
6869371c9d4SSatish Balay static PetscErrorCode TSGetRHSVec_Private(TS ts, Vec *Frhs) {
6872dd45cf8SJed Brown   Vec F;
688214bc6a2SJed Brown 
689214bc6a2SJed Brown   PetscFunctionBegin;
6900298fd71SBarry Smith   *Frhs = NULL;
6919566063dSJacob Faibussowitsch   PetscCall(TSGetIFunction(ts, &F, NULL, NULL));
6921e66621cSBarry Smith   if (!ts->Frhs) PetscCall(VecDuplicate(F, &ts->Frhs));
693214bc6a2SJed Brown   *Frhs = ts->Frhs;
694214bc6a2SJed Brown   PetscFunctionReturn(0);
695214bc6a2SJed Brown }
696214bc6a2SJed Brown 
6979371c9d4SSatish Balay PetscErrorCode TSGetRHSMats_Private(TS ts, Mat *Arhs, Mat *Brhs) {
698214bc6a2SJed Brown   Mat         A, B;
69941a1d4d2SBarry Smith   TSIJacobian ijacobian;
700214bc6a2SJed Brown 
701214bc6a2SJed Brown   PetscFunctionBegin;
702c0cd0301SJed Brown   if (Arhs) *Arhs = NULL;
703c0cd0301SJed Brown   if (Brhs) *Brhs = NULL;
7049566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts, &A, &B, &ijacobian, NULL));
705214bc6a2SJed Brown   if (Arhs) {
706214bc6a2SJed Brown     if (!ts->Arhs) {
70741a1d4d2SBarry Smith       if (ijacobian) {
7089566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &ts->Arhs));
7099566063dSJacob Faibussowitsch         PetscCall(TSSetMatStructure(ts, SAME_NONZERO_PATTERN));
71041a1d4d2SBarry Smith       } else {
71141a1d4d2SBarry Smith         ts->Arhs = A;
7129566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
71341a1d4d2SBarry Smith       }
7143565c898SBarry Smith     } else {
7153565c898SBarry Smith       PetscBool flg;
7169566063dSJacob Faibussowitsch       PetscCall(SNESGetUseMatrixFree(ts->snes, NULL, &flg));
7173565c898SBarry Smith       /* Handle case where user provided only RHSJacobian and used -snes_mf_operator */
7183565c898SBarry Smith       if (flg && !ijacobian && ts->Arhs == ts->Brhs) {
7199566063dSJacob Faibussowitsch         PetscCall(PetscObjectDereference((PetscObject)ts->Arhs));
7203565c898SBarry Smith         ts->Arhs = A;
7219566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
7223565c898SBarry Smith       }
723214bc6a2SJed Brown     }
724214bc6a2SJed Brown     *Arhs = ts->Arhs;
725214bc6a2SJed Brown   }
726214bc6a2SJed Brown   if (Brhs) {
727214bc6a2SJed Brown     if (!ts->Brhs) {
728bdb70873SJed Brown       if (A != B) {
72941a1d4d2SBarry Smith         if (ijacobian) {
7309566063dSJacob Faibussowitsch           PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &ts->Brhs));
731bdb70873SJed Brown         } else {
73241a1d4d2SBarry Smith           ts->Brhs = B;
7339566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)B));
73441a1d4d2SBarry Smith         }
73541a1d4d2SBarry Smith       } else {
7369566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)ts->Arhs));
73751699248SLisandro Dalcin         ts->Brhs = ts->Arhs;
738bdb70873SJed Brown       }
739214bc6a2SJed Brown     }
740214bc6a2SJed Brown     *Brhs = ts->Brhs;
741214bc6a2SJed Brown   }
742214bc6a2SJed Brown   PetscFunctionReturn(0);
743214bc6a2SJed Brown }
744214bc6a2SJed Brown 
745316643e7SJed Brown /*@
7460910c330SBarry Smith    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0
747316643e7SJed Brown 
748d083f849SBarry Smith    Collective on TS
749316643e7SJed Brown 
750316643e7SJed Brown    Input Parameters:
751316643e7SJed Brown +  ts - the TS context
752316643e7SJed Brown .  t - current time
7530910c330SBarry Smith .  U - state vector
7540910c330SBarry Smith .  Udot - time derivative of state vector
755214bc6a2SJed Brown -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate
756316643e7SJed Brown 
757316643e7SJed Brown    Output Parameter:
758316643e7SJed Brown .  Y - right hand side
759316643e7SJed Brown 
760316643e7SJed Brown    Note:
761316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
762316643e7SJed Brown    is used internally within the nonlinear solvers.
763316643e7SJed Brown 
764316643e7SJed Brown    If the user did did not write their equations in implicit form, this
765316643e7SJed Brown    function recasts them in implicit form.
766316643e7SJed Brown 
767316643e7SJed Brown    Level: developer
768316643e7SJed Brown 
769db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSComputeRHSFunction()`
770316643e7SJed Brown @*/
7719371c9d4SSatish Balay PetscErrorCode TSComputeIFunction(TS ts, PetscReal t, Vec U, Vec Udot, Vec Y, PetscBool imex) {
77224989b8cSPeter Brune   TSIFunction   ifunction;
77324989b8cSPeter Brune   TSRHSFunction rhsfunction;
77424989b8cSPeter Brune   void         *ctx;
77524989b8cSPeter Brune   DM            dm;
776316643e7SJed Brown 
777316643e7SJed Brown   PetscFunctionBegin;
7780700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
7790910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
7800910c330SBarry Smith   PetscValidHeaderSpecific(Udot, VEC_CLASSID, 4);
7810700a824SBarry Smith   PetscValidHeaderSpecific(Y, VEC_CLASSID, 5);
782316643e7SJed Brown 
7839566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
7849566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, &ifunction, &ctx));
7859566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
78624989b8cSPeter Brune 
7873c633725SBarry Smith   PetscCheck(rhsfunction || ifunction, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSFunction() and / or TSSetIFunction()");
788d90be118SSean Farley 
7899566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_FunctionEval, ts, U, Udot, Y));
79024989b8cSPeter Brune   if (ifunction) {
791792fecdfSBarry Smith     PetscCallBack("TS callback implicit function", (*ifunction)(ts, t, U, Udot, Y, ctx));
792a6ab3590SBarry Smith     ts->ifuncs++;
793214bc6a2SJed Brown   }
794214bc6a2SJed Brown   if (imex) {
7951e66621cSBarry Smith     if (!ifunction) PetscCall(VecCopy(Udot, Y));
79624989b8cSPeter Brune   } else if (rhsfunction) {
79724989b8cSPeter Brune     if (ifunction) {
798214bc6a2SJed Brown       Vec Frhs;
7999566063dSJacob Faibussowitsch       PetscCall(TSGetRHSVec_Private(ts, &Frhs));
8009566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts, t, U, Frhs));
8019566063dSJacob Faibussowitsch       PetscCall(VecAXPY(Y, -1, Frhs));
8022dd45cf8SJed Brown     } else {
8039566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts, t, U, Y));
8049566063dSJacob Faibussowitsch       PetscCall(VecAYPX(Y, -1, Udot));
805316643e7SJed Brown     }
8064a6899ffSJed Brown   }
8079566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_FunctionEval, ts, U, Udot, Y));
808316643e7SJed Brown   PetscFunctionReturn(0);
809316643e7SJed Brown }
810316643e7SJed Brown 
811cfa8a9a2SHong Zhang /*
812cfa8a9a2SHong Zhang    TSRecoverRHSJacobian - Recover the Jacobian matrix so that one can call TSComputeRHSJacobian() on it.
813cfa8a9a2SHong Zhang 
814cfa8a9a2SHong Zhang    Note:
815cfa8a9a2SHong Zhang    This routine is needed when one switches from TSComputeIJacobian() to TSComputeRHSJacobian() because the Jacobian matrix may be shifted or scaled in TSComputeIJacobian().
816cfa8a9a2SHong Zhang 
817cfa8a9a2SHong Zhang */
8189371c9d4SSatish Balay static PetscErrorCode TSRecoverRHSJacobian(TS ts, Mat A, Mat B) {
819cfa8a9a2SHong Zhang   PetscFunctionBegin;
820cfa8a9a2SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
8213c633725SBarry Smith   PetscCheck(A == ts->Arhs, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Invalid Amat");
8223c633725SBarry Smith   PetscCheck(B == ts->Brhs, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Invalid Bmat");
823cfa8a9a2SHong Zhang 
8241baa6e33SBarry Smith   if (ts->rhsjacobian.shift) PetscCall(MatShift(A, -ts->rhsjacobian.shift));
825*48a46eb9SPierre Jolivet   if (ts->rhsjacobian.scale == -1.) PetscCall(MatScale(A, -1));
826cfa8a9a2SHong Zhang   if (B && B == ts->Brhs && A != B) {
8271baa6e33SBarry Smith     if (ts->rhsjacobian.shift) PetscCall(MatShift(B, -ts->rhsjacobian.shift));
8281e66621cSBarry Smith     if (ts->rhsjacobian.scale == -1.) PetscCall(MatScale(B, -1));
829cfa8a9a2SHong Zhang   }
830cfa8a9a2SHong Zhang   ts->rhsjacobian.shift = 0;
831cfa8a9a2SHong Zhang   ts->rhsjacobian.scale = 1.;
832cfa8a9a2SHong Zhang   PetscFunctionReturn(0);
833cfa8a9a2SHong Zhang }
834cfa8a9a2SHong Zhang 
835316643e7SJed Brown /*@
836316643e7SJed Brown    TSComputeIJacobian - Evaluates the Jacobian of the DAE
837316643e7SJed Brown 
838d083f849SBarry Smith    Collective on TS
839316643e7SJed Brown 
840316643e7SJed Brown    Input
841316643e7SJed Brown       Input Parameters:
842316643e7SJed Brown +  ts - the TS context
843316643e7SJed Brown .  t - current timestep
8440910c330SBarry Smith .  U - state vector
8450910c330SBarry Smith .  Udot - time derivative of state vector
846214bc6a2SJed Brown .  shift - shift to apply, see note below
847214bc6a2SJed Brown -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate
848316643e7SJed Brown 
849316643e7SJed Brown    Output Parameters:
850316643e7SJed Brown +  A - Jacobian matrix
8513565c898SBarry Smith -  B - matrix from which the preconditioner is constructed; often the same as A
852316643e7SJed Brown 
853316643e7SJed Brown    Notes:
8540910c330SBarry Smith    If F(t,U,Udot)=0 is the DAE, the required Jacobian is
855316643e7SJed Brown 
8560910c330SBarry Smith    dF/dU + shift*dF/dUdot
857316643e7SJed Brown 
858316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
859316643e7SJed Brown    is used internally within the nonlinear solvers.
860316643e7SJed Brown 
861316643e7SJed Brown    Level: developer
862316643e7SJed Brown 
863db781477SPatrick Sanan .seealso: `TSSetIJacobian()`
86463495f91SJed Brown @*/
8659371c9d4SSatish Balay PetscErrorCode TSComputeIJacobian(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat A, Mat B, PetscBool imex) {
86624989b8cSPeter Brune   TSIJacobian   ijacobian;
86724989b8cSPeter Brune   TSRHSJacobian rhsjacobian;
86824989b8cSPeter Brune   DM            dm;
86924989b8cSPeter Brune   void         *ctx;
870316643e7SJed Brown 
871316643e7SJed Brown   PetscFunctionBegin;
8720700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
8730910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
8740910c330SBarry Smith   PetscValidHeaderSpecific(Udot, VEC_CLASSID, 4);
875316643e7SJed Brown   PetscValidPointer(A, 6);
87694ab13aaSBarry Smith   PetscValidHeaderSpecific(A, MAT_CLASSID, 6);
877316643e7SJed Brown   PetscValidPointer(B, 7);
87894ab13aaSBarry Smith   PetscValidHeaderSpecific(B, MAT_CLASSID, 7);
87924989b8cSPeter Brune 
8809566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
8819566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijacobian, &ctx));
8829566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL));
88324989b8cSPeter Brune 
8843c633725SBarry Smith   PetscCheck(rhsjacobian || ijacobian, PetscObjectComm((PetscObject)ts), PETSC_ERR_USER, "Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
885316643e7SJed Brown 
8869566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_JacobianEval, ts, U, A, B));
88724989b8cSPeter Brune   if (ijacobian) {
888792fecdfSBarry Smith     PetscCallBack("TS callback implicit Jacobian", (*ijacobian)(ts, t, U, Udot, shift, A, B, ctx));
889a6ab3590SBarry Smith     ts->ijacs++;
8904a6899ffSJed Brown   }
891214bc6a2SJed Brown   if (imex) {
892b5abc632SBarry Smith     if (!ijacobian) { /* system was written as Udot = G(t,U) */
8934c26be97Sstefano_zampini       PetscBool assembled;
894971015bcSStefano Zampini       if (rhsjacobian) {
895971015bcSStefano Zampini         Mat Arhs = NULL;
8969566063dSJacob Faibussowitsch         PetscCall(TSGetRHSMats_Private(ts, &Arhs, NULL));
897971015bcSStefano Zampini         if (A == Arhs) {
8983c633725SBarry 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 */
899971015bcSStefano Zampini           ts->rhsjacobian.time = PETSC_MIN_REAL;
900971015bcSStefano Zampini         }
901971015bcSStefano Zampini       }
9029566063dSJacob Faibussowitsch       PetscCall(MatZeroEntries(A));
9039566063dSJacob Faibussowitsch       PetscCall(MatAssembled(A, &assembled));
9044c26be97Sstefano_zampini       if (!assembled) {
9059566063dSJacob Faibussowitsch         PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
9069566063dSJacob Faibussowitsch         PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
9074c26be97Sstefano_zampini       }
9089566063dSJacob Faibussowitsch       PetscCall(MatShift(A, shift));
90994ab13aaSBarry Smith       if (A != B) {
9109566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(B));
9119566063dSJacob Faibussowitsch         PetscCall(MatAssembled(B, &assembled));
9124c26be97Sstefano_zampini         if (!assembled) {
9139566063dSJacob Faibussowitsch           PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
9149566063dSJacob Faibussowitsch           PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
9154c26be97Sstefano_zampini         }
9169566063dSJacob Faibussowitsch         PetscCall(MatShift(B, shift));
917214bc6a2SJed Brown       }
918214bc6a2SJed Brown     }
919214bc6a2SJed Brown   } else {
920e1244c69SJed Brown     Mat Arhs = NULL, Brhs = NULL;
9211e66621cSBarry Smith 
9221e66621cSBarry Smith     /* RHSJacobian needs to be converted to part of IJacobian if exists */
9231e66621cSBarry Smith     if (rhsjacobian) PetscCall(TSGetRHSMats_Private(ts, &Arhs, &Brhs));
924e8b1e424SHong Zhang     if (Arhs == A) { /* No IJacobian matrix, so we only have the RHS matrix */
925e8b1e424SHong Zhang       PetscObjectState Ustate;
926e8b1e424SHong Zhang       PetscObjectId    Uid;
927e8b1e424SHong Zhang       TSRHSFunction    rhsfunction;
928e8b1e424SHong Zhang 
9299566063dSJacob Faibussowitsch       PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
9309566063dSJacob Faibussowitsch       PetscCall(PetscObjectStateGet((PetscObject)U, &Ustate));
9319566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetId((PetscObject)U, &Uid));
9329371c9d4SSatish Balay       if ((rhsjacobian == TSComputeRHSJacobianConstant || (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && rhsfunction != TSComputeRHSFunctionLinear)) &&
9339371c9d4SSatish Balay           ts->rhsjacobian.scale == -1.) {                      /* No need to recompute RHSJacobian */
9349566063dSJacob Faibussowitsch         PetscCall(MatShift(A, shift - ts->rhsjacobian.shift)); /* revert the old shift and add the new shift with a single call to MatShift */
9351e66621cSBarry Smith         if (A != B) PetscCall(MatShift(B, shift - ts->rhsjacobian.shift));
936e8b1e424SHong Zhang       } else {
9373565c898SBarry Smith         PetscBool flg;
938e8b1e424SHong Zhang 
939e8b1e424SHong Zhang         if (ts->rhsjacobian.reuse) { /* Undo the damage */
940e8b1e424SHong Zhang           /* MatScale has a short path for this case.
941e8b1e424SHong Zhang              However, this code path is taken the first time TSComputeRHSJacobian is called
942e8b1e424SHong Zhang              and the matrices have not been assembled yet */
9439566063dSJacob Faibussowitsch           PetscCall(TSRecoverRHSJacobian(ts, A, B));
944e8b1e424SHong Zhang         }
9459566063dSJacob Faibussowitsch         PetscCall(TSComputeRHSJacobian(ts, t, U, A, B));
9469566063dSJacob Faibussowitsch         PetscCall(SNESGetUseMatrixFree(ts->snes, NULL, &flg));
9473565c898SBarry Smith         /* since -snes_mf_operator uses the full SNES function it does not need to be shifted or scaled here */
9483565c898SBarry Smith         if (!flg) {
9499566063dSJacob Faibussowitsch           PetscCall(MatScale(A, -1));
9509566063dSJacob Faibussowitsch           PetscCall(MatShift(A, shift));
9513565c898SBarry Smith         }
95294ab13aaSBarry Smith         if (A != B) {
9539566063dSJacob Faibussowitsch           PetscCall(MatScale(B, -1));
9549566063dSJacob Faibussowitsch           PetscCall(MatShift(B, shift));
955316643e7SJed Brown         }
956e8b1e424SHong Zhang       }
957e8b1e424SHong Zhang       ts->rhsjacobian.scale = -1;
958e8b1e424SHong Zhang       ts->rhsjacobian.shift = shift;
959d60b7d5cSBarry Smith     } else if (Arhs) {  /* Both IJacobian and RHSJacobian */
960e1244c69SJed Brown       if (!ijacobian) { /* No IJacobian provided, but we have a separate RHS matrix */
9619566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(A));
9629566063dSJacob Faibussowitsch         PetscCall(MatShift(A, shift));
96394ab13aaSBarry Smith         if (A != B) {
9649566063dSJacob Faibussowitsch           PetscCall(MatZeroEntries(B));
9659566063dSJacob Faibussowitsch           PetscCall(MatShift(B, shift));
966214bc6a2SJed Brown         }
967316643e7SJed Brown       }
9689566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSJacobian(ts, t, U, Arhs, Brhs));
9699566063dSJacob Faibussowitsch       PetscCall(MatAXPY(A, -1, Arhs, ts->axpy_pattern));
9701e66621cSBarry Smith       if (A != B) PetscCall(MatAXPY(B, -1, Brhs, ts->axpy_pattern));
971316643e7SJed Brown     }
972316643e7SJed Brown   }
9739566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_JacobianEval, ts, U, A, B));
974316643e7SJed Brown   PetscFunctionReturn(0);
975316643e7SJed Brown }
976316643e7SJed Brown 
977d763cef2SBarry Smith /*@C
978d763cef2SBarry Smith     TSSetRHSFunction - Sets the routine for evaluating the function,
979b5abc632SBarry Smith     where U_t = G(t,u).
980d763cef2SBarry Smith 
9813f9fe445SBarry Smith     Logically Collective on TS
982d763cef2SBarry Smith 
983d763cef2SBarry Smith     Input Parameters:
984d763cef2SBarry Smith +   ts - the TS context obtained from TSCreate()
9850298fd71SBarry Smith .   r - vector to put the computed right hand side (or NULL to have it created)
986d763cef2SBarry Smith .   f - routine for evaluating the right-hand-side function
987d763cef2SBarry Smith -   ctx - [optional] user-defined context for private data for the
9880298fd71SBarry Smith           function evaluation routine (may be NULL)
989d763cef2SBarry Smith 
990a96d6ef6SBarry Smith     Calling sequence of f:
991a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
992d763cef2SBarry Smith 
993a96d6ef6SBarry Smith +   ts - timestep context
994a96d6ef6SBarry Smith .   t - current timestep
995d763cef2SBarry Smith .   u - input vector
996d763cef2SBarry Smith .   F - function vector
997d763cef2SBarry Smith -   ctx - [optional] user-defined function context
998d763cef2SBarry Smith 
999d763cef2SBarry Smith     Level: beginner
1000d763cef2SBarry Smith 
100195452b02SPatrick Sanan     Notes:
100295452b02SPatrick Sanan     You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE.
10032bbac0d3SBarry Smith 
1004db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
1005d763cef2SBarry Smith @*/
10069371c9d4SSatish Balay PetscErrorCode TSSetRHSFunction(TS ts, Vec r, PetscErrorCode (*f)(TS, PetscReal, Vec, Vec, void *), void *ctx) {
1007089b2837SJed Brown   SNES snes;
10080298fd71SBarry Smith   Vec  ralloc = NULL;
100924989b8cSPeter Brune   DM   dm;
1010d763cef2SBarry Smith 
1011089b2837SJed Brown   PetscFunctionBegin;
10120700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1013ca94891dSJed Brown   if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
101424989b8cSPeter Brune 
10159566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
10169566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSFunction(dm, f, ctx));
10179566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
1018e856ceecSJed Brown   if (!r && !ts->dm && ts->vec_sol) {
10199566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol, &ralloc));
1020e856ceecSJed Brown     r = ralloc;
1021e856ceecSJed Brown   }
10229566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, r, SNESTSFormFunction, ts));
10239566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
1024d763cef2SBarry Smith   PetscFunctionReturn(0);
1025d763cef2SBarry Smith }
1026d763cef2SBarry Smith 
1027ef20d060SBarry Smith /*@C
1028abd5a294SJed Brown     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
1029ef20d060SBarry Smith 
1030ef20d060SBarry Smith     Logically Collective on TS
1031ef20d060SBarry Smith 
1032ef20d060SBarry Smith     Input Parameters:
1033ef20d060SBarry Smith +   ts - the TS context obtained from TSCreate()
1034ef20d060SBarry Smith .   f - routine for evaluating the solution
1035ef20d060SBarry Smith -   ctx - [optional] user-defined context for private data for the
10360298fd71SBarry Smith           function evaluation routine (may be NULL)
1037ef20d060SBarry Smith 
1038a96d6ef6SBarry Smith     Calling sequence of f:
1039a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
1040ef20d060SBarry Smith 
1041ef20d060SBarry Smith +   t - current timestep
1042ef20d060SBarry Smith .   u - output vector
1043ef20d060SBarry Smith -   ctx - [optional] user-defined function context
1044ef20d060SBarry Smith 
10450ed3bfb6SBarry Smith     Options Database:
10460ed3bfb6SBarry Smith +  -ts_monitor_lg_error - create a graphical monitor of error history, requires user to have provided TSSetSolutionFunction()
10470ed3bfb6SBarry Smith -  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
10480ed3bfb6SBarry Smith 
1049abd5a294SJed Brown     Notes:
1050abd5a294SJed Brown     This routine is used for testing accuracy of time integration schemes when you already know the solution.
1051abd5a294SJed Brown     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
1052abd5a294SJed Brown     create closed-form solutions with non-physical forcing terms.
1053abd5a294SJed Brown 
10544f09c107SBarry Smith     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
1055abd5a294SJed Brown 
1056ef20d060SBarry Smith     Level: beginner
1057ef20d060SBarry Smith 
1058db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSComputeSolutionFunction()`, `TSSetForcingFunction()`, `TSSetSolution()`, `TSGetSolution()`, `TSMonitorLGError()`, `TSMonitorDrawError()`
1059ef20d060SBarry Smith @*/
10609371c9d4SSatish Balay PetscErrorCode TSSetSolutionFunction(TS ts, PetscErrorCode (*f)(TS, PetscReal, Vec, void *), void *ctx) {
1061ef20d060SBarry Smith   DM dm;
1062ef20d060SBarry Smith 
1063ef20d060SBarry Smith   PetscFunctionBegin;
1064ef20d060SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
10659566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
10669566063dSJacob Faibussowitsch   PetscCall(DMTSSetSolutionFunction(dm, f, ctx));
1067ef20d060SBarry Smith   PetscFunctionReturn(0);
1068ef20d060SBarry Smith }
1069ef20d060SBarry Smith 
10709b7cd975SBarry Smith /*@C
10719b7cd975SBarry Smith     TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE
10729b7cd975SBarry Smith 
10739b7cd975SBarry Smith     Logically Collective on TS
10749b7cd975SBarry Smith 
10759b7cd975SBarry Smith     Input Parameters:
10769b7cd975SBarry Smith +   ts - the TS context obtained from TSCreate()
1077e162b725SBarry Smith .   func - routine for evaluating the forcing function
10789b7cd975SBarry Smith -   ctx - [optional] user-defined context for private data for the
10790298fd71SBarry Smith           function evaluation routine (may be NULL)
10809b7cd975SBarry Smith 
10819b7cd975SBarry Smith     Calling sequence of func:
10826bc98fa9SBarry Smith $     PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
10839b7cd975SBarry Smith 
10849b7cd975SBarry Smith +   t - current timestep
1085e162b725SBarry Smith .   f - output vector
10869b7cd975SBarry Smith -   ctx - [optional] user-defined function context
10879b7cd975SBarry Smith 
10889b7cd975SBarry Smith     Notes:
10899b7cd975SBarry Smith     This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to
1090e162b725SBarry 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
1091e162b725SBarry Smith     definition of the problem you are solving and hence possibly introducing bugs.
1092e162b725SBarry Smith 
1093e162b725SBarry Smith     This replaces the ODE F(u,u_t,t) = 0 the TS is solving with F(u,u_t,t) - func(t) = 0
1094e162b725SBarry Smith 
1095e162b725SBarry 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
1096e162b725SBarry Smith     parameters can be passed in the ctx variable.
10979b7cd975SBarry Smith 
10989b7cd975SBarry Smith     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
10999b7cd975SBarry Smith 
11009b7cd975SBarry Smith     Level: beginner
11019b7cd975SBarry Smith 
1102db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSComputeSolutionFunction()`, `TSSetSolutionFunction()`
11039b7cd975SBarry Smith @*/
11049371c9d4SSatish Balay PetscErrorCode TSSetForcingFunction(TS ts, TSForcingFunction func, void *ctx) {
11059b7cd975SBarry Smith   DM dm;
11069b7cd975SBarry Smith 
11079b7cd975SBarry Smith   PetscFunctionBegin;
11089b7cd975SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
11099566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
11109566063dSJacob Faibussowitsch   PetscCall(DMTSSetForcingFunction(dm, func, ctx));
11119b7cd975SBarry Smith   PetscFunctionReturn(0);
11129b7cd975SBarry Smith }
11139b7cd975SBarry Smith 
1114d763cef2SBarry Smith /*@C
1115f7ab8db6SBarry Smith    TSSetRHSJacobian - Sets the function to compute the Jacobian of G,
1116b5abc632SBarry Smith    where U_t = G(U,t), as well as the location to store the matrix.
1117d763cef2SBarry Smith 
11183f9fe445SBarry Smith    Logically Collective on TS
1119d763cef2SBarry Smith 
1120d763cef2SBarry Smith    Input Parameters:
1121d763cef2SBarry Smith +  ts  - the TS context obtained from TSCreate()
1122e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1123e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1124d763cef2SBarry Smith .  f   - the Jacobian evaluation routine
1125d763cef2SBarry Smith -  ctx - [optional] user-defined context for private data for the
11260298fd71SBarry Smith          Jacobian evaluation routine (may be NULL)
1127d763cef2SBarry Smith 
1128f7ab8db6SBarry Smith    Calling sequence of f:
1129a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
1130d763cef2SBarry Smith 
1131d763cef2SBarry Smith +  t - current timestep
1132d763cef2SBarry Smith .  u - input vector
1133e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1134e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1135d763cef2SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
1136d763cef2SBarry Smith 
11376cd88445SBarry Smith    Notes:
11386cd88445SBarry Smith    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
11396cd88445SBarry Smith 
11406cd88445SBarry Smith    The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1141ca5f011dSBarry Smith    You should not assume the values are the same in the next call to f() as you set them in the previous call.
1142d763cef2SBarry Smith 
1143d763cef2SBarry Smith    Level: beginner
1144d763cef2SBarry Smith 
1145db781477SPatrick Sanan .seealso: `SNESComputeJacobianDefaultColor()`, `TSSetRHSFunction()`, `TSRHSJacobianSetReuse()`, `TSSetIJacobian()`
1146d763cef2SBarry Smith 
1147d763cef2SBarry Smith @*/
11489371c9d4SSatish Balay PetscErrorCode TSSetRHSJacobian(TS ts, Mat Amat, Mat Pmat, TSRHSJacobian f, void *ctx) {
1149089b2837SJed Brown   SNES        snes;
115024989b8cSPeter Brune   DM          dm;
115124989b8cSPeter Brune   TSIJacobian ijacobian;
1152277b19d0SLisandro Dalcin 
1153d763cef2SBarry Smith   PetscFunctionBegin;
11540700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1155e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
1156e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
1157e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts, 1, Amat, 2);
1158e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts, 1, Pmat, 3);
1159d763cef2SBarry Smith 
11609566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
11619566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSJacobian(dm, f, ctx));
11629566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijacobian, NULL));
11639566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
11641e66621cSBarry Smith   if (!ijacobian) PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESTSFormJacobian, ts));
1165e5d3d808SBarry Smith   if (Amat) {
11669566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Amat));
11679566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Arhs));
1168e5d3d808SBarry Smith     ts->Arhs = Amat;
11690e4ef248SJed Brown   }
1170e5d3d808SBarry Smith   if (Pmat) {
11719566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Pmat));
11729566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Brhs));
1173e5d3d808SBarry Smith     ts->Brhs = Pmat;
11740e4ef248SJed Brown   }
1175d763cef2SBarry Smith   PetscFunctionReturn(0);
1176d763cef2SBarry Smith }
1177d763cef2SBarry Smith 
1178316643e7SJed Brown /*@C
1179b5abc632SBarry Smith    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
1180316643e7SJed Brown 
11813f9fe445SBarry Smith    Logically Collective on TS
1182316643e7SJed Brown 
1183316643e7SJed Brown    Input Parameters:
1184316643e7SJed Brown +  ts  - the TS context obtained from TSCreate()
11850298fd71SBarry Smith .  r   - vector to hold the residual (or NULL to have it created internally)
1186316643e7SJed Brown .  f   - the function evaluation routine
11870298fd71SBarry Smith -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1188316643e7SJed Brown 
1189316643e7SJed Brown    Calling sequence of f:
11906bc98fa9SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
1191316643e7SJed Brown 
1192316643e7SJed Brown +  t   - time at step/stage being solved
1193316643e7SJed Brown .  u   - state vector
1194316643e7SJed Brown .  u_t - time derivative of state vector
1195316643e7SJed Brown .  F   - function vector
1196316643e7SJed Brown -  ctx - [optional] user-defined context for matrix evaluation routine
1197316643e7SJed Brown 
1198316643e7SJed Brown    Important:
11992bbac0d3SBarry Smith    The user MUST call either this routine or TSSetRHSFunction() to define the ODE.  When solving DAEs you must use this function.
1200316643e7SJed Brown 
1201316643e7SJed Brown    Level: beginner
1202316643e7SJed Brown 
1203db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetRHSFunction()`, `TSSetIJacobian()`
1204316643e7SJed Brown @*/
12059371c9d4SSatish Balay PetscErrorCode TSSetIFunction(TS ts, Vec r, TSIFunction f, void *ctx) {
1206089b2837SJed Brown   SNES snes;
120751699248SLisandro Dalcin   Vec  ralloc = NULL;
120824989b8cSPeter Brune   DM   dm;
1209316643e7SJed Brown 
1210316643e7SJed Brown   PetscFunctionBegin;
12110700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
121251699248SLisandro Dalcin   if (r) PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
121324989b8cSPeter Brune 
12149566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12159566063dSJacob Faibussowitsch   PetscCall(DMTSSetIFunction(dm, f, ctx));
121624989b8cSPeter Brune 
12179566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
121851699248SLisandro Dalcin   if (!r && !ts->dm && ts->vec_sol) {
12199566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol, &ralloc));
122051699248SLisandro Dalcin     r = ralloc;
1221e856ceecSJed Brown   }
12229566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, r, SNESTSFormFunction, ts));
12239566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
1224089b2837SJed Brown   PetscFunctionReturn(0);
1225089b2837SJed Brown }
1226089b2837SJed Brown 
1227089b2837SJed Brown /*@C
1228a5b23f4aSJose E. Roman    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/context to compute it.
1229089b2837SJed Brown 
1230089b2837SJed Brown    Not Collective
1231089b2837SJed Brown 
1232089b2837SJed Brown    Input Parameter:
1233089b2837SJed Brown .  ts - the TS context
1234089b2837SJed Brown 
1235d8d19677SJose E. Roman    Output Parameters:
12360298fd71SBarry Smith +  r - vector to hold residual (or NULL)
12370298fd71SBarry Smith .  func - the function to compute residual (or NULL)
12380298fd71SBarry Smith -  ctx - the function context (or NULL)
1239089b2837SJed Brown 
1240089b2837SJed Brown    Level: advanced
1241089b2837SJed Brown 
1242db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `SNESGetFunction()`
1243089b2837SJed Brown @*/
12449371c9d4SSatish Balay PetscErrorCode TSGetIFunction(TS ts, Vec *r, TSIFunction *func, void **ctx) {
1245089b2837SJed Brown   SNES snes;
124624989b8cSPeter Brune   DM   dm;
1247089b2837SJed Brown 
1248089b2837SJed Brown   PetscFunctionBegin;
1249089b2837SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
12509566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
12519566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
12529566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12539566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm, func, ctx));
1254089b2837SJed Brown   PetscFunctionReturn(0);
1255089b2837SJed Brown }
1256089b2837SJed Brown 
1257089b2837SJed Brown /*@C
1258089b2837SJed Brown    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.
1259089b2837SJed Brown 
1260089b2837SJed Brown    Not Collective
1261089b2837SJed Brown 
1262089b2837SJed Brown    Input Parameter:
1263089b2837SJed Brown .  ts - the TS context
1264089b2837SJed Brown 
1265d8d19677SJose E. Roman    Output Parameters:
12660298fd71SBarry Smith +  r - vector to hold computed right hand side (or NULL)
12670298fd71SBarry Smith .  func - the function to compute right hand side (or NULL)
12680298fd71SBarry Smith -  ctx - the function context (or NULL)
1269089b2837SJed Brown 
1270089b2837SJed Brown    Level: advanced
1271089b2837SJed Brown 
1272db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `SNESGetFunction()`
1273089b2837SJed Brown @*/
12749371c9d4SSatish Balay PetscErrorCode TSGetRHSFunction(TS ts, Vec *r, TSRHSFunction *func, void **ctx) {
1275089b2837SJed Brown   SNES snes;
127624989b8cSPeter Brune   DM   dm;
1277089b2837SJed Brown 
1278089b2837SJed Brown   PetscFunctionBegin;
1279089b2837SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
12809566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
12819566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
12829566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
12839566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, func, ctx));
1284316643e7SJed Brown   PetscFunctionReturn(0);
1285316643e7SJed Brown }
1286316643e7SJed Brown 
1287316643e7SJed Brown /*@C
1288a4f0a591SBarry Smith    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
1289ae8867d6SBarry Smith         provided with TSSetIFunction().
1290316643e7SJed Brown 
12913f9fe445SBarry Smith    Logically Collective on TS
1292316643e7SJed Brown 
1293316643e7SJed Brown    Input Parameters:
1294316643e7SJed Brown +  ts  - the TS context obtained from TSCreate()
1295e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1296e5d3d808SBarry Smith .  Pmat - matrix used to compute preconditioner (usually the same as Amat)
1297316643e7SJed Brown .  f   - the Jacobian evaluation routine
12980298fd71SBarry Smith -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1299316643e7SJed Brown 
1300316643e7SJed Brown    Calling sequence of f:
13016bc98fa9SBarry Smith $    PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
1302316643e7SJed Brown 
1303316643e7SJed Brown +  t    - time at step/stage being solved
13041b4a444bSJed Brown .  U    - state vector
13051b4a444bSJed Brown .  U_t  - time derivative of state vector
1306316643e7SJed Brown .  a    - shift
1307e5d3d808SBarry Smith .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1308e5d3d808SBarry Smith .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1309316643e7SJed Brown -  ctx  - [optional] user-defined context for matrix evaluation routine
1310316643e7SJed Brown 
1311316643e7SJed Brown    Notes:
1312e5d3d808SBarry Smith    The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve.
1313316643e7SJed Brown 
1314895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
1315895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
1316895c21f2SBarry Smith 
1317a4f0a591SBarry Smith    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1318b5abc632SBarry Smith    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1319a4f0a591SBarry Smith    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1320a4f0a591SBarry Smith    a and vector W depend on the integration method, step size, and past states. For example with
1321a4f0a591SBarry Smith    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1322a4f0a591SBarry Smith    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1323a4f0a591SBarry Smith 
13246cd88445SBarry Smith    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
13256cd88445SBarry Smith 
13266cd88445SBarry Smith    The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1327ca5f011dSBarry Smith    You should not assume the values are the same in the next call to f() as you set them in the previous call.
1328ca5f011dSBarry Smith 
1329316643e7SJed Brown    Level: beginner
1330316643e7SJed Brown 
1331db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSSetRHSJacobian()`, `SNESComputeJacobianDefaultColor()`, `SNESComputeJacobianDefault()`, `TSSetRHSFunction()`
1332316643e7SJed Brown 
1333316643e7SJed Brown @*/
13349371c9d4SSatish Balay PetscErrorCode TSSetIJacobian(TS ts, Mat Amat, Mat Pmat, TSIJacobian f, void *ctx) {
1335089b2837SJed Brown   SNES snes;
133624989b8cSPeter Brune   DM   dm;
1337316643e7SJed Brown 
1338316643e7SJed Brown   PetscFunctionBegin;
13390700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1340e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
1341e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
1342e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts, 1, Amat, 2);
1343e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts, 1, Pmat, 3);
134424989b8cSPeter Brune 
13459566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
13469566063dSJacob Faibussowitsch   PetscCall(DMTSSetIJacobian(dm, f, ctx));
134724989b8cSPeter Brune 
13489566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
13499566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESTSFormJacobian, ts));
1350316643e7SJed Brown   PetscFunctionReturn(0);
1351316643e7SJed Brown }
1352316643e7SJed Brown 
1353e1244c69SJed Brown /*@
1354e1244c69SJed Brown    TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating.  Without this flag, TS will change the sign and
1355e1244c69SJed Brown    shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute
1356e1244c69SJed Brown    the entire Jacobian.  The reuse flag must be set if the evaluation function will assume that the matrix entries have
1357e1244c69SJed Brown    not been changed by the TS.
1358e1244c69SJed Brown 
1359e1244c69SJed Brown    Logically Collective
1360e1244c69SJed Brown 
13614165533cSJose E. Roman    Input Parameters:
1362e1244c69SJed Brown +  ts - TS context obtained from TSCreate()
1363e1244c69SJed Brown -  reuse - PETSC_TRUE if the RHS Jacobian
1364e1244c69SJed Brown 
1365e1244c69SJed Brown    Level: intermediate
1366e1244c69SJed Brown 
1367db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
1368e1244c69SJed Brown @*/
13699371c9d4SSatish Balay PetscErrorCode TSRHSJacobianSetReuse(TS ts, PetscBool reuse) {
1370e1244c69SJed Brown   PetscFunctionBegin;
1371e1244c69SJed Brown   ts->rhsjacobian.reuse = reuse;
1372e1244c69SJed Brown   PetscFunctionReturn(0);
1373e1244c69SJed Brown }
1374e1244c69SJed Brown 
1375efe9872eSLisandro Dalcin /*@C
1376efe9872eSLisandro Dalcin    TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved.
1377efe9872eSLisandro Dalcin 
1378efe9872eSLisandro Dalcin    Logically Collective on TS
1379efe9872eSLisandro Dalcin 
1380efe9872eSLisandro Dalcin    Input Parameters:
1381efe9872eSLisandro Dalcin +  ts  - the TS context obtained from TSCreate()
1382efe9872eSLisandro Dalcin .  F   - vector to hold the residual (or NULL to have it created internally)
1383efe9872eSLisandro Dalcin .  fun - the function evaluation routine
1384efe9872eSLisandro Dalcin -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1385efe9872eSLisandro Dalcin 
1386efe9872eSLisandro Dalcin    Calling sequence of fun:
13876bc98fa9SBarry Smith $     PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
1388efe9872eSLisandro Dalcin 
1389efe9872eSLisandro Dalcin +  t    - time at step/stage being solved
1390efe9872eSLisandro Dalcin .  U    - state vector
1391efe9872eSLisandro Dalcin .  U_t  - time derivative of state vector
1392efe9872eSLisandro Dalcin .  U_tt - second time derivative of state vector
1393efe9872eSLisandro Dalcin .  F    - function vector
1394efe9872eSLisandro Dalcin -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)
1395efe9872eSLisandro Dalcin 
1396efe9872eSLisandro Dalcin    Level: beginner
1397efe9872eSLisandro Dalcin 
1398db781477SPatrick Sanan .seealso: `TSSetI2Jacobian()`, `TSSetIFunction()`, `TSCreate()`, `TSSetRHSFunction()`
1399efe9872eSLisandro Dalcin @*/
14009371c9d4SSatish Balay PetscErrorCode TSSetI2Function(TS ts, Vec F, TSI2Function fun, void *ctx) {
1401efe9872eSLisandro Dalcin   DM dm;
1402efe9872eSLisandro Dalcin 
1403efe9872eSLisandro Dalcin   PetscFunctionBegin;
1404efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1405efe9872eSLisandro Dalcin   if (F) PetscValidHeaderSpecific(F, VEC_CLASSID, 2);
14069566063dSJacob Faibussowitsch   PetscCall(TSSetIFunction(ts, F, NULL, NULL));
14079566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14089566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Function(dm, fun, ctx));
1409efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1410efe9872eSLisandro Dalcin }
1411efe9872eSLisandro Dalcin 
1412efe9872eSLisandro Dalcin /*@C
1413a5b23f4aSJose E. Roman   TSGetI2Function - Returns the vector where the implicit residual is stored and the function/context to compute it.
1414efe9872eSLisandro Dalcin 
1415efe9872eSLisandro Dalcin   Not Collective
1416efe9872eSLisandro Dalcin 
1417efe9872eSLisandro Dalcin   Input Parameter:
1418efe9872eSLisandro Dalcin . ts - the TS context
1419efe9872eSLisandro Dalcin 
1420d8d19677SJose E. Roman   Output Parameters:
1421efe9872eSLisandro Dalcin + r - vector to hold residual (or NULL)
1422efe9872eSLisandro Dalcin . fun - the function to compute residual (or NULL)
1423efe9872eSLisandro Dalcin - ctx - the function context (or NULL)
1424efe9872eSLisandro Dalcin 
1425efe9872eSLisandro Dalcin   Level: advanced
1426efe9872eSLisandro Dalcin 
1427db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `SNESGetFunction()`, `TSCreate()`
1428efe9872eSLisandro Dalcin @*/
14299371c9d4SSatish Balay PetscErrorCode TSGetI2Function(TS ts, Vec *r, TSI2Function *fun, void **ctx) {
1430efe9872eSLisandro Dalcin   SNES snes;
1431efe9872eSLisandro Dalcin   DM   dm;
1432efe9872eSLisandro Dalcin 
1433efe9872eSLisandro Dalcin   PetscFunctionBegin;
1434efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
14359566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
14369566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
14379566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14389566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm, fun, ctx));
1439efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1440efe9872eSLisandro Dalcin }
1441efe9872eSLisandro Dalcin 
1442efe9872eSLisandro Dalcin /*@C
1443bc77d74cSLisandro Dalcin    TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t  + a*dF/dU_tt
1444efe9872eSLisandro Dalcin         where F(t,U,U_t,U_tt) is the function you provided with TSSetI2Function().
1445efe9872eSLisandro Dalcin 
1446efe9872eSLisandro Dalcin    Logically Collective on TS
1447efe9872eSLisandro Dalcin 
1448efe9872eSLisandro Dalcin    Input Parameters:
1449efe9872eSLisandro Dalcin +  ts  - the TS context obtained from TSCreate()
1450efe9872eSLisandro Dalcin .  J   - Jacobian matrix
1451efe9872eSLisandro Dalcin .  P   - preconditioning matrix for J (may be same as J)
1452efe9872eSLisandro Dalcin .  jac - the Jacobian evaluation routine
1453efe9872eSLisandro Dalcin -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1454efe9872eSLisandro Dalcin 
1455efe9872eSLisandro Dalcin    Calling sequence of jac:
14566bc98fa9SBarry 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);
1457efe9872eSLisandro Dalcin 
1458efe9872eSLisandro Dalcin +  t    - time at step/stage being solved
1459efe9872eSLisandro Dalcin .  U    - state vector
1460efe9872eSLisandro Dalcin .  U_t  - time derivative of state vector
1461efe9872eSLisandro Dalcin .  U_tt - second time derivative of state vector
1462efe9872eSLisandro Dalcin .  v    - shift for U_t
1463efe9872eSLisandro Dalcin .  a    - shift for U_tt
1464efe9872eSLisandro 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
1465efe9872eSLisandro Dalcin .  P    - preconditioning matrix for J, may be same as J
1466efe9872eSLisandro Dalcin -  ctx  - [optional] user-defined context for matrix evaluation routine
1467efe9872eSLisandro Dalcin 
1468efe9872eSLisandro Dalcin    Notes:
1469efe9872eSLisandro Dalcin    The matrices J and P are exactly the matrices that are used by SNES for the nonlinear solve.
1470efe9872eSLisandro Dalcin 
1471efe9872eSLisandro Dalcin    The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be
1472efe9872eSLisandro 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.
1473efe9872eSLisandro Dalcin    The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U  where the positive "shift"
1474bc77d74cSLisandro Dalcin    parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states.
1475efe9872eSLisandro Dalcin 
1476efe9872eSLisandro Dalcin    Level: beginner
1477efe9872eSLisandro Dalcin 
1478db781477SPatrick Sanan .seealso: `TSSetI2Function()`, `TSGetI2Jacobian()`
1479efe9872eSLisandro Dalcin @*/
14809371c9d4SSatish Balay PetscErrorCode TSSetI2Jacobian(TS ts, Mat J, Mat P, TSI2Jacobian jac, void *ctx) {
1481efe9872eSLisandro Dalcin   DM dm;
1482efe9872eSLisandro Dalcin 
1483efe9872eSLisandro Dalcin   PetscFunctionBegin;
1484efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1485efe9872eSLisandro Dalcin   if (J) PetscValidHeaderSpecific(J, MAT_CLASSID, 2);
1486efe9872eSLisandro Dalcin   if (P) PetscValidHeaderSpecific(P, MAT_CLASSID, 3);
14879566063dSJacob Faibussowitsch   PetscCall(TSSetIJacobian(ts, J, P, NULL, NULL));
14889566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
14899566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Jacobian(dm, jac, ctx));
1490efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1491efe9872eSLisandro Dalcin }
1492efe9872eSLisandro Dalcin 
1493efe9872eSLisandro Dalcin /*@C
1494efe9872eSLisandro Dalcin   TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep.
1495efe9872eSLisandro Dalcin 
1496efe9872eSLisandro Dalcin   Not Collective, but parallel objects are returned if TS is parallel
1497efe9872eSLisandro Dalcin 
1498efe9872eSLisandro Dalcin   Input Parameter:
1499efe9872eSLisandro Dalcin . ts  - The TS context obtained from TSCreate()
1500efe9872eSLisandro Dalcin 
1501efe9872eSLisandro Dalcin   Output Parameters:
1502efe9872eSLisandro Dalcin + J  - The (approximate) Jacobian of F(t,U,U_t,U_tt)
1503efe9872eSLisandro Dalcin . P - The matrix from which the preconditioner is constructed, often the same as J
1504efe9872eSLisandro Dalcin . jac - The function to compute the Jacobian matrices
1505efe9872eSLisandro Dalcin - ctx - User-defined context for Jacobian evaluation routine
1506efe9872eSLisandro Dalcin 
150795452b02SPatrick Sanan   Notes:
150895452b02SPatrick Sanan     You can pass in NULL for any return argument you do not need.
1509efe9872eSLisandro Dalcin 
1510efe9872eSLisandro Dalcin   Level: advanced
1511efe9872eSLisandro Dalcin 
1512db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`, `TSSetI2Jacobian()`, `TSGetI2Function()`, `TSCreate()`
1513efe9872eSLisandro Dalcin 
1514efe9872eSLisandro Dalcin @*/
15159371c9d4SSatish Balay PetscErrorCode TSGetI2Jacobian(TS ts, Mat *J, Mat *P, TSI2Jacobian *jac, void **ctx) {
1516efe9872eSLisandro Dalcin   SNES snes;
1517efe9872eSLisandro Dalcin   DM   dm;
1518efe9872eSLisandro Dalcin 
1519efe9872eSLisandro Dalcin   PetscFunctionBegin;
15209566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
15219566063dSJacob Faibussowitsch   PetscCall(SNESSetUpMatrices(snes));
15229566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, J, P, NULL, NULL));
15239566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
15249566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, jac, ctx));
1525efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1526efe9872eSLisandro Dalcin }
1527efe9872eSLisandro Dalcin 
1528efe9872eSLisandro Dalcin /*@
1529efe9872eSLisandro Dalcin   TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0
1530efe9872eSLisandro Dalcin 
1531d083f849SBarry Smith   Collective on TS
1532efe9872eSLisandro Dalcin 
1533efe9872eSLisandro Dalcin   Input Parameters:
1534efe9872eSLisandro Dalcin + ts - the TS context
1535efe9872eSLisandro Dalcin . t - current time
1536efe9872eSLisandro Dalcin . U - state vector
1537efe9872eSLisandro Dalcin . V - time derivative of state vector (U_t)
1538efe9872eSLisandro Dalcin - A - second time derivative of state vector (U_tt)
1539efe9872eSLisandro Dalcin 
1540efe9872eSLisandro Dalcin   Output Parameter:
1541efe9872eSLisandro Dalcin . F - the residual vector
1542efe9872eSLisandro Dalcin 
1543efe9872eSLisandro Dalcin   Note:
1544efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
1545efe9872eSLisandro Dalcin   is used internally within the nonlinear solvers.
1546efe9872eSLisandro Dalcin 
1547efe9872eSLisandro Dalcin   Level: developer
1548efe9872eSLisandro Dalcin 
1549db781477SPatrick Sanan .seealso: `TSSetI2Function()`, `TSGetI2Function()`
1550efe9872eSLisandro Dalcin @*/
15519371c9d4SSatish Balay PetscErrorCode TSComputeI2Function(TS ts, PetscReal t, Vec U, Vec V, Vec A, Vec F) {
1552efe9872eSLisandro Dalcin   DM            dm;
1553efe9872eSLisandro Dalcin   TSI2Function  I2Function;
1554efe9872eSLisandro Dalcin   void         *ctx;
1555efe9872eSLisandro Dalcin   TSRHSFunction rhsfunction;
1556efe9872eSLisandro Dalcin 
1557efe9872eSLisandro Dalcin   PetscFunctionBegin;
1558efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1559efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
1560efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V, VEC_CLASSID, 4);
1561efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A, VEC_CLASSID, 5);
1562efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(F, VEC_CLASSID, 6);
1563efe9872eSLisandro Dalcin 
15649566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
15659566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm, &I2Function, &ctx));
15669566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm, &rhsfunction, NULL));
1567efe9872eSLisandro Dalcin 
1568efe9872eSLisandro Dalcin   if (!I2Function) {
15699566063dSJacob Faibussowitsch     PetscCall(TSComputeIFunction(ts, t, U, A, F, PETSC_FALSE));
1570efe9872eSLisandro Dalcin     PetscFunctionReturn(0);
1571efe9872eSLisandro Dalcin   }
1572efe9872eSLisandro Dalcin 
15739566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_FunctionEval, ts, U, V, F));
1574efe9872eSLisandro Dalcin 
1575792fecdfSBarry Smith   PetscCallBack("TS callback implicit function", I2Function(ts, t, U, V, A, F, ctx));
1576efe9872eSLisandro Dalcin 
1577efe9872eSLisandro Dalcin   if (rhsfunction) {
1578efe9872eSLisandro Dalcin     Vec Frhs;
15799566063dSJacob Faibussowitsch     PetscCall(TSGetRHSVec_Private(ts, &Frhs));
15809566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSFunction(ts, t, U, Frhs));
15819566063dSJacob Faibussowitsch     PetscCall(VecAXPY(F, -1, Frhs));
1582efe9872eSLisandro Dalcin   }
1583efe9872eSLisandro Dalcin 
15849566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_FunctionEval, ts, U, V, F));
1585efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1586efe9872eSLisandro Dalcin }
1587efe9872eSLisandro Dalcin 
1588efe9872eSLisandro Dalcin /*@
1589efe9872eSLisandro Dalcin   TSComputeI2Jacobian - Evaluates the Jacobian of the DAE
1590efe9872eSLisandro Dalcin 
1591d083f849SBarry Smith   Collective on TS
1592efe9872eSLisandro Dalcin 
1593efe9872eSLisandro Dalcin   Input Parameters:
1594efe9872eSLisandro Dalcin + ts - the TS context
1595efe9872eSLisandro Dalcin . t - current timestep
1596efe9872eSLisandro Dalcin . U - state vector
1597efe9872eSLisandro Dalcin . V - time derivative of state vector
1598efe9872eSLisandro Dalcin . A - second time derivative of state vector
1599efe9872eSLisandro Dalcin . shiftV - shift to apply, see note below
1600efe9872eSLisandro Dalcin - shiftA - shift to apply, see note below
1601efe9872eSLisandro Dalcin 
1602efe9872eSLisandro Dalcin   Output Parameters:
1603efe9872eSLisandro Dalcin + J - Jacobian matrix
1604efe9872eSLisandro Dalcin - P - optional preconditioning matrix
1605efe9872eSLisandro Dalcin 
1606efe9872eSLisandro Dalcin   Notes:
1607efe9872eSLisandro Dalcin   If F(t,U,V,A)=0 is the DAE, the required Jacobian is
1608efe9872eSLisandro Dalcin 
1609efe9872eSLisandro Dalcin   dF/dU + shiftV*dF/dV + shiftA*dF/dA
1610efe9872eSLisandro Dalcin 
1611efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
1612efe9872eSLisandro Dalcin   is used internally within the nonlinear solvers.
1613efe9872eSLisandro Dalcin 
1614efe9872eSLisandro Dalcin   Level: developer
1615efe9872eSLisandro Dalcin 
1616db781477SPatrick Sanan .seealso: `TSSetI2Jacobian()`
1617efe9872eSLisandro Dalcin @*/
16189371c9d4SSatish Balay PetscErrorCode TSComputeI2Jacobian(TS ts, PetscReal t, Vec U, Vec V, Vec A, PetscReal shiftV, PetscReal shiftA, Mat J, Mat P) {
1619efe9872eSLisandro Dalcin   DM            dm;
1620efe9872eSLisandro Dalcin   TSI2Jacobian  I2Jacobian;
1621efe9872eSLisandro Dalcin   void         *ctx;
1622efe9872eSLisandro Dalcin   TSRHSJacobian rhsjacobian;
1623efe9872eSLisandro Dalcin 
1624efe9872eSLisandro Dalcin   PetscFunctionBegin;
1625efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1626efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
1627efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V, VEC_CLASSID, 4);
1628efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A, VEC_CLASSID, 5);
1629efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(J, MAT_CLASSID, 8);
1630efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(P, MAT_CLASSID, 9);
1631efe9872eSLisandro Dalcin 
16329566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
16339566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, &I2Jacobian, &ctx));
16349566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjacobian, NULL));
1635efe9872eSLisandro Dalcin 
1636efe9872eSLisandro Dalcin   if (!I2Jacobian) {
16379566063dSJacob Faibussowitsch     PetscCall(TSComputeIJacobian(ts, t, U, A, shiftA, J, P, PETSC_FALSE));
1638efe9872eSLisandro Dalcin     PetscFunctionReturn(0);
1639efe9872eSLisandro Dalcin   }
1640efe9872eSLisandro Dalcin 
16419566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_JacobianEval, ts, U, J, P));
1642792fecdfSBarry Smith   PetscCallBack("TS callback implicit Jacobian", I2Jacobian(ts, t, U, V, A, shiftV, shiftA, J, P, ctx));
1643efe9872eSLisandro Dalcin   if (rhsjacobian) {
1644d60b7d5cSBarry Smith     Mat Jrhs, Prhs;
16459566063dSJacob Faibussowitsch     PetscCall(TSGetRHSMats_Private(ts, &Jrhs, &Prhs));
16469566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSJacobian(ts, t, U, Jrhs, Prhs));
16479566063dSJacob Faibussowitsch     PetscCall(MatAXPY(J, -1, Jrhs, ts->axpy_pattern));
16489566063dSJacob Faibussowitsch     if (P != J) PetscCall(MatAXPY(P, -1, Prhs, ts->axpy_pattern));
1649efe9872eSLisandro Dalcin   }
1650efe9872eSLisandro Dalcin 
16519566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_JacobianEval, ts, U, J, P));
1652efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1653efe9872eSLisandro Dalcin }
1654efe9872eSLisandro Dalcin 
1655438f35afSJed Brown /*@C
1656438f35afSJed Brown    TSSetTransientVariable - sets function to transform from state to transient variables
1657438f35afSJed Brown 
1658438f35afSJed Brown    Logically Collective
1659438f35afSJed Brown 
16604165533cSJose E. Roman    Input Parameters:
1661438f35afSJed Brown +  ts - time stepping context on which to change the transient variable
1662a96d6ef6SBarry Smith .  tvar - a function that transforms to transient variables
1663438f35afSJed Brown -  ctx - a context for tvar
1664438f35afSJed Brown 
1665a96d6ef6SBarry Smith     Calling sequence of tvar:
1666a96d6ef6SBarry Smith $     PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
1667a96d6ef6SBarry Smith 
1668a96d6ef6SBarry Smith +   ts - timestep context
16696aad120cSJose E. Roman .   p - input vector (primitive form)
1670a96d6ef6SBarry Smith .   c - output vector, transient variables (conservative form)
1671a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
1672a96d6ef6SBarry Smith 
1673438f35afSJed Brown    Level: advanced
1674438f35afSJed Brown 
1675438f35afSJed Brown    Notes:
1676438f35afSJed Brown    This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF)
1677438f35afSJed Brown    can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
1678438f35afSJed Brown    well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
1679438f35afSJed Brown    C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
1680438f35afSJed Brown    evaluated via the chain rule, as in
1681438f35afSJed Brown 
1682438f35afSJed Brown      dF/dP + shift * dF/dCdot dC/dP.
1683438f35afSJed Brown 
1684db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `DMTSGetTransientVariable()`, `TSSetIFunction()`, `TSSetIJacobian()`
1685438f35afSJed Brown @*/
16869371c9d4SSatish Balay PetscErrorCode TSSetTransientVariable(TS ts, TSTransientVariable tvar, void *ctx) {
1687438f35afSJed Brown   DM dm;
1688438f35afSJed Brown 
1689438f35afSJed Brown   PetscFunctionBegin;
1690438f35afSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
16919566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
16929566063dSJacob Faibussowitsch   PetscCall(DMTSSetTransientVariable(dm, tvar, ctx));
1693438f35afSJed Brown   PetscFunctionReturn(0);
1694438f35afSJed Brown }
1695438f35afSJed Brown 
1696efe9872eSLisandro Dalcin /*@
1697e3c11fc1SJed Brown    TSComputeTransientVariable - transforms state (primitive) variables to transient (conservative) variables
1698e3c11fc1SJed Brown 
1699e3c11fc1SJed Brown    Logically Collective
1700e3c11fc1SJed Brown 
1701e3c11fc1SJed Brown    Input Parameters:
1702e3c11fc1SJed Brown +  ts - TS on which to compute
1703e3c11fc1SJed Brown -  U - state vector to be transformed to transient variables
1704e3c11fc1SJed Brown 
1705e3c11fc1SJed Brown    Output Parameters:
1706e3c11fc1SJed Brown .  C - transient (conservative) variable
1707e3c11fc1SJed Brown 
1708e3c11fc1SJed Brown    Developer Notes:
1709e3c11fc1SJed Brown    If DMTSSetTransientVariable() has not been called, then C is not modified in this routine and C=NULL is allowed.
1710e3c11fc1SJed Brown    This makes it safe to call without a guard.  One can use TSHasTransientVariable() to check if transient variables are
1711e3c11fc1SJed Brown    being used.
1712e3c11fc1SJed Brown 
1713e3c11fc1SJed Brown    Level: developer
1714e3c11fc1SJed Brown 
1715db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `TSComputeIFunction()`, `TSComputeIJacobian()`
1716e3c11fc1SJed Brown @*/
17179371c9d4SSatish Balay PetscErrorCode TSComputeTransientVariable(TS ts, Vec U, Vec C) {
1718e3c11fc1SJed Brown   DM   dm;
1719e3c11fc1SJed Brown   DMTS dmts;
1720e3c11fc1SJed Brown 
1721e3c11fc1SJed Brown   PetscFunctionBegin;
1722e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1723e3c11fc1SJed Brown   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
17249566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
17259566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
1726e3c11fc1SJed Brown   if (dmts->ops->transientvar) {
1727e3c11fc1SJed Brown     PetscValidHeaderSpecific(C, VEC_CLASSID, 3);
17289566063dSJacob Faibussowitsch     PetscCall((*dmts->ops->transientvar)(ts, U, C, dmts->transientvarctx));
1729e3c11fc1SJed Brown   }
1730e3c11fc1SJed Brown   PetscFunctionReturn(0);
1731e3c11fc1SJed Brown }
1732e3c11fc1SJed Brown 
1733e3c11fc1SJed Brown /*@
1734e3c11fc1SJed Brown    TSHasTransientVariable - determine whether transient variables have been set
1735e3c11fc1SJed Brown 
1736e3c11fc1SJed Brown    Logically Collective
1737e3c11fc1SJed Brown 
1738e3c11fc1SJed Brown    Input Parameters:
1739e3c11fc1SJed Brown .  ts - TS on which to compute
1740e3c11fc1SJed Brown 
1741e3c11fc1SJed Brown    Output Parameters:
1742e3c11fc1SJed Brown .  has - PETSC_TRUE if transient variables have been set
1743e3c11fc1SJed Brown 
1744e3c11fc1SJed Brown    Level: developer
1745e3c11fc1SJed Brown 
1746db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `TSComputeTransientVariable()`
1747e3c11fc1SJed Brown @*/
17489371c9d4SSatish Balay PetscErrorCode TSHasTransientVariable(TS ts, PetscBool *has) {
1749e3c11fc1SJed Brown   DM   dm;
1750e3c11fc1SJed Brown   DMTS dmts;
1751e3c11fc1SJed Brown 
1752e3c11fc1SJed Brown   PetscFunctionBegin;
1753e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
17549566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
17559566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm, &dmts));
1756e3c11fc1SJed Brown   *has = dmts->ops->transientvar ? PETSC_TRUE : PETSC_FALSE;
1757e3c11fc1SJed Brown   PetscFunctionReturn(0);
1758e3c11fc1SJed Brown }
1759e3c11fc1SJed Brown 
1760e3c11fc1SJed Brown /*@
1761efe9872eSLisandro Dalcin    TS2SetSolution - Sets the initial solution and time derivative vectors
1762efe9872eSLisandro Dalcin    for use by the TS routines handling second order equations.
1763efe9872eSLisandro Dalcin 
1764d083f849SBarry Smith    Logically Collective on TS
1765efe9872eSLisandro Dalcin 
1766efe9872eSLisandro Dalcin    Input Parameters:
1767efe9872eSLisandro Dalcin +  ts - the TS context obtained from TSCreate()
1768efe9872eSLisandro Dalcin .  u - the solution vector
1769efe9872eSLisandro Dalcin -  v - the time derivative vector
1770efe9872eSLisandro Dalcin 
1771efe9872eSLisandro Dalcin    Level: beginner
1772efe9872eSLisandro Dalcin 
1773efe9872eSLisandro Dalcin @*/
17749371c9d4SSatish Balay PetscErrorCode TS2SetSolution(TS ts, Vec u, Vec v) {
1775efe9872eSLisandro Dalcin   PetscFunctionBegin;
1776efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1777efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
1778efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(v, VEC_CLASSID, 3);
17799566063dSJacob Faibussowitsch   PetscCall(TSSetSolution(ts, u));
17809566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)v));
17819566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
1782efe9872eSLisandro Dalcin   ts->vec_dot = v;
1783efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1784efe9872eSLisandro Dalcin }
1785efe9872eSLisandro Dalcin 
1786efe9872eSLisandro Dalcin /*@
1787efe9872eSLisandro Dalcin    TS2GetSolution - Returns the solution and time derivative at the present timestep
1788efe9872eSLisandro Dalcin    for second order equations. It is valid to call this routine inside the function
1789efe9872eSLisandro Dalcin    that you are evaluating in order to move to the new timestep. This vector not
1790efe9872eSLisandro Dalcin    changed until the solution at the next timestep has been calculated.
1791efe9872eSLisandro Dalcin 
1792efe9872eSLisandro Dalcin    Not Collective, but Vec returned is parallel if TS is parallel
1793efe9872eSLisandro Dalcin 
1794efe9872eSLisandro Dalcin    Input Parameter:
1795efe9872eSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
1796efe9872eSLisandro Dalcin 
1797d8d19677SJose E. Roman    Output Parameters:
1798efe9872eSLisandro Dalcin +  u - the vector containing the solution
1799efe9872eSLisandro Dalcin -  v - the vector containing the time derivative
1800efe9872eSLisandro Dalcin 
1801efe9872eSLisandro Dalcin    Level: intermediate
1802efe9872eSLisandro Dalcin 
1803db781477SPatrick Sanan .seealso: `TS2SetSolution()`, `TSGetTimeStep()`, `TSGetTime()`
1804efe9872eSLisandro Dalcin 
1805efe9872eSLisandro Dalcin @*/
18069371c9d4SSatish Balay PetscErrorCode TS2GetSolution(TS ts, Vec *u, Vec *v) {
1807efe9872eSLisandro Dalcin   PetscFunctionBegin;
1808efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
1809efe9872eSLisandro Dalcin   if (u) PetscValidPointer(u, 2);
1810efe9872eSLisandro Dalcin   if (v) PetscValidPointer(v, 3);
1811efe9872eSLisandro Dalcin   if (u) *u = ts->vec_sol;
1812efe9872eSLisandro Dalcin   if (v) *v = ts->vec_dot;
1813efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1814efe9872eSLisandro Dalcin }
1815efe9872eSLisandro Dalcin 
181655849f57SBarry Smith /*@C
181755849f57SBarry Smith   TSLoad - Loads a KSP that has been stored in binary  with KSPView().
181855849f57SBarry Smith 
181955849f57SBarry Smith   Collective on PetscViewer
182055849f57SBarry Smith 
182155849f57SBarry Smith   Input Parameters:
182255849f57SBarry Smith + newdm - the newly loaded TS, this needs to have been created with TSCreate() or
182355849f57SBarry Smith            some related function before a call to TSLoad().
182455849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
182555849f57SBarry Smith 
182655849f57SBarry Smith    Level: intermediate
182755849f57SBarry Smith 
182855849f57SBarry Smith   Notes:
182955849f57SBarry Smith    The type is determined by the data in the file, any type set into the TS before this call is ignored.
183055849f57SBarry Smith 
183155849f57SBarry Smith   Notes for advanced users:
183255849f57SBarry Smith   Most users should not need to know the details of the binary storage
183355849f57SBarry Smith   format, since TSLoad() and TSView() completely hide these details.
183455849f57SBarry Smith   But for anyone who's interested, the standard binary matrix storage
183555849f57SBarry Smith   format is
183655849f57SBarry Smith .vb
183755849f57SBarry Smith      has not yet been determined
183855849f57SBarry Smith .ve
183955849f57SBarry Smith 
1840db781477SPatrick Sanan .seealso: `PetscViewerBinaryOpen()`, `TSView()`, `MatLoad()`, `VecLoad()`
184155849f57SBarry Smith @*/
18429371c9d4SSatish Balay PetscErrorCode TSLoad(TS ts, PetscViewer viewer) {
184355849f57SBarry Smith   PetscBool isbinary;
184455849f57SBarry Smith   PetscInt  classid;
184555849f57SBarry Smith   char      type[256];
18462d53ad75SBarry Smith   DMTS      sdm;
1847ad6bc421SBarry Smith   DM        dm;
184855849f57SBarry Smith 
184955849f57SBarry Smith   PetscFunctionBegin;
1850f2c2a1b9SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
185155849f57SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
18529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
18533c633725SBarry Smith   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
185455849f57SBarry Smith 
18559566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT));
18563c633725SBarry Smith   PetscCheck(classid == TS_FILE_CLASSID, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Not TS next in file");
18579566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR));
18589566063dSJacob Faibussowitsch   PetscCall(TSSetType(ts, type));
1859dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, load, viewer);
18609566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)ts), &dm));
18619566063dSJacob Faibussowitsch   PetscCall(DMLoad(dm, viewer));
18629566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts, dm));
18639566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(ts->dm, &ts->vec_sol));
18649566063dSJacob Faibussowitsch   PetscCall(VecLoad(ts->vec_sol, viewer));
18659566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm, &sdm));
18669566063dSJacob Faibussowitsch   PetscCall(DMTSLoad(sdm, viewer));
186755849f57SBarry Smith   PetscFunctionReturn(0);
186855849f57SBarry Smith }
186955849f57SBarry Smith 
18709804daf3SBarry Smith #include <petscdraw.h>
1871e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1872e04113cfSBarry Smith #include <petscviewersaws.h>
1873f05ece33SBarry Smith #endif
1874fe2efc57SMark 
1875fe2efc57SMark /*@C
1876fe2efc57SMark    TSViewFromOptions - View from Options
1877fe2efc57SMark 
1878fe2efc57SMark    Collective on TS
1879fe2efc57SMark 
1880fe2efc57SMark    Input Parameters:
1881fe2efc57SMark +  A - the application ordering context
1882736c3998SJose E. Roman .  obj - Optional object
1883736c3998SJose E. Roman -  name - command line option
1884fe2efc57SMark 
1885fe2efc57SMark    Level: intermediate
1886db781477SPatrick Sanan .seealso: `TS`, `TSView`, `PetscObjectViewFromOptions()`, `TSCreate()`
1887fe2efc57SMark @*/
18889371c9d4SSatish Balay PetscErrorCode TSViewFromOptions(TS A, PetscObject obj, const char name[]) {
1889fe2efc57SMark   PetscFunctionBegin;
1890fe2efc57SMark   PetscValidHeaderSpecific(A, TS_CLASSID, 1);
18919566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
1892fe2efc57SMark   PetscFunctionReturn(0);
1893fe2efc57SMark }
1894fe2efc57SMark 
18957e2c5f70SBarry Smith /*@C
1896d763cef2SBarry Smith     TSView - Prints the TS data structure.
1897d763cef2SBarry Smith 
18984c49b128SBarry Smith     Collective on TS
1899d763cef2SBarry Smith 
1900d763cef2SBarry Smith     Input Parameters:
1901d763cef2SBarry Smith +   ts - the TS context obtained from TSCreate()
1902d763cef2SBarry Smith -   viewer - visualization context
1903d763cef2SBarry Smith 
1904d763cef2SBarry Smith     Options Database Key:
1905d763cef2SBarry Smith .   -ts_view - calls TSView() at end of TSStep()
1906d763cef2SBarry Smith 
1907d763cef2SBarry Smith     Notes:
1908d763cef2SBarry Smith     The available visualization contexts include
1909b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1910b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1911d763cef2SBarry Smith          output where only the first processor opens
1912d763cef2SBarry Smith          the file.  All other processors send their
1913d763cef2SBarry Smith          data to the first processor to print.
1914d763cef2SBarry Smith 
1915d763cef2SBarry Smith     The user can open an alternative visualization context with
1916b0a32e0cSBarry Smith     PetscViewerASCIIOpen() - output to a specified file.
1917d763cef2SBarry Smith 
1918595c91d4SBarry Smith     In the debugger you can do "call TSView(ts,0)" to display the TS solver. (The same holds for any PETSc object viewer).
1919595c91d4SBarry Smith 
1920d763cef2SBarry Smith     Level: beginner
1921d763cef2SBarry Smith 
1922db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`
1923d763cef2SBarry Smith @*/
19249371c9d4SSatish Balay PetscErrorCode TSView(TS ts, PetscViewer viewer) {
192519fd82e9SBarry Smith   TSType    type;
19262b0a91c0SBarry Smith   PetscBool iascii, isstring, isundials, isbinary, isdraw;
19272d53ad75SBarry Smith   DMTS      sdm;
1928e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1929536b137fSBarry Smith   PetscBool issaws;
1930f05ece33SBarry Smith #endif
1931d763cef2SBarry Smith 
1932d763cef2SBarry Smith   PetscFunctionBegin;
19330700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
19341e66621cSBarry Smith   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts), &viewer));
19350700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1936c9780b6fSBarry Smith   PetscCheckSameComm(ts, 1, viewer, 2);
1937fd16b177SBarry Smith 
19389566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
19399566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
19409566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
19419566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
1942e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
19439566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
1944f05ece33SBarry Smith #endif
194532077d6dSBarry Smith   if (iascii) {
19469566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ts, viewer));
1947efd4aadfSBarry Smith     if (ts->ops->view) {
19489566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
1949dbbe0bcdSBarry Smith       PetscUseTypeMethod(ts, view, viewer);
19509566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
1951efd4aadfSBarry Smith     }
19521e66621cSBarry Smith     if (ts->max_steps < PETSC_MAX_INT) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum steps=%" PetscInt_FMT "\n", ts->max_steps));
19531e66621cSBarry Smith     if (ts->max_time < PETSC_MAX_REAL) PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum time=%g\n", (double)ts->max_time));
19541e66621cSBarry Smith     if (ts->ifuncs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of I function evaluations=%" PetscInt_FMT "\n", ts->ifuncs));
19551e66621cSBarry Smith     if (ts->ijacs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of I Jacobian evaluations=%" PetscInt_FMT "\n", ts->ijacs));
19561e66621cSBarry Smith     if (ts->rhsfuncs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of RHS function evaluations=%" PetscInt_FMT "\n", ts->rhsfuncs));
19571e66621cSBarry Smith     if (ts->rhsjacs) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of RHS Jacobian evaluations=%" PetscInt_FMT "\n", ts->rhsjacs));
1958efd4aadfSBarry Smith     if (ts->usessnes) {
1959efd4aadfSBarry Smith       PetscBool lin;
19601e66621cSBarry Smith       if (ts->problem_type == TS_NONLINEAR) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of nonlinear solver iterations=%" PetscInt_FMT "\n", ts->snes_its));
196163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of linear solver iterations=%" PetscInt_FMT "\n", ts->ksp_its));
19629566063dSJacob Faibussowitsch       PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes, &lin, SNESKSPONLY, SNESKSPTRANSPOSEONLY, ""));
196363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of %slinear solve failures=%" PetscInt_FMT "\n", lin ? "" : "non", ts->num_snes_failures));
1964efd4aadfSBarry Smith     }
196563a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of rejected steps=%" PetscInt_FMT "\n", ts->reject));
19661e66621cSBarry Smith     if (ts->vrtol) PetscCall(PetscViewerASCIIPrintf(viewer, "  using vector of relative error tolerances, "));
19671e66621cSBarry Smith     else PetscCall(PetscViewerASCIIPrintf(viewer, "  using relative error tolerance of %g, ", (double)ts->rtol));
19681e66621cSBarry Smith     if (ts->vatol) PetscCall(PetscViewerASCIIPrintf(viewer, "  using vector of absolute error tolerances\n"));
19691e66621cSBarry Smith     else PetscCall(PetscViewerASCIIPrintf(viewer, "  using absolute error tolerance of %g\n", (double)ts->atol));
19709566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
19719566063dSJacob Faibussowitsch     PetscCall(TSAdaptView(ts->adapt, viewer));
19729566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
19730f5bd95cSBarry Smith   } else if (isstring) {
19749566063dSJacob Faibussowitsch     PetscCall(TSGetType(ts, &type));
19759566063dSJacob Faibussowitsch     PetscCall(PetscViewerStringSPrintf(viewer, " TSType: %-7.7s", type));
1976dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
197755849f57SBarry Smith   } else if (isbinary) {
197855849f57SBarry Smith     PetscInt    classid = TS_FILE_CLASSID;
197955849f57SBarry Smith     MPI_Comm    comm;
198055849f57SBarry Smith     PetscMPIInt rank;
198155849f57SBarry Smith     char        type[256];
198255849f57SBarry Smith 
19839566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
19849566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
1985dd400576SPatrick Sanan     if (rank == 0) {
19869566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
19879566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(type, ((PetscObject)ts)->type_name, 256));
19889566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, type, 256, PETSC_CHAR));
198955849f57SBarry Smith     }
1990dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
19919566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt, viewer));
19929566063dSJacob Faibussowitsch     PetscCall(DMView(ts->dm, viewer));
19939566063dSJacob Faibussowitsch     PetscCall(VecView(ts->vec_sol, viewer));
19949566063dSJacob Faibussowitsch     PetscCall(DMGetDMTS(ts->dm, &sdm));
19959566063dSJacob Faibussowitsch     PetscCall(DMTSView(sdm, viewer));
19962b0a91c0SBarry Smith   } else if (isdraw) {
19972b0a91c0SBarry Smith     PetscDraw draw;
19982b0a91c0SBarry Smith     char      str[36];
199989fd9fafSBarry Smith     PetscReal x, y, bottom, h;
20002b0a91c0SBarry Smith 
20019566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
20029566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y));
20039566063dSJacob Faibussowitsch     PetscCall(PetscStrcpy(str, "TS: "));
20049566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(str, ((PetscObject)ts)->type_name));
20059566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLACK, PETSC_DRAW_BLACK, str, NULL, &h));
200689fd9fafSBarry Smith     bottom = y - h;
20079566063dSJacob Faibussowitsch     PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom));
2008dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
20099566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt, viewer));
20109566063dSJacob Faibussowitsch     if (ts->snes) PetscCall(SNESView(ts->snes, viewer));
20119566063dSJacob Faibussowitsch     PetscCall(PetscDrawPopCurrentPoint(draw));
2012e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
2013536b137fSBarry Smith   } else if (issaws) {
2014d45a07a7SBarry Smith     PetscMPIInt rank;
20152657e9d9SBarry Smith     const char *name;
20162657e9d9SBarry Smith 
20179566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)ts, &name));
20189566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
2019dd400576SPatrick Sanan     if (!((PetscObject)ts)->amsmem && rank == 0) {
2020d45a07a7SBarry Smith       char dir[1024];
2021d45a07a7SBarry Smith 
20229566063dSJacob Faibussowitsch       PetscCall(PetscObjectViewSAWs((PetscObject)ts, viewer));
20239566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/time_step", name));
2024792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, &ts->steps, 1, SAWs_READ, SAWs_INT));
20259566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/time", name));
2026792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, &ts->ptime, 1, SAWs_READ, SAWs_DOUBLE));
2027d763cef2SBarry Smith     }
2028dbbe0bcdSBarry Smith     PetscTryTypeMethod(ts, view, viewer);
2029f05ece33SBarry Smith #endif
2030f05ece33SBarry Smith   }
203136a9e3b9SBarry Smith   if (ts->snes && ts->usessnes) {
20329566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
20339566063dSJacob Faibussowitsch     PetscCall(SNESView(ts->snes, viewer));
20349566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
203536a9e3b9SBarry Smith   }
20369566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm, &sdm));
20379566063dSJacob Faibussowitsch   PetscCall(DMTSView(sdm, viewer));
2038f05ece33SBarry Smith 
20399566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
20409566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ts, TSSUNDIALS, &isundials));
20419566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2042d763cef2SBarry Smith   PetscFunctionReturn(0);
2043d763cef2SBarry Smith }
2044d763cef2SBarry Smith 
2045b07ff414SBarry Smith /*@
2046d763cef2SBarry Smith    TSSetApplicationContext - Sets an optional user-defined context for
2047d763cef2SBarry Smith    the timesteppers.
2048d763cef2SBarry Smith 
20493f9fe445SBarry Smith    Logically Collective on TS
2050d763cef2SBarry Smith 
2051d763cef2SBarry Smith    Input Parameters:
2052d763cef2SBarry Smith +  ts - the TS context obtained from TSCreate()
2053d763cef2SBarry Smith -  usrP - optional user context
2054d763cef2SBarry Smith 
205595452b02SPatrick Sanan    Fortran Notes:
205695452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
2057daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2058daf670e6SBarry Smith 
2059d763cef2SBarry Smith    Level: intermediate
2060d763cef2SBarry Smith 
2061db781477SPatrick Sanan .seealso: `TSGetApplicationContext()`
2062d763cef2SBarry Smith @*/
20639371c9d4SSatish Balay PetscErrorCode TSSetApplicationContext(TS ts, void *usrP) {
2064d763cef2SBarry Smith   PetscFunctionBegin;
20650700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2066d763cef2SBarry Smith   ts->user = usrP;
2067d763cef2SBarry Smith   PetscFunctionReturn(0);
2068d763cef2SBarry Smith }
2069d763cef2SBarry Smith 
2070b07ff414SBarry Smith /*@
2071d763cef2SBarry Smith     TSGetApplicationContext - Gets the user-defined context for the
2072d763cef2SBarry Smith     timestepper.
2073d763cef2SBarry Smith 
2074d763cef2SBarry Smith     Not Collective
2075d763cef2SBarry Smith 
2076d763cef2SBarry Smith     Input Parameter:
2077d763cef2SBarry Smith .   ts - the TS context obtained from TSCreate()
2078d763cef2SBarry Smith 
2079d763cef2SBarry Smith     Output Parameter:
2080d763cef2SBarry Smith .   usrP - user context
2081d763cef2SBarry Smith 
208295452b02SPatrick Sanan    Fortran Notes:
208395452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
2084daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2085daf670e6SBarry Smith 
2086d763cef2SBarry Smith     Level: intermediate
2087d763cef2SBarry Smith 
2088db781477SPatrick Sanan .seealso: `TSSetApplicationContext()`
2089d763cef2SBarry Smith @*/
20909371c9d4SSatish Balay PetscErrorCode TSGetApplicationContext(TS ts, void *usrP) {
2091d763cef2SBarry Smith   PetscFunctionBegin;
20920700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2093e71120c6SJed Brown   *(void **)usrP = ts->user;
2094d763cef2SBarry Smith   PetscFunctionReturn(0);
2095d763cef2SBarry Smith }
2096d763cef2SBarry Smith 
2097d763cef2SBarry Smith /*@
209880275a0aSLisandro Dalcin    TSGetStepNumber - Gets the number of steps completed.
2099d763cef2SBarry Smith 
2100d763cef2SBarry Smith    Not Collective
2101d763cef2SBarry Smith 
2102d763cef2SBarry Smith    Input Parameter:
2103d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2104d763cef2SBarry Smith 
2105d763cef2SBarry Smith    Output Parameter:
210680275a0aSLisandro Dalcin .  steps - number of steps completed so far
2107d763cef2SBarry Smith 
2108d763cef2SBarry Smith    Level: intermediate
2109d763cef2SBarry Smith 
2110db781477SPatrick Sanan .seealso: `TSGetTime()`, `TSGetTimeStep()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`
2111d763cef2SBarry Smith @*/
21129371c9d4SSatish Balay PetscErrorCode TSGetStepNumber(TS ts, PetscInt *steps) {
2113d763cef2SBarry Smith   PetscFunctionBegin;
21140700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
211580275a0aSLisandro Dalcin   PetscValidIntPointer(steps, 2);
211680275a0aSLisandro Dalcin   *steps = ts->steps;
211780275a0aSLisandro Dalcin   PetscFunctionReturn(0);
211880275a0aSLisandro Dalcin }
211980275a0aSLisandro Dalcin 
212080275a0aSLisandro Dalcin /*@
212180275a0aSLisandro Dalcin    TSSetStepNumber - Sets the number of steps completed.
212280275a0aSLisandro Dalcin 
212380275a0aSLisandro Dalcin    Logically Collective on TS
212480275a0aSLisandro Dalcin 
212580275a0aSLisandro Dalcin    Input Parameters:
212680275a0aSLisandro Dalcin +  ts - the TS context
212780275a0aSLisandro Dalcin -  steps - number of steps completed so far
212880275a0aSLisandro Dalcin 
212980275a0aSLisandro Dalcin    Notes:
213080275a0aSLisandro Dalcin    For most uses of the TS solvers the user need not explicitly call
213180275a0aSLisandro Dalcin    TSSetStepNumber(), as the step counter is appropriately updated in
213280275a0aSLisandro Dalcin    TSSolve()/TSStep()/TSRollBack(). Power users may call this routine to
213380275a0aSLisandro Dalcin    reinitialize timestepping by setting the step counter to zero (and time
213480275a0aSLisandro Dalcin    to the initial time) to solve a similar problem with different initial
213580275a0aSLisandro Dalcin    conditions or parameters. Other possible use case is to continue
213680275a0aSLisandro Dalcin    timestepping from a previously interrupted run in such a way that TS
213780275a0aSLisandro Dalcin    monitors will be called with a initial nonzero step counter.
213880275a0aSLisandro Dalcin 
213980275a0aSLisandro Dalcin    Level: advanced
214080275a0aSLisandro Dalcin 
2141db781477SPatrick Sanan .seealso: `TSGetStepNumber()`, `TSSetTime()`, `TSSetTimeStep()`, `TSSetSolution()`
214280275a0aSLisandro Dalcin @*/
21439371c9d4SSatish Balay PetscErrorCode TSSetStepNumber(TS ts, PetscInt steps) {
214480275a0aSLisandro Dalcin   PetscFunctionBegin;
214580275a0aSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
214680275a0aSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts, steps, 2);
21473c633725SBarry Smith   PetscCheck(steps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Step number must be non-negative");
214880275a0aSLisandro Dalcin   ts->steps = steps;
2149d763cef2SBarry Smith   PetscFunctionReturn(0);
2150d763cef2SBarry Smith }
2151d763cef2SBarry Smith 
2152d763cef2SBarry Smith /*@
2153d763cef2SBarry Smith    TSSetTimeStep - Allows one to reset the timestep at any time,
2154d763cef2SBarry Smith    useful for simple pseudo-timestepping codes.
2155d763cef2SBarry Smith 
21563f9fe445SBarry Smith    Logically Collective on TS
2157d763cef2SBarry Smith 
2158d763cef2SBarry Smith    Input Parameters:
2159d763cef2SBarry Smith +  ts - the TS context obtained from TSCreate()
2160d763cef2SBarry Smith -  time_step - the size of the timestep
2161d763cef2SBarry Smith 
2162d763cef2SBarry Smith    Level: intermediate
2163d763cef2SBarry Smith 
2164db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSSetTime()`
2165d763cef2SBarry Smith 
2166d763cef2SBarry Smith @*/
21679371c9d4SSatish Balay PetscErrorCode TSSetTimeStep(TS ts, PetscReal time_step) {
2168d763cef2SBarry Smith   PetscFunctionBegin;
21690700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2170c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts, time_step, 2);
2171d763cef2SBarry Smith   ts->time_step = time_step;
2172d763cef2SBarry Smith   PetscFunctionReturn(0);
2173d763cef2SBarry Smith }
2174d763cef2SBarry Smith 
2175a43b19c4SJed Brown /*@
217649354f04SShri Abhyankar    TSSetExactFinalTime - Determines whether to adapt the final time step to
217749354f04SShri Abhyankar      match the exact final time, interpolate solution to the exact final time,
217849354f04SShri Abhyankar      or just return at the final time TS computed.
2179a43b19c4SJed Brown 
2180a43b19c4SJed Brown   Logically Collective on TS
2181a43b19c4SJed Brown 
2182d8d19677SJose E. Roman    Input Parameters:
2183a43b19c4SJed Brown +   ts - the time-step context
218449354f04SShri Abhyankar -   eftopt - exact final time option
2185a43b19c4SJed Brown 
2186feed9e9dSBarry Smith $  TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded
2187feed9e9dSBarry Smith $  TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time
2188feed9e9dSBarry Smith $  TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time
2189feed9e9dSBarry Smith 
2190feed9e9dSBarry Smith    Options Database:
2191feed9e9dSBarry Smith .   -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime
2192feed9e9dSBarry Smith 
2193ee346746SBarry Smith    Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time
2194ee346746SBarry Smith     then the final time you selected.
2195ee346746SBarry Smith 
2196a43b19c4SJed Brown    Level: beginner
2197a43b19c4SJed Brown 
2198db781477SPatrick Sanan .seealso: `TSExactFinalTimeOption`, `TSGetExactFinalTime()`
2199a43b19c4SJed Brown @*/
22009371c9d4SSatish Balay PetscErrorCode TSSetExactFinalTime(TS ts, TSExactFinalTimeOption eftopt) {
2201a43b19c4SJed Brown   PetscFunctionBegin;
2202a43b19c4SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
220349354f04SShri Abhyankar   PetscValidLogicalCollectiveEnum(ts, eftopt, 2);
220449354f04SShri Abhyankar   ts->exact_final_time = eftopt;
2205a43b19c4SJed Brown   PetscFunctionReturn(0);
2206a43b19c4SJed Brown }
2207a43b19c4SJed Brown 
2208d763cef2SBarry Smith /*@
2209f6953c82SLisandro Dalcin    TSGetExactFinalTime - Gets the exact final time option.
2210f6953c82SLisandro Dalcin 
2211f6953c82SLisandro Dalcin    Not Collective
2212f6953c82SLisandro Dalcin 
2213f6953c82SLisandro Dalcin    Input Parameter:
2214f6953c82SLisandro Dalcin .  ts - the TS context
2215f6953c82SLisandro Dalcin 
2216f6953c82SLisandro Dalcin    Output Parameter:
2217f6953c82SLisandro Dalcin .  eftopt - exact final time option
2218f6953c82SLisandro Dalcin 
2219f6953c82SLisandro Dalcin    Level: beginner
2220f6953c82SLisandro Dalcin 
2221db781477SPatrick Sanan .seealso: `TSExactFinalTimeOption`, `TSSetExactFinalTime()`
2222f6953c82SLisandro Dalcin @*/
22239371c9d4SSatish Balay PetscErrorCode TSGetExactFinalTime(TS ts, TSExactFinalTimeOption *eftopt) {
2224f6953c82SLisandro Dalcin   PetscFunctionBegin;
2225f6953c82SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2226f6953c82SLisandro Dalcin   PetscValidPointer(eftopt, 2);
2227f6953c82SLisandro Dalcin   *eftopt = ts->exact_final_time;
2228f6953c82SLisandro Dalcin   PetscFunctionReturn(0);
2229f6953c82SLisandro Dalcin }
2230f6953c82SLisandro Dalcin 
2231f6953c82SLisandro Dalcin /*@
2232d763cef2SBarry Smith    TSGetTimeStep - Gets the current timestep size.
2233d763cef2SBarry Smith 
2234d763cef2SBarry Smith    Not Collective
2235d763cef2SBarry Smith 
2236d763cef2SBarry Smith    Input Parameter:
2237d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2238d763cef2SBarry Smith 
2239d763cef2SBarry Smith    Output Parameter:
2240d763cef2SBarry Smith .  dt - the current timestep size
2241d763cef2SBarry Smith 
2242d763cef2SBarry Smith    Level: intermediate
2243d763cef2SBarry Smith 
2244db781477SPatrick Sanan .seealso: `TSSetTimeStep()`, `TSGetTime()`
2245d763cef2SBarry Smith 
2246d763cef2SBarry Smith @*/
22479371c9d4SSatish Balay PetscErrorCode TSGetTimeStep(TS ts, PetscReal *dt) {
2248d763cef2SBarry Smith   PetscFunctionBegin;
22490700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2250f7cf8827SBarry Smith   PetscValidRealPointer(dt, 2);
2251d763cef2SBarry Smith   *dt = ts->time_step;
2252d763cef2SBarry Smith   PetscFunctionReturn(0);
2253d763cef2SBarry Smith }
2254d763cef2SBarry Smith 
2255d8e5e3e6SSatish Balay /*@
2256d763cef2SBarry Smith    TSGetSolution - Returns the solution at the present timestep. It
2257d763cef2SBarry Smith    is valid to call this routine inside the function that you are evaluating
2258d763cef2SBarry Smith    in order to move to the new timestep. This vector not changed until
2259d763cef2SBarry Smith    the solution at the next timestep has been calculated.
2260d763cef2SBarry Smith 
2261d763cef2SBarry Smith    Not Collective, but Vec returned is parallel if TS is parallel
2262d763cef2SBarry Smith 
2263d763cef2SBarry Smith    Input Parameter:
2264d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2265d763cef2SBarry Smith 
2266d763cef2SBarry Smith    Output Parameter:
2267d763cef2SBarry Smith .  v - the vector containing the solution
2268d763cef2SBarry Smith 
226963e21af5SBarry Smith    Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested
227063e21af5SBarry Smith    final time. It returns the solution at the next timestep.
227163e21af5SBarry Smith 
2272d763cef2SBarry Smith    Level: intermediate
2273d763cef2SBarry Smith 
2274db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetTime()`, `TSGetSolveTime()`, `TSGetSolutionComponents()`, `TSSetSolutionFunction()`
2275d763cef2SBarry Smith 
2276d763cef2SBarry Smith @*/
22779371c9d4SSatish Balay PetscErrorCode TSGetSolution(TS ts, Vec *v) {
2278d763cef2SBarry Smith   PetscFunctionBegin;
22790700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
22804482741eSBarry Smith   PetscValidPointer(v, 2);
22818737fe31SLisandro Dalcin   *v = ts->vec_sol;
2282d763cef2SBarry Smith   PetscFunctionReturn(0);
2283d763cef2SBarry Smith }
2284d763cef2SBarry Smith 
228503fe5f5eSDebojyoti Ghosh /*@
2286b2bf4f3aSDebojyoti Ghosh    TSGetSolutionComponents - Returns any solution components at the present
228703fe5f5eSDebojyoti Ghosh    timestep, if available for the time integration method being used.
2288b2bf4f3aSDebojyoti Ghosh    Solution components are quantities that share the same size and
228903fe5f5eSDebojyoti Ghosh    structure as the solution vector.
229003fe5f5eSDebojyoti Ghosh 
229103fe5f5eSDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
229203fe5f5eSDebojyoti Ghosh 
229303fe5f5eSDebojyoti Ghosh    Parameters :
2294a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2295b2bf4f3aSDebojyoti Ghosh .  n - If v is PETSC_NULL, then the number of solution components is
2296b2bf4f3aSDebojyoti Ghosh        returned through n, else the n-th solution component is
229703fe5f5eSDebojyoti Ghosh        returned in v.
2298a2b725a8SWilliam Gropp -  v - the vector containing the n-th solution component
229903fe5f5eSDebojyoti Ghosh        (may be PETSC_NULL to use this function to find out
2300b2bf4f3aSDebojyoti Ghosh         the number of solutions components).
230103fe5f5eSDebojyoti Ghosh 
23024cdd57e5SDebojyoti Ghosh    Level: advanced
230303fe5f5eSDebojyoti Ghosh 
2304db781477SPatrick Sanan .seealso: `TSGetSolution()`
230503fe5f5eSDebojyoti Ghosh 
230603fe5f5eSDebojyoti Ghosh @*/
23079371c9d4SSatish Balay PetscErrorCode TSGetSolutionComponents(TS ts, PetscInt *n, Vec *v) {
230803fe5f5eSDebojyoti Ghosh   PetscFunctionBegin;
230903fe5f5eSDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2310b2bf4f3aSDebojyoti Ghosh   if (!ts->ops->getsolutioncomponents) *n = 0;
2311dbbe0bcdSBarry Smith   else PetscUseTypeMethod(ts, getsolutioncomponents, n, v);
231203fe5f5eSDebojyoti Ghosh   PetscFunctionReturn(0);
231303fe5f5eSDebojyoti Ghosh }
231403fe5f5eSDebojyoti Ghosh 
23154cdd57e5SDebojyoti Ghosh /*@
23164cdd57e5SDebojyoti Ghosh    TSGetAuxSolution - Returns an auxiliary solution at the present
23174cdd57e5SDebojyoti Ghosh    timestep, if available for the time integration method being used.
23184cdd57e5SDebojyoti Ghosh 
23194cdd57e5SDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
23204cdd57e5SDebojyoti Ghosh 
23214cdd57e5SDebojyoti Ghosh    Parameters :
2322a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2323a2b725a8SWilliam Gropp -  v - the vector containing the auxiliary solution
23244cdd57e5SDebojyoti Ghosh 
23254cdd57e5SDebojyoti Ghosh    Level: intermediate
23264cdd57e5SDebojyoti Ghosh 
2327db781477SPatrick Sanan .seealso: `TSGetSolution()`
23284cdd57e5SDebojyoti Ghosh 
23294cdd57e5SDebojyoti Ghosh @*/
23309371c9d4SSatish Balay PetscErrorCode TSGetAuxSolution(TS ts, Vec *v) {
23314cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
23324cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2333dbbe0bcdSBarry Smith   if (ts->ops->getauxsolution) PetscUseTypeMethod(ts, getauxsolution, v);
23341e66621cSBarry Smith   else PetscCall(VecZeroEntries(*v));
23354cdd57e5SDebojyoti Ghosh   PetscFunctionReturn(0);
23364cdd57e5SDebojyoti Ghosh }
23374cdd57e5SDebojyoti Ghosh 
23384cdd57e5SDebojyoti Ghosh /*@
23394cdd57e5SDebojyoti Ghosh    TSGetTimeError - Returns the estimated error vector, if the chosen
23404cdd57e5SDebojyoti Ghosh    TSType has an error estimation functionality.
23414cdd57e5SDebojyoti Ghosh 
23424cdd57e5SDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
23434cdd57e5SDebojyoti Ghosh 
23449657682dSDebojyoti Ghosh    Note: MUST call after TSSetUp()
23459657682dSDebojyoti Ghosh 
23464cdd57e5SDebojyoti Ghosh    Parameters :
2347a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2348657c1e31SEmil Constantinescu .  n - current estimate (n=0) or previous one (n=-1)
2349a2b725a8SWilliam Gropp -  v - the vector containing the error (same size as the solution).
23504cdd57e5SDebojyoti Ghosh 
23514cdd57e5SDebojyoti Ghosh    Level: intermediate
23524cdd57e5SDebojyoti Ghosh 
2353db781477SPatrick Sanan .seealso: `TSGetSolution()`, `TSSetTimeError()`
23544cdd57e5SDebojyoti Ghosh 
23554cdd57e5SDebojyoti Ghosh @*/
23569371c9d4SSatish Balay PetscErrorCode TSGetTimeError(TS ts, PetscInt n, Vec *v) {
23574cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
23584cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2359dbbe0bcdSBarry Smith   if (ts->ops->gettimeerror) PetscUseTypeMethod(ts, gettimeerror, n, v);
23601e66621cSBarry Smith   else PetscCall(VecZeroEntries(*v));
23614cdd57e5SDebojyoti Ghosh   PetscFunctionReturn(0);
23624cdd57e5SDebojyoti Ghosh }
23634cdd57e5SDebojyoti Ghosh 
236457df6a1bSDebojyoti Ghosh /*@
236557df6a1bSDebojyoti Ghosh    TSSetTimeError - Sets the estimated error vector, if the chosen
236657df6a1bSDebojyoti Ghosh    TSType has an error estimation functionality. This can be used
236757df6a1bSDebojyoti Ghosh    to restart such a time integrator with a given error vector.
236857df6a1bSDebojyoti Ghosh 
236957df6a1bSDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
237057df6a1bSDebojyoti Ghosh 
237157df6a1bSDebojyoti Ghosh    Parameters :
2372a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2373a2b725a8SWilliam Gropp -  v - the vector containing the error (same size as the solution).
237457df6a1bSDebojyoti Ghosh 
237557df6a1bSDebojyoti Ghosh    Level: intermediate
237657df6a1bSDebojyoti Ghosh 
2377db781477SPatrick Sanan .seealso: `TSSetSolution()`, `TSGetTimeError)`
237857df6a1bSDebojyoti Ghosh 
237957df6a1bSDebojyoti Ghosh @*/
23809371c9d4SSatish Balay PetscErrorCode TSSetTimeError(TS ts, Vec v) {
238157df6a1bSDebojyoti Ghosh   PetscFunctionBegin;
238257df6a1bSDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
23833c633725SBarry Smith   PetscCheck(ts->setupcalled, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetUp() first");
2384dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, settimeerror, v);
238557df6a1bSDebojyoti Ghosh   PetscFunctionReturn(0);
238657df6a1bSDebojyoti Ghosh }
238757df6a1bSDebojyoti Ghosh 
2388bdad233fSMatthew Knepley /* ----- Routines to initialize and destroy a timestepper ---- */
2389d8e5e3e6SSatish Balay /*@
2390bdad233fSMatthew Knepley   TSSetProblemType - Sets the type of problem to be solved.
2391d763cef2SBarry Smith 
2392bdad233fSMatthew Knepley   Not collective
2393d763cef2SBarry Smith 
2394bdad233fSMatthew Knepley   Input Parameters:
2395bdad233fSMatthew Knepley + ts   - The TS
2396bdad233fSMatthew Knepley - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2397d763cef2SBarry Smith .vb
23980910c330SBarry Smith          U_t - A U = 0      (linear)
23990910c330SBarry Smith          U_t - A(t) U = 0   (linear)
24000910c330SBarry Smith          F(t,U,U_t) = 0     (nonlinear)
2401d763cef2SBarry Smith .ve
2402d763cef2SBarry Smith 
2403d763cef2SBarry Smith    Level: beginner
2404d763cef2SBarry Smith 
2405db781477SPatrick Sanan .seealso: `TSSetUp()`, `TSProblemType`, `TS`
2406d763cef2SBarry Smith @*/
24079371c9d4SSatish Balay PetscErrorCode TSSetProblemType(TS ts, TSProblemType type) {
2408d763cef2SBarry Smith   PetscFunctionBegin;
24090700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2410bdad233fSMatthew Knepley   ts->problem_type = type;
24119e2a6581SJed Brown   if (type == TS_LINEAR) {
24129e2a6581SJed Brown     SNES snes;
24139566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
24149566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes, SNESKSPONLY));
24159e2a6581SJed Brown   }
2416d763cef2SBarry Smith   PetscFunctionReturn(0);
2417d763cef2SBarry Smith }
2418d763cef2SBarry Smith 
2419bdad233fSMatthew Knepley /*@C
2420bdad233fSMatthew Knepley   TSGetProblemType - Gets the type of problem to be solved.
2421bdad233fSMatthew Knepley 
2422bdad233fSMatthew Knepley   Not collective
2423bdad233fSMatthew Knepley 
2424bdad233fSMatthew Knepley   Input Parameter:
2425bdad233fSMatthew Knepley . ts   - The TS
2426bdad233fSMatthew Knepley 
2427bdad233fSMatthew Knepley   Output Parameter:
2428bdad233fSMatthew Knepley . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2429bdad233fSMatthew Knepley .vb
2430089b2837SJed Brown          M U_t = A U
2431089b2837SJed Brown          M(t) U_t = A(t) U
2432b5abc632SBarry Smith          F(t,U,U_t)
2433bdad233fSMatthew Knepley .ve
2434bdad233fSMatthew Knepley 
2435bdad233fSMatthew Knepley    Level: beginner
2436bdad233fSMatthew Knepley 
2437db781477SPatrick Sanan .seealso: `TSSetUp()`, `TSProblemType`, `TS`
2438bdad233fSMatthew Knepley @*/
24399371c9d4SSatish Balay PetscErrorCode TSGetProblemType(TS ts, TSProblemType *type) {
2440bdad233fSMatthew Knepley   PetscFunctionBegin;
24410700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
24424482741eSBarry Smith   PetscValidIntPointer(type, 2);
2443bdad233fSMatthew Knepley   *type = ts->problem_type;
2444bdad233fSMatthew Knepley   PetscFunctionReturn(0);
2445bdad233fSMatthew Knepley }
2446d763cef2SBarry Smith 
2447303a5415SBarry Smith /*
2448303a5415SBarry 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()
2449303a5415SBarry Smith */
24509371c9d4SSatish Balay static PetscErrorCode TSSetExactFinalTimeDefault(TS ts) {
2451303a5415SBarry Smith   PetscBool isnone;
2452303a5415SBarry Smith 
2453303a5415SBarry Smith   PetscFunctionBegin;
24549566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
24559566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
2456303a5415SBarry Smith 
24579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ts->adapt, TSADAPTNONE, &isnone));
24581e66621cSBarry Smith   if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP;
24591e66621cSBarry Smith   else if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) ts->exact_final_time = TS_EXACTFINALTIME_INTERPOLATE;
2460303a5415SBarry Smith   PetscFunctionReturn(0);
2461303a5415SBarry Smith }
2462303a5415SBarry Smith 
2463d763cef2SBarry Smith /*@
2464303a5415SBarry Smith    TSSetUp - Sets up the internal data structures for the later use of a timestepper.
2465d763cef2SBarry Smith 
2466d763cef2SBarry Smith    Collective on TS
2467d763cef2SBarry Smith 
2468d763cef2SBarry Smith    Input Parameter:
2469d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2470d763cef2SBarry Smith 
2471d763cef2SBarry Smith    Notes:
2472d763cef2SBarry Smith    For basic use of the TS solvers the user need not explicitly call
2473d763cef2SBarry Smith    TSSetUp(), since these actions will automatically occur during
2474141bd67dSStefano Zampini    the call to TSStep() or TSSolve().  However, if one wishes to control this
2475d763cef2SBarry Smith    phase separately, TSSetUp() should be called after TSCreate()
2476141bd67dSStefano Zampini    and optional routines of the form TSSetXXX(), but before TSStep() and TSSolve().
2477d763cef2SBarry Smith 
2478d763cef2SBarry Smith    Level: advanced
2479d763cef2SBarry Smith 
2480db781477SPatrick Sanan .seealso: `TSCreate()`, `TSStep()`, `TSDestroy()`, `TSSolve()`
2481d763cef2SBarry Smith @*/
24829371c9d4SSatish Balay PetscErrorCode TSSetUp(TS ts) {
24836c6b9e74SPeter Brune   DM dm;
24846c6b9e74SPeter Brune   PetscErrorCode (*func)(SNES, Vec, Vec, void *);
2485d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *);
2486cd11d68dSLisandro Dalcin   TSIFunction   ifun;
24876c6b9e74SPeter Brune   TSIJacobian   ijac;
2488efe9872eSLisandro Dalcin   TSI2Jacobian  i2jac;
24896c6b9e74SPeter Brune   TSRHSJacobian rhsjac;
2490d763cef2SBarry Smith 
2491d763cef2SBarry Smith   PetscFunctionBegin;
24920700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2493277b19d0SLisandro Dalcin   if (ts->setupcalled) PetscFunctionReturn(0);
2494277b19d0SLisandro Dalcin 
24957adad957SLisandro Dalcin   if (!((PetscObject)ts)->type_name) {
24969566063dSJacob Faibussowitsch     PetscCall(TSGetIFunction(ts, NULL, &ifun, NULL));
24979566063dSJacob Faibussowitsch     PetscCall(TSSetType(ts, ifun ? TSBEULER : TSEULER));
2498d763cef2SBarry Smith   }
2499277b19d0SLisandro Dalcin 
25001a638600SStefano Zampini   if (!ts->vec_sol) {
25011e66621cSBarry Smith     PetscCheck(ts->dm, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call TSSetSolution() first");
25029566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(ts->dm, &ts->vec_sol));
25031a638600SStefano Zampini   }
2504277b19d0SLisandro Dalcin 
25054a658b32SHong Zhang   if (ts->tspan) {
25061e66621cSBarry Smith     if (!ts->tspan->vecs_sol) PetscCall(VecDuplicateVecs(ts->vec_sol, ts->tspan->num_span_times, &ts->tspan->vecs_sol));
25074a658b32SHong Zhang   }
2508298bade4SHong Zhang   if (!ts->Jacp && ts->Jacprhs) { /* IJacobianP shares the same matrix with RHSJacobianP if only RHSJacobianP is provided */
25099566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)ts->Jacprhs));
2510298bade4SHong Zhang     ts->Jacp = ts->Jacprhs;
2511298bade4SHong Zhang   }
2512298bade4SHong Zhang 
2513cd4cee2dSHong Zhang   if (ts->quadraturets) {
25149566063dSJacob Faibussowitsch     PetscCall(TSSetUp(ts->quadraturets));
25159566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
25169566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->quadraturets->vec_sol, &ts->vec_costintegrand));
2517cd4cee2dSHong Zhang   }
2518cd4cee2dSHong Zhang 
25199566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, NULL, NULL, &rhsjac, NULL));
2520f23ba4b3SHong Zhang   if (rhsjac == TSComputeRHSJacobianConstant) {
2521e1244c69SJed Brown     Mat  Amat, Pmat;
2522e1244c69SJed Brown     SNES snes;
25239566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
25249566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, &Amat, &Pmat, NULL, NULL));
2525e1244c69SJed Brown     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2526e1244c69SJed Brown      * have displaced the RHS matrix */
2527971015bcSStefano Zampini     if (Amat && Amat == ts->Arhs) {
2528abc0d4abSBarry 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 */
25299566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Arhs, MAT_COPY_VALUES, &Amat));
25309566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes, Amat, NULL, NULL, NULL));
25319566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Amat));
2532e1244c69SJed Brown     }
2533971015bcSStefano Zampini     if (Pmat && Pmat == ts->Brhs) {
25349566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Brhs, MAT_COPY_VALUES, &Pmat));
25359566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes, NULL, Pmat, NULL, NULL));
25369566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Pmat));
2537e1244c69SJed Brown     }
2538e1244c69SJed Brown   }
25392ffb9264SLisandro Dalcin 
25409566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts, &ts->adapt));
25419566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt, ts->default_adapt_type));
25422ffb9264SLisandro Dalcin 
2543dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, setup);
2544277b19d0SLisandro Dalcin 
25459566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
25462ffb9264SLisandro Dalcin 
2547a6772fa2SLisandro Dalcin   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
25486c6b9e74SPeter Brune      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
25496c6b9e74SPeter Brune    */
25509566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
25519566063dSJacob Faibussowitsch   PetscCall(DMSNESGetFunction(dm, &func, NULL));
25521e66621cSBarry Smith   if (!func) PetscCall(DMSNESSetFunction(dm, SNESTSFormFunction, ts));
25531e66621cSBarry Smith 
2554a6772fa2SLisandro 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.
25556c6b9e74SPeter Brune      Otherwise, the SNES will use coloring internally to form the Jacobian.
25566c6b9e74SPeter Brune    */
25579566063dSJacob Faibussowitsch   PetscCall(DMSNESGetJacobian(dm, &jac, NULL));
25589566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, &ijac, NULL));
25599566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm, &i2jac, NULL));
25609566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, &rhsjac, NULL));
25611e66621cSBarry Smith   if (!jac && (ijac || i2jac || rhsjac)) PetscCall(DMSNESSetJacobian(dm, SNESTSFormJacobian, ts));
2562c0517034SDebojyoti Ghosh 
2563c0517034SDebojyoti Ghosh   /* if time integration scheme has a starting method, call it */
2564dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, startingmethod);
2565c0517034SDebojyoti Ghosh 
2566277b19d0SLisandro Dalcin   ts->setupcalled = PETSC_TRUE;
2567277b19d0SLisandro Dalcin   PetscFunctionReturn(0);
2568277b19d0SLisandro Dalcin }
2569277b19d0SLisandro Dalcin 
2570f6a906c0SBarry Smith /*@
2571277b19d0SLisandro Dalcin    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
2572277b19d0SLisandro Dalcin 
2573277b19d0SLisandro Dalcin    Collective on TS
2574277b19d0SLisandro Dalcin 
2575277b19d0SLisandro Dalcin    Input Parameter:
2576277b19d0SLisandro Dalcin .  ts - the TS context obtained from TSCreate()
2577277b19d0SLisandro Dalcin 
2578277b19d0SLisandro Dalcin    Level: beginner
2579277b19d0SLisandro Dalcin 
2580db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetup()`, `TSDestroy()`
2581277b19d0SLisandro Dalcin @*/
25829371c9d4SSatish Balay PetscErrorCode TSReset(TS ts) {
25831d06f6b3SHong Zhang   TS_RHSSplitLink ilink = ts->tsrhssplit, next;
2584277b19d0SLisandro Dalcin 
2585277b19d0SLisandro Dalcin   PetscFunctionBegin;
2586277b19d0SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2587b18ea86cSHong Zhang 
2588dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, reset);
25899566063dSJacob Faibussowitsch   if (ts->snes) PetscCall(SNESReset(ts->snes));
25909566063dSJacob Faibussowitsch   if (ts->adapt) PetscCall(TSAdaptReset(ts->adapt));
2591bbd56ea5SKarl Rupp 
25929566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Arhs));
25939566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Brhs));
25949566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->Frhs));
25959566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
25969566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
25979566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vatol));
25989566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vrtol));
25999566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(ts->nwork, &ts->work));
2600bbd56ea5SKarl Rupp 
26019566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacprhs));
26029566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacp));
26031baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardReset(ts));
2604cd4cee2dSHong Zhang   if (ts->quadraturets) {
26059566063dSJacob Faibussowitsch     PetscCall(TSReset(ts->quadraturets));
26069566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
2607cd4cee2dSHong Zhang   }
26081d06f6b3SHong Zhang   while (ilink) {
26091d06f6b3SHong Zhang     next = ilink->next;
26109566063dSJacob Faibussowitsch     PetscCall(TSDestroy(&ilink->ts));
26119566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink->splitname));
26129566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ilink->is));
26139566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink));
26141d06f6b3SHong Zhang     ilink = next;
261587f4e208SHong Zhang   }
26166bf673ebSJoe Pusztay   ts->tsrhssplit     = NULL;
2617545aaa6fSHong Zhang   ts->num_rhs_splits = 0;
26184a658b32SHong Zhang   if (ts->tspan) {
26194a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan->span_times));
26204a658b32SHong Zhang     PetscCall(VecDestroyVecs(ts->tspan->num_span_times, &ts->tspan->vecs_sol));
26214a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan));
26224a658b32SHong Zhang   }
2623277b19d0SLisandro Dalcin   ts->setupcalled = PETSC_FALSE;
2624d763cef2SBarry Smith   PetscFunctionReturn(0);
2625d763cef2SBarry Smith }
2626d763cef2SBarry Smith 
26271fb7b255SJunchao Zhang /*@C
2628d763cef2SBarry Smith    TSDestroy - Destroys the timestepper context that was created
2629d763cef2SBarry Smith    with TSCreate().
2630d763cef2SBarry Smith 
2631d763cef2SBarry Smith    Collective on TS
2632d763cef2SBarry Smith 
2633d763cef2SBarry Smith    Input Parameter:
2634d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2635d763cef2SBarry Smith 
2636d763cef2SBarry Smith    Level: beginner
2637d763cef2SBarry Smith 
2638db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetUp()`, `TSSolve()`
2639d763cef2SBarry Smith @*/
26409371c9d4SSatish Balay PetscErrorCode TSDestroy(TS *ts) {
2641d763cef2SBarry Smith   PetscFunctionBegin;
26426bf464f9SBarry Smith   if (!*ts) PetscFunctionReturn(0);
2643ecf68647SHong Zhang   PetscValidHeaderSpecific(*ts, TS_CLASSID, 1);
26449371c9d4SSatish Balay   if (--((PetscObject)(*ts))->refct > 0) {
26459371c9d4SSatish Balay     *ts = NULL;
26469371c9d4SSatish Balay     PetscFunctionReturn(0);
26479371c9d4SSatish Balay   }
2648d763cef2SBarry Smith 
26499566063dSJacob Faibussowitsch   PetscCall(TSReset(*ts));
26509566063dSJacob Faibussowitsch   PetscCall(TSAdjointReset(*ts));
26511e66621cSBarry Smith   if ((*ts)->forward_solve) PetscCall(TSForwardReset(*ts));
26521e66621cSBarry Smith 
2653e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
26549566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*ts));
2655dbbe0bcdSBarry Smith   PetscTryTypeMethod((*ts), destroy);
26566d4c513bSLisandro Dalcin 
26579566063dSJacob Faibussowitsch   PetscCall(TSTrajectoryDestroy(&(*ts)->trajectory));
2658bc952696SBarry Smith 
26599566063dSJacob Faibussowitsch   PetscCall(TSAdaptDestroy(&(*ts)->adapt));
26609566063dSJacob Faibussowitsch   PetscCall(TSEventDestroy(&(*ts)->event));
26616427ac75SLisandro Dalcin 
26629566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&(*ts)->snes));
26639566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&(*ts)->dm));
26649566063dSJacob Faibussowitsch   PetscCall(TSMonitorCancel((*ts)));
26659566063dSJacob Faibussowitsch   PetscCall(TSAdjointMonitorCancel((*ts)));
26666d4c513bSLisandro Dalcin 
26679566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&(*ts)->quadraturets));
26689566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ts));
2669d763cef2SBarry Smith   PetscFunctionReturn(0);
2670d763cef2SBarry Smith }
2671d763cef2SBarry Smith 
2672d8e5e3e6SSatish Balay /*@
2673d763cef2SBarry Smith    TSGetSNES - Returns the SNES (nonlinear solver) associated with
2674d763cef2SBarry Smith    a TS (timestepper) context. Valid only for nonlinear problems.
2675d763cef2SBarry Smith 
2676d763cef2SBarry Smith    Not Collective, but SNES is parallel if TS is parallel
2677d763cef2SBarry Smith 
2678d763cef2SBarry Smith    Input Parameter:
2679d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2680d763cef2SBarry Smith 
2681d763cef2SBarry Smith    Output Parameter:
2682d763cef2SBarry Smith .  snes - the nonlinear solver context
2683d763cef2SBarry Smith 
2684d763cef2SBarry Smith    Notes:
2685d763cef2SBarry Smith    The user can then directly manipulate the SNES context to set various
2686d763cef2SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
268794b7f48cSBarry Smith    KSP, KSP, and PC contexts as well.
2688d763cef2SBarry Smith 
2689d763cef2SBarry Smith    TSGetSNES() does not work for integrators that do not use SNES; in
26900298fd71SBarry Smith    this case TSGetSNES() returns NULL in snes.
2691d763cef2SBarry Smith 
2692d763cef2SBarry Smith    Level: beginner
2693d763cef2SBarry Smith 
2694d763cef2SBarry Smith @*/
26959371c9d4SSatish Balay PetscErrorCode TSGetSNES(TS ts, SNES *snes) {
2696d763cef2SBarry Smith   PetscFunctionBegin;
26970700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
26984482741eSBarry Smith   PetscValidPointer(snes, 2);
2699d372ba47SLisandro Dalcin   if (!ts->snes) {
27009566063dSJacob Faibussowitsch     PetscCall(SNESCreate(PetscObjectComm((PetscObject)ts), &ts->snes));
27019566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)ts->snes, ((PetscObject)ts)->options));
27029566063dSJacob Faibussowitsch     PetscCall(SNESSetFunction(ts->snes, NULL, SNESTSFormFunction, ts));
27039566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)ts, (PetscObject)ts->snes));
27049566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->snes, (PetscObject)ts, 1));
27059566063dSJacob Faibussowitsch     if (ts->dm) PetscCall(SNESSetDM(ts->snes, ts->dm));
27061e66621cSBarry Smith     if (ts->problem_type == TS_LINEAR) PetscCall(SNESSetType(ts->snes, SNESKSPONLY));
2707d372ba47SLisandro Dalcin   }
2708d763cef2SBarry Smith   *snes = ts->snes;
2709d763cef2SBarry Smith   PetscFunctionReturn(0);
2710d763cef2SBarry Smith }
2711d763cef2SBarry Smith 
2712deb2cd25SJed Brown /*@
2713deb2cd25SJed Brown    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
2714deb2cd25SJed Brown 
2715deb2cd25SJed Brown    Collective
2716deb2cd25SJed Brown 
2717d8d19677SJose E. Roman    Input Parameters:
2718deb2cd25SJed Brown +  ts - the TS context obtained from TSCreate()
2719deb2cd25SJed Brown -  snes - the nonlinear solver context
2720deb2cd25SJed Brown 
2721deb2cd25SJed Brown    Notes:
2722deb2cd25SJed Brown    Most users should have the TS created by calling TSGetSNES()
2723deb2cd25SJed Brown 
2724deb2cd25SJed Brown    Level: developer
2725deb2cd25SJed Brown 
2726deb2cd25SJed Brown @*/
27279371c9d4SSatish Balay PetscErrorCode TSSetSNES(TS ts, SNES snes) {
2728d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES, Vec, Mat, Mat, void *);
2729deb2cd25SJed Brown 
2730deb2cd25SJed Brown   PetscFunctionBegin;
2731deb2cd25SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2732deb2cd25SJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 2);
27339566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)snes));
27349566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&ts->snes));
2735bbd56ea5SKarl Rupp 
2736deb2cd25SJed Brown   ts->snes = snes;
2737bbd56ea5SKarl Rupp 
27389566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(ts->snes, NULL, SNESTSFormFunction, ts));
27399566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(ts->snes, NULL, NULL, &func, NULL));
27401e66621cSBarry Smith   if (func == SNESTSFormJacobian) PetscCall(SNESSetJacobian(ts->snes, NULL, NULL, SNESTSFormJacobian, ts));
2741deb2cd25SJed Brown   PetscFunctionReturn(0);
2742deb2cd25SJed Brown }
2743deb2cd25SJed Brown 
2744d8e5e3e6SSatish Balay /*@
274594b7f48cSBarry Smith    TSGetKSP - Returns the KSP (linear solver) associated with
2746d763cef2SBarry Smith    a TS (timestepper) context.
2747d763cef2SBarry Smith 
274894b7f48cSBarry Smith    Not Collective, but KSP is parallel if TS is parallel
2749d763cef2SBarry Smith 
2750d763cef2SBarry Smith    Input Parameter:
2751d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2752d763cef2SBarry Smith 
2753d763cef2SBarry Smith    Output Parameter:
275494b7f48cSBarry Smith .  ksp - the nonlinear solver context
2755d763cef2SBarry Smith 
2756d763cef2SBarry Smith    Notes:
275794b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
2758d763cef2SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
2759d763cef2SBarry Smith    KSP and PC contexts as well.
2760d763cef2SBarry Smith 
276194b7f48cSBarry Smith    TSGetKSP() does not work for integrators that do not use KSP;
27620298fd71SBarry Smith    in this case TSGetKSP() returns NULL in ksp.
2763d763cef2SBarry Smith 
2764d763cef2SBarry Smith    Level: beginner
2765d763cef2SBarry Smith 
2766d763cef2SBarry Smith @*/
27679371c9d4SSatish Balay PetscErrorCode TSGetKSP(TS ts, KSP *ksp) {
2768089b2837SJed Brown   SNES snes;
2769d372ba47SLisandro Dalcin 
2770d763cef2SBarry Smith   PetscFunctionBegin;
27710700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
27724482741eSBarry Smith   PetscValidPointer(ksp, 2);
27733c633725SBarry Smith   PetscCheck(((PetscObject)ts)->type_name, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "KSP is not created yet. Call TSSetType() first");
27743c633725SBarry Smith   PetscCheck(ts->problem_type == TS_LINEAR, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Linear only; use TSGetSNES()");
27759566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
27769566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, ksp));
2777d763cef2SBarry Smith   PetscFunctionReturn(0);
2778d763cef2SBarry Smith }
2779d763cef2SBarry Smith 
2780d763cef2SBarry Smith /* ----------- Routines to set solver parameters ---------- */
2781d763cef2SBarry Smith 
2782adb62b0dSMatthew Knepley /*@
2783618ce8baSLisandro Dalcin    TSSetMaxSteps - Sets the maximum number of steps to use.
2784618ce8baSLisandro Dalcin 
2785618ce8baSLisandro Dalcin    Logically Collective on TS
2786618ce8baSLisandro Dalcin 
2787618ce8baSLisandro Dalcin    Input Parameters:
2788618ce8baSLisandro Dalcin +  ts - the TS context obtained from TSCreate()
2789618ce8baSLisandro Dalcin -  maxsteps - maximum number of steps to use
2790618ce8baSLisandro Dalcin 
2791618ce8baSLisandro Dalcin    Options Database Keys:
2792618ce8baSLisandro Dalcin .  -ts_max_steps <maxsteps> - Sets maxsteps
2793618ce8baSLisandro Dalcin 
2794618ce8baSLisandro Dalcin    Notes:
2795618ce8baSLisandro Dalcin    The default maximum number of steps is 5000
2796618ce8baSLisandro Dalcin 
2797618ce8baSLisandro Dalcin    Level: intermediate
2798618ce8baSLisandro Dalcin 
2799db781477SPatrick Sanan .seealso: `TSGetMaxSteps()`, `TSSetMaxTime()`, `TSSetExactFinalTime()`
2800618ce8baSLisandro Dalcin @*/
28019371c9d4SSatish Balay PetscErrorCode TSSetMaxSteps(TS ts, PetscInt maxsteps) {
2802618ce8baSLisandro Dalcin   PetscFunctionBegin;
2803618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2804618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts, maxsteps, 2);
28053c633725SBarry Smith   PetscCheck(maxsteps >= 0, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of steps must be non-negative");
2806618ce8baSLisandro Dalcin   ts->max_steps = maxsteps;
2807618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
2808618ce8baSLisandro Dalcin }
2809618ce8baSLisandro Dalcin 
2810618ce8baSLisandro Dalcin /*@
2811618ce8baSLisandro Dalcin    TSGetMaxSteps - Gets the maximum number of steps to use.
2812618ce8baSLisandro Dalcin 
2813618ce8baSLisandro Dalcin    Not Collective
2814618ce8baSLisandro Dalcin 
2815618ce8baSLisandro Dalcin    Input Parameters:
2816618ce8baSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
2817618ce8baSLisandro Dalcin 
2818618ce8baSLisandro Dalcin    Output Parameter:
2819618ce8baSLisandro Dalcin .  maxsteps - maximum number of steps to use
2820618ce8baSLisandro Dalcin 
2821618ce8baSLisandro Dalcin    Level: advanced
2822618ce8baSLisandro Dalcin 
2823db781477SPatrick Sanan .seealso: `TSSetMaxSteps()`, `TSGetMaxTime()`, `TSSetMaxTime()`
2824618ce8baSLisandro Dalcin @*/
28259371c9d4SSatish Balay PetscErrorCode TSGetMaxSteps(TS ts, PetscInt *maxsteps) {
2826618ce8baSLisandro Dalcin   PetscFunctionBegin;
2827618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2828618ce8baSLisandro Dalcin   PetscValidIntPointer(maxsteps, 2);
2829618ce8baSLisandro Dalcin   *maxsteps = ts->max_steps;
2830618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
2831618ce8baSLisandro Dalcin }
2832618ce8baSLisandro Dalcin 
2833618ce8baSLisandro Dalcin /*@
2834618ce8baSLisandro Dalcin    TSSetMaxTime - Sets the maximum (or final) time for timestepping.
2835618ce8baSLisandro Dalcin 
2836618ce8baSLisandro Dalcin    Logically Collective on TS
2837618ce8baSLisandro Dalcin 
2838618ce8baSLisandro Dalcin    Input Parameters:
2839618ce8baSLisandro Dalcin +  ts - the TS context obtained from TSCreate()
2840618ce8baSLisandro Dalcin -  maxtime - final time to step to
2841618ce8baSLisandro Dalcin 
2842618ce8baSLisandro Dalcin    Options Database Keys:
2843ef85077eSLisandro Dalcin .  -ts_max_time <maxtime> - Sets maxtime
2844618ce8baSLisandro Dalcin 
2845618ce8baSLisandro Dalcin    Notes:
2846618ce8baSLisandro Dalcin    The default maximum time is 5.0
2847618ce8baSLisandro Dalcin 
2848618ce8baSLisandro Dalcin    Level: intermediate
2849618ce8baSLisandro Dalcin 
2850db781477SPatrick Sanan .seealso: `TSGetMaxTime()`, `TSSetMaxSteps()`, `TSSetExactFinalTime()`
2851618ce8baSLisandro Dalcin @*/
28529371c9d4SSatish Balay PetscErrorCode TSSetMaxTime(TS ts, PetscReal maxtime) {
2853618ce8baSLisandro Dalcin   PetscFunctionBegin;
2854618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2855618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveReal(ts, maxtime, 2);
2856618ce8baSLisandro Dalcin   ts->max_time = maxtime;
2857618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
2858618ce8baSLisandro Dalcin }
2859618ce8baSLisandro Dalcin 
2860618ce8baSLisandro Dalcin /*@
2861618ce8baSLisandro Dalcin    TSGetMaxTime - Gets the maximum (or final) time for timestepping.
2862618ce8baSLisandro Dalcin 
2863618ce8baSLisandro Dalcin    Not Collective
2864618ce8baSLisandro Dalcin 
2865618ce8baSLisandro Dalcin    Input Parameters:
2866618ce8baSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
2867618ce8baSLisandro Dalcin 
2868618ce8baSLisandro Dalcin    Output Parameter:
2869618ce8baSLisandro Dalcin .  maxtime - final time to step to
2870618ce8baSLisandro Dalcin 
2871618ce8baSLisandro Dalcin    Level: advanced
2872618ce8baSLisandro Dalcin 
2873db781477SPatrick Sanan .seealso: `TSSetMaxTime()`, `TSGetMaxSteps()`, `TSSetMaxSteps()`
2874618ce8baSLisandro Dalcin @*/
28759371c9d4SSatish Balay PetscErrorCode TSGetMaxTime(TS ts, PetscReal *maxtime) {
2876618ce8baSLisandro Dalcin   PetscFunctionBegin;
2877618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2878618ce8baSLisandro Dalcin   PetscValidRealPointer(maxtime, 2);
2879618ce8baSLisandro Dalcin   *maxtime = ts->max_time;
2880618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
2881618ce8baSLisandro Dalcin }
2882618ce8baSLisandro Dalcin 
2883618ce8baSLisandro Dalcin /*@
2884aaa6c58dSLisandro Dalcin    TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep().
2885edc382c3SSatish Balay 
2886edc382c3SSatish Balay    Level: deprecated
2887edc382c3SSatish Balay 
2888aaa6c58dSLisandro Dalcin @*/
28899371c9d4SSatish Balay PetscErrorCode TSSetInitialTimeStep(TS ts, PetscReal initial_time, PetscReal time_step) {
2890aaa6c58dSLisandro Dalcin   PetscFunctionBegin;
2891aaa6c58dSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
28929566063dSJacob Faibussowitsch   PetscCall(TSSetTime(ts, initial_time));
28939566063dSJacob Faibussowitsch   PetscCall(TSSetTimeStep(ts, time_step));
2894aaa6c58dSLisandro Dalcin   PetscFunctionReturn(0);
2895aaa6c58dSLisandro Dalcin }
2896aaa6c58dSLisandro Dalcin 
2897aaa6c58dSLisandro Dalcin /*@
289819eac22cSLisandro Dalcin    TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime().
2899edc382c3SSatish Balay 
2900edc382c3SSatish Balay    Level: deprecated
2901edc382c3SSatish Balay 
2902adb62b0dSMatthew Knepley @*/
29039371c9d4SSatish Balay PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime) {
2904adb62b0dSMatthew Knepley   PetscFunctionBegin;
29050700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2906abc0a331SBarry Smith   if (maxsteps) {
29074482741eSBarry Smith     PetscValidIntPointer(maxsteps, 2);
2908adb62b0dSMatthew Knepley     *maxsteps = ts->max_steps;
2909adb62b0dSMatthew Knepley   }
2910abc0a331SBarry Smith   if (maxtime) {
2911064a246eSJacob Faibussowitsch     PetscValidRealPointer(maxtime, 3);
2912adb62b0dSMatthew Knepley     *maxtime = ts->max_time;
2913adb62b0dSMatthew Knepley   }
2914adb62b0dSMatthew Knepley   PetscFunctionReturn(0);
2915adb62b0dSMatthew Knepley }
2916adb62b0dSMatthew Knepley 
2917d763cef2SBarry Smith /*@
291819eac22cSLisandro Dalcin    TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime().
2919edc382c3SSatish Balay 
2920edc382c3SSatish Balay    Level: deprecated
2921edc382c3SSatish Balay 
2922d763cef2SBarry Smith @*/
29239371c9d4SSatish Balay PetscErrorCode TSSetDuration(TS ts, PetscInt maxsteps, PetscReal maxtime) {
2924d763cef2SBarry Smith   PetscFunctionBegin;
29250700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
2926c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(ts, maxsteps, 2);
2927064a246eSJacob Faibussowitsch   PetscValidLogicalCollectiveReal(ts, maxtime, 3);
292839b7ec4bSSean Farley   if (maxsteps >= 0) ts->max_steps = maxsteps;
292939b7ec4bSSean Farley   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
2930d763cef2SBarry Smith   PetscFunctionReturn(0);
2931d763cef2SBarry Smith }
2932d763cef2SBarry Smith 
2933d763cef2SBarry Smith /*@
29345c5f5948SLisandro Dalcin    TSGetTimeStepNumber - Deprecated, use TSGetStepNumber().
2935edc382c3SSatish Balay 
2936edc382c3SSatish Balay    Level: deprecated
2937edc382c3SSatish Balay 
29385c5f5948SLisandro Dalcin @*/
29399371c9d4SSatish Balay PetscErrorCode TSGetTimeStepNumber(TS ts, PetscInt *steps) {
29409371c9d4SSatish Balay   return TSGetStepNumber(ts, steps);
29419371c9d4SSatish Balay }
29425c5f5948SLisandro Dalcin 
294319eac22cSLisandro Dalcin /*@
29444f4e0956SLisandro Dalcin    TSGetTotalSteps - Deprecated, use TSGetStepNumber().
2945edc382c3SSatish Balay 
2946edc382c3SSatish Balay    Level: deprecated
2947edc382c3SSatish Balay 
29484f4e0956SLisandro Dalcin @*/
29499371c9d4SSatish Balay PetscErrorCode TSGetTotalSteps(TS ts, PetscInt *steps) {
29509371c9d4SSatish Balay   return TSGetStepNumber(ts, steps);
29519371c9d4SSatish Balay }
29524f4e0956SLisandro Dalcin 
29534f4e0956SLisandro Dalcin /*@
2954d763cef2SBarry Smith    TSSetSolution - Sets the initial solution vector
2955d763cef2SBarry Smith    for use by the TS routines.
2956d763cef2SBarry Smith 
2957d083f849SBarry Smith    Logically Collective on TS
2958d763cef2SBarry Smith 
2959d763cef2SBarry Smith    Input Parameters:
2960d763cef2SBarry Smith +  ts - the TS context obtained from TSCreate()
29610910c330SBarry Smith -  u - the solution vector
2962d763cef2SBarry Smith 
2963d763cef2SBarry Smith    Level: beginner
2964d763cef2SBarry Smith 
2965db781477SPatrick Sanan .seealso: `TSSetSolutionFunction()`, `TSGetSolution()`, `TSCreate()`
2966d763cef2SBarry Smith @*/
29679371c9d4SSatish Balay PetscErrorCode TSSetSolution(TS ts, Vec u) {
2968496e6a7aSJed Brown   DM dm;
29698737fe31SLisandro Dalcin 
2970d763cef2SBarry Smith   PetscFunctionBegin;
29710700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
29720910c330SBarry Smith   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
29739566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)u));
29749566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
29750910c330SBarry Smith   ts->vec_sol = u;
2976bbd56ea5SKarl Rupp 
29779566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
29789566063dSJacob Faibussowitsch   PetscCall(DMShellSetGlobalVector(dm, u));
2979d763cef2SBarry Smith   PetscFunctionReturn(0);
2980d763cef2SBarry Smith }
2981d763cef2SBarry Smith 
2982ac226902SBarry Smith /*@C
2983000e7ae3SMatthew Knepley   TSSetPreStep - Sets the general-purpose function
29843f2090d5SJed Brown   called once at the beginning of each time step.
2985000e7ae3SMatthew Knepley 
29863f9fe445SBarry Smith   Logically Collective on TS
2987000e7ae3SMatthew Knepley 
2988000e7ae3SMatthew Knepley   Input Parameters:
2989000e7ae3SMatthew Knepley + ts   - The TS context obtained from TSCreate()
2990000e7ae3SMatthew Knepley - func - The function
2991000e7ae3SMatthew Knepley 
2992000e7ae3SMatthew Knepley   Calling sequence of func:
299367b8a455SSatish Balay .vb
299467b8a455SSatish Balay   PetscErrorCode func (TS ts);
299567b8a455SSatish Balay .ve
2996000e7ae3SMatthew Knepley 
2997000e7ae3SMatthew Knepley   Level: intermediate
2998000e7ae3SMatthew Knepley 
2999db781477SPatrick Sanan .seealso: `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`, `TSStep()`, `TSRestartStep()`
3000000e7ae3SMatthew Knepley @*/
30019371c9d4SSatish Balay PetscErrorCode TSSetPreStep(TS ts, PetscErrorCode (*func)(TS)) {
3002000e7ae3SMatthew Knepley   PetscFunctionBegin;
30030700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3004ae60f76fSBarry Smith   ts->prestep = func;
3005000e7ae3SMatthew Knepley   PetscFunctionReturn(0);
3006000e7ae3SMatthew Knepley }
3007000e7ae3SMatthew Knepley 
300809ee8438SJed Brown /*@
30093f2090d5SJed Brown   TSPreStep - Runs the user-defined pre-step function.
30103f2090d5SJed Brown 
30113f2090d5SJed Brown   Collective on TS
30123f2090d5SJed Brown 
30133f2090d5SJed Brown   Input Parameters:
30143f2090d5SJed Brown . ts   - The TS context obtained from TSCreate()
30153f2090d5SJed Brown 
30163f2090d5SJed Brown   Notes:
30173f2090d5SJed Brown   TSPreStep() is typically used within time stepping implementations,
30183f2090d5SJed Brown   so most users would not generally call this routine themselves.
30193f2090d5SJed Brown 
30203f2090d5SJed Brown   Level: developer
30213f2090d5SJed Brown 
3022db781477SPatrick Sanan .seealso: `TSSetPreStep()`, `TSPreStage()`, `TSPostStage()`, `TSPostStep()`
30233f2090d5SJed Brown @*/
30249371c9d4SSatish Balay PetscErrorCode TSPreStep(TS ts) {
30253f2090d5SJed Brown   PetscFunctionBegin;
30260700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3027ae60f76fSBarry Smith   if (ts->prestep) {
30285efd42a4SStefano Zampini     Vec              U;
3029ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3030ef8d1ce0SJohann Rudi     PetscBool        sameObject;
30315efd42a4SStefano Zampini     PetscObjectState sprev, spost;
30325efd42a4SStefano Zampini 
30339566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
30349566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U, &idprev));
30359566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
303625e27a38SBarry Smith     PetscCallBack("TS callback preset", (*ts->prestep)(ts));
30379566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
30389566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U, idprev, &sameObject));
30399566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
30409566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
3041312ce896SJed Brown   }
30423f2090d5SJed Brown   PetscFunctionReturn(0);
30433f2090d5SJed Brown }
30443f2090d5SJed Brown 
3045b8123daeSJed Brown /*@C
3046b8123daeSJed Brown   TSSetPreStage - Sets the general-purpose function
3047b8123daeSJed Brown   called once at the beginning of each stage.
3048b8123daeSJed Brown 
3049b8123daeSJed Brown   Logically Collective on TS
3050b8123daeSJed Brown 
3051b8123daeSJed Brown   Input Parameters:
3052b8123daeSJed Brown + ts   - The TS context obtained from TSCreate()
3053b8123daeSJed Brown - func - The function
3054b8123daeSJed Brown 
3055b8123daeSJed Brown   Calling sequence of func:
305667b8a455SSatish Balay .vb
305767b8a455SSatish Balay   PetscErrorCode func(TS ts, PetscReal stagetime);
305867b8a455SSatish Balay .ve
3059b8123daeSJed Brown 
3060b8123daeSJed Brown   Level: intermediate
3061b8123daeSJed Brown 
3062b8123daeSJed Brown   Note:
3063b8123daeSJed Brown   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
306480275a0aSLisandro Dalcin   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
3065b8123daeSJed Brown   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3066b8123daeSJed Brown 
3067db781477SPatrick Sanan .seealso: `TSSetPostStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3068b8123daeSJed Brown @*/
30699371c9d4SSatish Balay PetscErrorCode TSSetPreStage(TS ts, PetscErrorCode (*func)(TS, PetscReal)) {
3070b8123daeSJed Brown   PetscFunctionBegin;
3071b8123daeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3072ae60f76fSBarry Smith   ts->prestage = func;
3073b8123daeSJed Brown   PetscFunctionReturn(0);
3074b8123daeSJed Brown }
3075b8123daeSJed Brown 
30769be3e283SDebojyoti Ghosh /*@C
30779be3e283SDebojyoti Ghosh   TSSetPostStage - Sets the general-purpose function
30789be3e283SDebojyoti Ghosh   called once at the end of each stage.
30799be3e283SDebojyoti Ghosh 
30809be3e283SDebojyoti Ghosh   Logically Collective on TS
30819be3e283SDebojyoti Ghosh 
30829be3e283SDebojyoti Ghosh   Input Parameters:
30839be3e283SDebojyoti Ghosh + ts   - The TS context obtained from TSCreate()
30849be3e283SDebojyoti Ghosh - func - The function
30859be3e283SDebojyoti Ghosh 
30869be3e283SDebojyoti Ghosh   Calling sequence of func:
308767b8a455SSatish Balay .vb
308867b8a455SSatish Balay   PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
308967b8a455SSatish Balay .ve
30909be3e283SDebojyoti Ghosh 
30919be3e283SDebojyoti Ghosh   Level: intermediate
30929be3e283SDebojyoti Ghosh 
30939be3e283SDebojyoti Ghosh   Note:
30949be3e283SDebojyoti Ghosh   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
309580275a0aSLisandro Dalcin   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
30969be3e283SDebojyoti Ghosh   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
30979be3e283SDebojyoti Ghosh 
3098db781477SPatrick Sanan .seealso: `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
30999be3e283SDebojyoti Ghosh @*/
31009371c9d4SSatish Balay PetscErrorCode TSSetPostStage(TS ts, PetscErrorCode (*func)(TS, PetscReal, PetscInt, Vec *)) {
31019be3e283SDebojyoti Ghosh   PetscFunctionBegin;
31029be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
31039be3e283SDebojyoti Ghosh   ts->poststage = func;
31049be3e283SDebojyoti Ghosh   PetscFunctionReturn(0);
31059be3e283SDebojyoti Ghosh }
31069be3e283SDebojyoti Ghosh 
3107c688d042SShri Abhyankar /*@C
3108c688d042SShri Abhyankar   TSSetPostEvaluate - Sets the general-purpose function
3109c688d042SShri Abhyankar   called once at the end of each step evaluation.
3110c688d042SShri Abhyankar 
3111c688d042SShri Abhyankar   Logically Collective on TS
3112c688d042SShri Abhyankar 
3113c688d042SShri Abhyankar   Input Parameters:
3114c688d042SShri Abhyankar + ts   - The TS context obtained from TSCreate()
3115c688d042SShri Abhyankar - func - The function
3116c688d042SShri Abhyankar 
3117c688d042SShri Abhyankar   Calling sequence of func:
311867b8a455SSatish Balay .vb
311967b8a455SSatish Balay   PetscErrorCode func(TS ts);
312067b8a455SSatish Balay .ve
3121c688d042SShri Abhyankar 
3122c688d042SShri Abhyankar   Level: intermediate
3123c688d042SShri Abhyankar 
3124c688d042SShri Abhyankar   Note:
31251785ff2aSShri Abhyankar   Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling
31261785ff2aSShri Abhyankar   thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep()
3127e7e94ed4SShri Abhyankar   may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step
3128e7e94ed4SShri Abhyankar   solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step
3129e7e94ed4SShri Abhyankar   with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime()
3130c688d042SShri Abhyankar 
3131db781477SPatrick Sanan .seealso: `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3132c688d042SShri Abhyankar @*/
31339371c9d4SSatish Balay PetscErrorCode TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS)) {
3134c688d042SShri Abhyankar   PetscFunctionBegin;
3135c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3136c688d042SShri Abhyankar   ts->postevaluate = func;
3137c688d042SShri Abhyankar   PetscFunctionReturn(0);
3138c688d042SShri Abhyankar }
3139c688d042SShri Abhyankar 
3140b8123daeSJed Brown /*@
3141b8123daeSJed Brown   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
3142b8123daeSJed Brown 
3143b8123daeSJed Brown   Collective on TS
3144b8123daeSJed Brown 
3145b8123daeSJed Brown   Input Parameters:
3146b8123daeSJed Brown . ts          - The TS context obtained from TSCreate()
31479be3e283SDebojyoti Ghosh   stagetime   - The absolute time of the current stage
3148b8123daeSJed Brown 
3149b8123daeSJed Brown   Notes:
3150b8123daeSJed Brown   TSPreStage() is typically used within time stepping implementations,
3151b8123daeSJed Brown   most users would not generally call this routine themselves.
3152b8123daeSJed Brown 
3153b8123daeSJed Brown   Level: developer
3154b8123daeSJed Brown 
3155db781477SPatrick Sanan .seealso: `TSPostStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3156b8123daeSJed Brown @*/
31579371c9d4SSatish Balay PetscErrorCode TSPreStage(TS ts, PetscReal stagetime) {
3158b8123daeSJed Brown   PetscFunctionBegin;
3159b8123daeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
31601e66621cSBarry Smith   if (ts->prestage) PetscCallBack("TS callback prestage", (*ts->prestage)(ts, stagetime));
3161b8123daeSJed Brown   PetscFunctionReturn(0);
3162b8123daeSJed Brown }
3163b8123daeSJed Brown 
31649be3e283SDebojyoti Ghosh /*@
31659be3e283SDebojyoti Ghosh   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
31669be3e283SDebojyoti Ghosh 
31679be3e283SDebojyoti Ghosh   Collective on TS
31689be3e283SDebojyoti Ghosh 
31699be3e283SDebojyoti Ghosh   Input Parameters:
31709be3e283SDebojyoti Ghosh . ts          - The TS context obtained from TSCreate()
31719be3e283SDebojyoti Ghosh   stagetime   - The absolute time of the current stage
31729be3e283SDebojyoti Ghosh   stageindex  - Stage number
31739be3e283SDebojyoti Ghosh   Y           - Array of vectors (of size = total number
31749be3e283SDebojyoti Ghosh                 of stages) with the stage solutions
31759be3e283SDebojyoti Ghosh 
31769be3e283SDebojyoti Ghosh   Notes:
31779be3e283SDebojyoti Ghosh   TSPostStage() is typically used within time stepping implementations,
31789be3e283SDebojyoti Ghosh   most users would not generally call this routine themselves.
31799be3e283SDebojyoti Ghosh 
31809be3e283SDebojyoti Ghosh   Level: developer
31819be3e283SDebojyoti Ghosh 
3182db781477SPatrick Sanan .seealso: `TSPreStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
31839be3e283SDebojyoti Ghosh @*/
31849371c9d4SSatish Balay PetscErrorCode TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y) {
31859be3e283SDebojyoti Ghosh   PetscFunctionBegin;
31869be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
31871e66621cSBarry Smith   if (ts->poststage) PetscCallBack("TS callback poststage", (*ts->poststage)(ts, stagetime, stageindex, Y));
31889be3e283SDebojyoti Ghosh   PetscFunctionReturn(0);
31899be3e283SDebojyoti Ghosh }
31909be3e283SDebojyoti Ghosh 
3191c688d042SShri Abhyankar /*@
3192c688d042SShri Abhyankar   TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate()
3193c688d042SShri Abhyankar 
3194c688d042SShri Abhyankar   Collective on TS
3195c688d042SShri Abhyankar 
3196c688d042SShri Abhyankar   Input Parameters:
3197c688d042SShri Abhyankar . ts          - The TS context obtained from TSCreate()
3198c688d042SShri Abhyankar 
3199c688d042SShri Abhyankar   Notes:
3200c688d042SShri Abhyankar   TSPostEvaluate() is typically used within time stepping implementations,
3201c688d042SShri Abhyankar   most users would not generally call this routine themselves.
3202c688d042SShri Abhyankar 
3203c688d042SShri Abhyankar   Level: developer
3204c688d042SShri Abhyankar 
3205db781477SPatrick Sanan .seealso: `TSSetPostEvaluate()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3206c688d042SShri Abhyankar @*/
32079371c9d4SSatish Balay PetscErrorCode TSPostEvaluate(TS ts) {
3208c688d042SShri Abhyankar   PetscFunctionBegin;
3209c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3210c688d042SShri Abhyankar   if (ts->postevaluate) {
3211dcb233daSLisandro Dalcin     Vec              U;
3212dcb233daSLisandro Dalcin     PetscObjectState sprev, spost;
3213dcb233daSLisandro Dalcin 
32149566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
32159566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
321625e27a38SBarry Smith     PetscCallBack("TS callback postevaluate", (*ts->postevaluate)(ts));
32179566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
32189566063dSJacob Faibussowitsch     if (sprev != spost) PetscCall(TSRestartStep(ts));
3219c688d042SShri Abhyankar   }
3220c688d042SShri Abhyankar   PetscFunctionReturn(0);
3221c688d042SShri Abhyankar }
3222c688d042SShri Abhyankar 
3223ac226902SBarry Smith /*@C
3224000e7ae3SMatthew Knepley   TSSetPostStep - Sets the general-purpose function
32253f2090d5SJed Brown   called once at the end of each time step.
3226000e7ae3SMatthew Knepley 
32273f9fe445SBarry Smith   Logically Collective on TS
3228000e7ae3SMatthew Knepley 
3229000e7ae3SMatthew Knepley   Input Parameters:
3230000e7ae3SMatthew Knepley + ts   - The TS context obtained from TSCreate()
3231000e7ae3SMatthew Knepley - func - The function
3232000e7ae3SMatthew Knepley 
3233000e7ae3SMatthew Knepley   Calling sequence of func:
3234b8123daeSJed Brown $ func (TS ts);
3235000e7ae3SMatthew Knepley 
32361785ff2aSShri Abhyankar   Notes:
32371785ff2aSShri Abhyankar   The function set by TSSetPostStep() is called after each successful step. The solution vector X
32381785ff2aSShri Abhyankar   obtained by TSGetSolution() may be different than that computed at the step end if the event handler
32391785ff2aSShri Abhyankar   locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead.
32401785ff2aSShri Abhyankar 
3241000e7ae3SMatthew Knepley   Level: intermediate
3242000e7ae3SMatthew Knepley 
3243db781477SPatrick Sanan .seealso: `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostEvaluate()`, `TSGetTimeStep()`, `TSGetStepNumber()`, `TSGetTime()`, `TSRestartStep()`
3244000e7ae3SMatthew Knepley @*/
32459371c9d4SSatish Balay PetscErrorCode TSSetPostStep(TS ts, PetscErrorCode (*func)(TS)) {
3246000e7ae3SMatthew Knepley   PetscFunctionBegin;
32470700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3248ae60f76fSBarry Smith   ts->poststep = func;
3249000e7ae3SMatthew Knepley   PetscFunctionReturn(0);
3250000e7ae3SMatthew Knepley }
3251000e7ae3SMatthew Knepley 
325209ee8438SJed Brown /*@
32533f2090d5SJed Brown   TSPostStep - Runs the user-defined post-step function.
32543f2090d5SJed Brown 
32553f2090d5SJed Brown   Collective on TS
32563f2090d5SJed Brown 
32573f2090d5SJed Brown   Input Parameters:
32583f2090d5SJed Brown . ts   - The TS context obtained from TSCreate()
32593f2090d5SJed Brown 
32603f2090d5SJed Brown   Notes:
32613f2090d5SJed Brown   TSPostStep() is typically used within time stepping implementations,
32623f2090d5SJed Brown   so most users would not generally call this routine themselves.
32633f2090d5SJed Brown 
32643f2090d5SJed Brown   Level: developer
32653f2090d5SJed Brown 
32663f2090d5SJed Brown @*/
32679371c9d4SSatish Balay PetscErrorCode TSPostStep(TS ts) {
32683f2090d5SJed Brown   PetscFunctionBegin;
32690700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3270ae60f76fSBarry Smith   if (ts->poststep) {
32715efd42a4SStefano Zampini     Vec              U;
3272ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3273ef8d1ce0SJohann Rudi     PetscBool        sameObject;
32745efd42a4SStefano Zampini     PetscObjectState sprev, spost;
32755efd42a4SStefano Zampini 
32769566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
32779566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U, &idprev));
32789566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &sprev));
327925e27a38SBarry Smith     PetscCallBack("TS callback poststep", (*ts->poststep)(ts));
32809566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts, &U));
32819566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U, idprev, &sameObject));
32829566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U, &spost));
32839566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
328472ac3e02SJed Brown   }
32853f2090d5SJed Brown   PetscFunctionReturn(0);
32863f2090d5SJed Brown }
32873f2090d5SJed Brown 
3288cd652676SJed Brown /*@
3289cd652676SJed Brown    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3290cd652676SJed Brown 
3291cd652676SJed Brown    Collective on TS
3292cd652676SJed Brown 
32934165533cSJose E. Roman    Input Parameters:
3294cd652676SJed Brown +  ts - time stepping context
3295cd652676SJed Brown -  t - time to interpolate to
3296cd652676SJed Brown 
32974165533cSJose E. Roman    Output Parameter:
32980910c330SBarry Smith .  U - state at given time
3299cd652676SJed Brown 
3300cd652676SJed Brown    Level: intermediate
3301cd652676SJed Brown 
3302cd652676SJed Brown    Developer Notes:
3303cd652676SJed Brown    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3304cd652676SJed Brown 
3305db781477SPatrick Sanan .seealso: `TSSetExactFinalTime()`, `TSSolve()`
3306cd652676SJed Brown @*/
33079371c9d4SSatish Balay PetscErrorCode TSInterpolate(TS ts, PetscReal t, Vec U) {
3308cd652676SJed Brown   PetscFunctionBegin;
3309cd652676SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3310b06615a5SLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
331163a3b9bcSJacob 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);
3312dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, interpolate, t, U);
3313cd652676SJed Brown   PetscFunctionReturn(0);
3314cd652676SJed Brown }
3315cd652676SJed Brown 
3316d763cef2SBarry Smith /*@
33176d9e5789SSean Farley    TSStep - Steps one time step
3318d763cef2SBarry Smith 
3319d763cef2SBarry Smith    Collective on TS
3320d763cef2SBarry Smith 
3321d763cef2SBarry Smith    Input Parameter:
3322d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
3323d763cef2SBarry Smith 
332427829d71SBarry Smith    Level: developer
3325d763cef2SBarry Smith 
3326b8123daeSJed Brown    Notes:
332727829d71SBarry Smith    The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine.
332827829d71SBarry Smith 
3329b8123daeSJed Brown    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
3330b8123daeSJed Brown    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3331b8123daeSJed Brown 
333219eac22cSLisandro Dalcin    This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the
333319eac22cSLisandro Dalcin    time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
333425cb2221SBarry Smith 
3335db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSInterpolate()`
3336d763cef2SBarry Smith @*/
33379371c9d4SSatish Balay PetscErrorCode TSStep(TS ts) {
3338fffbeea8SBarry Smith   static PetscBool cite = PETSC_FALSE;
3339be5899b3SLisandro Dalcin   PetscReal        ptime;
3340d763cef2SBarry Smith 
3341d763cef2SBarry Smith   PetscFunctionBegin;
33420700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3343d0609cedSBarry Smith   PetscCall(PetscCitationsRegister("@article{tspaper,\n"
3344fffbeea8SBarry Smith                                    "  title         = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3345f1d62c27SHong Zhang                                    "  author        = {Abhyankar, Shrirang and Brown, Jed and Constantinescu, Emil and Ghosh, Debojyoti and Smith, Barry F. and Zhang, Hong},\n"
3346f1d62c27SHong Zhang                                    "  journal       = {arXiv e-preprints},\n"
3347f1d62c27SHong Zhang                                    "  eprint        = {1806.01437},\n"
3348f1d62c27SHong Zhang                                    "  archivePrefix = {arXiv},\n"
33499371c9d4SSatish Balay                                    "  year          = {2018}\n}\n",
33509371c9d4SSatish Balay                                    &cite));
33519566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
33529566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory, ts));
3353d405a339SMatthew Knepley 
33543c633725SBarry 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>");
33553c633725SBarry 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()");
33563c633725SBarry 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");
3357a6772fa2SLisandro Dalcin 
3358be5899b3SLisandro Dalcin   if (!ts->steps) ts->ptime_prev = ts->ptime;
33599371c9d4SSatish Balay   ptime                   = ts->ptime;
33609371c9d4SSatish Balay   ts->ptime_prev_rollback = ts->ptime_prev;
33612808aa04SLisandro Dalcin   ts->reason              = TS_CONVERGED_ITERATING;
3362fc8dbba5SLisandro Dalcin 
33639566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_Step, ts, 0, 0, 0));
3364dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, step);
33659566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_Step, ts, 0, 0, 0));
3366fc8dbba5SLisandro Dalcin 
33679371c9d4SSatish 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)
33689371c9d4SSatish Balay     PetscCall(VecCopy(ts->vec_sol, ts->tspan->vecs_sol[ts->tspan->spanctr++]));
3369fc8dbba5SLisandro Dalcin   if (ts->reason >= 0) {
3370be5899b3SLisandro Dalcin     ts->ptime_prev = ptime;
33712808aa04SLisandro Dalcin     ts->steps++;
3372be5899b3SLisandro Dalcin     ts->steprollback = PETSC_FALSE;
337328d5b5d6SLisandro Dalcin     ts->steprestart  = PETSC_FALSE;
3374d2daff3dSHong Zhang   }
3375fc8dbba5SLisandro Dalcin   if (!ts->reason) {
337608c7845fSBarry Smith     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
337708c7845fSBarry Smith     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
337808c7845fSBarry Smith   }
3379fc8dbba5SLisandro Dalcin 
33803c633725SBarry Smith   PetscCheck(ts->reason >= 0 || !ts->errorifstepfailed || 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]);
33813c633725SBarry Smith   PetscCheck(ts->reason >= 0 || !ts->errorifstepfailed, PetscObjectComm((PetscObject)ts), PETSC_ERR_NOT_CONVERGED, "TSStep has failed due to %s", TSConvergedReasons[ts->reason]);
338208c7845fSBarry Smith   PetscFunctionReturn(0);
338308c7845fSBarry Smith }
338408c7845fSBarry Smith 
338508c7845fSBarry Smith /*@
33867cbde773SLisandro Dalcin    TSEvaluateWLTE - Evaluate the weighted local truncation error norm
33877cbde773SLisandro Dalcin    at the end of a time step with a given order of accuracy.
33887cbde773SLisandro Dalcin 
33897cbde773SLisandro Dalcin    Collective on TS
33907cbde773SLisandro Dalcin 
33914165533cSJose E. Roman    Input Parameters:
33927cbde773SLisandro Dalcin +  ts - time stepping context
339397bb3fdcSJose E. Roman -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
33947cbde773SLisandro Dalcin 
339597bb3fdcSJose E. Roman    Input/Output Parameter:
339697bb3fdcSJose E. Roman .  order - optional, desired order for the error evaluation or PETSC_DECIDE;
339797bb3fdcSJose E. Roman            on output, the actual order of the error evaluation
339897bb3fdcSJose E. Roman 
339997bb3fdcSJose E. Roman    Output Parameter:
340097bb3fdcSJose E. Roman .  wlte - the weighted local truncation error norm
34017cbde773SLisandro Dalcin 
34027cbde773SLisandro Dalcin    Level: advanced
34037cbde773SLisandro Dalcin 
34047cbde773SLisandro Dalcin    Notes:
34057cbde773SLisandro Dalcin    If the timestepper cannot evaluate the error in a particular step
34067cbde773SLisandro Dalcin    (eg. in the first step or restart steps after event handling),
34077cbde773SLisandro Dalcin    this routine returns wlte=-1.0 .
34087cbde773SLisandro Dalcin 
3409db781477SPatrick Sanan .seealso: `TSStep()`, `TSAdapt`, `TSErrorWeightedNorm()`
34107cbde773SLisandro Dalcin @*/
34119371c9d4SSatish Balay PetscErrorCode TSEvaluateWLTE(TS ts, NormType wnormtype, PetscInt *order, PetscReal *wlte) {
34127cbde773SLisandro Dalcin   PetscFunctionBegin;
34137cbde773SLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
34147cbde773SLisandro Dalcin   PetscValidType(ts, 1);
3415064a246eSJacob Faibussowitsch   PetscValidLogicalCollectiveEnum(ts, wnormtype, 2);
34167cbde773SLisandro Dalcin   if (order) PetscValidIntPointer(order, 3);
34177cbde773SLisandro Dalcin   if (order) PetscValidLogicalCollectiveInt(ts, *order, 3);
34187cbde773SLisandro Dalcin   PetscValidRealPointer(wlte, 4);
34193c633725SBarry Smith   PetscCheck(wnormtype == NORM_2 || wnormtype == NORM_INFINITY, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
3420dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, evaluatewlte, wnormtype, order, wlte);
34217cbde773SLisandro Dalcin   PetscFunctionReturn(0);
34227cbde773SLisandro Dalcin }
34237cbde773SLisandro Dalcin 
342405175c85SJed Brown /*@
342505175c85SJed Brown    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
342605175c85SJed Brown 
34271c3436cfSJed Brown    Collective on TS
342805175c85SJed Brown 
34294165533cSJose E. Roman    Input Parameters:
34301c3436cfSJed Brown +  ts - time stepping context
34311c3436cfSJed Brown .  order - desired order of accuracy
34320298fd71SBarry Smith -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
343305175c85SJed Brown 
34344165533cSJose E. Roman    Output Parameter:
34350910c330SBarry Smith .  U - state at the end of the current step
343605175c85SJed Brown 
343705175c85SJed Brown    Level: advanced
343805175c85SJed Brown 
3439108c343cSJed Brown    Notes:
3440108c343cSJed Brown    This function cannot be called until all stages have been evaluated.
3441108c343cSJed Brown    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.
3442108c343cSJed Brown 
3443db781477SPatrick Sanan .seealso: `TSStep()`, `TSAdapt`
344405175c85SJed Brown @*/
34459371c9d4SSatish Balay PetscErrorCode TSEvaluateStep(TS ts, PetscInt order, Vec U, PetscBool *done) {
344605175c85SJed Brown   PetscFunctionBegin;
344705175c85SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
344805175c85SJed Brown   PetscValidType(ts, 1);
34490910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
3450dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, evaluatestep, order, U, done);
345105175c85SJed Brown   PetscFunctionReturn(0);
345205175c85SJed Brown }
345305175c85SJed Brown 
3454aad739acSMatthew G. Knepley /*@C
34552e61be88SMatthew G. Knepley   TSGetComputeInitialCondition - Get the function used to automatically compute an initial condition for the timestepping.
3456aad739acSMatthew G. Knepley 
3457aad739acSMatthew G. Knepley   Not collective
3458aad739acSMatthew G. Knepley 
34594165533cSJose E. Roman   Input Parameter:
3460aad739acSMatthew G. Knepley . ts        - time stepping context
3461aad739acSMatthew G. Knepley 
34624165533cSJose E. Roman   Output Parameter:
34632e61be88SMatthew G. Knepley . initConditions - The function which computes an initial condition
3464aad739acSMatthew G. Knepley 
3465aad739acSMatthew G. Knepley    Level: advanced
3466aad739acSMatthew G. Knepley 
3467aad739acSMatthew G. Knepley    Notes:
3468aad739acSMatthew G. Knepley    The calling sequence for the function is
34692e61be88SMatthew G. Knepley $ initCondition(TS ts, Vec u)
3470aad739acSMatthew G. Knepley $ ts - The timestepping context
34712e61be88SMatthew G. Knepley $ u  - The input vector in which the initial condition is stored
3472aad739acSMatthew G. Knepley 
3473db781477SPatrick Sanan .seealso: `TSSetComputeInitialCondition()`, `TSComputeInitialCondition()`
3474aad739acSMatthew G. Knepley @*/
34759371c9d4SSatish Balay PetscErrorCode TSGetComputeInitialCondition(TS ts, PetscErrorCode (**initCondition)(TS, Vec)) {
3476aad739acSMatthew G. Knepley   PetscFunctionBegin;
3477aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
34782e61be88SMatthew G. Knepley   PetscValidPointer(initCondition, 2);
34792e61be88SMatthew G. Knepley   *initCondition = ts->ops->initcondition;
3480aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3481aad739acSMatthew G. Knepley }
3482aad739acSMatthew G. Knepley 
3483aad739acSMatthew G. Knepley /*@C
34842e61be88SMatthew G. Knepley   TSSetComputeInitialCondition - Set the function used to automatically compute an initial condition for the timestepping.
3485aad739acSMatthew G. Knepley 
3486aad739acSMatthew G. Knepley   Logically collective on ts
3487aad739acSMatthew G. Knepley 
34884165533cSJose E. Roman   Input Parameters:
3489aad739acSMatthew G. Knepley + ts        - time stepping context
34902e61be88SMatthew G. Knepley - initCondition - The function which computes an initial condition
3491aad739acSMatthew G. Knepley 
3492aad739acSMatthew G. Knepley   Level: advanced
3493aad739acSMatthew G. Knepley 
3494a96d6ef6SBarry Smith   Calling sequence for initCondition:
3495a96d6ef6SBarry Smith $ PetscErrorCode initCondition(TS ts, Vec u)
3496a96d6ef6SBarry Smith 
3497a96d6ef6SBarry Smith + ts - The timestepping context
3498a96d6ef6SBarry Smith - u  - The input vector in which the initial condition is to be stored
3499aad739acSMatthew G. Knepley 
3500db781477SPatrick Sanan .seealso: `TSGetComputeInitialCondition()`, `TSComputeInitialCondition()`
3501aad739acSMatthew G. Knepley @*/
35029371c9d4SSatish Balay PetscErrorCode TSSetComputeInitialCondition(TS ts, PetscErrorCode (*initCondition)(TS, Vec)) {
3503aad739acSMatthew G. Knepley   PetscFunctionBegin;
3504aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
35052e61be88SMatthew G. Knepley   PetscValidFunction(initCondition, 2);
35062e61be88SMatthew G. Knepley   ts->ops->initcondition = initCondition;
3507aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3508aad739acSMatthew G. Knepley }
3509aad739acSMatthew G. Knepley 
3510aad739acSMatthew G. Knepley /*@
35112e61be88SMatthew G. Knepley   TSComputeInitialCondition - Compute an initial condition for the timestepping using the function previously set.
3512aad739acSMatthew G. Knepley 
3513aad739acSMatthew G. Knepley   Collective on ts
3514aad739acSMatthew G. Knepley 
35154165533cSJose E. Roman   Input Parameters:
3516aad739acSMatthew G. Knepley + ts - time stepping context
35172e61be88SMatthew G. Knepley - u  - The Vec to store the condition in which will be used in TSSolve()
3518aad739acSMatthew G. Knepley 
3519aad739acSMatthew G. Knepley   Level: advanced
3520aad739acSMatthew G. Knepley 
3521db781477SPatrick Sanan .seealso: `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3522aad739acSMatthew G. Knepley @*/
35239371c9d4SSatish Balay PetscErrorCode TSComputeInitialCondition(TS ts, Vec u) {
3524aad739acSMatthew G. Knepley   PetscFunctionBegin;
3525aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3526aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3527dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, initcondition, u);
3528aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3529aad739acSMatthew G. Knepley }
3530aad739acSMatthew G. Knepley 
3531aad739acSMatthew G. Knepley /*@C
3532aad739acSMatthew G. Knepley   TSGetComputeExactError - Get the function used to automatically compute the exact error for the timestepping.
3533aad739acSMatthew G. Knepley 
3534aad739acSMatthew G. Knepley   Not collective
3535aad739acSMatthew G. Knepley 
35364165533cSJose E. Roman   Input Parameter:
3537aad739acSMatthew G. Knepley . ts         - time stepping context
3538aad739acSMatthew G. Knepley 
35394165533cSJose E. Roman   Output Parameter:
3540aad739acSMatthew G. Knepley . exactError - The function which computes the solution error
3541aad739acSMatthew G. Knepley 
3542aad739acSMatthew G. Knepley   Level: advanced
3543aad739acSMatthew G. Knepley 
3544a96d6ef6SBarry Smith   Calling sequence for exactError:
3545a96d6ef6SBarry Smith $ PetscErrorCode exactError(TS ts, Vec u)
3546a96d6ef6SBarry Smith 
3547a96d6ef6SBarry Smith + ts - The timestepping context
3548a96d6ef6SBarry Smith . u  - The approximate solution vector
3549a96d6ef6SBarry Smith - e  - The input vector in which the error is stored
3550aad739acSMatthew G. Knepley 
3551db781477SPatrick Sanan .seealso: `TSGetComputeExactError()`, `TSComputeExactError()`
3552aad739acSMatthew G. Knepley @*/
35539371c9d4SSatish Balay PetscErrorCode TSGetComputeExactError(TS ts, PetscErrorCode (**exactError)(TS, Vec, Vec)) {
3554aad739acSMatthew G. Knepley   PetscFunctionBegin;
3555aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3556aad739acSMatthew G. Knepley   PetscValidPointer(exactError, 2);
3557aad739acSMatthew G. Knepley   *exactError = ts->ops->exacterror;
3558aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3559aad739acSMatthew G. Knepley }
3560aad739acSMatthew G. Knepley 
3561aad739acSMatthew G. Knepley /*@C
3562aad739acSMatthew G. Knepley   TSSetComputeExactError - Set the function used to automatically compute the exact error for the timestepping.
3563aad739acSMatthew G. Knepley 
3564aad739acSMatthew G. Knepley   Logically collective on ts
3565aad739acSMatthew G. Knepley 
35664165533cSJose E. Roman   Input Parameters:
3567aad739acSMatthew G. Knepley + ts         - time stepping context
3568aad739acSMatthew G. Knepley - exactError - The function which computes the solution error
3569aad739acSMatthew G. Knepley 
3570aad739acSMatthew G. Knepley   Level: advanced
3571aad739acSMatthew G. Knepley 
3572a96d6ef6SBarry Smith   Calling sequence for exactError:
3573a96d6ef6SBarry Smith $ PetscErrorCode exactError(TS ts, Vec u)
3574a96d6ef6SBarry Smith 
3575a96d6ef6SBarry Smith + ts - The timestepping context
3576a96d6ef6SBarry Smith . u  - The approximate solution vector
3577a96d6ef6SBarry Smith - e  - The input vector in which the error is stored
3578aad739acSMatthew G. Knepley 
3579db781477SPatrick Sanan .seealso: `TSGetComputeExactError()`, `TSComputeExactError()`
3580aad739acSMatthew G. Knepley @*/
35819371c9d4SSatish Balay PetscErrorCode TSSetComputeExactError(TS ts, PetscErrorCode (*exactError)(TS, Vec, Vec)) {
3582aad739acSMatthew G. Knepley   PetscFunctionBegin;
3583aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3584f907fdbfSMatthew G. Knepley   PetscValidFunction(exactError, 2);
3585aad739acSMatthew G. Knepley   ts->ops->exacterror = exactError;
3586aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3587aad739acSMatthew G. Knepley }
3588aad739acSMatthew G. Knepley 
3589aad739acSMatthew G. Knepley /*@
3590aad739acSMatthew G. Knepley   TSComputeExactError - Compute the solution error for the timestepping using the function previously set.
3591aad739acSMatthew G. Knepley 
3592aad739acSMatthew G. Knepley   Collective on ts
3593aad739acSMatthew G. Knepley 
35944165533cSJose E. Roman   Input Parameters:
3595aad739acSMatthew G. Knepley + ts - time stepping context
3596aad739acSMatthew G. Knepley . u  - The approximate solution
3597aad739acSMatthew G. Knepley - e  - The Vec used to store the error
3598aad739acSMatthew G. Knepley 
3599aad739acSMatthew G. Knepley   Level: advanced
3600aad739acSMatthew G. Knepley 
3601db781477SPatrick Sanan .seealso: `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3602aad739acSMatthew G. Knepley @*/
36039371c9d4SSatish Balay PetscErrorCode TSComputeExactError(TS ts, Vec u, Vec e) {
3604aad739acSMatthew G. Knepley   PetscFunctionBegin;
3605aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3606aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3607aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(e, VEC_CLASSID, 3);
3608dbbe0bcdSBarry Smith   PetscTryTypeMethod(ts, exacterror, u, e);
3609aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3610aad739acSMatthew G. Knepley }
3611aad739acSMatthew G. Knepley 
3612b1cb36f3SHong Zhang /*@
36136a4d4014SLisandro Dalcin    TSSolve - Steps the requested number of timesteps.
36146a4d4014SLisandro Dalcin 
36156a4d4014SLisandro Dalcin    Collective on TS
36166a4d4014SLisandro Dalcin 
3617d8d19677SJose E. Roman    Input Parameters:
36186a4d4014SLisandro Dalcin +  ts - the TS context obtained from TSCreate()
361963e21af5SBarry Smith -  u - the solution vector  (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used,
362063e21af5SBarry Smith                              otherwise must contain the initial conditions and will contain the solution at the final requested time
36215a3a76d0SJed Brown 
36226a4d4014SLisandro Dalcin    Level: beginner
36236a4d4014SLisandro Dalcin 
36245a3a76d0SJed Brown    Notes:
36255a3a76d0SJed Brown    The final time returned by this function may be different from the time of the internally
36265a3a76d0SJed Brown    held state accessible by TSGetSolution() and TSGetTime() because the method may have
36275a3a76d0SJed Brown    stepped over the final time.
36285a3a76d0SJed Brown 
3629db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetSolution()`, `TSStep()`, `TSGetTime()`, `TSGetSolveTime()`
36306a4d4014SLisandro Dalcin @*/
36319371c9d4SSatish Balay PetscErrorCode TSSolve(TS ts, Vec u) {
3632b06615a5SLisandro Dalcin   Vec solution;
3633f22f69f0SBarry Smith 
36346a4d4014SLisandro Dalcin   PetscFunctionBegin;
36350700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3636f2c2a1b9SBarry Smith   if (u) PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3637303a5415SBarry Smith 
36389566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
3639ee41a567SStefano 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 */
36400910c330SBarry Smith     if (!ts->vec_sol || u == ts->vec_sol) {
36419566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u, &solution));
36429566063dSJacob Faibussowitsch       PetscCall(TSSetSolution(ts, solution));
36439566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&solution)); /* grant ownership */
36445a3a76d0SJed Brown     }
36459566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, ts->vec_sol));
36463c633725SBarry Smith     PetscCheck(!ts->forward_solve, PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE");
36471baa6e33SBarry Smith   } else if (u) PetscCall(TSSetSolution(ts, u));
36489566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
36499566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory, ts));
3650a6772fa2SLisandro Dalcin 
36513c633725SBarry 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>");
36523c633725SBarry 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()");
36533c633725SBarry 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");
36544a658b32SHong 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");
36554a658b32SHong Zhang 
3656e1db57b0SHong 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 */
36574a658b32SHong Zhang     PetscCall(VecCopy(ts->vec_sol, ts->tspan->vecs_sol[0]));
36584a658b32SHong Zhang     ts->tspan->spanctr = 1;
36594a658b32SHong Zhang   }
3660a6772fa2SLisandro Dalcin 
36611baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardSetUp(ts));
3662715f1b00SHong Zhang 
3663e7069c78SShri   /* reset number of steps only when the step is not restarted. ARKIMEX
3664715f1b00SHong Zhang      restarts the step after an event. Resetting these counters in such case causes
3665e7069c78SShri      TSTrajectory to incorrectly save the output files
3666e7069c78SShri   */
3667715f1b00SHong Zhang   /* reset time step and iteration counters */
36682808aa04SLisandro Dalcin   if (!ts->steps) {
36695ef26d82SJed Brown     ts->ksp_its           = 0;
36705ef26d82SJed Brown     ts->snes_its          = 0;
3671c610991cSLisandro Dalcin     ts->num_snes_failures = 0;
3672c610991cSLisandro Dalcin     ts->reject            = 0;
36732808aa04SLisandro Dalcin     ts->steprestart       = PETSC_TRUE;
36742808aa04SLisandro Dalcin     ts->steprollback      = PETSC_FALSE;
36757d51462cSStefano Zampini     ts->rhsjacobian.time  = PETSC_MIN_REAL;
36762808aa04SLisandro Dalcin   }
3677e97c63d7SStefano Zampini 
36784a658b32SHong Zhang   /* make sure initial time step does not overshoot final time or the next point in tspan */
3679e97c63d7SStefano Zampini   if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
36804a658b32SHong Zhang     PetscReal maxdt;
3681e97c63d7SStefano Zampini     PetscReal dt = ts->time_step;
3682e97c63d7SStefano Zampini 
36834a658b32SHong Zhang     if (ts->tspan) maxdt = ts->tspan->span_times[ts->tspan->spanctr] - ts->ptime;
36844a658b32SHong Zhang     else maxdt = ts->max_time - ts->ptime;
3685e97c63d7SStefano Zampini     ts->time_step = dt >= maxdt ? maxdt : (PetscIsCloseAtTol(dt, maxdt, 10 * PETSC_MACHINE_EPSILON, 0) ? maxdt : dt);
3686e97c63d7SStefano Zampini   }
3687193ac0bcSJed Brown   ts->reason = TS_CONVERGED_ITERATING;
3688193ac0bcSJed Brown 
3689900f6b5bSMatthew G. Knepley   {
3690900f6b5bSMatthew G. Knepley     PetscViewer       viewer;
3691900f6b5bSMatthew G. Knepley     PetscViewerFormat format;
3692900f6b5bSMatthew G. Knepley     PetscBool         flg;
3693900f6b5bSMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
3694900f6b5bSMatthew G. Knepley 
3695900f6b5bSMatthew G. Knepley     if (!incall) {
3696900f6b5bSMatthew G. Knepley       /* Estimate the convergence rate of the time discretization */
36979566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)ts), ((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_convergence_estimate", &viewer, &format, &flg));
3698900f6b5bSMatthew G. Knepley       if (flg) {
3699900f6b5bSMatthew G. Knepley         PetscConvEst conv;
3700900f6b5bSMatthew G. Knepley         DM           dm;
3701900f6b5bSMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
3702900f6b5bSMatthew G. Knepley         PetscInt     Nf;
3703f2ed2dc7SMatthew G. Knepley         PetscBool    checkTemporal = PETSC_TRUE;
3704900f6b5bSMatthew G. Knepley 
3705900f6b5bSMatthew G. Knepley         incall = PETSC_TRUE;
37069566063dSJacob Faibussowitsch         PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_convergence_temporal", &checkTemporal, &flg));
37079566063dSJacob Faibussowitsch         PetscCall(TSGetDM(ts, &dm));
37089566063dSJacob Faibussowitsch         PetscCall(DMGetNumFields(dm, &Nf));
37099566063dSJacob Faibussowitsch         PetscCall(PetscCalloc1(PetscMax(Nf, 1), &alpha));
37109566063dSJacob Faibussowitsch         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)ts), &conv));
37119566063dSJacob Faibussowitsch         PetscCall(PetscConvEstUseTS(conv, checkTemporal));
37129566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetSolver(conv, (PetscObject)ts));
37139566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetFromOptions(conv));
37149566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetUp(conv));
37159566063dSJacob Faibussowitsch         PetscCall(PetscConvEstGetConvRate(conv, alpha));
37169566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(viewer, format));
37179566063dSJacob Faibussowitsch         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
37189566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(viewer));
37199566063dSJacob Faibussowitsch         PetscCall(PetscViewerDestroy(&viewer));
37209566063dSJacob Faibussowitsch         PetscCall(PetscConvEstDestroy(&conv));
37219566063dSJacob Faibussowitsch         PetscCall(PetscFree(alpha));
3722900f6b5bSMatthew G. Knepley         incall = PETSC_FALSE;
3723900f6b5bSMatthew G. Knepley       }
3724900f6b5bSMatthew G. Knepley     }
3725900f6b5bSMatthew G. Knepley   }
3726900f6b5bSMatthew G. Knepley 
37279566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts, NULL, "-ts_view_pre"));
3728f05ece33SBarry Smith 
3729193ac0bcSJed Brown   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
3730dbbe0bcdSBarry Smith     PetscUseTypeMethod(ts, solve);
37319566063dSJacob Faibussowitsch     if (u) PetscCall(VecCopy(ts->vec_sol, u));
3732cc708dedSBarry Smith     ts->solvetime = ts->ptime;
3733a6772fa2SLisandro Dalcin     solution      = ts->vec_sol;
3734be5899b3SLisandro Dalcin   } else { /* Step the requested number of timesteps. */
3735db4deed7SKarl Rupp     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
3736db4deed7SKarl Rupp     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3737e7069c78SShri 
37382808aa04SLisandro Dalcin     if (!ts->steps) {
37399566063dSJacob Faibussowitsch       PetscCall(TSTrajectorySet(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
37409566063dSJacob Faibussowitsch       PetscCall(TSEventInitialize(ts->event, ts, ts->ptime, ts->vec_sol));
37412808aa04SLisandro Dalcin     }
37426427ac75SLisandro Dalcin 
3743e1a7a14fSJed Brown     while (!ts->reason) {
37449566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts, ts->steps, ts->ptime, ts->vec_sol));
37451e66621cSBarry Smith       if (!ts->steprollback) PetscCall(TSPreStep(ts));
37469566063dSJacob Faibussowitsch       PetscCall(TSStep(ts));
37471baa6e33SBarry Smith       if (ts->testjacobian) PetscCall(TSRHSJacobianTest(ts, NULL));
37481baa6e33SBarry Smith       if (ts->testjacobiantranspose) PetscCall(TSRHSJacobianTestTranspose(ts, NULL));
3749cd4cee2dSHong Zhang       if (ts->quadraturets && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
37507b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--;            /* Revert the step number changed by TSStep() */
37519566063dSJacob Faibussowitsch         PetscCall(TSForwardCostIntegral(ts));
37527b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
3753b1cb36f3SHong Zhang       }
375458818c2dSLisandro Dalcin       if (ts->forward_solve) {            /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */
37557b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */
37569566063dSJacob Faibussowitsch         PetscCall(TSForwardStep(ts));
37577b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
3758715f1b00SHong Zhang       }
37599566063dSJacob Faibussowitsch       PetscCall(TSPostEvaluate(ts));
37609566063dSJacob 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. */
37611baa6e33SBarry Smith       if (ts->steprollback) PetscCall(TSPostEvaluate(ts));
3762e783b05fSHong Zhang       if (!ts->steprollback) {
37639566063dSJacob Faibussowitsch         PetscCall(TSTrajectorySet(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
37649566063dSJacob Faibussowitsch         PetscCall(TSPostStep(ts));
3765aeb4809dSShri Abhyankar       }
3766193ac0bcSJed Brown     }
37679566063dSJacob Faibussowitsch     PetscCall(TSMonitor(ts, ts->steps, ts->ptime, ts->vec_sol));
37686427ac75SLisandro Dalcin 
376949354f04SShri Abhyankar     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
37709566063dSJacob Faibussowitsch       PetscCall(TSInterpolate(ts, ts->max_time, u));
3771cc708dedSBarry Smith       ts->solvetime = ts->max_time;
3772b06615a5SLisandro Dalcin       solution      = u;
37739566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts, -1, ts->solvetime, solution));
37740574a7fbSJed Brown     } else {
37759566063dSJacob Faibussowitsch       if (u) PetscCall(VecCopy(ts->vec_sol, u));
3776cc708dedSBarry Smith       ts->solvetime = ts->ptime;
3777b06615a5SLisandro Dalcin       solution      = ts->vec_sol;
37780574a7fbSJed Brown     }
3779193ac0bcSJed Brown   }
3780d2daff3dSHong Zhang 
37819566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts, NULL, "-ts_view"));
37829566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(solution, (PetscObject)ts, "-ts_view_solution"));
37839566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsBlock((PetscObject)ts));
37841baa6e33SBarry Smith   if (ts->adjoint_solve) PetscCall(TSAdjointSolve(ts));
37856a4d4014SLisandro Dalcin   PetscFunctionReturn(0);
37866a4d4014SLisandro Dalcin }
37876a4d4014SLisandro Dalcin 
3788d763cef2SBarry Smith /*@
3789b8123daeSJed Brown    TSGetTime - Gets the time of the most recently completed step.
3790d763cef2SBarry Smith 
3791d763cef2SBarry Smith    Not Collective
3792d763cef2SBarry Smith 
3793d763cef2SBarry Smith    Input Parameter:
3794d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
3795d763cef2SBarry Smith 
3796d763cef2SBarry Smith    Output Parameter:
379719eac22cSLisandro Dalcin .  t  - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime().
3798d763cef2SBarry Smith 
3799d763cef2SBarry Smith    Level: beginner
3800d763cef2SBarry Smith 
3801b8123daeSJed Brown    Note:
3802b8123daeSJed Brown    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
38039be3e283SDebojyoti Ghosh    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
3804b8123daeSJed Brown 
3805db781477SPatrick Sanan .seealso: `TSGetSolveTime()`, `TSSetTime()`, `TSGetTimeStep()`, `TSGetStepNumber()`
3806d763cef2SBarry Smith 
3807d763cef2SBarry Smith @*/
38089371c9d4SSatish Balay PetscErrorCode TSGetTime(TS ts, PetscReal *t) {
3809d763cef2SBarry Smith   PetscFunctionBegin;
38100700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3811f7cf8827SBarry Smith   PetscValidRealPointer(t, 2);
3812d763cef2SBarry Smith   *t = ts->ptime;
3813d763cef2SBarry Smith   PetscFunctionReturn(0);
3814d763cef2SBarry Smith }
3815d763cef2SBarry Smith 
3816e5e524a1SHong Zhang /*@
3817e5e524a1SHong Zhang    TSGetPrevTime - Gets the starting time of the previously completed step.
3818e5e524a1SHong Zhang 
3819e5e524a1SHong Zhang    Not Collective
3820e5e524a1SHong Zhang 
3821e5e524a1SHong Zhang    Input Parameter:
3822e5e524a1SHong Zhang .  ts - the TS context obtained from TSCreate()
3823e5e524a1SHong Zhang 
3824e5e524a1SHong Zhang    Output Parameter:
3825e5e524a1SHong Zhang .  t  - the previous time
3826e5e524a1SHong Zhang 
3827e5e524a1SHong Zhang    Level: beginner
3828e5e524a1SHong Zhang 
3829db781477SPatrick Sanan .seealso: `TSGetTime()`, `TSGetSolveTime()`, `TSGetTimeStep()`
3830e5e524a1SHong Zhang 
3831e5e524a1SHong Zhang @*/
38329371c9d4SSatish Balay PetscErrorCode TSGetPrevTime(TS ts, PetscReal *t) {
3833e5e524a1SHong Zhang   PetscFunctionBegin;
3834e5e524a1SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3835e5e524a1SHong Zhang   PetscValidRealPointer(t, 2);
3836e5e524a1SHong Zhang   *t = ts->ptime_prev;
3837e5e524a1SHong Zhang   PetscFunctionReturn(0);
3838e5e524a1SHong Zhang }
3839e5e524a1SHong Zhang 
38406a4d4014SLisandro Dalcin /*@
38416a4d4014SLisandro Dalcin    TSSetTime - Allows one to reset the time.
38426a4d4014SLisandro Dalcin 
38433f9fe445SBarry Smith    Logically Collective on TS
38446a4d4014SLisandro Dalcin 
38456a4d4014SLisandro Dalcin    Input Parameters:
38466a4d4014SLisandro Dalcin +  ts - the TS context obtained from TSCreate()
38476a4d4014SLisandro Dalcin -  time - the time
38486a4d4014SLisandro Dalcin 
38496a4d4014SLisandro Dalcin    Level: intermediate
38506a4d4014SLisandro Dalcin 
3851db781477SPatrick Sanan .seealso: `TSGetTime()`, `TSSetMaxSteps()`
38526a4d4014SLisandro Dalcin 
38536a4d4014SLisandro Dalcin @*/
38549371c9d4SSatish Balay PetscErrorCode TSSetTime(TS ts, PetscReal t) {
38556a4d4014SLisandro Dalcin   PetscFunctionBegin;
38560700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3857c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts, t, 2);
38586a4d4014SLisandro Dalcin   ts->ptime = t;
38596a4d4014SLisandro Dalcin   PetscFunctionReturn(0);
38606a4d4014SLisandro Dalcin }
38616a4d4014SLisandro Dalcin 
3862d763cef2SBarry Smith /*@C
3863d763cef2SBarry Smith    TSSetOptionsPrefix - Sets the prefix used for searching for all
3864d763cef2SBarry Smith    TS options in the database.
3865d763cef2SBarry Smith 
38663f9fe445SBarry Smith    Logically Collective on TS
3867d763cef2SBarry Smith 
3868d8d19677SJose E. Roman    Input Parameters:
3869d763cef2SBarry Smith +  ts     - The TS context
3870d763cef2SBarry Smith -  prefix - The prefix to prepend to all option names
3871d763cef2SBarry Smith 
3872d763cef2SBarry Smith    Notes:
3873d763cef2SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
3874d763cef2SBarry Smith    The first character of all runtime options is AUTOMATICALLY the
3875d763cef2SBarry Smith    hyphen.
3876d763cef2SBarry Smith 
3877d763cef2SBarry Smith    Level: advanced
3878d763cef2SBarry Smith 
3879db781477SPatrick Sanan .seealso: `TSSetFromOptions()`
3880d763cef2SBarry Smith 
3881d763cef2SBarry Smith @*/
38829371c9d4SSatish Balay PetscErrorCode TSSetOptionsPrefix(TS ts, const char prefix[]) {
3883089b2837SJed Brown   SNES snes;
3884d763cef2SBarry Smith 
3885d763cef2SBarry Smith   PetscFunctionBegin;
38860700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
38879566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ts, prefix));
38889566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
38899566063dSJacob Faibussowitsch   PetscCall(SNESSetOptionsPrefix(snes, prefix));
3890d763cef2SBarry Smith   PetscFunctionReturn(0);
3891d763cef2SBarry Smith }
3892d763cef2SBarry Smith 
3893d763cef2SBarry Smith /*@C
3894d763cef2SBarry Smith    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
3895d763cef2SBarry Smith    TS options in the database.
3896d763cef2SBarry Smith 
38973f9fe445SBarry Smith    Logically Collective on TS
3898d763cef2SBarry Smith 
3899d8d19677SJose E. Roman    Input Parameters:
3900d763cef2SBarry Smith +  ts     - The TS context
3901d763cef2SBarry Smith -  prefix - The prefix to prepend to all option names
3902d763cef2SBarry Smith 
3903d763cef2SBarry Smith    Notes:
3904d763cef2SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
3905d763cef2SBarry Smith    The first character of all runtime options is AUTOMATICALLY the
3906d763cef2SBarry Smith    hyphen.
3907d763cef2SBarry Smith 
3908d763cef2SBarry Smith    Level: advanced
3909d763cef2SBarry Smith 
3910db781477SPatrick Sanan .seealso: `TSGetOptionsPrefix()`
3911d763cef2SBarry Smith 
3912d763cef2SBarry Smith @*/
39139371c9d4SSatish Balay PetscErrorCode TSAppendOptionsPrefix(TS ts, const char prefix[]) {
3914089b2837SJed Brown   SNES snes;
3915d763cef2SBarry Smith 
3916d763cef2SBarry Smith   PetscFunctionBegin;
39170700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
39189566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)ts, prefix));
39199566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
39209566063dSJacob Faibussowitsch   PetscCall(SNESAppendOptionsPrefix(snes, prefix));
3921d763cef2SBarry Smith   PetscFunctionReturn(0);
3922d763cef2SBarry Smith }
3923d763cef2SBarry Smith 
3924d763cef2SBarry Smith /*@C
3925d763cef2SBarry Smith    TSGetOptionsPrefix - Sets the prefix used for searching for all
3926d763cef2SBarry Smith    TS options in the database.
3927d763cef2SBarry Smith 
3928d763cef2SBarry Smith    Not Collective
3929d763cef2SBarry Smith 
3930d763cef2SBarry Smith    Input Parameter:
3931d763cef2SBarry Smith .  ts - The TS context
3932d763cef2SBarry Smith 
3933d763cef2SBarry Smith    Output Parameter:
3934d763cef2SBarry Smith .  prefix - A pointer to the prefix string used
3935d763cef2SBarry Smith 
393695452b02SPatrick Sanan    Notes:
393795452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prifix' of
3938d763cef2SBarry Smith    sufficient length to hold the prefix.
3939d763cef2SBarry Smith 
3940d763cef2SBarry Smith    Level: intermediate
3941d763cef2SBarry Smith 
3942db781477SPatrick Sanan .seealso: `TSAppendOptionsPrefix()`
3943d763cef2SBarry Smith @*/
39449371c9d4SSatish Balay PetscErrorCode TSGetOptionsPrefix(TS ts, const char *prefix[]) {
3945d763cef2SBarry Smith   PetscFunctionBegin;
39460700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
39474482741eSBarry Smith   PetscValidPointer(prefix, 2);
39489566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts, prefix));
3949d763cef2SBarry Smith   PetscFunctionReturn(0);
3950d763cef2SBarry Smith }
3951d763cef2SBarry Smith 
3952d763cef2SBarry Smith /*@C
3953d763cef2SBarry Smith    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
3954d763cef2SBarry Smith 
3955d763cef2SBarry Smith    Not Collective, but parallel objects are returned if TS is parallel
3956d763cef2SBarry Smith 
3957d763cef2SBarry Smith    Input Parameter:
3958d763cef2SBarry Smith .  ts  - The TS context obtained from TSCreate()
3959d763cef2SBarry Smith 
3960d763cef2SBarry Smith    Output Parameters:
3961e4357dc4SBarry Smith +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
3962e4357dc4SBarry Smith .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
3963e4357dc4SBarry Smith .  func - Function to compute the Jacobian of the RHS  (or NULL)
3964e4357dc4SBarry Smith -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
3965d763cef2SBarry Smith 
396695452b02SPatrick Sanan    Notes:
396795452b02SPatrick Sanan     You can pass in NULL for any return argument you do not need.
3968d763cef2SBarry Smith 
3969d763cef2SBarry Smith    Level: intermediate
3970d763cef2SBarry Smith 
3971db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
3972d763cef2SBarry Smith 
3973d763cef2SBarry Smith @*/
39749371c9d4SSatish Balay PetscErrorCode TSGetRHSJacobian(TS ts, Mat *Amat, Mat *Pmat, TSRHSJacobian *func, void **ctx) {
397524989b8cSPeter Brune   DM dm;
3976089b2837SJed Brown 
3977d763cef2SBarry Smith   PetscFunctionBegin;
397823a57915SBarry Smith   if (Amat || Pmat) {
397923a57915SBarry Smith     SNES snes;
39809566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
39819566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
39829566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
398323a57915SBarry Smith   }
39849566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
39859566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm, func, ctx));
3986d763cef2SBarry Smith   PetscFunctionReturn(0);
3987d763cef2SBarry Smith }
3988d763cef2SBarry Smith 
39892eca1d9cSJed Brown /*@C
39902eca1d9cSJed Brown    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
39912eca1d9cSJed Brown 
39922eca1d9cSJed Brown    Not Collective, but parallel objects are returned if TS is parallel
39932eca1d9cSJed Brown 
39942eca1d9cSJed Brown    Input Parameter:
39952eca1d9cSJed Brown .  ts  - The TS context obtained from TSCreate()
39962eca1d9cSJed Brown 
39972eca1d9cSJed Brown    Output Parameters:
3998e4357dc4SBarry Smith +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
3999e4357dc4SBarry Smith .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
40002eca1d9cSJed Brown .  f   - The function to compute the matrices
40012eca1d9cSJed Brown - ctx - User-defined context for Jacobian evaluation routine
40022eca1d9cSJed Brown 
400395452b02SPatrick Sanan    Notes:
400495452b02SPatrick Sanan     You can pass in NULL for any return argument you do not need.
40052eca1d9cSJed Brown 
40062eca1d9cSJed Brown    Level: advanced
40072eca1d9cSJed Brown 
4008db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetRHSJacobian()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
40092eca1d9cSJed Brown 
40102eca1d9cSJed Brown @*/
40119371c9d4SSatish Balay PetscErrorCode TSGetIJacobian(TS ts, Mat *Amat, Mat *Pmat, TSIJacobian *f, void **ctx) {
401224989b8cSPeter Brune   DM dm;
40130910c330SBarry Smith 
40142eca1d9cSJed Brown   PetscFunctionBegin;
4015c0aab802Sstefano_zampini   if (Amat || Pmat) {
4016c0aab802Sstefano_zampini     SNES snes;
40179566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts, &snes));
40189566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
40199566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
4020c0aab802Sstefano_zampini   }
40219566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
40229566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm, f, ctx));
40232eca1d9cSJed Brown   PetscFunctionReturn(0);
40242eca1d9cSJed Brown }
40252eca1d9cSJed Brown 
4026af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
40276c699258SBarry Smith /*@
40282a808120SBarry Smith    TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS
40296c699258SBarry Smith 
4030d083f849SBarry Smith    Logically Collective on ts
40316c699258SBarry Smith 
40326c699258SBarry Smith    Input Parameters:
40332a808120SBarry Smith +  ts - the ODE integrator object
40342a808120SBarry Smith -  dm - the dm, cannot be NULL
40356c699258SBarry Smith 
4036e03a659cSJed Brown    Notes:
4037e03a659cSJed Brown    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
4038e03a659cSJed Brown    even when not using interfaces like DMTSSetIFunction().  Use DMClone() to get a distinct DM when solving
4039e03a659cSJed Brown    different problems using the same function space.
4040e03a659cSJed Brown 
40416c699258SBarry Smith    Level: intermediate
40426c699258SBarry Smith 
4043db781477SPatrick Sanan .seealso: `TSGetDM()`, `SNESSetDM()`, `SNESGetDM()`
40446c699258SBarry Smith @*/
40459371c9d4SSatish Balay PetscErrorCode TSSetDM(TS ts, DM dm) {
4046089b2837SJed Brown   SNES snes;
4047942e3340SBarry Smith   DMTS tsdm;
40486c699258SBarry Smith 
40496c699258SBarry Smith   PetscFunctionBegin;
40500700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
40512a808120SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
40529566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)dm));
4053942e3340SBarry Smith   if (ts->dm) { /* Move the DMTS context over to the new DM unless the new DM already has one */
40542a34c10cSBarry Smith     if (ts->dm->dmts && !dm->dmts) {
40559566063dSJacob Faibussowitsch       PetscCall(DMCopyDMTS(ts->dm, dm));
40569566063dSJacob Faibussowitsch       PetscCall(DMGetDMTS(ts->dm, &tsdm));
40571e66621cSBarry Smith       /* Grant write privileges to the replacement DM */
40581e66621cSBarry Smith       if (tsdm->originaldm == ts->dm) tsdm->originaldm = dm;
405924989b8cSPeter Brune     }
40609566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&ts->dm));
406124989b8cSPeter Brune   }
40626c699258SBarry Smith   ts->dm = dm;
4063bbd56ea5SKarl Rupp 
40649566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
40659566063dSJacob Faibussowitsch   PetscCall(SNESSetDM(snes, dm));
40666c699258SBarry Smith   PetscFunctionReturn(0);
40676c699258SBarry Smith }
40686c699258SBarry Smith 
40696c699258SBarry Smith /*@
40706c699258SBarry Smith    TSGetDM - Gets the DM that may be used by some preconditioners
40716c699258SBarry Smith 
40723f9fe445SBarry Smith    Not Collective
40736c699258SBarry Smith 
40746c699258SBarry Smith    Input Parameter:
40756c699258SBarry Smith . ts - the preconditioner context
40766c699258SBarry Smith 
40776c699258SBarry Smith    Output Parameter:
40786c699258SBarry Smith .  dm - the dm
40796c699258SBarry Smith 
40806c699258SBarry Smith    Level: intermediate
40816c699258SBarry Smith 
4082db781477SPatrick Sanan .seealso: `TSSetDM()`, `SNESSetDM()`, `SNESGetDM()`
40836c699258SBarry Smith @*/
40849371c9d4SSatish Balay PetscErrorCode TSGetDM(TS ts, DM *dm) {
40856c699258SBarry Smith   PetscFunctionBegin;
40860700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4087496e6a7aSJed Brown   if (!ts->dm) {
40889566063dSJacob Faibussowitsch     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)ts), &ts->dm));
40899566063dSJacob Faibussowitsch     if (ts->snes) PetscCall(SNESSetDM(ts->snes, ts->dm));
4090496e6a7aSJed Brown   }
40916c699258SBarry Smith   *dm = ts->dm;
40926c699258SBarry Smith   PetscFunctionReturn(0);
40936c699258SBarry Smith }
40941713a123SBarry Smith 
40950f5c6efeSJed Brown /*@
40960f5c6efeSJed Brown    SNESTSFormFunction - Function to evaluate nonlinear residual
40970f5c6efeSJed Brown 
40983f9fe445SBarry Smith    Logically Collective on SNES
40990f5c6efeSJed Brown 
4100d8d19677SJose E. Roman    Input Parameters:
4101d42a1c89SJed Brown + snes - nonlinear solver
41020910c330SBarry Smith . U - the current state at which to evaluate the residual
4103d42a1c89SJed Brown - ctx - user context, must be a TS
41040f5c6efeSJed Brown 
41050f5c6efeSJed Brown    Output Parameter:
41060f5c6efeSJed Brown . F - the nonlinear residual
41070f5c6efeSJed Brown 
41080f5c6efeSJed Brown    Notes:
41090f5c6efeSJed Brown    This function is not normally called by users and is automatically registered with the SNES used by TS.
41100f5c6efeSJed Brown    It is most frequently passed to MatFDColoringSetFunction().
41110f5c6efeSJed Brown 
41120f5c6efeSJed Brown    Level: advanced
41130f5c6efeSJed Brown 
4114db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `MatFDColoringSetFunction()`
41150f5c6efeSJed Brown @*/
41169371c9d4SSatish Balay PetscErrorCode SNESTSFormFunction(SNES snes, Vec U, Vec F, void *ctx) {
41170f5c6efeSJed Brown   TS ts = (TS)ctx;
41180f5c6efeSJed Brown 
41190f5c6efeSJed Brown   PetscFunctionBegin;
41200f5c6efeSJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
41210910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
41220f5c6efeSJed Brown   PetscValidHeaderSpecific(F, VEC_CLASSID, 3);
41230f5c6efeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 4);
41249566063dSJacob Faibussowitsch   PetscCall((ts->ops->snesfunction)(snes, U, F, ts));
41250f5c6efeSJed Brown   PetscFunctionReturn(0);
41260f5c6efeSJed Brown }
41270f5c6efeSJed Brown 
41280f5c6efeSJed Brown /*@
41290f5c6efeSJed Brown    SNESTSFormJacobian - Function to evaluate the Jacobian
41300f5c6efeSJed Brown 
41310f5c6efeSJed Brown    Collective on SNES
41320f5c6efeSJed Brown 
4133d8d19677SJose E. Roman    Input Parameters:
41340f5c6efeSJed Brown + snes - nonlinear solver
41350910c330SBarry Smith . U - the current state at which to evaluate the residual
41360f5c6efeSJed Brown - ctx - user context, must be a TS
41370f5c6efeSJed Brown 
4138d8d19677SJose E. Roman    Output Parameters:
41390f5c6efeSJed Brown + A - the Jacobian
41406b867d5aSJose E. Roman - B - the preconditioning matrix (may be the same as A)
41410f5c6efeSJed Brown 
41420f5c6efeSJed Brown    Notes:
41430f5c6efeSJed Brown    This function is not normally called by users and is automatically registered with the SNES used by TS.
41440f5c6efeSJed Brown 
41450f5c6efeSJed Brown    Level: developer
41460f5c6efeSJed Brown 
4147db781477SPatrick Sanan .seealso: `SNESSetJacobian()`
41480f5c6efeSJed Brown @*/
41499371c9d4SSatish Balay PetscErrorCode SNESTSFormJacobian(SNES snes, Vec U, Mat A, Mat B, void *ctx) {
41500f5c6efeSJed Brown   TS ts = (TS)ctx;
41510f5c6efeSJed Brown 
41520f5c6efeSJed Brown   PetscFunctionBegin;
41530f5c6efeSJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
41540910c330SBarry Smith   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
41550f5c6efeSJed Brown   PetscValidPointer(A, 3);
415694ab13aaSBarry Smith   PetscValidHeaderSpecific(A, MAT_CLASSID, 3);
41570f5c6efeSJed Brown   PetscValidPointer(B, 4);
415894ab13aaSBarry Smith   PetscValidHeaderSpecific(B, MAT_CLASSID, 4);
4159064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(ts, TS_CLASSID, 5);
41609566063dSJacob Faibussowitsch   PetscCall((ts->ops->snesjacobian)(snes, U, A, B, ts));
41610f5c6efeSJed Brown   PetscFunctionReturn(0);
41620f5c6efeSJed Brown }
4163325fc9f4SBarry Smith 
41640e4ef248SJed Brown /*@C
41659ae8fd06SBarry Smith    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
41660e4ef248SJed Brown 
41670e4ef248SJed Brown    Collective on TS
41680e4ef248SJed Brown 
41694165533cSJose E. Roman    Input Parameters:
41700e4ef248SJed Brown +  ts - time stepping context
41710e4ef248SJed Brown .  t - time at which to evaluate
41720910c330SBarry Smith .  U - state at which to evaluate
41730e4ef248SJed Brown -  ctx - context
41740e4ef248SJed Brown 
41754165533cSJose E. Roman    Output Parameter:
41760e4ef248SJed Brown .  F - right hand side
41770e4ef248SJed Brown 
41780e4ef248SJed Brown    Level: intermediate
41790e4ef248SJed Brown 
41800e4ef248SJed Brown    Notes:
41810e4ef248SJed Brown    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
41820e4ef248SJed Brown    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
41830e4ef248SJed Brown 
4184db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
41850e4ef248SJed Brown @*/
41869371c9d4SSatish Balay PetscErrorCode TSComputeRHSFunctionLinear(TS ts, PetscReal t, Vec U, Vec F, void *ctx) {
41870e4ef248SJed Brown   Mat Arhs, Brhs;
41880e4ef248SJed Brown 
41890e4ef248SJed Brown   PetscFunctionBegin;
41909566063dSJacob Faibussowitsch   PetscCall(TSGetRHSMats_Private(ts, &Arhs, &Brhs));
41912663174eSHong Zhang   /* undo the damage caused by shifting */
41929566063dSJacob Faibussowitsch   PetscCall(TSRecoverRHSJacobian(ts, Arhs, Brhs));
41939566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSJacobian(ts, t, U, Arhs, Brhs));
41949566063dSJacob Faibussowitsch   PetscCall(MatMult(Arhs, U, F));
41950e4ef248SJed Brown   PetscFunctionReturn(0);
41960e4ef248SJed Brown }
41970e4ef248SJed Brown 
41980e4ef248SJed Brown /*@C
41990e4ef248SJed Brown    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
42000e4ef248SJed Brown 
42010e4ef248SJed Brown    Collective on TS
42020e4ef248SJed Brown 
42034165533cSJose E. Roman    Input Parameters:
42040e4ef248SJed Brown +  ts - time stepping context
42050e4ef248SJed Brown .  t - time at which to evaluate
42060910c330SBarry Smith .  U - state at which to evaluate
42070e4ef248SJed Brown -  ctx - context
42080e4ef248SJed Brown 
42094165533cSJose E. Roman    Output Parameters:
42100e4ef248SJed Brown +  A - pointer to operator
421197bb3fdcSJose E. Roman -  B - pointer to preconditioning matrix
42120e4ef248SJed Brown 
42130e4ef248SJed Brown    Level: intermediate
42140e4ef248SJed Brown 
42150e4ef248SJed Brown    Notes:
42160e4ef248SJed Brown    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
42170e4ef248SJed Brown 
4218db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSFunctionLinear()`
42190e4ef248SJed Brown @*/
42209371c9d4SSatish Balay PetscErrorCode TSComputeRHSJacobianConstant(TS ts, PetscReal t, Vec U, Mat A, Mat B, void *ctx) {
42210e4ef248SJed Brown   PetscFunctionBegin;
42220e4ef248SJed Brown   PetscFunctionReturn(0);
42230e4ef248SJed Brown }
42240e4ef248SJed Brown 
42250026cea9SSean Farley /*@C
42260026cea9SSean Farley    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
42270026cea9SSean Farley 
42280026cea9SSean Farley    Collective on TS
42290026cea9SSean Farley 
42304165533cSJose E. Roman    Input Parameters:
42310026cea9SSean Farley +  ts - time stepping context
42320026cea9SSean Farley .  t - time at which to evaluate
42330910c330SBarry Smith .  U - state at which to evaluate
42340910c330SBarry Smith .  Udot - time derivative of state vector
42350026cea9SSean Farley -  ctx - context
42360026cea9SSean Farley 
42374165533cSJose E. Roman    Output Parameter:
42380026cea9SSean Farley .  F - left hand side
42390026cea9SSean Farley 
42400026cea9SSean Farley    Level: intermediate
42410026cea9SSean Farley 
42420026cea9SSean Farley    Notes:
42430910c330SBarry 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
42440026cea9SSean Farley    user is required to write their own TSComputeIFunction.
42450026cea9SSean Farley    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
42460026cea9SSean Farley    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
42470026cea9SSean Farley 
42489ae8fd06SBarry Smith    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
42499ae8fd06SBarry Smith 
4250db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIJacobianConstant()`, `TSComputeRHSFunctionLinear()`
42510026cea9SSean Farley @*/
42529371c9d4SSatish Balay PetscErrorCode TSComputeIFunctionLinear(TS ts, PetscReal t, Vec U, Vec Udot, Vec F, void *ctx) {
42530026cea9SSean Farley   Mat A, B;
42540026cea9SSean Farley 
42550026cea9SSean Farley   PetscFunctionBegin;
42569566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts, &A, &B, NULL, NULL));
42579566063dSJacob Faibussowitsch   PetscCall(TSComputeIJacobian(ts, t, U, Udot, 1.0, A, B, PETSC_TRUE));
42589566063dSJacob Faibussowitsch   PetscCall(MatMult(A, Udot, F));
42590026cea9SSean Farley   PetscFunctionReturn(0);
42600026cea9SSean Farley }
42610026cea9SSean Farley 
42620026cea9SSean Farley /*@C
4263b41af12eSJed Brown    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
42640026cea9SSean Farley 
42650026cea9SSean Farley    Collective on TS
42660026cea9SSean Farley 
42674165533cSJose E. Roman    Input Parameters:
42680026cea9SSean Farley +  ts - time stepping context
42690026cea9SSean Farley .  t - time at which to evaluate
42700910c330SBarry Smith .  U - state at which to evaluate
42710910c330SBarry Smith .  Udot - time derivative of state vector
42720026cea9SSean Farley .  shift - shift to apply
42730026cea9SSean Farley -  ctx - context
42740026cea9SSean Farley 
42754165533cSJose E. Roman    Output Parameters:
42760026cea9SSean Farley +  A - pointer to operator
427797bb3fdcSJose E. Roman -  B - pointer to preconditioning matrix
42780026cea9SSean Farley 
4279b41af12eSJed Brown    Level: advanced
42800026cea9SSean Farley 
42810026cea9SSean Farley    Notes:
42820026cea9SSean Farley    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
42830026cea9SSean Farley 
4284b41af12eSJed Brown    It is only appropriate for problems of the form
4285b41af12eSJed Brown 
4286b41af12eSJed Brown $     M Udot = F(U,t)
4287b41af12eSJed Brown 
4288b41af12eSJed Brown   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
4289b41af12eSJed Brown   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
4290b41af12eSJed Brown   an implicit operator of the form
4291b41af12eSJed Brown 
4292b41af12eSJed Brown $    shift*M + J
4293b41af12eSJed Brown 
4294b41af12eSJed 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
4295b41af12eSJed Brown   a copy of M or reassemble it when requested.
4296b41af12eSJed Brown 
4297db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIFunctionLinear()`
42980026cea9SSean Farley @*/
42999371c9d4SSatish Balay PetscErrorCode TSComputeIJacobianConstant(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat A, Mat B, void *ctx) {
43000026cea9SSean Farley   PetscFunctionBegin;
43019566063dSJacob Faibussowitsch   PetscCall(MatScale(A, shift / ts->ijacobian.shift));
4302b41af12eSJed Brown   ts->ijacobian.shift = shift;
43030026cea9SSean Farley   PetscFunctionReturn(0);
43040026cea9SSean Farley }
4305b41af12eSJed Brown 
4306e817cc15SEmil Constantinescu /*@
4307e817cc15SEmil Constantinescu    TSGetEquationType - Gets the type of the equation that TS is solving.
4308e817cc15SEmil Constantinescu 
4309e817cc15SEmil Constantinescu    Not Collective
4310e817cc15SEmil Constantinescu 
4311e817cc15SEmil Constantinescu    Input Parameter:
4312e817cc15SEmil Constantinescu .  ts - the TS context
4313e817cc15SEmil Constantinescu 
4314e817cc15SEmil Constantinescu    Output Parameter:
43154e6b9ce4SEmil Constantinescu .  equation_type - see TSEquationType
4316e817cc15SEmil Constantinescu 
4317e817cc15SEmil Constantinescu    Level: beginner
4318e817cc15SEmil Constantinescu 
4319db781477SPatrick Sanan .seealso: `TSSetEquationType()`, `TSEquationType`
4320e817cc15SEmil Constantinescu @*/
43219371c9d4SSatish Balay PetscErrorCode TSGetEquationType(TS ts, TSEquationType *equation_type) {
4322e817cc15SEmil Constantinescu   PetscFunctionBegin;
4323e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4324e817cc15SEmil Constantinescu   PetscValidPointer(equation_type, 2);
4325e817cc15SEmil Constantinescu   *equation_type = ts->equation_type;
4326e817cc15SEmil Constantinescu   PetscFunctionReturn(0);
4327e817cc15SEmil Constantinescu }
4328e817cc15SEmil Constantinescu 
4329e817cc15SEmil Constantinescu /*@
4330e817cc15SEmil Constantinescu    TSSetEquationType - Sets the type of the equation that TS is solving.
4331e817cc15SEmil Constantinescu 
4332e817cc15SEmil Constantinescu    Not Collective
4333e817cc15SEmil Constantinescu 
4334d8d19677SJose E. Roman    Input Parameters:
4335e817cc15SEmil Constantinescu +  ts - the TS context
43361297b224SEmil Constantinescu -  equation_type - see TSEquationType
4337e817cc15SEmil Constantinescu 
4338e817cc15SEmil Constantinescu    Level: advanced
4339e817cc15SEmil Constantinescu 
4340db781477SPatrick Sanan .seealso: `TSGetEquationType()`, `TSEquationType`
4341e817cc15SEmil Constantinescu @*/
43429371c9d4SSatish Balay PetscErrorCode TSSetEquationType(TS ts, TSEquationType equation_type) {
4343e817cc15SEmil Constantinescu   PetscFunctionBegin;
4344e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4345e817cc15SEmil Constantinescu   ts->equation_type = equation_type;
4346e817cc15SEmil Constantinescu   PetscFunctionReturn(0);
4347e817cc15SEmil Constantinescu }
43480026cea9SSean Farley 
43494af1b03aSJed Brown /*@
43504af1b03aSJed Brown    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
43514af1b03aSJed Brown 
43524af1b03aSJed Brown    Not Collective
43534af1b03aSJed Brown 
43544af1b03aSJed Brown    Input Parameter:
43554af1b03aSJed Brown .  ts - the TS context
43564af1b03aSJed Brown 
43574af1b03aSJed Brown    Output Parameter:
43584af1b03aSJed Brown .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
43594af1b03aSJed Brown             manual pages for the individual convergence tests for complete lists
43604af1b03aSJed Brown 
4361487e0bb9SJed Brown    Level: beginner
43624af1b03aSJed Brown 
4363cd652676SJed Brown    Notes:
4364cd652676SJed Brown    Can only be called after the call to TSSolve() is complete.
43654af1b03aSJed Brown 
4366db781477SPatrick Sanan .seealso: `TSSetConvergenceTest()`, `TSConvergedReason`
43674af1b03aSJed Brown @*/
43689371c9d4SSatish Balay PetscErrorCode TSGetConvergedReason(TS ts, TSConvergedReason *reason) {
43694af1b03aSJed Brown   PetscFunctionBegin;
43704af1b03aSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
43714af1b03aSJed Brown   PetscValidPointer(reason, 2);
43724af1b03aSJed Brown   *reason = ts->reason;
43734af1b03aSJed Brown   PetscFunctionReturn(0);
43744af1b03aSJed Brown }
43754af1b03aSJed Brown 
4376d6ad946cSShri Abhyankar /*@
4377d6ad946cSShri Abhyankar    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
4378d6ad946cSShri Abhyankar 
43796b221cbeSPatrick Sanan    Logically Collective; reason must contain common value
4380d6ad946cSShri Abhyankar 
43816b221cbeSPatrick Sanan    Input Parameters:
4382d6ad946cSShri Abhyankar +  ts - the TS context
43836b221cbeSPatrick Sanan -  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4384d6ad946cSShri Abhyankar             manual pages for the individual convergence tests for complete lists
4385d6ad946cSShri Abhyankar 
4386f5abba47SShri Abhyankar    Level: advanced
4387d6ad946cSShri Abhyankar 
4388d6ad946cSShri Abhyankar    Notes:
43896b221cbeSPatrick Sanan    Can only be called while TSSolve() is active.
4390d6ad946cSShri Abhyankar 
4391db781477SPatrick Sanan .seealso: `TSConvergedReason`
4392d6ad946cSShri Abhyankar @*/
43939371c9d4SSatish Balay PetscErrorCode TSSetConvergedReason(TS ts, TSConvergedReason reason) {
4394d6ad946cSShri Abhyankar   PetscFunctionBegin;
4395d6ad946cSShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4396d6ad946cSShri Abhyankar   ts->reason = reason;
4397d6ad946cSShri Abhyankar   PetscFunctionReturn(0);
4398d6ad946cSShri Abhyankar }
4399d6ad946cSShri Abhyankar 
4400cc708dedSBarry Smith /*@
4401cc708dedSBarry Smith    TSGetSolveTime - Gets the time after a call to TSSolve()
4402cc708dedSBarry Smith 
4403cc708dedSBarry Smith    Not Collective
4404cc708dedSBarry Smith 
4405cc708dedSBarry Smith    Input Parameter:
4406cc708dedSBarry Smith .  ts - the TS context
4407cc708dedSBarry Smith 
4408cc708dedSBarry Smith    Output Parameter:
440919eac22cSLisandro Dalcin .  ftime - the final time. This time corresponds to the final time set with TSSetMaxTime()
4410cc708dedSBarry Smith 
4411487e0bb9SJed Brown    Level: beginner
4412cc708dedSBarry Smith 
4413cc708dedSBarry Smith    Notes:
4414cc708dedSBarry Smith    Can only be called after the call to TSSolve() is complete.
4415cc708dedSBarry Smith 
4416db781477SPatrick Sanan .seealso: `TSSetConvergenceTest()`, `TSConvergedReason`
4417cc708dedSBarry Smith @*/
44189371c9d4SSatish Balay PetscErrorCode TSGetSolveTime(TS ts, PetscReal *ftime) {
4419cc708dedSBarry Smith   PetscFunctionBegin;
4420cc708dedSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4421dadcf809SJacob Faibussowitsch   PetscValidRealPointer(ftime, 2);
4422cc708dedSBarry Smith   *ftime = ts->solvetime;
4423cc708dedSBarry Smith   PetscFunctionReturn(0);
4424cc708dedSBarry Smith }
4425cc708dedSBarry Smith 
44262c18e0fdSBarry Smith /*@
44275ef26d82SJed Brown    TSGetSNESIterations - Gets the total number of nonlinear iterations
44289f67acb7SJed Brown    used by the time integrator.
44299f67acb7SJed Brown 
44309f67acb7SJed Brown    Not Collective
44319f67acb7SJed Brown 
44329f67acb7SJed Brown    Input Parameter:
44339f67acb7SJed Brown .  ts - TS context
44349f67acb7SJed Brown 
44359f67acb7SJed Brown    Output Parameter:
44369f67acb7SJed Brown .  nits - number of nonlinear iterations
44379f67acb7SJed Brown 
44389f67acb7SJed Brown    Notes:
44399f67acb7SJed Brown    This counter is reset to zero for each successive call to TSSolve().
44409f67acb7SJed Brown 
44419f67acb7SJed Brown    Level: intermediate
44429f67acb7SJed Brown 
4443db781477SPatrick Sanan .seealso: `TSGetKSPIterations()`
44449f67acb7SJed Brown @*/
44459371c9d4SSatish Balay PetscErrorCode TSGetSNESIterations(TS ts, PetscInt *nits) {
44469f67acb7SJed Brown   PetscFunctionBegin;
44479f67acb7SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
44489f67acb7SJed Brown   PetscValidIntPointer(nits, 2);
44495ef26d82SJed Brown   *nits = ts->snes_its;
44509f67acb7SJed Brown   PetscFunctionReturn(0);
44519f67acb7SJed Brown }
44529f67acb7SJed Brown 
44539f67acb7SJed Brown /*@
44545ef26d82SJed Brown    TSGetKSPIterations - Gets the total number of linear iterations
44559f67acb7SJed Brown    used by the time integrator.
44569f67acb7SJed Brown 
44579f67acb7SJed Brown    Not Collective
44589f67acb7SJed Brown 
44599f67acb7SJed Brown    Input Parameter:
44609f67acb7SJed Brown .  ts - TS context
44619f67acb7SJed Brown 
44629f67acb7SJed Brown    Output Parameter:
44639f67acb7SJed Brown .  lits - number of linear iterations
44649f67acb7SJed Brown 
44659f67acb7SJed Brown    Notes:
44669f67acb7SJed Brown    This counter is reset to zero for each successive call to TSSolve().
44679f67acb7SJed Brown 
44689f67acb7SJed Brown    Level: intermediate
44699f67acb7SJed Brown 
4470db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `SNESGetKSPIterations()`
44719f67acb7SJed Brown @*/
44729371c9d4SSatish Balay PetscErrorCode TSGetKSPIterations(TS ts, PetscInt *lits) {
44739f67acb7SJed Brown   PetscFunctionBegin;
44749f67acb7SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
44759f67acb7SJed Brown   PetscValidIntPointer(lits, 2);
44765ef26d82SJed Brown   *lits = ts->ksp_its;
44779f67acb7SJed Brown   PetscFunctionReturn(0);
44789f67acb7SJed Brown }
44799f67acb7SJed Brown 
4480cef5090cSJed Brown /*@
4481cef5090cSJed Brown    TSGetStepRejections - Gets the total number of rejected steps.
4482cef5090cSJed Brown 
4483cef5090cSJed Brown    Not Collective
4484cef5090cSJed Brown 
4485cef5090cSJed Brown    Input Parameter:
4486cef5090cSJed Brown .  ts - TS context
4487cef5090cSJed Brown 
4488cef5090cSJed Brown    Output Parameter:
4489cef5090cSJed Brown .  rejects - number of steps rejected
4490cef5090cSJed Brown 
4491cef5090cSJed Brown    Notes:
4492cef5090cSJed Brown    This counter is reset to zero for each successive call to TSSolve().
4493cef5090cSJed Brown 
4494cef5090cSJed Brown    Level: intermediate
4495cef5090cSJed Brown 
4496db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetSNESFailures()`, `TSSetMaxSNESFailures()`, `TSSetErrorIfStepFails()`
4497cef5090cSJed Brown @*/
44989371c9d4SSatish Balay PetscErrorCode TSGetStepRejections(TS ts, PetscInt *rejects) {
4499cef5090cSJed Brown   PetscFunctionBegin;
4500cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4501cef5090cSJed Brown   PetscValidIntPointer(rejects, 2);
4502cef5090cSJed Brown   *rejects = ts->reject;
4503cef5090cSJed Brown   PetscFunctionReturn(0);
4504cef5090cSJed Brown }
4505cef5090cSJed Brown 
4506cef5090cSJed Brown /*@
4507cef5090cSJed Brown    TSGetSNESFailures - Gets the total number of failed SNES solves
4508cef5090cSJed Brown 
4509cef5090cSJed Brown    Not Collective
4510cef5090cSJed Brown 
4511cef5090cSJed Brown    Input Parameter:
4512cef5090cSJed Brown .  ts - TS context
4513cef5090cSJed Brown 
4514cef5090cSJed Brown    Output Parameter:
4515cef5090cSJed Brown .  fails - number of failed nonlinear solves
4516cef5090cSJed Brown 
4517cef5090cSJed Brown    Notes:
4518cef5090cSJed Brown    This counter is reset to zero for each successive call to TSSolve().
4519cef5090cSJed Brown 
4520cef5090cSJed Brown    Level: intermediate
4521cef5090cSJed Brown 
4522db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSSetMaxSNESFailures()`
4523cef5090cSJed Brown @*/
45249371c9d4SSatish Balay PetscErrorCode TSGetSNESFailures(TS ts, PetscInt *fails) {
4525cef5090cSJed Brown   PetscFunctionBegin;
4526cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4527cef5090cSJed Brown   PetscValidIntPointer(fails, 2);
4528cef5090cSJed Brown   *fails = ts->num_snes_failures;
4529cef5090cSJed Brown   PetscFunctionReturn(0);
4530cef5090cSJed Brown }
4531cef5090cSJed Brown 
4532cef5090cSJed Brown /*@
4533cef5090cSJed Brown    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
4534cef5090cSJed Brown 
4535cef5090cSJed Brown    Not Collective
4536cef5090cSJed Brown 
4537d8d19677SJose E. Roman    Input Parameters:
4538cef5090cSJed Brown +  ts - TS context
4539cef5090cSJed Brown -  rejects - maximum number of rejected steps, pass -1 for unlimited
4540cef5090cSJed Brown 
4541cef5090cSJed Brown    Notes:
4542cef5090cSJed Brown    The counter is reset to zero for each step
4543cef5090cSJed Brown 
4544cef5090cSJed Brown    Options Database Key:
4545cef5090cSJed Brown .  -ts_max_reject - Maximum number of step rejections before a step fails
4546cef5090cSJed Brown 
4547cef5090cSJed Brown    Level: intermediate
4548cef5090cSJed Brown 
4549db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxSNESFailures()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSSetErrorIfStepFails()`, `TSGetConvergedReason()`
4550cef5090cSJed Brown @*/
45519371c9d4SSatish Balay PetscErrorCode TSSetMaxStepRejections(TS ts, PetscInt rejects) {
4552cef5090cSJed Brown   PetscFunctionBegin;
4553cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4554cef5090cSJed Brown   ts->max_reject = rejects;
4555cef5090cSJed Brown   PetscFunctionReturn(0);
4556cef5090cSJed Brown }
4557cef5090cSJed Brown 
4558cef5090cSJed Brown /*@
4559cef5090cSJed Brown    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
4560cef5090cSJed Brown 
4561cef5090cSJed Brown    Not Collective
4562cef5090cSJed Brown 
4563d8d19677SJose E. Roman    Input Parameters:
4564cef5090cSJed Brown +  ts - TS context
4565cef5090cSJed Brown -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
4566cef5090cSJed Brown 
4567cef5090cSJed Brown    Notes:
4568cef5090cSJed Brown    The counter is reset to zero for each successive call to TSSolve().
4569cef5090cSJed Brown 
4570cef5090cSJed Brown    Options Database Key:
4571cef5090cSJed Brown .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
4572cef5090cSJed Brown 
4573cef5090cSJed Brown    Level: intermediate
4574cef5090cSJed Brown 
4575db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `SNESGetConvergedReason()`, `TSGetConvergedReason()`
4576cef5090cSJed Brown @*/
45779371c9d4SSatish Balay PetscErrorCode TSSetMaxSNESFailures(TS ts, PetscInt fails) {
4578cef5090cSJed Brown   PetscFunctionBegin;
4579cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4580cef5090cSJed Brown   ts->max_snes_failures = fails;
4581cef5090cSJed Brown   PetscFunctionReturn(0);
4582cef5090cSJed Brown }
4583cef5090cSJed Brown 
4584cef5090cSJed Brown /*@
4585cef5090cSJed Brown    TSSetErrorIfStepFails - Error if no step succeeds
4586cef5090cSJed Brown 
4587cef5090cSJed Brown    Not Collective
4588cef5090cSJed Brown 
4589d8d19677SJose E. Roman    Input Parameters:
4590cef5090cSJed Brown +  ts - TS context
4591cef5090cSJed Brown -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
4592cef5090cSJed Brown 
4593cef5090cSJed Brown    Options Database Key:
4594cef5090cSJed Brown .  -ts_error_if_step_fails - Error if no step succeeds
4595cef5090cSJed Brown 
4596cef5090cSJed Brown    Level: intermediate
4597cef5090cSJed Brown 
4598db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSSetErrorIfStepFails()`, `TSGetConvergedReason()`
4599cef5090cSJed Brown @*/
46009371c9d4SSatish Balay PetscErrorCode TSSetErrorIfStepFails(TS ts, PetscBool err) {
4601cef5090cSJed Brown   PetscFunctionBegin;
4602cef5090cSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4603cef5090cSJed Brown   ts->errorifstepfailed = err;
4604cef5090cSJed Brown   PetscFunctionReturn(0);
4605cef5090cSJed Brown }
4606cef5090cSJed Brown 
460784df9cb4SJed Brown /*@
4608552698daSJed Brown    TSGetAdapt - Get the adaptive controller context for the current method
460984df9cb4SJed Brown 
4610ed81e22dSJed Brown    Collective on TS if controller has not been created yet
461184df9cb4SJed Brown 
46124165533cSJose E. Roman    Input Parameter:
4613ed81e22dSJed Brown .  ts - time stepping context
461484df9cb4SJed Brown 
46154165533cSJose E. Roman    Output Parameter:
4616ed81e22dSJed Brown .  adapt - adaptive controller
461784df9cb4SJed Brown 
461884df9cb4SJed Brown    Level: intermediate
461984df9cb4SJed Brown 
4620db781477SPatrick Sanan .seealso: `TSAdapt`, `TSAdaptSetType()`, `TSAdaptChoose()`
462184df9cb4SJed Brown @*/
46229371c9d4SSatish Balay PetscErrorCode TSGetAdapt(TS ts, TSAdapt *adapt) {
462384df9cb4SJed Brown   PetscFunctionBegin;
462484df9cb4SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4625bec58848SLisandro Dalcin   PetscValidPointer(adapt, 2);
462684df9cb4SJed Brown   if (!ts->adapt) {
46279566063dSJacob Faibussowitsch     PetscCall(TSAdaptCreate(PetscObjectComm((PetscObject)ts), &ts->adapt));
46289566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)ts, (PetscObject)ts->adapt));
46299566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->adapt, (PetscObject)ts, 1));
463084df9cb4SJed Brown   }
4631bec58848SLisandro Dalcin   *adapt = ts->adapt;
463284df9cb4SJed Brown   PetscFunctionReturn(0);
463384df9cb4SJed Brown }
4634d6ebe24aSShri Abhyankar 
46351c3436cfSJed Brown /*@
46361c3436cfSJed Brown    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
46371c3436cfSJed Brown 
46381c3436cfSJed Brown    Logically Collective
46391c3436cfSJed Brown 
46404165533cSJose E. Roman    Input Parameters:
46411c3436cfSJed Brown +  ts - time integration context
46421c3436cfSJed Brown .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
46430298fd71SBarry Smith .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
46441c3436cfSJed Brown .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
46450298fd71SBarry Smith -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
46461c3436cfSJed Brown 
4647a3cdaa26SBarry Smith    Options Database keys:
4648a3cdaa26SBarry Smith +  -ts_rtol <rtol> - relative tolerance for local truncation error
464967b8a455SSatish Balay -  -ts_atol <atol> - Absolute tolerance for local truncation error
4650a3cdaa26SBarry Smith 
46513ff766beSShri Abhyankar    Notes:
46523ff766beSShri Abhyankar    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
46533ff766beSShri Abhyankar    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
46543ff766beSShri Abhyankar    computed only for the differential or the algebraic part then this can be done using the vector of
46553ff766beSShri Abhyankar    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
46563ff766beSShri Abhyankar    differential part and infinity for the algebraic part, the LTE calculation will include only the
46573ff766beSShri Abhyankar    differential variables.
46583ff766beSShri Abhyankar 
46591c3436cfSJed Brown    Level: beginner
46601c3436cfSJed Brown 
4661db781477SPatrick Sanan .seealso: `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSGetTolerances()`
46621c3436cfSJed Brown @*/
46639371c9d4SSatish Balay PetscErrorCode TSSetTolerances(TS ts, PetscReal atol, Vec vatol, PetscReal rtol, Vec vrtol) {
46641c3436cfSJed Brown   PetscFunctionBegin;
4665c5033834SJed Brown   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
46661c3436cfSJed Brown   if (vatol) {
46679566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vatol));
46689566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vatol));
46691c3436cfSJed Brown     ts->vatol = vatol;
46701c3436cfSJed Brown   }
4671c5033834SJed Brown   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
46721c3436cfSJed Brown   if (vrtol) {
46739566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vrtol));
46749566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vrtol));
46751c3436cfSJed Brown     ts->vrtol = vrtol;
46761c3436cfSJed Brown   }
46771c3436cfSJed Brown   PetscFunctionReturn(0);
46781c3436cfSJed Brown }
46791c3436cfSJed Brown 
4680c5033834SJed Brown /*@
4681c5033834SJed Brown    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
4682c5033834SJed Brown 
4683c5033834SJed Brown    Logically Collective
4684c5033834SJed Brown 
46854165533cSJose E. Roman    Input Parameter:
4686c5033834SJed Brown .  ts - time integration context
4687c5033834SJed Brown 
46884165533cSJose E. Roman    Output Parameters:
46890298fd71SBarry Smith +  atol - scalar absolute tolerances, NULL to ignore
46900298fd71SBarry Smith .  vatol - vector of absolute tolerances, NULL to ignore
46910298fd71SBarry Smith .  rtol - scalar relative tolerances, NULL to ignore
46920298fd71SBarry Smith -  vrtol - vector of relative tolerances, NULL to ignore
4693c5033834SJed Brown 
4694c5033834SJed Brown    Level: beginner
4695c5033834SJed Brown 
4696db781477SPatrick Sanan .seealso: `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSSetTolerances()`
4697c5033834SJed Brown @*/
46989371c9d4SSatish Balay PetscErrorCode TSGetTolerances(TS ts, PetscReal *atol, Vec *vatol, PetscReal *rtol, Vec *vrtol) {
4699c5033834SJed Brown   PetscFunctionBegin;
4700c5033834SJed Brown   if (atol) *atol = ts->atol;
4701c5033834SJed Brown   if (vatol) *vatol = ts->vatol;
4702c5033834SJed Brown   if (rtol) *rtol = ts->rtol;
4703c5033834SJed Brown   if (vrtol) *vrtol = ts->vrtol;
4704c5033834SJed Brown   PetscFunctionReturn(0);
4705c5033834SJed Brown }
4706c5033834SJed Brown 
47079c6b16b5SShri Abhyankar /*@
4708a4868fbcSLisandro Dalcin    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
47099c6b16b5SShri Abhyankar 
47109c6b16b5SShri Abhyankar    Collective on TS
47119c6b16b5SShri Abhyankar 
47124165533cSJose E. Roman    Input Parameters:
47139c6b16b5SShri Abhyankar +  ts - time stepping context
4714a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
4715a4868fbcSLisandro Dalcin -  Y - state vector to be compared to U
47169c6b16b5SShri Abhyankar 
47174165533cSJose E. Roman    Output Parameters:
4718a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
47197453f775SEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
4720a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
47219c6b16b5SShri Abhyankar 
47229c6b16b5SShri Abhyankar    Level: developer
47239c6b16b5SShri Abhyankar 
4724db781477SPatrick Sanan .seealso: `TSErrorWeightedNorm()`, `TSErrorWeightedNormInfinity()`
47259c6b16b5SShri Abhyankar @*/
47269371c9d4SSatish Balay PetscErrorCode TSErrorWeightedNorm2(TS ts, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr) {
47279c6b16b5SShri Abhyankar   PetscInt           i, n, N, rstart;
47287453f775SEmil Constantinescu   PetscInt           n_loc, na_loc, nr_loc;
47297453f775SEmil Constantinescu   PetscReal          n_glb, na_glb, nr_glb;
47309c6b16b5SShri Abhyankar   const PetscScalar *u, *y;
47317453f775SEmil Constantinescu   PetscReal          sum, suma, sumr, gsum, gsuma, gsumr, diff;
47327453f775SEmil Constantinescu   PetscReal          tol, tola, tolr;
47337453f775SEmil Constantinescu   PetscReal          err_loc[6], err_glb[6];
47349c6b16b5SShri Abhyankar 
47359c6b16b5SShri Abhyankar   PetscFunctionBegin;
47369c6b16b5SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4737a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
4738a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(Y, VEC_CLASSID, 3);
4739a4868fbcSLisandro Dalcin   PetscValidType(U, 2);
4740a4868fbcSLisandro Dalcin   PetscValidType(Y, 3);
4741a4868fbcSLisandro Dalcin   PetscCheckSameComm(U, 2, Y, 3);
4742dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 4);
4743dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 5);
4744dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 6);
47453c633725SBarry Smith   PetscCheck(U != Y, PetscObjectComm((PetscObject)U), PETSC_ERR_ARG_IDN, "U and Y cannot be the same vector");
47469c6b16b5SShri Abhyankar 
47479566063dSJacob Faibussowitsch   PetscCall(VecGetSize(U, &N));
47489566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &n));
47499566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(U, &rstart, NULL));
47509566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
47519566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
47529371c9d4SSatish Balay   sum    = 0.;
47539371c9d4SSatish Balay   n_loc  = 0;
47549371c9d4SSatish Balay   suma   = 0.;
47559371c9d4SSatish Balay   na_loc = 0;
47569371c9d4SSatish Balay   sumr   = 0.;
47579371c9d4SSatish Balay   nr_loc = 0;
47589c6b16b5SShri Abhyankar   if (ts->vatol && ts->vrtol) {
47599c6b16b5SShri Abhyankar     const PetscScalar *atol, *rtol;
47609566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
47619566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
47629c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
476376cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
47647453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
47657453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
47667453f775SEmil Constantinescu       if (tola > 0.) {
47677453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
47687453f775SEmil Constantinescu         na_loc++;
47697453f775SEmil Constantinescu       }
47707453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
47717453f775SEmil Constantinescu       if (tolr > 0.) {
47727453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
47737453f775SEmil Constantinescu         nr_loc++;
47747453f775SEmil Constantinescu       }
47757453f775SEmil Constantinescu       tol = tola + tolr;
47767453f775SEmil Constantinescu       if (tol > 0.) {
47777453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
47787453f775SEmil Constantinescu         n_loc++;
47797453f775SEmil Constantinescu       }
47809c6b16b5SShri Abhyankar     }
47819566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
47829566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
47839c6b16b5SShri Abhyankar   } else if (ts->vatol) { /* vector atol, scalar rtol */
47849c6b16b5SShri Abhyankar     const PetscScalar *atol;
47859566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
47869c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
478776cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
47887453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
47897453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
47907453f775SEmil Constantinescu       if (tola > 0.) {
47917453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
47927453f775SEmil Constantinescu         na_loc++;
47937453f775SEmil Constantinescu       }
47947453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
47957453f775SEmil Constantinescu       if (tolr > 0.) {
47967453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
47977453f775SEmil Constantinescu         nr_loc++;
47987453f775SEmil Constantinescu       }
47997453f775SEmil Constantinescu       tol = tola + tolr;
48007453f775SEmil Constantinescu       if (tol > 0.) {
48017453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
48027453f775SEmil Constantinescu         n_loc++;
48037453f775SEmil Constantinescu       }
48049c6b16b5SShri Abhyankar     }
48059566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
48069c6b16b5SShri Abhyankar   } else if (ts->vrtol) { /* scalar atol, vector rtol */
48079c6b16b5SShri Abhyankar     const PetscScalar *rtol;
48089566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
48099c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
481076cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
48117453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
48127453f775SEmil Constantinescu       tola = ts->atol;
48137453f775SEmil Constantinescu       if (tola > 0.) {
48147453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
48157453f775SEmil Constantinescu         na_loc++;
48167453f775SEmil Constantinescu       }
48177453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
48187453f775SEmil Constantinescu       if (tolr > 0.) {
48197453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
48207453f775SEmil Constantinescu         nr_loc++;
48217453f775SEmil Constantinescu       }
48227453f775SEmil Constantinescu       tol = tola + tolr;
48237453f775SEmil Constantinescu       if (tol > 0.) {
48247453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
48257453f775SEmil Constantinescu         n_loc++;
48267453f775SEmil Constantinescu       }
48279c6b16b5SShri Abhyankar     }
48289566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
48299c6b16b5SShri Abhyankar   } else { /* scalar atol, scalar rtol */
48309c6b16b5SShri Abhyankar     for (i = 0; i < n; i++) {
483176cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
48327453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
48337453f775SEmil Constantinescu       tola = ts->atol;
48347453f775SEmil Constantinescu       if (tola > 0.) {
48357453f775SEmil Constantinescu         suma += PetscSqr(diff / tola);
48367453f775SEmil Constantinescu         na_loc++;
48377453f775SEmil Constantinescu       }
48387453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
48397453f775SEmil Constantinescu       if (tolr > 0.) {
48407453f775SEmil Constantinescu         sumr += PetscSqr(diff / tolr);
48417453f775SEmil Constantinescu         nr_loc++;
48427453f775SEmil Constantinescu       }
48437453f775SEmil Constantinescu       tol = tola + tolr;
48447453f775SEmil Constantinescu       if (tol > 0.) {
48457453f775SEmil Constantinescu         sum += PetscSqr(diff / tol);
48467453f775SEmil Constantinescu         n_loc++;
48477453f775SEmil Constantinescu       }
48489c6b16b5SShri Abhyankar     }
48499c6b16b5SShri Abhyankar   }
48509566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
48519566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
48529c6b16b5SShri Abhyankar 
48537453f775SEmil Constantinescu   err_loc[0] = sum;
48547453f775SEmil Constantinescu   err_loc[1] = suma;
48557453f775SEmil Constantinescu   err_loc[2] = sumr;
48567453f775SEmil Constantinescu   err_loc[3] = (PetscReal)n_loc;
48577453f775SEmil Constantinescu   err_loc[4] = (PetscReal)na_loc;
48587453f775SEmil Constantinescu   err_loc[5] = (PetscReal)nr_loc;
48597453f775SEmil Constantinescu 
48601c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 6, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ts)));
48617453f775SEmil Constantinescu 
48627453f775SEmil Constantinescu   gsum   = err_glb[0];
48637453f775SEmil Constantinescu   gsuma  = err_glb[1];
48647453f775SEmil Constantinescu   gsumr  = err_glb[2];
48657453f775SEmil Constantinescu   n_glb  = err_glb[3];
48667453f775SEmil Constantinescu   na_glb = err_glb[4];
48677453f775SEmil Constantinescu   nr_glb = err_glb[5];
48687453f775SEmil Constantinescu 
4869b1316ef9SEmil Constantinescu   *norm = 0.;
48701e66621cSBarry Smith   if (n_glb > 0.) *norm = PetscSqrtReal(gsum / n_glb);
4871b1316ef9SEmil Constantinescu   *norma = 0.;
48721e66621cSBarry Smith   if (na_glb > 0.) *norma = PetscSqrtReal(gsuma / na_glb);
4873b1316ef9SEmil Constantinescu   *normr = 0.;
48741e66621cSBarry Smith   if (nr_glb > 0.) *normr = PetscSqrtReal(gsumr / nr_glb);
48759c6b16b5SShri Abhyankar 
48763c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
48773c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
48783c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
48799c6b16b5SShri Abhyankar   PetscFunctionReturn(0);
48809c6b16b5SShri Abhyankar }
48819c6b16b5SShri Abhyankar 
48829c6b16b5SShri Abhyankar /*@
4883a4868fbcSLisandro Dalcin    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
48849c6b16b5SShri Abhyankar 
48859c6b16b5SShri Abhyankar    Collective on TS
48869c6b16b5SShri Abhyankar 
48874165533cSJose E. Roman    Input Parameters:
48889c6b16b5SShri Abhyankar +  ts - time stepping context
4889a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
4890a4868fbcSLisandro Dalcin -  Y - state vector to be compared to U
48919c6b16b5SShri Abhyankar 
48924165533cSJose E. Roman    Output Parameters:
4893a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
48947453f775SEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
4895a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
48969c6b16b5SShri Abhyankar 
48979c6b16b5SShri Abhyankar    Level: developer
48989c6b16b5SShri Abhyankar 
4899db781477SPatrick Sanan .seealso: `TSErrorWeightedNorm()`, `TSErrorWeightedNorm2()`
49009c6b16b5SShri Abhyankar @*/
49019371c9d4SSatish Balay PetscErrorCode TSErrorWeightedNormInfinity(TS ts, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr) {
49027453f775SEmil Constantinescu   PetscInt           i, n, N, rstart;
49039c6b16b5SShri Abhyankar   const PetscScalar *u, *y;
49047453f775SEmil Constantinescu   PetscReal          max, gmax, maxa, gmaxa, maxr, gmaxr;
49057453f775SEmil Constantinescu   PetscReal          tol, tola, tolr, diff;
49067453f775SEmil Constantinescu   PetscReal          err_loc[3], err_glb[3];
49079c6b16b5SShri Abhyankar 
49089c6b16b5SShri Abhyankar   PetscFunctionBegin;
49099c6b16b5SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
4910a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(U, VEC_CLASSID, 2);
4911a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(Y, VEC_CLASSID, 3);
4912a4868fbcSLisandro Dalcin   PetscValidType(U, 2);
4913a4868fbcSLisandro Dalcin   PetscValidType(Y, 3);
4914a4868fbcSLisandro Dalcin   PetscCheckSameComm(U, 2, Y, 3);
4915dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 4);
4916dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 5);
4917dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 6);
49183c633725SBarry Smith   PetscCheck(U != Y, PetscObjectComm((PetscObject)U), PETSC_ERR_ARG_IDN, "U and Y cannot be the same vector");
49199c6b16b5SShri Abhyankar 
49209566063dSJacob Faibussowitsch   PetscCall(VecGetSize(U, &N));
49219566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U, &n));
49229566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(U, &rstart, NULL));
49239566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
49249566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
49257453f775SEmil Constantinescu 
49267453f775SEmil Constantinescu   max  = 0.;
49277453f775SEmil Constantinescu   maxa = 0.;
49287453f775SEmil Constantinescu   maxr = 0.;
49297453f775SEmil Constantinescu 
49307453f775SEmil Constantinescu   if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */
49319c6b16b5SShri Abhyankar     const PetscScalar *atol, *rtol;
49329566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
49339566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
49347453f775SEmil Constantinescu 
49357453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
493676cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
49377453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49387453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
49397453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
49407453f775SEmil Constantinescu       tol  = tola + tolr;
49411e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
49421e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
49431e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
49449c6b16b5SShri Abhyankar     }
49459566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
49469566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
49479c6b16b5SShri Abhyankar   } else if (ts->vatol) { /* vector atol, scalar rtol */
49489c6b16b5SShri Abhyankar     const PetscScalar *atol;
49499566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
49507453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
495176cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
49527453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49537453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
49547453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
49557453f775SEmil Constantinescu       tol  = tola + tolr;
49561e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
49571e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
49581e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
49599c6b16b5SShri Abhyankar     }
49609566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
49619c6b16b5SShri Abhyankar   } else if (ts->vrtol) { /* scalar atol, vector rtol */
49629c6b16b5SShri Abhyankar     const PetscScalar *rtol;
49639566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
49647453f775SEmil Constantinescu 
49657453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
496676cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
49677453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49687453f775SEmil Constantinescu       tola = ts->atol;
49697453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
49707453f775SEmil Constantinescu       tol  = tola + tolr;
49711e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
49721e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
49731e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
49749c6b16b5SShri Abhyankar     }
49759566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
49769c6b16b5SShri Abhyankar   } else { /* scalar atol, scalar rtol */
49777453f775SEmil Constantinescu 
49787453f775SEmil Constantinescu     for (i = 0; i < n; i++) {
497976cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
49807453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49817453f775SEmil Constantinescu       tola = ts->atol;
49827453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
49837453f775SEmil Constantinescu       tol  = tola + tolr;
49841e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, diff / tola);
49851e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, diff / tolr);
49861e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, diff / tol);
49879c6b16b5SShri Abhyankar     }
49889c6b16b5SShri Abhyankar   }
49899566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
49909566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
49917453f775SEmil Constantinescu   err_loc[0] = max;
49927453f775SEmil Constantinescu   err_loc[1] = maxa;
49937453f775SEmil Constantinescu   err_loc[2] = maxr;
49941c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)ts)));
49957453f775SEmil Constantinescu   gmax  = err_glb[0];
49967453f775SEmil Constantinescu   gmaxa = err_glb[1];
49977453f775SEmil Constantinescu   gmaxr = err_glb[2];
49989c6b16b5SShri Abhyankar 
49999c6b16b5SShri Abhyankar   *norm  = gmax;
50007453f775SEmil Constantinescu   *norma = gmaxa;
50017453f775SEmil Constantinescu   *normr = gmaxr;
50023c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
50033c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
50043c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
50059c6b16b5SShri Abhyankar   PetscFunctionReturn(0);
50069c6b16b5SShri Abhyankar }
50079c6b16b5SShri Abhyankar 
50081c3436cfSJed Brown /*@
50098a175baeSEmil Constantinescu    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
50101c3436cfSJed Brown 
50111c3436cfSJed Brown    Collective on TS
50121c3436cfSJed Brown 
50134165533cSJose E. Roman    Input Parameters:
50141c3436cfSJed Brown +  ts - time stepping context
5015a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
5016a4868fbcSLisandro Dalcin .  Y - state vector to be compared to U
5017a4868fbcSLisandro Dalcin -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
50187619abb3SShri 
50194165533cSJose E. Roman    Output Parameters:
5020a2b725a8SWilliam Gropp +  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
50218a175baeSEmil Constantinescu .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5022a2b725a8SWilliam Gropp -  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
5023a4868fbcSLisandro Dalcin 
5024a4868fbcSLisandro Dalcin    Options Database Keys:
5025a4868fbcSLisandro Dalcin .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
5026a4868fbcSLisandro Dalcin 
50271c3436cfSJed Brown    Level: developer
50281c3436cfSJed Brown 
5029db781477SPatrick Sanan .seealso: `TSErrorWeightedNormInfinity()`, `TSErrorWeightedNorm2()`, `TSErrorWeightedENorm`
50301c3436cfSJed Brown @*/
50319371c9d4SSatish Balay PetscErrorCode TSErrorWeightedNorm(TS ts, Vec U, Vec Y, NormType wnormtype, PetscReal *norm, PetscReal *norma, PetscReal *normr) {
50321c3436cfSJed Brown   PetscFunctionBegin;
50331e66621cSBarry Smith   if (wnormtype == NORM_2) PetscCall(TSErrorWeightedNorm2(ts, U, Y, norm, norma, normr));
50341e66621cSBarry Smith   else if (wnormtype == NORM_INFINITY) PetscCall(TSErrorWeightedNormInfinity(ts, U, Y, norm, norma, normr));
50351e66621cSBarry Smith   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
50361c3436cfSJed Brown   PetscFunctionReturn(0);
50371c3436cfSJed Brown }
50381c3436cfSJed Brown 
50398a175baeSEmil Constantinescu /*@
50408a175baeSEmil Constantinescu    TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances
50418a175baeSEmil Constantinescu 
50428a175baeSEmil Constantinescu    Collective on TS
50438a175baeSEmil Constantinescu 
50444165533cSJose E. Roman    Input Parameters:
50458a175baeSEmil Constantinescu +  ts - time stepping context
50468a175baeSEmil Constantinescu .  E - error vector
50478a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
50488a175baeSEmil Constantinescu -  Y - state vector, previous time step
50498a175baeSEmil Constantinescu 
50504165533cSJose E. Roman    Output Parameters:
5051a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
50528a175baeSEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5053a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
50548a175baeSEmil Constantinescu 
50558a175baeSEmil Constantinescu    Level: developer
50568a175baeSEmil Constantinescu 
5057db781477SPatrick Sanan .seealso: `TSErrorWeightedENorm()`, `TSErrorWeightedENormInfinity()`
50588a175baeSEmil Constantinescu @*/
50599371c9d4SSatish Balay PetscErrorCode TSErrorWeightedENorm2(TS ts, Vec E, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr) {
50608a175baeSEmil Constantinescu   PetscInt           i, n, N, rstart;
50618a175baeSEmil Constantinescu   PetscInt           n_loc, na_loc, nr_loc;
50628a175baeSEmil Constantinescu   PetscReal          n_glb, na_glb, nr_glb;
50638a175baeSEmil Constantinescu   const PetscScalar *e, *u, *y;
50648a175baeSEmil Constantinescu   PetscReal          err, sum, suma, sumr, gsum, gsuma, gsumr;
50658a175baeSEmil Constantinescu   PetscReal          tol, tola, tolr;
50668a175baeSEmil Constantinescu   PetscReal          err_loc[6], err_glb[6];
50678a175baeSEmil Constantinescu 
50688a175baeSEmil Constantinescu   PetscFunctionBegin;
50698a175baeSEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
50708a175baeSEmil Constantinescu   PetscValidHeaderSpecific(E, VEC_CLASSID, 2);
50718a175baeSEmil Constantinescu   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
50728a175baeSEmil Constantinescu   PetscValidHeaderSpecific(Y, VEC_CLASSID, 4);
50738a175baeSEmil Constantinescu   PetscValidType(E, 2);
50748a175baeSEmil Constantinescu   PetscValidType(U, 3);
50758a175baeSEmil Constantinescu   PetscValidType(Y, 4);
50768a175baeSEmil Constantinescu   PetscCheckSameComm(E, 2, U, 3);
5077064a246eSJacob Faibussowitsch   PetscCheckSameComm(U, 3, Y, 4);
5078dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 5);
5079dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 6);
5080dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 7);
50818a175baeSEmil Constantinescu 
50829566063dSJacob Faibussowitsch   PetscCall(VecGetSize(E, &N));
50839566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(E, &n));
50849566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(E, &rstart, NULL));
50859566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(E, &e));
50869566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
50879566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
50889371c9d4SSatish Balay   sum    = 0.;
50899371c9d4SSatish Balay   n_loc  = 0;
50909371c9d4SSatish Balay   suma   = 0.;
50919371c9d4SSatish Balay   na_loc = 0;
50929371c9d4SSatish Balay   sumr   = 0.;
50939371c9d4SSatish Balay   nr_loc = 0;
50948a175baeSEmil Constantinescu   if (ts->vatol && ts->vrtol) {
50958a175baeSEmil Constantinescu     const PetscScalar *atol, *rtol;
50969566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
50979566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
50988a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
509976cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
51008a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
51018a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
51028a175baeSEmil Constantinescu       if (tola > 0.) {
51038a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
51048a175baeSEmil Constantinescu         na_loc++;
51058a175baeSEmil Constantinescu       }
51068a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
51078a175baeSEmil Constantinescu       if (tolr > 0.) {
51088a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
51098a175baeSEmil Constantinescu         nr_loc++;
51108a175baeSEmil Constantinescu       }
51118a175baeSEmil Constantinescu       tol = tola + tolr;
51128a175baeSEmil Constantinescu       if (tol > 0.) {
51138a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
51148a175baeSEmil Constantinescu         n_loc++;
51158a175baeSEmil Constantinescu       }
51168a175baeSEmil Constantinescu     }
51179566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
51189566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
51198a175baeSEmil Constantinescu   } else if (ts->vatol) { /* vector atol, scalar rtol */
51208a175baeSEmil Constantinescu     const PetscScalar *atol;
51219566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
51228a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
512376cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
51248a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
51258a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
51268a175baeSEmil Constantinescu       if (tola > 0.) {
51278a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
51288a175baeSEmil Constantinescu         na_loc++;
51298a175baeSEmil Constantinescu       }
51308a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
51318a175baeSEmil Constantinescu       if (tolr > 0.) {
51328a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
51338a175baeSEmil Constantinescu         nr_loc++;
51348a175baeSEmil Constantinescu       }
51358a175baeSEmil Constantinescu       tol = tola + tolr;
51368a175baeSEmil Constantinescu       if (tol > 0.) {
51378a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
51388a175baeSEmil Constantinescu         n_loc++;
51398a175baeSEmil Constantinescu       }
51408a175baeSEmil Constantinescu     }
51419566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
51428a175baeSEmil Constantinescu   } else if (ts->vrtol) { /* scalar atol, vector rtol */
51438a175baeSEmil Constantinescu     const PetscScalar *rtol;
51449566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
51458a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
514676cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
51478a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
51488a175baeSEmil Constantinescu       tola = ts->atol;
51498a175baeSEmil Constantinescu       if (tola > 0.) {
51508a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
51518a175baeSEmil Constantinescu         na_loc++;
51528a175baeSEmil Constantinescu       }
51538a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
51548a175baeSEmil Constantinescu       if (tolr > 0.) {
51558a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
51568a175baeSEmil Constantinescu         nr_loc++;
51578a175baeSEmil Constantinescu       }
51588a175baeSEmil Constantinescu       tol = tola + tolr;
51598a175baeSEmil Constantinescu       if (tol > 0.) {
51608a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
51618a175baeSEmil Constantinescu         n_loc++;
51628a175baeSEmil Constantinescu       }
51638a175baeSEmil Constantinescu     }
51649566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
51658a175baeSEmil Constantinescu   } else { /* scalar atol, scalar rtol */
51668a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
516776cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
51688a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
51698a175baeSEmil Constantinescu       tola = ts->atol;
51708a175baeSEmil Constantinescu       if (tola > 0.) {
51718a175baeSEmil Constantinescu         suma += PetscSqr(err / tola);
51728a175baeSEmil Constantinescu         na_loc++;
51738a175baeSEmil Constantinescu       }
51748a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
51758a175baeSEmil Constantinescu       if (tolr > 0.) {
51768a175baeSEmil Constantinescu         sumr += PetscSqr(err / tolr);
51778a175baeSEmil Constantinescu         nr_loc++;
51788a175baeSEmil Constantinescu       }
51798a175baeSEmil Constantinescu       tol = tola + tolr;
51808a175baeSEmil Constantinescu       if (tol > 0.) {
51818a175baeSEmil Constantinescu         sum += PetscSqr(err / tol);
51828a175baeSEmil Constantinescu         n_loc++;
51838a175baeSEmil Constantinescu       }
51848a175baeSEmil Constantinescu     }
51858a175baeSEmil Constantinescu   }
51869566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(E, &e));
51879566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
51889566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
51898a175baeSEmil Constantinescu 
51908a175baeSEmil Constantinescu   err_loc[0] = sum;
51918a175baeSEmil Constantinescu   err_loc[1] = suma;
51928a175baeSEmil Constantinescu   err_loc[2] = sumr;
51938a175baeSEmil Constantinescu   err_loc[3] = (PetscReal)n_loc;
51948a175baeSEmil Constantinescu   err_loc[4] = (PetscReal)na_loc;
51958a175baeSEmil Constantinescu   err_loc[5] = (PetscReal)nr_loc;
51968a175baeSEmil Constantinescu 
51971c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 6, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)ts)));
51988a175baeSEmil Constantinescu 
51998a175baeSEmil Constantinescu   gsum   = err_glb[0];
52008a175baeSEmil Constantinescu   gsuma  = err_glb[1];
52018a175baeSEmil Constantinescu   gsumr  = err_glb[2];
52028a175baeSEmil Constantinescu   n_glb  = err_glb[3];
52038a175baeSEmil Constantinescu   na_glb = err_glb[4];
52048a175baeSEmil Constantinescu   nr_glb = err_glb[5];
52058a175baeSEmil Constantinescu 
52068a175baeSEmil Constantinescu   *norm = 0.;
52071e66621cSBarry Smith   if (n_glb > 0.) *norm = PetscSqrtReal(gsum / n_glb);
52088a175baeSEmil Constantinescu   *norma = 0.;
52091e66621cSBarry Smith   if (na_glb > 0.) *norma = PetscSqrtReal(gsuma / na_glb);
52108a175baeSEmil Constantinescu   *normr = 0.;
52111e66621cSBarry Smith   if (nr_glb > 0.) *normr = PetscSqrtReal(gsumr / nr_glb);
52128a175baeSEmil Constantinescu 
52133c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
52143c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
52153c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
52168a175baeSEmil Constantinescu   PetscFunctionReturn(0);
52178a175baeSEmil Constantinescu }
52188a175baeSEmil Constantinescu 
52198a175baeSEmil Constantinescu /*@
52208a175baeSEmil Constantinescu    TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances
52218a175baeSEmil Constantinescu    Collective on TS
52228a175baeSEmil Constantinescu 
52234165533cSJose E. Roman    Input Parameters:
52248a175baeSEmil Constantinescu +  ts - time stepping context
52258a175baeSEmil Constantinescu .  E - error vector
52268a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
52278a175baeSEmil Constantinescu -  Y - state vector, previous time step
52288a175baeSEmil Constantinescu 
52294165533cSJose E. Roman    Output Parameters:
5230a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
52318a175baeSEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5232a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
52338a175baeSEmil Constantinescu 
52348a175baeSEmil Constantinescu    Level: developer
52358a175baeSEmil Constantinescu 
5236db781477SPatrick Sanan .seealso: `TSErrorWeightedENorm()`, `TSErrorWeightedENorm2()`
52378a175baeSEmil Constantinescu @*/
52389371c9d4SSatish Balay PetscErrorCode TSErrorWeightedENormInfinity(TS ts, Vec E, Vec U, Vec Y, PetscReal *norm, PetscReal *norma, PetscReal *normr) {
52398a175baeSEmil Constantinescu   PetscInt           i, n, N, rstart;
52408a175baeSEmil Constantinescu   const PetscScalar *e, *u, *y;
52418a175baeSEmil Constantinescu   PetscReal          err, max, gmax, maxa, gmaxa, maxr, gmaxr;
52428a175baeSEmil Constantinescu   PetscReal          tol, tola, tolr;
52438a175baeSEmil Constantinescu   PetscReal          err_loc[3], err_glb[3];
52448a175baeSEmil Constantinescu 
52458a175baeSEmil Constantinescu   PetscFunctionBegin;
52468a175baeSEmil Constantinescu   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
52478a175baeSEmil Constantinescu   PetscValidHeaderSpecific(E, VEC_CLASSID, 2);
52488a175baeSEmil Constantinescu   PetscValidHeaderSpecific(U, VEC_CLASSID, 3);
52498a175baeSEmil Constantinescu   PetscValidHeaderSpecific(Y, VEC_CLASSID, 4);
52508a175baeSEmil Constantinescu   PetscValidType(E, 2);
52518a175baeSEmil Constantinescu   PetscValidType(U, 3);
52528a175baeSEmil Constantinescu   PetscValidType(Y, 4);
52538a175baeSEmil Constantinescu   PetscCheckSameComm(E, 2, U, 3);
5254064a246eSJacob Faibussowitsch   PetscCheckSameComm(U, 3, Y, 4);
5255dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 5);
5256dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma, 6);
5257dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr, 7);
52588a175baeSEmil Constantinescu 
52599566063dSJacob Faibussowitsch   PetscCall(VecGetSize(E, &N));
52609566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(E, &n));
52619566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(E, &rstart, NULL));
52629566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(E, &e));
52639566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U, &u));
52649566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y, &y));
52658a175baeSEmil Constantinescu 
52668a175baeSEmil Constantinescu   max  = 0.;
52678a175baeSEmil Constantinescu   maxa = 0.;
52688a175baeSEmil Constantinescu   maxr = 0.;
52698a175baeSEmil Constantinescu 
52708a175baeSEmil Constantinescu   if (ts->vatol && ts->vrtol) { /* vector atol, vector rtol */
52718a175baeSEmil Constantinescu     const PetscScalar *atol, *rtol;
52729566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
52739566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
52748a175baeSEmil Constantinescu 
52758a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
527676cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
52778a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
52788a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
52798a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
52808a175baeSEmil Constantinescu       tol  = tola + tolr;
52811e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
52821e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
52831e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
52848a175baeSEmil Constantinescu     }
52859566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
52869566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
52878a175baeSEmil Constantinescu   } else if (ts->vatol) { /* vector atol, scalar rtol */
52888a175baeSEmil Constantinescu     const PetscScalar *atol;
52899566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol, &atol));
52908a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
529176cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
52928a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
52938a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
52948a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
52958a175baeSEmil Constantinescu       tol  = tola + tolr;
52961e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
52971e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
52981e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
52998a175baeSEmil Constantinescu     }
53009566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol, &atol));
53018a175baeSEmil Constantinescu   } else if (ts->vrtol) { /* scalar atol, vector rtol */
53028a175baeSEmil Constantinescu     const PetscScalar *rtol;
53039566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol, &rtol));
53048a175baeSEmil Constantinescu 
53058a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
530676cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
53078a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
53088a175baeSEmil Constantinescu       tola = ts->atol;
53098a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
53108a175baeSEmil Constantinescu       tol  = tola + tolr;
53111e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
53121e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
53131e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
53148a175baeSEmil Constantinescu     }
53159566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol, &rtol));
53168a175baeSEmil Constantinescu   } else { /* scalar atol, scalar rtol */
53178a175baeSEmil Constantinescu 
53188a175baeSEmil Constantinescu     for (i = 0; i < n; i++) {
531976cddca1SEmil Constantinescu       SkipSmallValue(y[i], u[i], ts->adapt->ignore_max);
53208a175baeSEmil Constantinescu       err  = PetscAbsScalar(e[i]);
53218a175baeSEmil Constantinescu       tola = ts->atol;
53228a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
53238a175baeSEmil Constantinescu       tol  = tola + tolr;
53241e66621cSBarry Smith       if (tola > 0.) maxa = PetscMax(maxa, err / tola);
53251e66621cSBarry Smith       if (tolr > 0.) maxr = PetscMax(maxr, err / tolr);
53261e66621cSBarry Smith       if (tol > 0.) max = PetscMax(max, err / tol);
53278a175baeSEmil Constantinescu     }
53288a175baeSEmil Constantinescu   }
53299566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(E, &e));
53309566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U, &u));
53319566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y, &y));
53328a175baeSEmil Constantinescu   err_loc[0] = max;
53338a175baeSEmil Constantinescu   err_loc[1] = maxa;
53348a175baeSEmil Constantinescu   err_loc[2] = maxr;
53351c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc, err_glb, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)ts)));
53368a175baeSEmil Constantinescu   gmax  = err_glb[0];
53378a175baeSEmil Constantinescu   gmaxa = err_glb[1];
53388a175baeSEmil Constantinescu   gmaxr = err_glb[2];
53398a175baeSEmil Constantinescu 
53408a175baeSEmil Constantinescu   *norm  = gmax;
53418a175baeSEmil Constantinescu   *norma = gmaxa;
53428a175baeSEmil Constantinescu   *normr = gmaxr;
53433c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norm");
53443c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in norma");
53453c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr), PetscObjectComm((PetscObject)ts), PETSC_ERR_FP, "Infinite or not-a-number generated in normr");
53468a175baeSEmil Constantinescu   PetscFunctionReturn(0);
53478a175baeSEmil Constantinescu }
53488a175baeSEmil Constantinescu 
53498a175baeSEmil Constantinescu /*@
53508a175baeSEmil Constantinescu    TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
53518a175baeSEmil Constantinescu 
53528a175baeSEmil Constantinescu    Collective on TS
53538a175baeSEmil Constantinescu 
53544165533cSJose E. Roman    Input Parameters:
53558a175baeSEmil Constantinescu +  ts - time stepping context
53568a175baeSEmil Constantinescu .  E - error vector
53578a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
53588a175baeSEmil Constantinescu .  Y - state vector, previous time step
53598a175baeSEmil Constantinescu -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
53608a175baeSEmil Constantinescu 
53614165533cSJose E. Roman    Output Parameters:
5362a2b725a8SWilliam Gropp +  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
53638a175baeSEmil Constantinescu .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5364a2b725a8SWilliam Gropp -  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
53658a175baeSEmil Constantinescu 
53668a175baeSEmil Constantinescu    Options Database Keys:
53678a175baeSEmil Constantinescu .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
53688a175baeSEmil Constantinescu 
53698a175baeSEmil Constantinescu    Level: developer
53708a175baeSEmil Constantinescu 
5371db781477SPatrick Sanan .seealso: `TSErrorWeightedENormInfinity()`, `TSErrorWeightedENorm2()`, `TSErrorWeightedNormInfinity()`, `TSErrorWeightedNorm2()`
53728a175baeSEmil Constantinescu @*/
53739371c9d4SSatish Balay PetscErrorCode TSErrorWeightedENorm(TS ts, Vec E, Vec U, Vec Y, NormType wnormtype, PetscReal *norm, PetscReal *norma, PetscReal *normr) {
53748a175baeSEmil Constantinescu   PetscFunctionBegin;
53751e66621cSBarry Smith   if (wnormtype == NORM_2) PetscCall(TSErrorWeightedENorm2(ts, E, U, Y, norm, norma, normr));
53761e66621cSBarry Smith   else if (wnormtype == NORM_INFINITY) PetscCall(TSErrorWeightedENormInfinity(ts, E, U, Y, norm, norma, normr));
53771e66621cSBarry Smith   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
53788a175baeSEmil Constantinescu   PetscFunctionReturn(0);
53798a175baeSEmil Constantinescu }
53808a175baeSEmil Constantinescu 
53818d59e960SJed Brown /*@
53828d59e960SJed Brown    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
53838d59e960SJed Brown 
53848d59e960SJed Brown    Logically Collective on TS
53858d59e960SJed Brown 
53864165533cSJose E. Roman    Input Parameters:
53878d59e960SJed Brown +  ts - time stepping context
53888d59e960SJed Brown -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
53898d59e960SJed Brown 
53908d59e960SJed Brown    Note:
53918d59e960SJed Brown    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
53928d59e960SJed Brown 
53938d59e960SJed Brown    Level: intermediate
53948d59e960SJed Brown 
5395db781477SPatrick Sanan .seealso: `TSGetCFLTime()`, `TSADAPTCFL`
53968d59e960SJed Brown @*/
53979371c9d4SSatish Balay PetscErrorCode TSSetCFLTimeLocal(TS ts, PetscReal cfltime) {
53988d59e960SJed Brown   PetscFunctionBegin;
53998d59e960SJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
54008d59e960SJed Brown   ts->cfltime_local = cfltime;
54018d59e960SJed Brown   ts->cfltime       = -1.;
54028d59e960SJed Brown   PetscFunctionReturn(0);
54038d59e960SJed Brown }
54048d59e960SJed Brown 
54058d59e960SJed Brown /*@
54068d59e960SJed Brown    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
54078d59e960SJed Brown 
54088d59e960SJed Brown    Collective on TS
54098d59e960SJed Brown 
54104165533cSJose E. Roman    Input Parameter:
54118d59e960SJed Brown .  ts - time stepping context
54128d59e960SJed Brown 
54134165533cSJose E. Roman    Output Parameter:
54148d59e960SJed Brown .  cfltime - maximum stable time step for forward Euler
54158d59e960SJed Brown 
54168d59e960SJed Brown    Level: advanced
54178d59e960SJed Brown 
5418db781477SPatrick Sanan .seealso: `TSSetCFLTimeLocal()`
54198d59e960SJed Brown @*/
54209371c9d4SSatish Balay PetscErrorCode TSGetCFLTime(TS ts, PetscReal *cfltime) {
54218d59e960SJed Brown   PetscFunctionBegin;
54221e66621cSBarry Smith   if (ts->cfltime < 0) PetscCall(MPIU_Allreduce(&ts->cfltime_local, &ts->cfltime, 1, MPIU_REAL, MPIU_MIN, PetscObjectComm((PetscObject)ts)));
54238d59e960SJed Brown   *cfltime = ts->cfltime;
54248d59e960SJed Brown   PetscFunctionReturn(0);
54258d59e960SJed Brown }
54268d59e960SJed Brown 
5427d6ebe24aSShri Abhyankar /*@
5428d6ebe24aSShri Abhyankar    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
5429d6ebe24aSShri Abhyankar 
5430d6ebe24aSShri Abhyankar    Input Parameters:
5431a2b725a8SWilliam Gropp +  ts   - the TS context.
5432d6ebe24aSShri Abhyankar .  xl   - lower bound.
5433a2b725a8SWilliam Gropp -  xu   - upper bound.
5434d6ebe24aSShri Abhyankar 
5435d6ebe24aSShri Abhyankar    Notes:
5436d6ebe24aSShri Abhyankar    If this routine is not called then the lower and upper bounds are set to
5437e270355aSBarry Smith    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
5438d6ebe24aSShri Abhyankar 
54392bd2b0e6SSatish Balay    Level: advanced
54402bd2b0e6SSatish Balay 
5441d6ebe24aSShri Abhyankar @*/
54429371c9d4SSatish Balay PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu) {
5443d6ebe24aSShri Abhyankar   SNES snes;
5444d6ebe24aSShri Abhyankar 
5445d6ebe24aSShri Abhyankar   PetscFunctionBegin;
54469566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
54479566063dSJacob Faibussowitsch   PetscCall(SNESVISetVariableBounds(snes, xl, xu));
5448d6ebe24aSShri Abhyankar   PetscFunctionReturn(0);
5449d6ebe24aSShri Abhyankar }
5450d6ebe24aSShri Abhyankar 
5451f9c1d6abSBarry Smith /*@
5452f9c1d6abSBarry Smith    TSComputeLinearStability - computes the linear stability function at a point
5453f9c1d6abSBarry Smith 
5454d083f849SBarry Smith    Collective on TS
5455f9c1d6abSBarry Smith 
5456f9c1d6abSBarry Smith    Input Parameters:
5457f9c1d6abSBarry Smith +  ts - the TS context
5458f9c1d6abSBarry Smith -  xr,xi - real and imaginary part of input arguments
5459f9c1d6abSBarry Smith 
5460f9c1d6abSBarry Smith    Output Parameters:
5461f9c1d6abSBarry Smith .  yr,yi - real and imaginary part of function value
5462f9c1d6abSBarry Smith 
5463f9c1d6abSBarry Smith    Level: developer
5464f9c1d6abSBarry Smith 
5465db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSComputeIFunction()`
5466f9c1d6abSBarry Smith @*/
54679371c9d4SSatish Balay PetscErrorCode TSComputeLinearStability(TS ts, PetscReal xr, PetscReal xi, PetscReal *yr, PetscReal *yi) {
5468f9c1d6abSBarry Smith   PetscFunctionBegin;
5469f9c1d6abSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5470dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, linearstability, xr, xi, yr, yi);
5471f9c1d6abSBarry Smith   PetscFunctionReturn(0);
5472f9c1d6abSBarry Smith }
547324655328SShri 
547424655328SShri /*@
5475dcb233daSLisandro Dalcin    TSRestartStep - Flags the solver to restart the next step
5476dcb233daSLisandro Dalcin 
5477dcb233daSLisandro Dalcin    Collective on TS
5478dcb233daSLisandro Dalcin 
5479dcb233daSLisandro Dalcin    Input Parameter:
5480dcb233daSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
5481dcb233daSLisandro Dalcin 
5482dcb233daSLisandro Dalcin    Level: advanced
5483dcb233daSLisandro Dalcin 
5484dcb233daSLisandro Dalcin    Notes:
5485dcb233daSLisandro Dalcin    Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of
5486dcb233daSLisandro Dalcin    discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution
5487dcb233daSLisandro Dalcin    vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For
5488dcb233daSLisandro Dalcin    the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce
5489dcb233daSLisandro Dalcin    discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with
5490dcb233daSLisandro Dalcin    discontinuous source terms).
5491dcb233daSLisandro Dalcin 
5492db781477SPatrick Sanan .seealso: `TSSolve()`, `TSSetPreStep()`, `TSSetPostStep()`
5493dcb233daSLisandro Dalcin @*/
54949371c9d4SSatish Balay PetscErrorCode TSRestartStep(TS ts) {
5495dcb233daSLisandro Dalcin   PetscFunctionBegin;
5496dcb233daSLisandro Dalcin   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5497dcb233daSLisandro Dalcin   ts->steprestart = PETSC_TRUE;
5498dcb233daSLisandro Dalcin   PetscFunctionReturn(0);
5499dcb233daSLisandro Dalcin }
5500dcb233daSLisandro Dalcin 
5501dcb233daSLisandro Dalcin /*@
550224655328SShri    TSRollBack - Rolls back one time step
550324655328SShri 
550424655328SShri    Collective on TS
550524655328SShri 
550624655328SShri    Input Parameter:
550724655328SShri .  ts - the TS context obtained from TSCreate()
550824655328SShri 
550924655328SShri    Level: advanced
551024655328SShri 
5511db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSInterpolate()`
551224655328SShri @*/
55139371c9d4SSatish Balay PetscErrorCode TSRollBack(TS ts) {
551424655328SShri   PetscFunctionBegin;
551524655328SShri   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
55163c633725SBarry Smith   PetscCheck(!ts->steprollback, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONGSTATE, "TSRollBack already called");
5517dbbe0bcdSBarry Smith   PetscUseTypeMethod(ts, rollback);
551824655328SShri   ts->time_step  = ts->ptime - ts->ptime_prev;
551924655328SShri   ts->ptime      = ts->ptime_prev;
5520be5899b3SLisandro Dalcin   ts->ptime_prev = ts->ptime_prev_rollback;
55212808aa04SLisandro Dalcin   ts->steps--;
5522b3de5cdeSLisandro Dalcin   ts->steprollback = PETSC_TRUE;
552324655328SShri   PetscFunctionReturn(0);
552424655328SShri }
5525aeb4809dSShri Abhyankar 
5526ff22ae23SHong Zhang /*@
5527ff22ae23SHong Zhang    TSGetStages - Get the number of stages and stage values
5528ff22ae23SHong Zhang 
5529ff22ae23SHong Zhang    Input Parameter:
5530ff22ae23SHong Zhang .  ts - the TS context obtained from TSCreate()
5531ff22ae23SHong Zhang 
55320429704eSStefano Zampini    Output Parameters:
55330429704eSStefano Zampini +  ns - the number of stages
55340429704eSStefano Zampini -  Y - the current stage vectors
55350429704eSStefano Zampini 
5536ff22ae23SHong Zhang    Level: advanced
5537ff22ae23SHong Zhang 
55380429704eSStefano Zampini    Notes: Both ns and Y can be NULL.
55390429704eSStefano Zampini 
5540db781477SPatrick Sanan .seealso: `TSCreate()`
5541ff22ae23SHong Zhang @*/
55429371c9d4SSatish Balay PetscErrorCode TSGetStages(TS ts, PetscInt *ns, Vec **Y) {
5543ff22ae23SHong Zhang   PetscFunctionBegin;
5544ff22ae23SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5545dadcf809SJacob Faibussowitsch   if (ns) PetscValidIntPointer(ns, 2);
55460429704eSStefano Zampini   if (Y) PetscValidPointer(Y, 3);
55470429704eSStefano Zampini   if (!ts->ops->getstages) {
55480429704eSStefano Zampini     if (ns) *ns = 0;
55490429704eSStefano Zampini     if (Y) *Y = NULL;
5550dbbe0bcdSBarry Smith   } else PetscUseTypeMethod(ts, getstages, ns, Y);
5551ff22ae23SHong Zhang   PetscFunctionReturn(0);
5552ff22ae23SHong Zhang }
5553ff22ae23SHong Zhang 
5554847ff0e1SMatthew G. Knepley /*@C
5555847ff0e1SMatthew G. Knepley   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
5556847ff0e1SMatthew G. Knepley 
5557847ff0e1SMatthew G. Knepley   Collective on SNES
5558847ff0e1SMatthew G. Knepley 
5559847ff0e1SMatthew G. Knepley   Input Parameters:
5560847ff0e1SMatthew G. Knepley + ts - the TS context
5561847ff0e1SMatthew G. Knepley . t - current timestep
5562847ff0e1SMatthew G. Knepley . U - state vector
5563847ff0e1SMatthew G. Knepley . Udot - time derivative of state vector
5564847ff0e1SMatthew G. Knepley . shift - shift to apply, see note below
5565847ff0e1SMatthew G. Knepley - ctx - an optional user context
5566847ff0e1SMatthew G. Knepley 
5567847ff0e1SMatthew G. Knepley   Output Parameters:
5568847ff0e1SMatthew G. Knepley + J - Jacobian matrix (not altered in this routine)
5569847ff0e1SMatthew G. Knepley - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
5570847ff0e1SMatthew G. Knepley 
5571847ff0e1SMatthew G. Knepley   Level: intermediate
5572847ff0e1SMatthew G. Knepley 
5573847ff0e1SMatthew G. Knepley   Notes:
5574847ff0e1SMatthew G. Knepley   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
5575847ff0e1SMatthew G. Knepley 
5576847ff0e1SMatthew G. Knepley   dF/dU + shift*dF/dUdot
5577847ff0e1SMatthew G. Knepley 
5578847ff0e1SMatthew G. Knepley   Most users should not need to explicitly call this routine, as it
5579847ff0e1SMatthew G. Knepley   is used internally within the nonlinear solvers.
5580847ff0e1SMatthew G. Knepley 
5581847ff0e1SMatthew G. Knepley   This will first try to get the coloring from the DM.  If the DM type has no coloring
5582847ff0e1SMatthew G. Knepley   routine, then it will try to get the coloring from the matrix.  This requires that the
5583847ff0e1SMatthew G. Knepley   matrix have nonzero entries precomputed.
5584847ff0e1SMatthew G. Knepley 
5585db781477SPatrick Sanan .seealso: `TSSetIJacobian()`, `MatFDColoringCreate()`, `MatFDColoringSetFunction()`
5586847ff0e1SMatthew G. Knepley @*/
55879371c9d4SSatish Balay PetscErrorCode TSComputeIJacobianDefaultColor(TS ts, PetscReal t, Vec U, Vec Udot, PetscReal shift, Mat J, Mat B, void *ctx) {
5588847ff0e1SMatthew G. Knepley   SNES          snes;
5589847ff0e1SMatthew G. Knepley   MatFDColoring color;
5590847ff0e1SMatthew G. Knepley   PetscBool     hascolor, matcolor = PETSC_FALSE;
5591847ff0e1SMatthew G. Knepley 
5592847ff0e1SMatthew G. Knepley   PetscFunctionBegin;
55939566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject)ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL));
55949566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)B, "TSMatFDColoring", (PetscObject *)&color));
5595847ff0e1SMatthew G. Knepley   if (!color) {
5596847ff0e1SMatthew G. Knepley     DM         dm;
5597847ff0e1SMatthew G. Knepley     ISColoring iscoloring;
5598847ff0e1SMatthew G. Knepley 
55999566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
56009566063dSJacob Faibussowitsch     PetscCall(DMHasColoring(dm, &hascolor));
5601847ff0e1SMatthew G. Knepley     if (hascolor && !matcolor) {
56029566063dSJacob Faibussowitsch       PetscCall(DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring));
56039566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
56049566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(color, (PetscErrorCode(*)(void))SNESTSFormFunction, (void *)ts));
56059566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
56069566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
56079566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5608847ff0e1SMatthew G. Knepley     } else {
5609847ff0e1SMatthew G. Knepley       MatColoring mc;
5610847ff0e1SMatthew G. Knepley 
56119566063dSJacob Faibussowitsch       PetscCall(MatColoringCreate(B, &mc));
56129566063dSJacob Faibussowitsch       PetscCall(MatColoringSetDistance(mc, 2));
56139566063dSJacob Faibussowitsch       PetscCall(MatColoringSetType(mc, MATCOLORINGSL));
56149566063dSJacob Faibussowitsch       PetscCall(MatColoringSetFromOptions(mc));
56159566063dSJacob Faibussowitsch       PetscCall(MatColoringApply(mc, &iscoloring));
56169566063dSJacob Faibussowitsch       PetscCall(MatColoringDestroy(&mc));
56179566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
56189566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(color, (PetscErrorCode(*)(void))SNESTSFormFunction, (void *)ts));
56199566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
56209566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
56219566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5622847ff0e1SMatthew G. Knepley     }
56239566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject)B, "TSMatFDColoring", (PetscObject)color));
56249566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)color));
5625847ff0e1SMatthew G. Knepley   }
56269566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
56279566063dSJacob Faibussowitsch   PetscCall(MatFDColoringApply(B, color, U, snes));
5628847ff0e1SMatthew G. Knepley   if (J != B) {
56299566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
56309566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
5631847ff0e1SMatthew G. Knepley   }
5632847ff0e1SMatthew G. Knepley   PetscFunctionReturn(0);
5633847ff0e1SMatthew G. Knepley }
563493b34091SDebojyoti Ghosh 
5635cb9d8021SPierre Barbier de Reuille /*@
56366bc98fa9SBarry Smith     TSSetFunctionDomainError - Set a function that tests if the current state vector is valid
5637cb9d8021SPierre Barbier de Reuille 
5638cb9d8021SPierre Barbier de Reuille     Input Parameters:
56396bc98fa9SBarry Smith +    ts - the TS context
56406bc98fa9SBarry Smith -    func - function called within TSFunctionDomainError
56416bc98fa9SBarry Smith 
56426bc98fa9SBarry Smith     Calling sequence of func:
56436bc98fa9SBarry Smith $     PetscErrorCode func(TS ts,PetscReal time,Vec state,PetscBool reject)
56446bc98fa9SBarry Smith 
56456bc98fa9SBarry Smith +   ts - the TS context
56466bc98fa9SBarry Smith .   time - the current time (of the stage)
56476bc98fa9SBarry Smith .   state - the state to check if it is valid
56486bc98fa9SBarry Smith -   reject - (output parameter) PETSC_FALSE if the state is acceptable, PETSC_TRUE if not acceptable
5649cb9d8021SPierre Barbier de Reuille 
5650cb9d8021SPierre Barbier de Reuille     Level: intermediate
5651cb9d8021SPierre Barbier de Reuille 
56526bc98fa9SBarry Smith     Notes:
56536bc98fa9SBarry Smith       If an implicit ODE solver is being used then, in addition to providing this routine, the
56546bc98fa9SBarry Smith       user's code should call SNESSetFunctionDomainError() when domain errors occur during
56556bc98fa9SBarry Smith       function evaluations where the functions are provided by TSSetIFunction() or TSSetRHSFunction().
56566bc98fa9SBarry Smith       Use TSGetSNES() to obtain the SNES object
56576bc98fa9SBarry Smith 
56586bc98fa9SBarry Smith     Developer Notes:
56596bc98fa9SBarry Smith       The naming of this function is inconsistent with the SNESSetFunctionDomainError()
56606bc98fa9SBarry Smith       since one takes a function pointer and the other does not.
56616bc98fa9SBarry Smith 
5662db781477SPatrick Sanan .seealso: `TSAdaptCheckStage()`, `TSFunctionDomainError()`, `SNESSetFunctionDomainError()`, `TSGetSNES()`
5663cb9d8021SPierre Barbier de Reuille @*/
5664cb9d8021SPierre Barbier de Reuille 
56659371c9d4SSatish Balay PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS, PetscReal, Vec, PetscBool *)) {
5666cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5667cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5668cb9d8021SPierre Barbier de Reuille   ts->functiondomainerror = func;
5669cb9d8021SPierre Barbier de Reuille   PetscFunctionReturn(0);
5670cb9d8021SPierre Barbier de Reuille }
5671cb9d8021SPierre Barbier de Reuille 
5672cb9d8021SPierre Barbier de Reuille /*@
56736bc98fa9SBarry Smith     TSFunctionDomainError - Checks if the current state is valid
5674cb9d8021SPierre Barbier de Reuille 
5675cb9d8021SPierre Barbier de Reuille     Input Parameters:
56766bc98fa9SBarry Smith +    ts - the TS context
56776bc98fa9SBarry Smith .    stagetime - time of the simulation
56786bc98fa9SBarry Smith -    Y - state vector to check.
5679cb9d8021SPierre Barbier de Reuille 
5680cb9d8021SPierre Barbier de Reuille     Output Parameter:
56816bc98fa9SBarry Smith .    accept - Set to PETSC_FALSE if the current state vector is valid.
5682cb9d8021SPierre Barbier de Reuille 
5683cb9d8021SPierre Barbier de Reuille     Note:
56846bc98fa9SBarry Smith     This function is called by the TS integration routines and calls the user provided function (set with TSSetFunctionDomainError())
56856bc98fa9SBarry Smith     to check if the current state is valid.
568696a0c994SBarry Smith 
56876bc98fa9SBarry Smith     Level: developer
56886bc98fa9SBarry Smith 
5689db781477SPatrick Sanan .seealso: `TSSetFunctionDomainError()`
5690cb9d8021SPierre Barbier de Reuille @*/
56919371c9d4SSatish Balay PetscErrorCode TSFunctionDomainError(TS ts, PetscReal stagetime, Vec Y, PetscBool *accept) {
5692cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5693cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5694cb9d8021SPierre Barbier de Reuille   *accept = PETSC_TRUE;
56951e66621cSBarry Smith   if (ts->functiondomainerror) PetscCall((*ts->functiondomainerror)(ts, stagetime, Y, accept));
5696cb9d8021SPierre Barbier de Reuille   PetscFunctionReturn(0);
5697cb9d8021SPierre Barbier de Reuille }
56981ceb14c0SBarry Smith 
569993b34091SDebojyoti Ghosh /*@C
5700e5168f73SEmil Constantinescu   TSClone - This function clones a time step object.
570193b34091SDebojyoti Ghosh 
5702d083f849SBarry Smith   Collective
570393b34091SDebojyoti Ghosh 
570493b34091SDebojyoti Ghosh   Input Parameter:
570593b34091SDebojyoti Ghosh . tsin    - The input TS
570693b34091SDebojyoti Ghosh 
570793b34091SDebojyoti Ghosh   Output Parameter:
5708e5168f73SEmil Constantinescu . tsout   - The output TS (cloned)
570993b34091SDebojyoti Ghosh 
57105eca1a21SEmil Constantinescu   Notes:
57115eca1a21SEmil Constantinescu   This function is used to create a clone of a TS object. It is used in ARKIMEX for initializing the slope for first stage explicit methods. It will likely be replaced in the future with a mechanism of switching methods on the fly.
57125eca1a21SEmil Constantinescu 
5713928bb9adSStefano Zampini   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);
57145eca1a21SEmil Constantinescu 
57155eca1a21SEmil Constantinescu   Level: developer
571693b34091SDebojyoti Ghosh 
5717db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetType()`, `TSSetUp()`, `TSDestroy()`, `TSSetProblemType()`
571893b34091SDebojyoti Ghosh @*/
57199371c9d4SSatish Balay PetscErrorCode TSClone(TS tsin, TS *tsout) {
572093b34091SDebojyoti Ghosh   TS     t;
5721dc846ba4SSatish Balay   SNES   snes_start;
5722dc846ba4SSatish Balay   DM     dm;
5723dc846ba4SSatish Balay   TSType type;
572493b34091SDebojyoti Ghosh 
572593b34091SDebojyoti Ghosh   PetscFunctionBegin;
572693b34091SDebojyoti Ghosh   PetscValidPointer(tsin, 1);
572793b34091SDebojyoti Ghosh   *tsout = NULL;
572893b34091SDebojyoti Ghosh 
57299566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView));
573093b34091SDebojyoti Ghosh 
573193b34091SDebojyoti Ghosh   /* General TS description */
573293b34091SDebojyoti Ghosh   t->numbermonitors    = 0;
5733d0c080abSJoseph Pusztay   t->monitorFrequency  = 1;
573493b34091SDebojyoti Ghosh   t->setupcalled       = 0;
573593b34091SDebojyoti Ghosh   t->ksp_its           = 0;
573693b34091SDebojyoti Ghosh   t->snes_its          = 0;
573793b34091SDebojyoti Ghosh   t->nwork             = 0;
57387d51462cSStefano Zampini   t->rhsjacobian.time  = PETSC_MIN_REAL;
573993b34091SDebojyoti Ghosh   t->rhsjacobian.scale = 1.;
574093b34091SDebojyoti Ghosh   t->ijacobian.shift   = 1.;
574193b34091SDebojyoti Ghosh 
57429566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(tsin, &snes_start));
57439566063dSJacob Faibussowitsch   PetscCall(TSSetSNES(t, snes_start));
5744d15a3a53SEmil Constantinescu 
57459566063dSJacob Faibussowitsch   PetscCall(TSGetDM(tsin, &dm));
57469566063dSJacob Faibussowitsch   PetscCall(TSSetDM(t, dm));
574793b34091SDebojyoti Ghosh 
574893b34091SDebojyoti Ghosh   t->adapt = tsin->adapt;
57499566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->adapt));
575093b34091SDebojyoti Ghosh 
5751e7069c78SShri   t->trajectory = tsin->trajectory;
57529566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->trajectory));
5753e7069c78SShri 
5754e7069c78SShri   t->event = tsin->event;
57556b10a48eSSatish Balay   if (t->event) t->event->refct++;
5756e7069c78SShri 
575793b34091SDebojyoti Ghosh   t->problem_type      = tsin->problem_type;
575893b34091SDebojyoti Ghosh   t->ptime             = tsin->ptime;
5759e7069c78SShri   t->ptime_prev        = tsin->ptime_prev;
576093b34091SDebojyoti Ghosh   t->time_step         = tsin->time_step;
576193b34091SDebojyoti Ghosh   t->max_time          = tsin->max_time;
576293b34091SDebojyoti Ghosh   t->steps             = tsin->steps;
576393b34091SDebojyoti Ghosh   t->max_steps         = tsin->max_steps;
576493b34091SDebojyoti Ghosh   t->equation_type     = tsin->equation_type;
576593b34091SDebojyoti Ghosh   t->atol              = tsin->atol;
576693b34091SDebojyoti Ghosh   t->rtol              = tsin->rtol;
576793b34091SDebojyoti Ghosh   t->max_snes_failures = tsin->max_snes_failures;
576893b34091SDebojyoti Ghosh   t->max_reject        = tsin->max_reject;
576993b34091SDebojyoti Ghosh   t->errorifstepfailed = tsin->errorifstepfailed;
577093b34091SDebojyoti Ghosh 
57719566063dSJacob Faibussowitsch   PetscCall(TSGetType(tsin, &type));
57729566063dSJacob Faibussowitsch   PetscCall(TSSetType(t, type));
577393b34091SDebojyoti Ghosh 
577493b34091SDebojyoti Ghosh   t->vec_sol = NULL;
577593b34091SDebojyoti Ghosh 
577693b34091SDebojyoti Ghosh   t->cfltime          = tsin->cfltime;
577793b34091SDebojyoti Ghosh   t->cfltime_local    = tsin->cfltime_local;
577893b34091SDebojyoti Ghosh   t->exact_final_time = tsin->exact_final_time;
577993b34091SDebojyoti Ghosh 
57809566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(t->ops, tsin->ops, sizeof(struct _TSOps)));
578193b34091SDebojyoti Ghosh 
57820d4fed19SBarry Smith   if (((PetscObject)tsin)->fortran_func_pointers) {
57830d4fed19SBarry Smith     PetscInt i;
57849566063dSJacob Faibussowitsch     PetscCall(PetscMalloc((10) * sizeof(void (*)(void)), &((PetscObject)t)->fortran_func_pointers));
57859371c9d4SSatish Balay     for (i = 0; i < 10; i++) { ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i]; }
57860d4fed19SBarry Smith   }
578793b34091SDebojyoti Ghosh   *tsout = t;
578893b34091SDebojyoti Ghosh   PetscFunctionReturn(0);
578993b34091SDebojyoti Ghosh }
5790f3b1f45cSBarry Smith 
57919371c9d4SSatish Balay static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void *ctx, Vec x, Vec y) {
5792f3b1f45cSBarry Smith   TS ts = (TS)ctx;
5793f3b1f45cSBarry Smith 
5794f3b1f45cSBarry Smith   PetscFunctionBegin;
57959566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSFunction(ts, 0, x, y));
5796f3b1f45cSBarry Smith   PetscFunctionReturn(0);
5797f3b1f45cSBarry Smith }
5798f3b1f45cSBarry Smith 
5799f3b1f45cSBarry Smith /*@
5800f3b1f45cSBarry Smith     TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function.
5801f3b1f45cSBarry Smith 
5802d083f849SBarry Smith    Logically Collective on TS
5803f3b1f45cSBarry Smith 
5804f3b1f45cSBarry Smith     Input Parameters:
5805f3b1f45cSBarry Smith     TS - the time stepping routine
5806f3b1f45cSBarry Smith 
5807f3b1f45cSBarry Smith    Output Parameter:
5808f3b1f45cSBarry Smith .   flg - PETSC_TRUE if the multiply is likely correct
5809f3b1f45cSBarry Smith 
5810f3b1f45cSBarry Smith    Options Database:
5811f3b1f45cSBarry Smith  .   -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator
5812f3b1f45cSBarry Smith 
5813f3b1f45cSBarry Smith    Level: advanced
5814f3b1f45cSBarry Smith 
581595452b02SPatrick Sanan    Notes:
581695452b02SPatrick Sanan     This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
5817f3b1f45cSBarry Smith 
5818db781477SPatrick Sanan .seealso: `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTestTranspose()`
5819f3b1f45cSBarry Smith @*/
58209371c9d4SSatish Balay PetscErrorCode TSRHSJacobianTest(TS ts, PetscBool *flg) {
5821f3b1f45cSBarry Smith   Mat           J, B;
5822f3b1f45cSBarry Smith   TSRHSJacobian func;
5823f3b1f45cSBarry Smith   void         *ctx;
5824f3b1f45cSBarry Smith 
5825f3b1f45cSBarry Smith   PetscFunctionBegin;
58269566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, &J, &B, &func, &ctx));
58279566063dSJacob Faibussowitsch   PetscCall((*func)(ts, 0.0, ts->vec_sol, J, B, ctx));
58289566063dSJacob Faibussowitsch   PetscCall(MatShellTestMult(J, RHSWrapperFunction_TSRHSJacobianTest, ts->vec_sol, ts, flg));
5829f3b1f45cSBarry Smith   PetscFunctionReturn(0);
5830f3b1f45cSBarry Smith }
5831f3b1f45cSBarry Smith 
5832f3b1f45cSBarry Smith /*@C
5833f3b1f45cSBarry Smith     TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function.
5834f3b1f45cSBarry Smith 
5835d083f849SBarry Smith    Logically Collective on TS
5836f3b1f45cSBarry Smith 
5837f3b1f45cSBarry Smith     Input Parameters:
5838f3b1f45cSBarry Smith     TS - the time stepping routine
5839f3b1f45cSBarry Smith 
5840f3b1f45cSBarry Smith    Output Parameter:
5841f3b1f45cSBarry Smith .   flg - PETSC_TRUE if the multiply is likely correct
5842f3b1f45cSBarry Smith 
5843f3b1f45cSBarry Smith    Options Database:
5844f3b1f45cSBarry Smith .   -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator
5845f3b1f45cSBarry Smith 
584695452b02SPatrick Sanan    Notes:
584795452b02SPatrick Sanan     This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
5848f3b1f45cSBarry Smith 
5849f3b1f45cSBarry Smith    Level: advanced
5850f3b1f45cSBarry Smith 
5851db781477SPatrick Sanan .seealso: `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTest()`
5852f3b1f45cSBarry Smith @*/
58539371c9d4SSatish Balay PetscErrorCode TSRHSJacobianTestTranspose(TS ts, PetscBool *flg) {
5854f3b1f45cSBarry Smith   Mat           J, B;
5855f3b1f45cSBarry Smith   void         *ctx;
5856f3b1f45cSBarry Smith   TSRHSJacobian func;
5857f3b1f45cSBarry Smith 
5858f3b1f45cSBarry Smith   PetscFunctionBegin;
58599566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts, &J, &B, &func, &ctx));
58609566063dSJacob Faibussowitsch   PetscCall((*func)(ts, 0.0, ts->vec_sol, J, B, ctx));
58619566063dSJacob Faibussowitsch   PetscCall(MatShellTestMultTranspose(J, RHSWrapperFunction_TSRHSJacobianTest, ts->vec_sol, ts, flg));
5862f3b1f45cSBarry Smith   PetscFunctionReturn(0);
5863f3b1f45cSBarry Smith }
58640fe4d17eSHong Zhang 
58650fe4d17eSHong Zhang /*@
58660fe4d17eSHong Zhang   TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used.
58670fe4d17eSHong Zhang 
58680fe4d17eSHong Zhang   Logically collective
58690fe4d17eSHong Zhang 
5870d8d19677SJose E. Roman   Input Parameters:
58710fe4d17eSHong Zhang +  ts - timestepping context
58720fe4d17eSHong Zhang -  use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used
58730fe4d17eSHong Zhang 
58740fe4d17eSHong Zhang   Options Database:
58750fe4d17eSHong Zhang .   -ts_use_splitrhsfunction - <true,false>
58760fe4d17eSHong Zhang 
58770fe4d17eSHong Zhang   Notes:
58780fe4d17eSHong Zhang     This is only useful for multirate methods
58790fe4d17eSHong Zhang 
58800fe4d17eSHong Zhang   Level: intermediate
58810fe4d17eSHong Zhang 
5882db781477SPatrick Sanan .seealso: `TSGetUseSplitRHSFunction()`
58830fe4d17eSHong Zhang @*/
58849371c9d4SSatish Balay PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction) {
58850fe4d17eSHong Zhang   PetscFunctionBegin;
58860fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
58870fe4d17eSHong Zhang   ts->use_splitrhsfunction = use_splitrhsfunction;
58880fe4d17eSHong Zhang   PetscFunctionReturn(0);
58890fe4d17eSHong Zhang }
58900fe4d17eSHong Zhang 
58910fe4d17eSHong Zhang /*@
58920fe4d17eSHong Zhang   TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used.
58930fe4d17eSHong Zhang 
58940fe4d17eSHong Zhang   Not collective
58950fe4d17eSHong Zhang 
58960fe4d17eSHong Zhang   Input Parameter:
58970fe4d17eSHong Zhang .  ts - timestepping context
58980fe4d17eSHong Zhang 
58990fe4d17eSHong Zhang   Output Parameter:
59000fe4d17eSHong Zhang .  use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used
59010fe4d17eSHong Zhang 
59020fe4d17eSHong Zhang   Level: intermediate
59030fe4d17eSHong Zhang 
5904db781477SPatrick Sanan .seealso: `TSSetUseSplitRHSFunction()`
59050fe4d17eSHong Zhang @*/
59069371c9d4SSatish Balay PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction) {
59070fe4d17eSHong Zhang   PetscFunctionBegin;
59080fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
59090fe4d17eSHong Zhang   *use_splitrhsfunction = ts->use_splitrhsfunction;
59100fe4d17eSHong Zhang   PetscFunctionReturn(0);
59110fe4d17eSHong Zhang }
5912d60b7d5cSBarry Smith 
5913d60b7d5cSBarry Smith /*@
5914d60b7d5cSBarry Smith     TSSetMatStructure - sets the relationship between the nonzero structure of the RHS Jacobian matrix to the IJacobian matrix.
5915d60b7d5cSBarry Smith 
5916d60b7d5cSBarry Smith    Logically  Collective on ts
5917d60b7d5cSBarry Smith 
5918d60b7d5cSBarry Smith    Input Parameters:
5919d60b7d5cSBarry Smith +  ts - the time-stepper
5920d60b7d5cSBarry Smith -  str - the structure (the default is UNKNOWN_NONZERO_PATTERN)
5921d60b7d5cSBarry Smith 
5922d60b7d5cSBarry Smith    Level: intermediate
5923d60b7d5cSBarry Smith 
5924d60b7d5cSBarry Smith    Notes:
5925d60b7d5cSBarry Smith      When the relationship between the nonzero structures is known and supplied the solution process can be much faster
5926d60b7d5cSBarry Smith 
5927db781477SPatrick Sanan .seealso: `MatAXPY()`, `MatStructure`
5928d60b7d5cSBarry Smith  @*/
59299371c9d4SSatish Balay PetscErrorCode TSSetMatStructure(TS ts, MatStructure str) {
5930d60b7d5cSBarry Smith   PetscFunctionBegin;
5931d60b7d5cSBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
5932d60b7d5cSBarry Smith   ts->axpy_pattern = str;
5933d60b7d5cSBarry Smith   PetscFunctionReturn(0);
5934d60b7d5cSBarry Smith }
59354a658b32SHong Zhang 
59364a658b32SHong Zhang /*@
59374a658b32SHong Zhang   TSSetTimeSpan - sets the time span. The solution will be computed and stored for each time requested.
59384a658b32SHong Zhang 
59394a658b32SHong Zhang   Collective on ts
59404a658b32SHong Zhang 
59414a658b32SHong Zhang   Input Parameters:
59424a658b32SHong Zhang + ts - the time-stepper
59434a658b32SHong Zhang . n - number of the time points (>=2)
59444a658b32SHong Zhang - span_times - array of the time points. The first element and the last element are the initial time and the final time respectively.
59454a658b32SHong Zhang 
59464a658b32SHong Zhang   Options Database Keys:
59474a658b32SHong Zhang . -ts_time_span <t0,...tf> - Sets the time span
59484a658b32SHong Zhang 
59494a658b32SHong Zhang   Level: beginner
59504a658b32SHong Zhang 
59514a658b32SHong Zhang   Notes:
59524a658b32SHong Zhang   The elements in tspan must be all increasing. They correspond to the intermediate points for time integration.
59534a658b32SHong Zhang   TS_EXACTFINALTIME_MATCHSTEP must be used to make the last time step in each sub-interval match the intermediate points specified.
59544a658b32SHong Zhang   The intermediate solutions are saved in a vector array that can be accessed with TSGetSolutions(). Thus using time span may
59554a658b32SHong Zhang   pressure the memory system when using a large number of span points.
59564a658b32SHong Zhang 
5957c2e3fba1SPatrick Sanan .seealso: `TSGetTimeSpan()`, `TSGetSolutions()`
59584a658b32SHong Zhang  @*/
59599371c9d4SSatish Balay PetscErrorCode TSSetTimeSpan(TS ts, PetscInt n, PetscReal *span_times) {
59604a658b32SHong Zhang   PetscFunctionBegin;
59614a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
596263a3b9bcSJacob Faibussowitsch   PetscCheck(n >= 2, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_WRONG, "Minimum time span size is 2 but %" PetscInt_FMT " is provided", n);
59634a658b32SHong Zhang   if (ts->tspan && n != ts->tspan->num_span_times) {
59644a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan->span_times));
59654a658b32SHong Zhang     PetscCall(VecDestroyVecs(ts->tspan->num_span_times, &ts->tspan->vecs_sol));
59664a658b32SHong Zhang     PetscCall(PetscMalloc1(n, &ts->tspan->span_times));
59674a658b32SHong Zhang   }
59684a658b32SHong Zhang   if (!ts->tspan) {
59694a658b32SHong Zhang     TSTimeSpan tspan;
59704a658b32SHong Zhang     PetscCall(PetscNew(&tspan));
59714a658b32SHong Zhang     PetscCall(PetscMalloc1(n, &tspan->span_times));
5972e1db57b0SHong Zhang     tspan->reltol = 1e-6;
5973e1db57b0SHong Zhang     tspan->abstol = 10 * PETSC_MACHINE_EPSILON;
59744a658b32SHong Zhang     ts->tspan     = tspan;
59754a658b32SHong Zhang   }
59764a658b32SHong Zhang   ts->tspan->num_span_times = n;
59774a658b32SHong Zhang   PetscCall(PetscArraycpy(ts->tspan->span_times, span_times, n));
59784a658b32SHong Zhang   PetscCall(TSSetTime(ts, ts->tspan->span_times[0]));
59794a658b32SHong Zhang   PetscCall(TSSetMaxTime(ts, ts->tspan->span_times[n - 1]));
59804a658b32SHong Zhang   PetscFunctionReturn(0);
59814a658b32SHong Zhang }
59824a658b32SHong Zhang 
59834a658b32SHong Zhang /*@C
59844a658b32SHong Zhang   TSGetTimeSpan - gets the time span.
59854a658b32SHong Zhang 
59864a658b32SHong Zhang   Not Collective
59874a658b32SHong Zhang 
59884a658b32SHong Zhang   Input Parameter:
59894a658b32SHong Zhang . ts - the time-stepper
59904a658b32SHong Zhang 
59914a658b32SHong Zhang   Output Parameters:
59924a658b32SHong Zhang + n - number of the time points (>=2)
59934a658b32SHong Zhang - span_times - array of the time points. The first element and the last element are the initial time and the final time respectively. The values are valid until the TS object is destroyed.
59944a658b32SHong Zhang 
59954a658b32SHong Zhang   Level: beginner
59964a658b32SHong Zhang   Notes: Both n and span_times can be NULL.
59974a658b32SHong Zhang 
5998c2e3fba1SPatrick Sanan .seealso: `TSSetTimeSpan()`, `TSGetSolutions()`
59994a658b32SHong Zhang  @*/
60009371c9d4SSatish Balay PetscErrorCode TSGetTimeSpan(TS ts, PetscInt *n, const PetscReal **span_times) {
60014a658b32SHong Zhang   PetscFunctionBegin;
60024a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
60034a658b32SHong Zhang   if (n) PetscValidIntPointer(n, 2);
60044a658b32SHong Zhang   if (span_times) PetscValidPointer(span_times, 3);
60054a658b32SHong Zhang   if (!ts->tspan) {
60064a658b32SHong Zhang     if (n) *n = 0;
60074a658b32SHong Zhang     if (span_times) *span_times = NULL;
60084a658b32SHong Zhang   } else {
60094a658b32SHong Zhang     if (n) *n = ts->tspan->num_span_times;
60104a658b32SHong Zhang     if (span_times) *span_times = ts->tspan->span_times;
60114a658b32SHong Zhang   }
60124a658b32SHong Zhang   PetscFunctionReturn(0);
60134a658b32SHong Zhang }
60144a658b32SHong Zhang 
60154a658b32SHong Zhang /*@
60164a658b32SHong Zhang    TSGetTimeSpanSolutions - Get the number of solutions and the solutions at the time points specified by the time span.
60174a658b32SHong Zhang 
60184a658b32SHong Zhang    Input Parameter:
60194a658b32SHong Zhang .  ts - the TS context obtained from TSCreate()
60204a658b32SHong Zhang 
60214a658b32SHong Zhang    Output Parameters:
60224a658b32SHong Zhang +  nsol - the number of solutions
60234a658b32SHong Zhang -  Sols - the solution vectors
60244a658b32SHong Zhang 
60254a658b32SHong Zhang    Level: beginner
60264a658b32SHong Zhang 
602740bd4cedSHong Zhang    Notes:
602840bd4cedSHong Zhang     Both nsol and Sols can be NULL.
602940bd4cedSHong Zhang     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(). For example, manipulating the step size, especially with a reduced precision, may cause TS to step over certain points in the span.
60304a658b32SHong Zhang 
6031db781477SPatrick Sanan .seealso: `TSSetTimeSpan()`
60324a658b32SHong Zhang @*/
60339371c9d4SSatish Balay PetscErrorCode TSGetTimeSpanSolutions(TS ts, PetscInt *nsol, Vec **Sols) {
60344a658b32SHong Zhang   PetscFunctionBegin;
60354a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
60364a658b32SHong Zhang   if (nsol) PetscValidIntPointer(nsol, 2);
60374a658b32SHong Zhang   if (Sols) PetscValidPointer(Sols, 3);
60384a658b32SHong Zhang   if (!ts->tspan) {
60394a658b32SHong Zhang     if (nsol) *nsol = 0;
60404a658b32SHong Zhang     if (Sols) *Sols = NULL;
60414a658b32SHong Zhang   } else {
604240bd4cedSHong Zhang     if (nsol) *nsol = ts->tspan->spanctr;
60434a658b32SHong Zhang     if (Sols) *Sols = ts->tspan->vecs_sol;
60444a658b32SHong Zhang   }
60454a658b32SHong Zhang   PetscFunctionReturn(0);
60464a658b32SHong Zhang }
6047