xref: /petsc/src/ts/interface/ts.c (revision 792fecdfe9134cce4d631112660ddd34f063bc17)
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 
81c167fc2SEmil Constantinescu #define SkipSmallValue(a,b,tol) if (PetscAbsScalar(a)< tol || PetscAbsScalar(b)< tol) continue;
91c167fc2SEmil Constantinescu 
10d5ba7fb7SMatthew Knepley /* Logging support */
11d74926cbSBarry Smith PetscClassId  TS_CLASSID, DMTS_CLASSID;
12a05bf03eSHong Zhang PetscLogEvent TS_Step, TS_PseudoComputeTimeStep, TS_FunctionEval, TS_JacobianEval;
13d405a339SMatthew Knepley 
14c793f718SLisandro Dalcin const char *const TSExactFinalTimeOptions[] = {"UNSPECIFIED","STEPOVER","INTERPOLATE","MATCHSTEP","TSExactFinalTimeOption","TS_EXACTFINALTIME_",NULL};
1549354f04SShri Abhyankar 
162ffb9264SLisandro Dalcin static PetscErrorCode TSAdaptSetDefaultType(TSAdapt adapt,TSAdaptType default_type)
172ffb9264SLisandro Dalcin {
182ffb9264SLisandro Dalcin   PetscFunctionBegin;
19b92453a8SLisandro Dalcin   PetscValidHeaderSpecific(adapt,TSADAPT_CLASSID,1);
20b92453a8SLisandro Dalcin   PetscValidCharPointer(default_type,2);
212ffb9264SLisandro Dalcin   if (!((PetscObject)adapt)->type_name) {
229566063dSJacob Faibussowitsch     PetscCall(TSAdaptSetType(adapt,default_type));
232ffb9264SLisandro Dalcin   }
242ffb9264SLisandro Dalcin   PetscFunctionReturn(0);
252ffb9264SLisandro Dalcin }
262ffb9264SLisandro Dalcin 
27bdad233fSMatthew Knepley /*@
28bdad233fSMatthew Knepley    TSSetFromOptions - Sets various TS parameters from user options.
29bdad233fSMatthew Knepley 
30bdad233fSMatthew Knepley    Collective on TS
31bdad233fSMatthew Knepley 
32bdad233fSMatthew Knepley    Input Parameter:
33bdad233fSMatthew Knepley .  ts - the TS context obtained from TSCreate()
34bdad233fSMatthew Knepley 
35bdad233fSMatthew Knepley    Options Database Keys:
36d2567f34SHong Zhang +  -ts_type <type> - TSEULER, TSBEULER, TSSUNDIALS, TSPSEUDO, TSCN, TSRK, TSTHETA, TSALPHA, TSGLLE, TSSSP, TSGLEE, TSBSYMP, TSIRK
37ef222394SBarry Smith .  -ts_save_trajectory - checkpoint the solution at each time-step
38ef85077eSLisandro Dalcin .  -ts_max_time <time> - maximum time to compute to
394a658b32SHong Zhang .  -ts_time_span <t0,...tf> - sets the time span, solutions are computed and stored for each indicated time
40ef85077eSLisandro Dalcin .  -ts_max_steps <steps> - maximum number of time-steps to take
41ef85077eSLisandro Dalcin .  -ts_init_time <time> - initial time to start computation
424dc72f7fSBarry Smith .  -ts_final_time <time> - final time to compute to (deprecated: use -ts_max_time)
433e4cdcaaSBarry Smith .  -ts_dt <dt> - initial time step
441628793fSSatish Balay .  -ts_exact_final_time <stepover,interpolate,matchstep> - whether to stop at the exact given final time and how to compute the solution at that time
45a3cdaa26SBarry Smith .  -ts_max_snes_failures <maxfailures> - Maximum number of nonlinear solve failures allowed
46a3cdaa26SBarry Smith .  -ts_max_reject <maxrejects> - Maximum number of step rejections before step fails
47a3cdaa26SBarry Smith .  -ts_error_if_step_fails <true,false> - Error if no step succeeds
48a3cdaa26SBarry Smith .  -ts_rtol <rtol> - relative tolerance for local truncation error
4967b8a455SSatish Balay .  -ts_atol <atol> - Absolute tolerance for local truncation error
50f3b1f45cSBarry Smith .  -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - test the Jacobian at each iteration against finite difference with RHS function
51f3b1f45cSBarry 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
5267b8a455SSatish Balay .  -ts_adjoint_solve <yes,no> - After solving the ODE/DAE solve the adjoint problem (requires -ts_save_trajectory)
53847ff0e1SMatthew G. Knepley .  -ts_fd_color - Use finite differences with coloring to compute IJacobian
54bdad233fSMatthew Knepley .  -ts_monitor - print information at each timestep
55aee7a9fbSMatthew G. Knepley .  -ts_monitor_cancel - Cancel all monitors
56de06c3feSJed Brown .  -ts_monitor_lg_solution - Monitor solution graphically
57de06c3feSJed Brown .  -ts_monitor_lg_error - Monitor error graphically
587cf37e64SBarry Smith .  -ts_monitor_error - Monitors norm of error
596934998bSLisandro Dalcin .  -ts_monitor_lg_timestep - Monitor timestep size graphically
608b668821SLisandro Dalcin .  -ts_monitor_lg_timestep_log - Monitor log timestep size graphically
61de06c3feSJed Brown .  -ts_monitor_lg_snes_iterations - Monitor number nonlinear iterations for each timestep graphically
62de06c3feSJed Brown .  -ts_monitor_lg_ksp_iterations - Monitor number nonlinear iterations for each timestep graphically
63de06c3feSJed Brown .  -ts_monitor_sp_eig - Monitor eigenvalues of linearized operator graphically
64de06c3feSJed Brown .  -ts_monitor_draw_solution - Monitor solution graphically
653e4cdcaaSBarry Smith .  -ts_monitor_draw_solution_phase  <xleft,yleft,xright,yright> - Monitor solution graphically with phase diagram, requires problem with exactly 2 degrees of freedom
663e4cdcaaSBarry Smith .  -ts_monitor_draw_error - Monitor error graphically, requires use to have provided TSSetSolutionFunction()
67fde5950dSBarry Smith .  -ts_monitor_solution [ascii binary draw][:filename][:viewerformat] - monitors the solution at each timestep
6863a3b9bcSJacob 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)
699e336e28SPatrick Sanan -  -ts_monitor_envelope - determine maximum and minimum value of each component of the solution over the solution time
7053ea634cSHong Zhang 
713d5a8a6aSBarry Smith    Notes:
723d5a8a6aSBarry Smith      See SNESSetFromOptions() and KSPSetFromOptions() for how to control the nonlinear and linear solves used by the time-stepper.
733d5a8a6aSBarry Smith 
743d5a8a6aSBarry Smith      Certain SNES options get reset for each new nonlinear solver, for example -snes_lag_jacobian <its> and -snes_lag_preconditioner <its>, in order
753d5a8a6aSBarry Smith      to retain them over the multiple nonlinear solves that TS uses you mush also provide -snes_lag_jacobian_persists true and
763d5a8a6aSBarry Smith      -snes_lag_preconditioner_persists true
773d5a8a6aSBarry Smith 
789e336e28SPatrick Sanan    Developer Note:
799e336e28SPatrick Sanan      We should unify all the -ts_monitor options in the way that -xxx_view has been unified
80bdad233fSMatthew Knepley 
81bdad233fSMatthew Knepley    Level: beginner
82bdad233fSMatthew Knepley 
83db781477SPatrick Sanan .seealso: `TSGetType()`
84bdad233fSMatthew Knepley @*/
857087cfbeSBarry Smith PetscErrorCode  TSSetFromOptions(TS ts)
86bdad233fSMatthew Knepley {
87bc952696SBarry Smith   PetscBool              opt,flg,tflg;
88eabae89aSBarry Smith   char                   monfilename[PETSC_MAX_PATH_LEN];
894a658b32SHong Zhang   PetscReal              time_step,tspan[100];
904a658b32SHong Zhang   PetscInt               nt = PETSC_STATIC_ARRAY_LENGTH(tspan);
9149354f04SShri Abhyankar   TSExactFinalTimeOption eftopt;
92d1212d36SBarry Smith   char                   dir[16];
93cd11d68dSLisandro Dalcin   TSIFunction            ifun;
946991f827SBarry Smith   const char             *defaultType;
956991f827SBarry Smith   char                   typeName[256];
96bdad233fSMatthew Knepley 
97bdad233fSMatthew Knepley   PetscFunctionBegin;
980700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
996991f827SBarry Smith 
1009566063dSJacob Faibussowitsch   PetscCall(TSRegisterAll());
1019566063dSJacob Faibussowitsch   PetscCall(TSGetIFunction(ts,NULL,&ifun,NULL));
102cd11d68dSLisandro Dalcin 
103d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)ts);
1041ef27442SStefano Zampini   if (((PetscObject)ts)->type_name) defaultType = ((PetscObject)ts)->type_name;
1051ef27442SStefano Zampini   else defaultType = ifun ? TSBEULER : TSEULER;
1069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-ts_type","TS method","TSSetType",TSList,defaultType,typeName,256,&opt));
1076991f827SBarry Smith   if (opt) {
1089566063dSJacob Faibussowitsch     PetscCall(TSSetType(ts,typeName));
1096991f827SBarry Smith   } else {
1109566063dSJacob Faibussowitsch     PetscCall(TSSetType(ts,defaultType));
1116991f827SBarry Smith   }
112bdad233fSMatthew Knepley 
113bdad233fSMatthew Knepley   /* Handle generic TS options */
1149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDeprecated("-ts_final_time","-ts_max_time","3.10",NULL));
1159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_max_time","Maximum time to run to","TSSetMaxTime",ts->max_time,&ts->max_time,NULL));
1164a658b32SHong Zhang   PetscCall(PetscOptionsRealArray("-ts_time_span","Time span","TSSetTimeSpan",tspan,&nt,&flg));
1174a658b32SHong Zhang   if (flg) PetscCall(TSSetTimeSpan(ts,nt,tspan));
1189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_steps","Maximum number of time steps","TSSetMaxSteps",ts->max_steps,&ts->max_steps,NULL));
1199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_init_time","Initial time","TSSetTime",ts->ptime,&ts->ptime,NULL));
1209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_dt","Initial time step","TSSetTimeStep",ts->time_step,&time_step,&flg));
1219566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetTimeStep(ts,time_step));
1229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-ts_exact_final_time","Option for handling of final time step","TSSetExactFinalTime",TSExactFinalTimeOptions,(PetscEnum)ts->exact_final_time,(PetscEnum*)&eftopt,&flg));
1239566063dSJacob Faibussowitsch   if (flg) PetscCall(TSSetExactFinalTime(ts,eftopt));
1249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_snes_failures","Maximum number of nonlinear solve failures","TSSetMaxSNESFailures",ts->max_snes_failures,&ts->max_snes_failures,NULL));
1259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_max_reject","Maximum number of step rejections before step fails","TSSetMaxStepRejections",ts->max_reject,&ts->max_reject,NULL));
1269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_error_if_step_fails","Error if no step succeeds","TSSetErrorIfStepFails",ts->errorifstepfailed,&ts->errorifstepfailed,NULL));
1279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_rtol","Relative tolerance for local truncation error","TSSetTolerances",ts->rtol,&ts->rtol,NULL));
1289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-ts_atol","Absolute tolerance for local truncation error","TSSetTolerances",ts->atol,&ts->atol,NULL));
129bdad233fSMatthew Knepley 
1309566063dSJacob 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));
1319566063dSJacob 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));
1329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_use_splitrhsfunction","Use the split RHS function for multirate solvers ","TSSetUseSplitRHSFunction",ts->use_splitrhsfunction,&ts->use_splitrhsfunction,NULL));
13356f85f32SBarry Smith #if defined(PETSC_HAVE_SAWS)
13456f85f32SBarry Smith   {
13556f85f32SBarry Smith     PetscBool set;
13656f85f32SBarry Smith     flg  = PETSC_FALSE;
1379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-ts_saws_block","Block for SAWs memory snooper at end of TSSolve","PetscObjectSAWsBlock",((PetscObject)ts)->amspublishblock,&flg,&set));
1381baa6e33SBarry Smith     if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)ts,flg));
13956f85f32SBarry Smith   }
14056f85f32SBarry Smith #endif
14156f85f32SBarry Smith 
142bdad233fSMatthew Knepley   /* Monitor options */
1439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-ts_monitor_frequency", "Number of time steps between monitor output", "TSMonitorSetFrequency", ts->monitorFrequency, &ts->monitorFrequency, NULL));
1449566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts,"-ts_monitor","Monitor time and timestep size","TSMonitorDefault",TSMonitorDefault,NULL));
1459566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts,"-ts_monitor_extreme","Monitor extreme values of the solution","TSMonitorExtreme",TSMonitorExtreme,NULL));
1469566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts,"-ts_monitor_solution","View the solution at each timestep","TSMonitorSolution",TSMonitorSolution,NULL));
1479566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts,"-ts_dmswarm_monitor_moments","Monitor moments of particle distribution","TSDMSwarmMonitorMoments",TSDMSwarmMonitorMoments,NULL));
148fde5950dSBarry Smith 
1499566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_python","Use Python function","TSMonitorSet",NULL,monfilename,sizeof(monfilename),&flg));
1509566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)ts,monfilename));
1515180491cSLisandro Dalcin 
1529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",&opt));
153b3603a34SBarry Smith   if (opt) {
1543923b477SBarry Smith     PetscInt       howoften = 1;
155e669de00SBarry Smith     DM             dm;
156e669de00SBarry Smith     PetscBool      net;
157b3603a34SBarry Smith 
1589566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_solution","Monitor solution graphically","TSMonitorLGSolution",howoften,&howoften,NULL));
1599566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts,&dm));
1609566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dm,DMNETWORK,&net));
161e669de00SBarry Smith     if (net) {
162e669de00SBarry Smith       TSMonitorLGCtxNetwork ctx;
1639566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxNetworkCreate(ts,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&ctx));
1649566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts,TSMonitorLGCtxNetworkSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxNetworkDestroy));
1659566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_lg_solution_semilogy","Plot the solution with a semi-log axis","",ctx->semilogy,&ctx->semilogy,NULL));
166e669de00SBarry Smith     } else {
167e669de00SBarry Smith       TSMonitorLGCtx ctx;
1689566063dSJacob Faibussowitsch       PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx));
1699566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts,TSMonitorLGSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy));
170bdad233fSMatthew Knepley     }
171e669de00SBarry Smith   }
1726ba87a44SLisandro Dalcin 
1739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",&opt));
174ef20d060SBarry Smith   if (opt) {
1750b039ecaSBarry Smith     TSMonitorLGCtx ctx;
1763923b477SBarry Smith     PetscInt       howoften = 1;
177ef20d060SBarry Smith 
1789566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_error","Monitor error graphically","TSMonitorLGError",howoften,&howoften,NULL));
1799566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx));
1809566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorLGError,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy));
181ef20d060SBarry Smith   }
1829566063dSJacob Faibussowitsch   PetscCall(TSMonitorSetFromOptions(ts,"-ts_monitor_error","View the error at each timestep","TSMonitorError",TSMonitorError,NULL));
1837cf37e64SBarry Smith 
1849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",&opt));
1856934998bSLisandro Dalcin   if (opt) {
1866934998bSLisandro Dalcin     TSMonitorLGCtx ctx;
1876934998bSLisandro Dalcin     PetscInt       howoften = 1;
1886934998bSLisandro Dalcin 
1899566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep","Monitor timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL));
1909566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx));
1919566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy));
1926934998bSLisandro Dalcin   }
1939566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",&opt));
1948b668821SLisandro Dalcin   if (opt) {
1958b668821SLisandro Dalcin     TSMonitorLGCtx ctx;
1968b668821SLisandro Dalcin     PetscInt       howoften = 1;
1978b668821SLisandro Dalcin 
1989566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_timestep_log","Monitor log timestep size graphically","TSMonitorLGTimeStep",howoften,&howoften,NULL));
1999566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx));
2009566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorLGTimeStep,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy));
2018b668821SLisandro Dalcin     ctx->semilogy = PETSC_TRUE;
2028b668821SLisandro Dalcin   }
2038b668821SLisandro Dalcin 
2049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",&opt));
205201da799SBarry Smith   if (opt) {
206201da799SBarry Smith     TSMonitorLGCtx ctx;
207201da799SBarry Smith     PetscInt       howoften = 1;
208201da799SBarry Smith 
2099566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_snes_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGSNESIterations",howoften,&howoften,NULL));
2109566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx));
2119566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorLGSNESIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy));
212201da799SBarry Smith   }
2139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",&opt));
214201da799SBarry Smith   if (opt) {
215201da799SBarry Smith     TSMonitorLGCtx ctx;
216201da799SBarry Smith     PetscInt       howoften = 1;
217201da799SBarry Smith 
2189566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_lg_ksp_iterations","Monitor number nonlinear iterations for each timestep graphically","TSMonitorLGKSPIterations",howoften,&howoften,NULL));
2199566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,howoften,&ctx));
2209566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorLGKSPIterations,ctx,(PetscErrorCode (*)(void**))TSMonitorLGCtxDestroy));
221201da799SBarry Smith   }
2229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",&opt));
2238189c53fSBarry Smith   if (opt) {
2248189c53fSBarry Smith     TSMonitorSPEigCtx ctx;
2258189c53fSBarry Smith     PetscInt          howoften = 1;
2268189c53fSBarry Smith 
2279566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_sp_eig","Monitor eigenvalues of linearized operator graphically","TSMonitorSPEig",howoften,&howoften,NULL));
2289566063dSJacob Faibussowitsch     PetscCall(TSMonitorSPEigCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx));
2299566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorSPEig,ctx,(PetscErrorCode (*)(void**))TSMonitorSPEigCtxDestroy));
2308189c53fSBarry Smith   }
2319566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_sp_swarm","Display particle phase from the DMSwarm","TSMonitorSPSwarm",&opt));
2321b575b74SJoseph Pusztay   if (opt) {
2331b575b74SJoseph Pusztay     TSMonitorSPCtx  ctx;
234d7462660SMatthew Knepley     PetscInt        howoften = 1, retain = 0;
2356a5217c0SMatthew G. Knepley     PetscBool       phase = PETSC_TRUE, create = PETSC_TRUE;
236d7462660SMatthew Knepley 
2376a5217c0SMatthew G. Knepley     for (PetscInt i = 0; i < ts->numbermonitors; ++i) if (ts->monitor[i] == TSMonitorSPSwarmSolution) {create = PETSC_FALSE;break;}
2386a5217c0SMatthew G. Knepley     if (create) {
2399566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm","Display particles phase from the DMSwarm", "TSMonitorSPSwarm", howoften, &howoften, NULL));
2409566063dSJacob Faibussowitsch       PetscCall(PetscOptionsInt("-ts_monitor_sp_swarm_retain", "Retain n points plotted to show trajectory, -1 for all points", "TSMonitorSPSwarm", retain, &retain, NULL));
2419566063dSJacob Faibussowitsch       PetscCall(PetscOptionsBool("-ts_monitor_sp_swarm_phase", "Plot in phase space rather than coordinate space", "TSMonitorSPSwarm", phase, &phase, NULL));
2429566063dSJacob Faibussowitsch       PetscCall(TSMonitorSPCtxCreate(PetscObjectComm((PetscObject) ts), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 300, 300, howoften, retain, phase, &ctx));
2439566063dSJacob Faibussowitsch       PetscCall(TSMonitorSet(ts, TSMonitorSPSwarmSolution, ctx, (PetscErrorCode (*)(void**))TSMonitorSPCtxDestroy));
2441b575b74SJoseph Pusztay     }
2456a5217c0SMatthew G. Knepley   }
246ef20d060SBarry Smith   opt  = PETSC_FALSE;
2479566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",&opt));
248a7cc72afSBarry Smith   if (opt) {
24983a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
25083a4ac43SBarry Smith     PetscInt         howoften = 1;
251a80ad3e0SBarry Smith 
2529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution","Monitor solution graphically","TSMonitorDrawSolution",howoften,&howoften,NULL));
2539566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Computed Solution",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx));
2549566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorDrawSolution,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy));
255bdad233fSMatthew Knepley   }
256fb1732b5SBarry Smith   opt  = PETSC_FALSE;
2579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",&opt));
2582d5ee99bSBarry Smith   if (opt) {
2592d5ee99bSBarry Smith     TSMonitorDrawCtx ctx;
2602d5ee99bSBarry Smith     PetscReal        bounds[4];
2612d5ee99bSBarry Smith     PetscInt         n = 4;
2622d5ee99bSBarry Smith     PetscDraw        draw;
2636934998bSLisandro Dalcin     PetscDrawAxis    axis;
2642d5ee99bSBarry Smith 
2659566063dSJacob Faibussowitsch     PetscCall(PetscOptionsRealArray("-ts_monitor_draw_solution_phase","Monitor solution graphically","TSMonitorDrawSolutionPhase",bounds,&n,NULL));
2663c633725SBarry Smith     PetscCheck(n == 4,PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Must provide bounding box of phase field");
2679566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,300,300,1,&ctx));
2689566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(ctx->viewer,0,&draw));
2699566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDrawAxis(ctx->viewer,0,&axis));
2709566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLimits(axis,bounds[0],bounds[2],bounds[1],bounds[3]));
2719566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLabels(axis,"Phase Diagram","Variable 1","Variable 2"));
2729566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorDrawSolutionPhase,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy));
2732d5ee99bSBarry Smith   }
2742d5ee99bSBarry Smith   opt  = PETSC_FALSE;
2759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",&opt));
2763a471f94SBarry Smith   if (opt) {
27783a4ac43SBarry Smith     TSMonitorDrawCtx ctx;
27883a4ac43SBarry Smith     PetscInt         howoften = 1;
2793a471f94SBarry Smith 
2809566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_error","Monitor error graphically","TSMonitorDrawError",howoften,&howoften,NULL));
2819566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Error",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx));
2829566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorDrawError,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy));
2833a471f94SBarry Smith   }
2840ed3bfb6SBarry Smith   opt  = PETSC_FALSE;
2859566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",&opt));
2860ed3bfb6SBarry Smith   if (opt) {
2870ed3bfb6SBarry Smith     TSMonitorDrawCtx ctx;
2880ed3bfb6SBarry Smith     PetscInt         howoften = 1;
2890ed3bfb6SBarry Smith 
2909566063dSJacob Faibussowitsch     PetscCall(PetscOptionsInt("-ts_monitor_draw_solution_function","Monitor solution provided by TSMonitorSetSolutionFunction() graphically","TSMonitorDrawSolutionFunction",howoften,&howoften,NULL));
2919566063dSJacob Faibussowitsch     PetscCall(TSMonitorDrawCtxCreate(PetscObjectComm((PetscObject)ts),NULL,"Solution provided by user function",PETSC_DECIDE,PETSC_DECIDE,300,300,howoften,&ctx));
2929566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorDrawSolutionFunction,ctx,(PetscErrorCode (*)(void**))TSMonitorDrawCtxDestroy));
2930ed3bfb6SBarry Smith   }
294fde5950dSBarry Smith 
295ed81e22dSJed Brown   opt  = PETSC_FALSE;
29663a3b9bcSJacob 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));
297ed81e22dSJed Brown   if (flg) {
298ed81e22dSJed Brown     const char *ptr,*ptr2;
299ed81e22dSJed Brown     char       *filetemplate;
30063a3b9bcSJacob 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");
301ed81e22dSJed Brown     /* Do some cursory validation of the input. */
3029566063dSJacob Faibussowitsch     PetscCall(PetscStrstr(monfilename,"%",(char**)&ptr));
30363a3b9bcSJacob Faibussowitsch     PetscCheck(ptr,PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"-ts_monitor_solution_vtk requires a file template, e.g. filename-%%03" PetscInt_FMT ".vts");
304ed81e22dSJed Brown     for (ptr++; ptr && *ptr; ptr++) {
3059566063dSJacob Faibussowitsch       PetscCall(PetscStrchr("DdiouxX",*ptr,(char**)&ptr2));
30663a3b9bcSJacob 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");
307ed81e22dSJed Brown       if (ptr2) break;
308ed81e22dSJed Brown     }
3099566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(monfilename,&filetemplate));
3109566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorSolutionVTK,filetemplate,(PetscErrorCode (*)(void**))TSMonitorSolutionVTKDestroy));
311ed81e22dSJed Brown   }
312bdad233fSMatthew Knepley 
3139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_dmda_ray","Display a ray of the solution","None","y=0",dir,sizeof(dir),&flg));
314d1212d36SBarry Smith   if (flg) {
315d1212d36SBarry Smith     TSMonitorDMDARayCtx *rayctx;
316d1212d36SBarry Smith     int                  ray = 0;
3173ee9839eSMatthew G. Knepley     DMDirection          ddir;
318d1212d36SBarry Smith     DM                   da;
319d1212d36SBarry Smith     PetscMPIInt          rank;
320d1212d36SBarry Smith 
3213c633725SBarry Smith     PetscCheck(dir[1] == '=',PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
3223ee9839eSMatthew G. Knepley     if (dir[0] == 'x') ddir = DM_X;
3233ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
32498921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Unknown ray %s",dir);
325d1212d36SBarry Smith     sscanf(dir+2,"%d",&ray);
326d1212d36SBarry Smith 
3279566063dSJacob Faibussowitsch     PetscCall(PetscInfo(((PetscObject)ts),"Displaying DMDA ray %c = %d\n",dir[0],ray));
3289566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3299566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts,&da));
3309566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da,ddir,ray,&rayctx->ray,&rayctx->scatter));
3319566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)ts),&rank));
332dd400576SPatrick Sanan     if (rank == 0) {
3339566063dSJacob Faibussowitsch       PetscCall(PetscViewerDrawOpen(PETSC_COMM_SELF,NULL,NULL,0,0,600,300,&rayctx->viewer));
334d1212d36SBarry Smith     }
33551b4a12fSMatthew G. Knepley     rayctx->lgctx = NULL;
3369566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorDMDARay,rayctx,TSMonitorDMDARayDestroy));
337d1212d36SBarry Smith   }
3389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-ts_monitor_lg_dmda_ray","Display a ray of the solution","None","x=0",dir,sizeof(dir),&flg));
33951b4a12fSMatthew G. Knepley   if (flg) {
34051b4a12fSMatthew G. Knepley     TSMonitorDMDARayCtx *rayctx;
34151b4a12fSMatthew G. Knepley     int                 ray = 0;
3423ee9839eSMatthew G. Knepley     DMDirection         ddir;
34351b4a12fSMatthew G. Knepley     DM                  da;
34451b4a12fSMatthew G. Knepley     PetscInt            howoften = 1;
345d1212d36SBarry Smith 
3463c633725SBarry Smith     PetscCheck(dir[1] == '=',PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Malformed ray %s", dir);
3473ee9839eSMatthew G. Knepley     if      (dir[0] == 'x') ddir = DM_X;
3483ee9839eSMatthew G. Knepley     else if (dir[0] == 'y') ddir = DM_Y;
34998921bdaSJacob Faibussowitsch     else SETERRQ(PetscObjectComm((PetscObject) ts), PETSC_ERR_ARG_WRONG, "Unknown ray direction %s", dir);
35051b4a12fSMatthew G. Knepley     sscanf(dir+2, "%d", &ray);
3511c3436cfSJed Brown 
3529566063dSJacob Faibussowitsch     PetscCall(PetscInfo(((PetscObject) ts),"Displaying LG DMDA ray %c = %d\n", dir[0], ray));
3539566063dSJacob Faibussowitsch     PetscCall(PetscNew(&rayctx));
3549566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &da));
3559566063dSJacob Faibussowitsch     PetscCall(DMDAGetRay(da, ddir, ray, &rayctx->ray, &rayctx->scatter));
3569566063dSJacob Faibussowitsch     PetscCall(TSMonitorLGCtxCreate(PETSC_COMM_SELF,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,400,howoften,&rayctx->lgctx));
3579566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts, TSMonitorLGDMDARay, rayctx, TSMonitorDMDARayDestroy));
35851b4a12fSMatthew G. Knepley   }
359a7a1495cSBarry Smith 
3609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-ts_monitor_envelope","Monitor maximum and minimum value of each component of the solution","TSMonitorEnvelope",&opt));
361b3d3934dSBarry Smith   if (opt) {
362b3d3934dSBarry Smith     TSMonitorEnvelopeCtx ctx;
363b3d3934dSBarry Smith 
3649566063dSJacob Faibussowitsch     PetscCall(TSMonitorEnvelopeCtxCreate(ts,&ctx));
3659566063dSJacob Faibussowitsch     PetscCall(TSMonitorSet(ts,TSMonitorEnvelope,ctx,(PetscErrorCode (*)(void**))TSMonitorEnvelopeCtxDestroy));
366b3d3934dSBarry Smith   }
367aee7a9fbSMatthew G. Knepley   flg  = PETSC_FALSE;
3689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_monitor_cancel","Remove all monitors","TSMonitorCancel",flg,&flg,&opt));
3699566063dSJacob Faibussowitsch   if (opt && flg) PetscCall(TSMonitorCancel(ts));
370b3d3934dSBarry Smith 
371847ff0e1SMatthew G. Knepley   flg  = PETSC_FALSE;
3729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_fd_color", "Use finite differences with coloring to compute IJacobian", "TSComputeJacobianDefaultColor", flg, &flg, NULL));
373847ff0e1SMatthew G. Knepley   if (flg) {
374847ff0e1SMatthew G. Knepley     DM   dm;
375847ff0e1SMatthew G. Knepley     DMTS tdm;
376847ff0e1SMatthew G. Knepley 
3779566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
3789566063dSJacob Faibussowitsch     PetscCall(DMGetDMTS(dm, &tdm));
379847ff0e1SMatthew G. Knepley     tdm->ijacobianctx = NULL;
3809566063dSJacob Faibussowitsch     PetscCall(TSSetIJacobian(ts, NULL, NULL, TSComputeIJacobianDefaultColor, NULL));
3819566063dSJacob Faibussowitsch     PetscCall(PetscInfo(ts, "Setting default finite difference coloring Jacobian matrix\n"));
382847ff0e1SMatthew G. Knepley   }
383847ff0e1SMatthew G. Knepley 
384d763cef2SBarry Smith   /* Handle specific TS options */
3851baa6e33SBarry Smith   if (ts->ops->setfromoptions) PetscCall((*ts->ops->setfromoptions)(PetscOptionsObject,ts));
386fbc52257SHong Zhang 
387a7bdc993SLisandro Dalcin   /* Handle TSAdapt options */
3889566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts,&ts->adapt));
3899566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type));
3909566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetFromOptions(PetscOptionsObject,ts->adapt));
391a7bdc993SLisandro Dalcin 
39268bece0bSHong Zhang   /* TS trajectory must be set after TS, since it may use some TS options above */
3934f122a70SLisandro Dalcin   tflg = ts->trajectory ? PETSC_TRUE : PETSC_FALSE;
3949566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-ts_save_trajectory","Save the solution at each timestep","TSSetSaveTrajectory",tflg,&tflg,NULL));
3951baa6e33SBarry Smith   if (tflg) PetscCall(TSSetSaveTrajectory(ts));
396a05bf03eSHong Zhang 
3979566063dSJacob Faibussowitsch   PetscCall(TSAdjointSetFromOptions(PetscOptionsObject,ts));
398d763cef2SBarry Smith 
399d763cef2SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
4009566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ts));
401d0609cedSBarry Smith   PetscOptionsEnd();
402d763cef2SBarry Smith 
4031baa6e33SBarry Smith   if (ts->trajectory) PetscCall(TSTrajectorySetFromOptions(ts->trajectory,ts));
40468bece0bSHong Zhang 
4051ef27442SStefano Zampini   /* why do we have to do this here and not during TSSetUp? */
4069566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&ts->snes));
4071ef27442SStefano Zampini   if (ts->problem_type == TS_LINEAR) {
4089566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes,&flg,SNESKSPONLY,SNESKSPTRANSPOSEONLY,""));
4099566063dSJacob Faibussowitsch     if (!flg) PetscCall(SNESSetType(ts->snes,SNESKSPONLY));
4101ef27442SStefano Zampini   }
4119566063dSJacob Faibussowitsch   PetscCall(SNESSetFromOptions(ts->snes));
412d763cef2SBarry Smith   PetscFunctionReturn(0);
413d763cef2SBarry Smith }
414d763cef2SBarry Smith 
415d2daff3dSHong Zhang /*@
41678fbdcc8SBarry Smith    TSGetTrajectory - Gets the trajectory from a TS if it exists
41778fbdcc8SBarry Smith 
41878fbdcc8SBarry Smith    Collective on TS
41978fbdcc8SBarry Smith 
42078fbdcc8SBarry Smith    Input Parameters:
42178fbdcc8SBarry Smith .  ts - the TS context obtained from TSCreate()
42278fbdcc8SBarry Smith 
4237a7aea1fSJed Brown    Output Parameters:
42478fbdcc8SBarry Smith .  tr - the TSTrajectory object, if it exists
42578fbdcc8SBarry Smith 
42678fbdcc8SBarry Smith    Note: This routine should be called after all TS options have been set
42778fbdcc8SBarry Smith 
42878fbdcc8SBarry Smith    Level: advanced
42978fbdcc8SBarry Smith 
430db781477SPatrick Sanan .seealso: `TSGetTrajectory()`, `TSAdjointSolve()`, `TSTrajectory`, `TSTrajectoryCreate()`
43178fbdcc8SBarry Smith 
43278fbdcc8SBarry Smith @*/
43378fbdcc8SBarry Smith PetscErrorCode  TSGetTrajectory(TS ts,TSTrajectory *tr)
43478fbdcc8SBarry Smith {
43578fbdcc8SBarry Smith   PetscFunctionBegin;
43678fbdcc8SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
43778fbdcc8SBarry Smith   *tr = ts->trajectory;
43878fbdcc8SBarry Smith   PetscFunctionReturn(0);
43978fbdcc8SBarry Smith }
44078fbdcc8SBarry Smith 
44178fbdcc8SBarry Smith /*@
442bc952696SBarry Smith    TSSetSaveTrajectory - Causes the TS to save its solutions as it iterates forward in time in a TSTrajectory object
443d2daff3dSHong Zhang 
444d2daff3dSHong Zhang    Collective on TS
445d2daff3dSHong Zhang 
446f899ff85SJose E. Roman    Input Parameter:
447bc952696SBarry Smith .  ts - the TS context obtained from TSCreate()
448bc952696SBarry Smith 
44978fbdcc8SBarry Smith    Options Database:
45078fbdcc8SBarry Smith +  -ts_save_trajectory - saves the trajectory to a file
45167b8a455SSatish Balay -  -ts_trajectory_type type - set trajectory type
45278fbdcc8SBarry Smith 
45368bece0bSHong Zhang Note: This routine should be called after all TS options have been set
454d2daff3dSHong Zhang 
455c3a89c15SBarry Smith     The TSTRAJECTORYVISUALIZATION files can be loaded into Python with $PETSC_DIR/lib/petsc/bin/PetscBinaryIOTrajectory.py and
45678fbdcc8SBarry Smith    MATLAB with $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m
45778fbdcc8SBarry Smith 
458d2daff3dSHong Zhang    Level: intermediate
459d2daff3dSHong Zhang 
460db781477SPatrick Sanan .seealso: `TSGetTrajectory()`, `TSAdjointSolve()`
461d2daff3dSHong Zhang 
462d2daff3dSHong Zhang @*/
463bc952696SBarry Smith PetscErrorCode  TSSetSaveTrajectory(TS ts)
464d2daff3dSHong Zhang {
465d2daff3dSHong Zhang   PetscFunctionBegin;
466d2daff3dSHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
46763a3b9bcSJacob Faibussowitsch   if (!ts->trajectory) PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory));
468d2daff3dSHong Zhang   PetscFunctionReturn(0);
469d2daff3dSHong Zhang }
470d2daff3dSHong Zhang 
471a7a1495cSBarry Smith /*@
4722d29f1f2SStefano Zampini    TSResetTrajectory - Destroys and recreates the internal TSTrajectory object
4732d29f1f2SStefano Zampini 
4742d29f1f2SStefano Zampini    Collective on TS
4752d29f1f2SStefano Zampini 
4762d29f1f2SStefano Zampini    Input Parameters:
4772d29f1f2SStefano Zampini .  ts - the TS context obtained from TSCreate()
4782d29f1f2SStefano Zampini 
4792d29f1f2SStefano Zampini    Level: intermediate
4802d29f1f2SStefano Zampini 
481db781477SPatrick Sanan .seealso: `TSGetTrajectory()`, `TSAdjointSolve()`, `TSRemoveTrajectory()`
4822d29f1f2SStefano Zampini 
4832d29f1f2SStefano Zampini @*/
4842d29f1f2SStefano Zampini PetscErrorCode  TSResetTrajectory(TS ts)
4852d29f1f2SStefano Zampini {
4862d29f1f2SStefano Zampini   PetscFunctionBegin;
4872d29f1f2SStefano Zampini   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4882d29f1f2SStefano Zampini   if (ts->trajectory) {
4899566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryDestroy(&ts->trajectory));
4909566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryCreate(PetscObjectComm((PetscObject)ts),&ts->trajectory));
4912d29f1f2SStefano Zampini   }
4922d29f1f2SStefano Zampini   PetscFunctionReturn(0);
4932d29f1f2SStefano Zampini }
4942d29f1f2SStefano Zampini 
4952d29f1f2SStefano Zampini /*@
49667a3cfb0SHong Zhang    TSRemoveTrajectory - Destroys and removes the internal TSTrajectory object from TS
49767a3cfb0SHong Zhang 
49867a3cfb0SHong Zhang    Collective on TS
49967a3cfb0SHong Zhang 
50067a3cfb0SHong Zhang    Input Parameters:
50167a3cfb0SHong Zhang .  ts - the TS context obtained from TSCreate()
50267a3cfb0SHong Zhang 
50367a3cfb0SHong Zhang    Level: intermediate
50467a3cfb0SHong Zhang 
505db781477SPatrick Sanan .seealso: `TSResetTrajectory()`, `TSAdjointSolve()`
50667a3cfb0SHong Zhang 
50767a3cfb0SHong Zhang @*/
50867a3cfb0SHong Zhang PetscErrorCode TSRemoveTrajectory(TS ts)
50967a3cfb0SHong Zhang {
51067a3cfb0SHong Zhang   PetscFunctionBegin;
51167a3cfb0SHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
51267a3cfb0SHong Zhang   if (ts->trajectory) {
5139566063dSJacob Faibussowitsch     PetscCall(TSTrajectoryDestroy(&ts->trajectory));
51467a3cfb0SHong Zhang   }
51567a3cfb0SHong Zhang   PetscFunctionReturn(0);
51667a3cfb0SHong Zhang }
51767a3cfb0SHong Zhang 
51867a3cfb0SHong Zhang /*@
519a7a1495cSBarry Smith    TSComputeRHSJacobian - Computes the Jacobian matrix that has been
520a7a1495cSBarry Smith       set with TSSetRHSJacobian().
521a7a1495cSBarry Smith 
522d083f849SBarry Smith    Collective on TS
523a7a1495cSBarry Smith 
524a7a1495cSBarry Smith    Input Parameters:
525316643e7SJed Brown +  ts - the TS context
526a7a1495cSBarry Smith .  t - current timestep
5270910c330SBarry Smith -  U - input vector
528a7a1495cSBarry Smith 
529a7a1495cSBarry Smith    Output Parameters:
530a7a1495cSBarry Smith +  A - Jacobian matrix
5316b867d5aSJose E. Roman -  B - optional preconditioning matrix
532a7a1495cSBarry Smith 
533a7a1495cSBarry Smith    Notes:
534a7a1495cSBarry Smith    Most users should not need to explicitly call this routine, as it
535a7a1495cSBarry Smith    is used internally within the nonlinear solvers.
536a7a1495cSBarry Smith 
537a7a1495cSBarry Smith    Level: developer
538a7a1495cSBarry Smith 
539db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `KSPSetOperators()`
540a7a1495cSBarry Smith @*/
541d1e9a80fSBarry Smith PetscErrorCode  TSComputeRHSJacobian(TS ts,PetscReal t,Vec U,Mat A,Mat B)
542a7a1495cSBarry Smith {
543270bf2e7SJed Brown   PetscObjectState Ustate;
5446c1e1eecSBarry Smith   PetscObjectId    Uid;
54524989b8cSPeter Brune   DM               dm;
546942e3340SBarry Smith   DMTS             tsdm;
54724989b8cSPeter Brune   TSRHSJacobian    rhsjacobianfunc;
54824989b8cSPeter Brune   void             *ctx;
549b2df71adSDebojyoti Ghosh   TSRHSFunction    rhsfunction;
550a7a1495cSBarry Smith 
551a7a1495cSBarry Smith   PetscFunctionBegin;
5520700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5530910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
5540910c330SBarry Smith   PetscCheckSameComm(ts,1,U,3);
5559566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
5569566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&tsdm));
5579566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm,&rhsfunction,NULL));
5589566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm,&rhsjacobianfunc,&ctx));
5599566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U,&Ustate));
5609566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U,&Uid));
561971015bcSStefano Zampini 
5622663174eSHong Zhang   if (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && (rhsfunction != TSComputeRHSFunctionLinear)) PetscFunctionReturn(0);
563d90be118SSean Farley 
56463a3b9bcSJacob 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);
56524989b8cSPeter Brune   if (rhsjacobianfunc) {
5669566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TS_JacobianEval,ts,U,A,B));
567*792fecdfSBarry Smith     PetscCallBack("TS callback Jacobian",(*rhsjacobianfunc)(ts,t,U,A,B,ctx));
568a6ab3590SBarry Smith     ts->rhsjacs++;
5699566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TS_JacobianEval,ts,U,A,B));
570ef66eb69SBarry Smith   } else {
5719566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(A));
5729566063dSJacob Faibussowitsch     if (B && A != B) PetscCall(MatZeroEntries(B));
573ef66eb69SBarry Smith   }
5740e4ef248SJed Brown   ts->rhsjacobian.time  = t;
575971015bcSStefano Zampini   ts->rhsjacobian.shift = 0;
576971015bcSStefano Zampini   ts->rhsjacobian.scale = 1.;
5779566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetId((PetscObject)U,&ts->rhsjacobian.Xid));
5789566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateGet((PetscObject)U,&ts->rhsjacobian.Xstate));
579a7a1495cSBarry Smith   PetscFunctionReturn(0);
580a7a1495cSBarry Smith }
581a7a1495cSBarry Smith 
582316643e7SJed Brown /*@
583d763cef2SBarry Smith    TSComputeRHSFunction - Evaluates the right-hand-side function.
584d763cef2SBarry Smith 
585d083f849SBarry Smith    Collective on TS
586316643e7SJed Brown 
587316643e7SJed Brown    Input Parameters:
588316643e7SJed Brown +  ts - the TS context
589316643e7SJed Brown .  t - current time
5900910c330SBarry Smith -  U - state vector
591316643e7SJed Brown 
592316643e7SJed Brown    Output Parameter:
593316643e7SJed Brown .  y - right hand side
594316643e7SJed Brown 
595316643e7SJed Brown    Note:
596316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
597316643e7SJed Brown    is used internally within the nonlinear solvers.
598316643e7SJed Brown 
599316643e7SJed Brown    Level: developer
600316643e7SJed Brown 
601db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSComputeIFunction()`
602316643e7SJed Brown @*/
6030910c330SBarry Smith PetscErrorCode TSComputeRHSFunction(TS ts,PetscReal t,Vec U,Vec y)
604d763cef2SBarry Smith {
60524989b8cSPeter Brune   TSRHSFunction  rhsfunction;
60624989b8cSPeter Brune   TSIFunction    ifunction;
60724989b8cSPeter Brune   void           *ctx;
60824989b8cSPeter Brune   DM             dm;
60924989b8cSPeter Brune 
610d763cef2SBarry Smith   PetscFunctionBegin;
6110700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6120910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6130700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,4);
6149566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
6159566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm,&rhsfunction,&ctx));
6169566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm,&ifunction,NULL));
617d763cef2SBarry Smith 
6183c633725SBarry Smith   PetscCheck(rhsfunction || ifunction,PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
619d763cef2SBarry Smith 
62024989b8cSPeter Brune   if (rhsfunction) {
6219566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(TS_FunctionEval,ts,U,y,0));
6229566063dSJacob Faibussowitsch     PetscCall(VecLockReadPush(U));
623*792fecdfSBarry Smith     PetscCallBack("TS callback right-hand-side",(*rhsfunction)(ts,t,U,y,ctx));
6249566063dSJacob Faibussowitsch     PetscCall(VecLockReadPop(U));
625a6ab3590SBarry Smith     ts->rhsfuncs++;
6269566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(TS_FunctionEval,ts,U,y,0));
627214bc6a2SJed Brown   } else {
6289566063dSJacob Faibussowitsch     PetscCall(VecZeroEntries(y));
629b2cd27e8SJed Brown   }
630d763cef2SBarry Smith   PetscFunctionReturn(0);
631d763cef2SBarry Smith }
632d763cef2SBarry Smith 
633ef20d060SBarry Smith /*@
634ef20d060SBarry Smith    TSComputeSolutionFunction - Evaluates the solution function.
635ef20d060SBarry Smith 
636d083f849SBarry Smith    Collective on TS
637ef20d060SBarry Smith 
638ef20d060SBarry Smith    Input Parameters:
639ef20d060SBarry Smith +  ts - the TS context
640ef20d060SBarry Smith -  t - current time
641ef20d060SBarry Smith 
642ef20d060SBarry Smith    Output Parameter:
6430910c330SBarry Smith .  U - the solution
644ef20d060SBarry Smith 
645ef20d060SBarry Smith    Note:
646ef20d060SBarry Smith    Most users should not need to explicitly call this routine, as it
647ef20d060SBarry Smith    is used internally within the nonlinear solvers.
648ef20d060SBarry Smith 
649ef20d060SBarry Smith    Level: developer
650ef20d060SBarry Smith 
651db781477SPatrick Sanan .seealso: `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
652ef20d060SBarry Smith @*/
6530910c330SBarry Smith PetscErrorCode TSComputeSolutionFunction(TS ts,PetscReal t,Vec U)
654ef20d060SBarry Smith {
655ef20d060SBarry Smith   TSSolutionFunction solutionfunction;
656ef20d060SBarry Smith   void               *ctx;
657ef20d060SBarry Smith   DM                 dm;
658ef20d060SBarry Smith 
659ef20d060SBarry Smith   PetscFunctionBegin;
660ef20d060SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6610910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6629566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
6639566063dSJacob Faibussowitsch   PetscCall(DMTSGetSolutionFunction(dm,&solutionfunction,&ctx));
664ef20d060SBarry Smith 
665*792fecdfSBarry Smith   if (solutionfunction) PetscCallBack("TS callback solution",(*solutionfunction)(ts,t,U,ctx));
666ef20d060SBarry Smith   PetscFunctionReturn(0);
667ef20d060SBarry Smith }
6689b7cd975SBarry Smith /*@
6699b7cd975SBarry Smith    TSComputeForcingFunction - Evaluates the forcing function.
6709b7cd975SBarry Smith 
671d083f849SBarry Smith    Collective on TS
6729b7cd975SBarry Smith 
6739b7cd975SBarry Smith    Input Parameters:
6749b7cd975SBarry Smith +  ts - the TS context
6759b7cd975SBarry Smith -  t - current time
6769b7cd975SBarry Smith 
6779b7cd975SBarry Smith    Output Parameter:
6789b7cd975SBarry Smith .  U - the function value
6799b7cd975SBarry Smith 
6809b7cd975SBarry Smith    Note:
6819b7cd975SBarry Smith    Most users should not need to explicitly call this routine, as it
6829b7cd975SBarry Smith    is used internally within the nonlinear solvers.
6839b7cd975SBarry Smith 
6849b7cd975SBarry Smith    Level: developer
6859b7cd975SBarry Smith 
686db781477SPatrick Sanan .seealso: `TSSetSolutionFunction()`, `TSSetRHSFunction()`, `TSComputeIFunction()`
6879b7cd975SBarry Smith @*/
6889b7cd975SBarry Smith PetscErrorCode TSComputeForcingFunction(TS ts,PetscReal t,Vec U)
6899b7cd975SBarry Smith {
6909b7cd975SBarry Smith   void              *ctx;
6919b7cd975SBarry Smith   DM                 dm;
6925f80ce2aSJacob Faibussowitsch   TSForcingFunction  forcing;
6939b7cd975SBarry Smith 
6949b7cd975SBarry Smith   PetscFunctionBegin;
6959b7cd975SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6969b7cd975SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
6979566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
6989566063dSJacob Faibussowitsch   PetscCall(DMTSGetForcingFunction(dm,&forcing,&ctx));
6999b7cd975SBarry Smith 
700*792fecdfSBarry Smith   if (forcing) PetscCallBack("TS callback forcing function",(*forcing)(ts,t,U,ctx));
7019b7cd975SBarry Smith   PetscFunctionReturn(0);
7029b7cd975SBarry Smith }
703ef20d060SBarry Smith 
704214bc6a2SJed Brown static PetscErrorCode TSGetRHSVec_Private(TS ts,Vec *Frhs)
705214bc6a2SJed Brown {
7062dd45cf8SJed Brown   Vec            F;
707214bc6a2SJed Brown 
708214bc6a2SJed Brown   PetscFunctionBegin;
7090298fd71SBarry Smith   *Frhs = NULL;
7109566063dSJacob Faibussowitsch   PetscCall(TSGetIFunction(ts,&F,NULL,NULL));
711214bc6a2SJed Brown   if (!ts->Frhs) {
7129566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(F,&ts->Frhs));
713214bc6a2SJed Brown   }
714214bc6a2SJed Brown   *Frhs = ts->Frhs;
715214bc6a2SJed Brown   PetscFunctionReturn(0);
716214bc6a2SJed Brown }
717214bc6a2SJed Brown 
718971015bcSStefano Zampini PetscErrorCode TSGetRHSMats_Private(TS ts,Mat *Arhs,Mat *Brhs)
719214bc6a2SJed Brown {
720214bc6a2SJed Brown   Mat            A,B;
72141a1d4d2SBarry Smith   TSIJacobian    ijacobian;
722214bc6a2SJed Brown 
723214bc6a2SJed Brown   PetscFunctionBegin;
724c0cd0301SJed Brown   if (Arhs) *Arhs = NULL;
725c0cd0301SJed Brown   if (Brhs) *Brhs = NULL;
7269566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts,&A,&B,&ijacobian,NULL));
727214bc6a2SJed Brown   if (Arhs) {
728214bc6a2SJed Brown     if (!ts->Arhs) {
72941a1d4d2SBarry Smith       if (ijacobian) {
7309566063dSJacob Faibussowitsch         PetscCall(MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&ts->Arhs));
7319566063dSJacob Faibussowitsch         PetscCall(TSSetMatStructure(ts,SAME_NONZERO_PATTERN));
73241a1d4d2SBarry Smith       } else {
73341a1d4d2SBarry Smith         ts->Arhs = A;
7349566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
73541a1d4d2SBarry Smith       }
7363565c898SBarry Smith     } else {
7373565c898SBarry Smith       PetscBool flg;
7389566063dSJacob Faibussowitsch       PetscCall(SNESGetUseMatrixFree(ts->snes,NULL,&flg));
7393565c898SBarry Smith       /* Handle case where user provided only RHSJacobian and used -snes_mf_operator */
7403565c898SBarry Smith       if (flg && !ijacobian && ts->Arhs == ts->Brhs) {
7419566063dSJacob Faibussowitsch         PetscCall(PetscObjectDereference((PetscObject)ts->Arhs));
7423565c898SBarry Smith         ts->Arhs = A;
7439566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)A));
7443565c898SBarry Smith       }
745214bc6a2SJed Brown     }
746214bc6a2SJed Brown     *Arhs = ts->Arhs;
747214bc6a2SJed Brown   }
748214bc6a2SJed Brown   if (Brhs) {
749214bc6a2SJed Brown     if (!ts->Brhs) {
750bdb70873SJed Brown       if (A != B) {
75141a1d4d2SBarry Smith         if (ijacobian) {
7529566063dSJacob Faibussowitsch           PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&ts->Brhs));
753bdb70873SJed Brown         } else {
75441a1d4d2SBarry Smith           ts->Brhs = B;
7559566063dSJacob Faibussowitsch           PetscCall(PetscObjectReference((PetscObject)B));
75641a1d4d2SBarry Smith         }
75741a1d4d2SBarry Smith       } else {
7589566063dSJacob Faibussowitsch         PetscCall(PetscObjectReference((PetscObject)ts->Arhs));
75951699248SLisandro Dalcin         ts->Brhs = ts->Arhs;
760bdb70873SJed Brown       }
761214bc6a2SJed Brown     }
762214bc6a2SJed Brown     *Brhs = ts->Brhs;
763214bc6a2SJed Brown   }
764214bc6a2SJed Brown   PetscFunctionReturn(0);
765214bc6a2SJed Brown }
766214bc6a2SJed Brown 
767316643e7SJed Brown /*@
7680910c330SBarry Smith    TSComputeIFunction - Evaluates the DAE residual written in implicit form F(t,U,Udot)=0
769316643e7SJed Brown 
770d083f849SBarry Smith    Collective on TS
771316643e7SJed Brown 
772316643e7SJed Brown    Input Parameters:
773316643e7SJed Brown +  ts - the TS context
774316643e7SJed Brown .  t - current time
7750910c330SBarry Smith .  U - state vector
7760910c330SBarry Smith .  Udot - time derivative of state vector
777214bc6a2SJed Brown -  imex - flag indicates if the method is IMEX so that the RHSFunction should be kept separate
778316643e7SJed Brown 
779316643e7SJed Brown    Output Parameter:
780316643e7SJed Brown .  Y - right hand side
781316643e7SJed Brown 
782316643e7SJed Brown    Note:
783316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
784316643e7SJed Brown    is used internally within the nonlinear solvers.
785316643e7SJed Brown 
786316643e7SJed Brown    If the user did did not write their equations in implicit form, this
787316643e7SJed Brown    function recasts them in implicit form.
788316643e7SJed Brown 
789316643e7SJed Brown    Level: developer
790316643e7SJed Brown 
791db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSComputeRHSFunction()`
792316643e7SJed Brown @*/
7930910c330SBarry Smith PetscErrorCode TSComputeIFunction(TS ts,PetscReal t,Vec U,Vec Udot,Vec Y,PetscBool imex)
794316643e7SJed Brown {
79524989b8cSPeter Brune   TSIFunction    ifunction;
79624989b8cSPeter Brune   TSRHSFunction  rhsfunction;
79724989b8cSPeter Brune   void           *ctx;
79824989b8cSPeter Brune   DM             dm;
799316643e7SJed Brown 
800316643e7SJed Brown   PetscFunctionBegin;
8010700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
8020910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
8030910c330SBarry Smith   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
8040700a824SBarry Smith   PetscValidHeaderSpecific(Y,VEC_CLASSID,5);
805316643e7SJed Brown 
8069566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
8079566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm,&ifunction,&ctx));
8089566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm,&rhsfunction,NULL));
80924989b8cSPeter Brune 
8103c633725SBarry Smith   PetscCheck(rhsfunction || ifunction,PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSFunction() and / or TSSetIFunction()");
811d90be118SSean Farley 
8129566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_FunctionEval,ts,U,Udot,Y));
81324989b8cSPeter Brune   if (ifunction) {
814*792fecdfSBarry Smith     PetscCallBack("TS callback implicit function",(*ifunction)(ts,t,U,Udot,Y,ctx));
815a6ab3590SBarry Smith     ts->ifuncs++;
816214bc6a2SJed Brown   }
817214bc6a2SJed Brown   if (imex) {
81824989b8cSPeter Brune     if (!ifunction) {
8199566063dSJacob Faibussowitsch       PetscCall(VecCopy(Udot,Y));
8202dd45cf8SJed Brown     }
82124989b8cSPeter Brune   } else if (rhsfunction) {
82224989b8cSPeter Brune     if (ifunction) {
823214bc6a2SJed Brown       Vec Frhs;
8249566063dSJacob Faibussowitsch       PetscCall(TSGetRHSVec_Private(ts,&Frhs));
8259566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts,t,U,Frhs));
8269566063dSJacob Faibussowitsch       PetscCall(VecAXPY(Y,-1,Frhs));
8272dd45cf8SJed Brown     } else {
8289566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSFunction(ts,t,U,Y));
8299566063dSJacob Faibussowitsch       PetscCall(VecAYPX(Y,-1,Udot));
830316643e7SJed Brown     }
8314a6899ffSJed Brown   }
8329566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_FunctionEval,ts,U,Udot,Y));
833316643e7SJed Brown   PetscFunctionReturn(0);
834316643e7SJed Brown }
835316643e7SJed Brown 
836cfa8a9a2SHong Zhang /*
837cfa8a9a2SHong Zhang    TSRecoverRHSJacobian - Recover the Jacobian matrix so that one can call TSComputeRHSJacobian() on it.
838cfa8a9a2SHong Zhang 
839cfa8a9a2SHong Zhang    Note:
840cfa8a9a2SHong Zhang    This routine is needed when one switches from TSComputeIJacobian() to TSComputeRHSJacobian() because the Jacobian matrix may be shifted or scaled in TSComputeIJacobian().
841cfa8a9a2SHong Zhang 
842cfa8a9a2SHong Zhang */
843cfa8a9a2SHong Zhang static PetscErrorCode TSRecoverRHSJacobian(TS ts,Mat A,Mat B)
844cfa8a9a2SHong Zhang {
845cfa8a9a2SHong Zhang   PetscFunctionBegin;
846cfa8a9a2SHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
8473c633725SBarry Smith   PetscCheck(A == ts->Arhs,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Invalid Amat");
8483c633725SBarry Smith   PetscCheck(B == ts->Brhs,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Invalid Bmat");
849cfa8a9a2SHong Zhang 
8501baa6e33SBarry Smith   if (ts->rhsjacobian.shift) PetscCall(MatShift(A,-ts->rhsjacobian.shift));
851cfa8a9a2SHong Zhang   if (ts->rhsjacobian.scale == -1.) {
8529566063dSJacob Faibussowitsch     PetscCall(MatScale(A,-1));
853cfa8a9a2SHong Zhang   }
854cfa8a9a2SHong Zhang   if (B && B == ts->Brhs && A != B) {
8551baa6e33SBarry Smith     if (ts->rhsjacobian.shift) PetscCall(MatShift(B,-ts->rhsjacobian.shift));
856cfa8a9a2SHong Zhang     if (ts->rhsjacobian.scale == -1.) {
8579566063dSJacob Faibussowitsch       PetscCall(MatScale(B,-1));
858cfa8a9a2SHong Zhang     }
859cfa8a9a2SHong Zhang   }
860cfa8a9a2SHong Zhang   ts->rhsjacobian.shift = 0;
861cfa8a9a2SHong Zhang   ts->rhsjacobian.scale = 1.;
862cfa8a9a2SHong Zhang   PetscFunctionReturn(0);
863cfa8a9a2SHong Zhang }
864cfa8a9a2SHong Zhang 
865316643e7SJed Brown /*@
866316643e7SJed Brown    TSComputeIJacobian - Evaluates the Jacobian of the DAE
867316643e7SJed Brown 
868d083f849SBarry Smith    Collective on TS
869316643e7SJed Brown 
870316643e7SJed Brown    Input
871316643e7SJed Brown       Input Parameters:
872316643e7SJed Brown +  ts - the TS context
873316643e7SJed Brown .  t - current timestep
8740910c330SBarry Smith .  U - state vector
8750910c330SBarry Smith .  Udot - time derivative of state vector
876214bc6a2SJed Brown .  shift - shift to apply, see note below
877214bc6a2SJed Brown -  imex - flag indicates if the method is IMEX so that the RHSJacobian should be kept separate
878316643e7SJed Brown 
879316643e7SJed Brown    Output Parameters:
880316643e7SJed Brown +  A - Jacobian matrix
8813565c898SBarry Smith -  B - matrix from which the preconditioner is constructed; often the same as A
882316643e7SJed Brown 
883316643e7SJed Brown    Notes:
8840910c330SBarry Smith    If F(t,U,Udot)=0 is the DAE, the required Jacobian is
885316643e7SJed Brown 
8860910c330SBarry Smith    dF/dU + shift*dF/dUdot
887316643e7SJed Brown 
888316643e7SJed Brown    Most users should not need to explicitly call this routine, as it
889316643e7SJed Brown    is used internally within the nonlinear solvers.
890316643e7SJed Brown 
891316643e7SJed Brown    Level: developer
892316643e7SJed Brown 
893db781477SPatrick Sanan .seealso: `TSSetIJacobian()`
89463495f91SJed Brown @*/
895d1e9a80fSBarry Smith PetscErrorCode TSComputeIJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,PetscBool imex)
896316643e7SJed Brown {
89724989b8cSPeter Brune   TSIJacobian    ijacobian;
89824989b8cSPeter Brune   TSRHSJacobian  rhsjacobian;
89924989b8cSPeter Brune   DM             dm;
90024989b8cSPeter Brune   void           *ctx;
901316643e7SJed Brown 
902316643e7SJed Brown   PetscFunctionBegin;
9030700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
9040910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
9050910c330SBarry Smith   PetscValidHeaderSpecific(Udot,VEC_CLASSID,4);
906316643e7SJed Brown   PetscValidPointer(A,6);
90794ab13aaSBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,6);
908316643e7SJed Brown   PetscValidPointer(B,7);
90994ab13aaSBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,7);
91024989b8cSPeter Brune 
9119566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
9129566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm,&ijacobian,&ctx));
9139566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm,&rhsjacobian,NULL));
91424989b8cSPeter Brune 
9153c633725SBarry Smith   PetscCheck(rhsjacobian || ijacobian,PetscObjectComm((PetscObject)ts),PETSC_ERR_USER,"Must call TSSetRHSJacobian() and / or TSSetIJacobian()");
916316643e7SJed Brown 
9179566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_JacobianEval,ts,U,A,B));
91824989b8cSPeter Brune   if (ijacobian) {
919*792fecdfSBarry Smith     PetscCallBack("TS callback implicit Jacobian",(*ijacobian)(ts,t,U,Udot,shift,A,B,ctx));
920a6ab3590SBarry Smith     ts->ijacs++;
9214a6899ffSJed Brown   }
922214bc6a2SJed Brown   if (imex) {
923b5abc632SBarry Smith     if (!ijacobian) {  /* system was written as Udot = G(t,U) */
9244c26be97Sstefano_zampini       PetscBool assembled;
925971015bcSStefano Zampini       if (rhsjacobian) {
926971015bcSStefano Zampini         Mat Arhs = NULL;
9279566063dSJacob Faibussowitsch         PetscCall(TSGetRHSMats_Private(ts,&Arhs,NULL));
928971015bcSStefano Zampini         if (A == Arhs) {
9293c633725SBarry 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 */
930971015bcSStefano Zampini           ts->rhsjacobian.time = PETSC_MIN_REAL;
931971015bcSStefano Zampini         }
932971015bcSStefano Zampini       }
9339566063dSJacob Faibussowitsch       PetscCall(MatZeroEntries(A));
9349566063dSJacob Faibussowitsch       PetscCall(MatAssembled(A,&assembled));
9354c26be97Sstefano_zampini       if (!assembled) {
9369566063dSJacob Faibussowitsch         PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
9379566063dSJacob Faibussowitsch         PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
9384c26be97Sstefano_zampini       }
9399566063dSJacob Faibussowitsch       PetscCall(MatShift(A,shift));
94094ab13aaSBarry Smith       if (A != B) {
9419566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(B));
9429566063dSJacob Faibussowitsch         PetscCall(MatAssembled(B,&assembled));
9434c26be97Sstefano_zampini         if (!assembled) {
9449566063dSJacob Faibussowitsch           PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
9459566063dSJacob Faibussowitsch           PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
9464c26be97Sstefano_zampini         }
9479566063dSJacob Faibussowitsch         PetscCall(MatShift(B,shift));
948214bc6a2SJed Brown       }
949214bc6a2SJed Brown     }
950214bc6a2SJed Brown   } else {
951e1244c69SJed Brown     Mat Arhs = NULL,Brhs = NULL;
952e8b1e424SHong Zhang     if (rhsjacobian) { /* RHSJacobian needs to be converted to part of IJacobian if exists */
9539566063dSJacob Faibussowitsch       PetscCall(TSGetRHSMats_Private(ts,&Arhs,&Brhs));
954e1244c69SJed Brown     }
955e8b1e424SHong Zhang     if (Arhs == A) { /* No IJacobian matrix, so we only have the RHS matrix */
956e8b1e424SHong Zhang       PetscObjectState Ustate;
957e8b1e424SHong Zhang       PetscObjectId    Uid;
958e8b1e424SHong Zhang       TSRHSFunction    rhsfunction;
959e8b1e424SHong Zhang 
9609566063dSJacob Faibussowitsch       PetscCall(DMTSGetRHSFunction(dm,&rhsfunction,NULL));
9619566063dSJacob Faibussowitsch       PetscCall(PetscObjectStateGet((PetscObject)U,&Ustate));
9629566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetId((PetscObject)U,&Uid));
963097a96a2SHong Zhang       if ((rhsjacobian == TSComputeRHSJacobianConstant || (ts->rhsjacobian.time == t && (ts->problem_type == TS_LINEAR || (ts->rhsjacobian.Xid == Uid && ts->rhsjacobian.Xstate == Ustate)) && rhsfunction != TSComputeRHSFunctionLinear)) && ts->rhsjacobian.scale == -1.) { /* No need to recompute RHSJacobian */
9649566063dSJacob Faibussowitsch         PetscCall(MatShift(A,shift-ts->rhsjacobian.shift)); /* revert the old shift and add the new shift with a single call to MatShift */
96534d322a1SHong Zhang         if (A != B) {
9669566063dSJacob Faibussowitsch           PetscCall(MatShift(B,shift-ts->rhsjacobian.shift));
96734d322a1SHong Zhang         }
968e8b1e424SHong Zhang       } else {
9693565c898SBarry Smith         PetscBool flg;
970e8b1e424SHong Zhang 
971e8b1e424SHong Zhang         if (ts->rhsjacobian.reuse) { /* Undo the damage */
972e8b1e424SHong Zhang           /* MatScale has a short path for this case.
973e8b1e424SHong Zhang              However, this code path is taken the first time TSComputeRHSJacobian is called
974e8b1e424SHong Zhang              and the matrices have not been assembled yet */
9759566063dSJacob Faibussowitsch           PetscCall(TSRecoverRHSJacobian(ts,A,B));
976e8b1e424SHong Zhang         }
9779566063dSJacob Faibussowitsch         PetscCall(TSComputeRHSJacobian(ts,t,U,A,B));
9789566063dSJacob Faibussowitsch         PetscCall(SNESGetUseMatrixFree(ts->snes,NULL,&flg));
9793565c898SBarry Smith         /* since -snes_mf_operator uses the full SNES function it does not need to be shifted or scaled here */
9803565c898SBarry Smith         if (!flg) {
9819566063dSJacob Faibussowitsch           PetscCall(MatScale(A,-1));
9829566063dSJacob Faibussowitsch           PetscCall(MatShift(A,shift));
9833565c898SBarry Smith         }
98494ab13aaSBarry Smith         if (A != B) {
9859566063dSJacob Faibussowitsch           PetscCall(MatScale(B,-1));
9869566063dSJacob Faibussowitsch           PetscCall(MatShift(B,shift));
987316643e7SJed Brown         }
988e8b1e424SHong Zhang       }
989e8b1e424SHong Zhang       ts->rhsjacobian.scale = -1;
990e8b1e424SHong Zhang       ts->rhsjacobian.shift = shift;
991d60b7d5cSBarry Smith     } else if (Arhs) {          /* Both IJacobian and RHSJacobian */
992e1244c69SJed Brown       if (!ijacobian) {         /* No IJacobian provided, but we have a separate RHS matrix */
9939566063dSJacob Faibussowitsch         PetscCall(MatZeroEntries(A));
9949566063dSJacob Faibussowitsch         PetscCall(MatShift(A,shift));
99594ab13aaSBarry Smith         if (A != B) {
9969566063dSJacob Faibussowitsch           PetscCall(MatZeroEntries(B));
9979566063dSJacob Faibussowitsch           PetscCall(MatShift(B,shift));
998214bc6a2SJed Brown         }
999316643e7SJed Brown       }
10009566063dSJacob Faibussowitsch       PetscCall(TSComputeRHSJacobian(ts,t,U,Arhs,Brhs));
10019566063dSJacob Faibussowitsch       PetscCall(MatAXPY(A,-1,Arhs,ts->axpy_pattern));
100294ab13aaSBarry Smith       if (A != B) {
10039566063dSJacob Faibussowitsch         PetscCall(MatAXPY(B,-1,Brhs,ts->axpy_pattern));
1004316643e7SJed Brown       }
1005316643e7SJed Brown     }
1006316643e7SJed Brown   }
10079566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_JacobianEval,ts,U,A,B));
1008316643e7SJed Brown   PetscFunctionReturn(0);
1009316643e7SJed Brown }
1010316643e7SJed Brown 
1011d763cef2SBarry Smith /*@C
1012d763cef2SBarry Smith     TSSetRHSFunction - Sets the routine for evaluating the function,
1013b5abc632SBarry Smith     where U_t = G(t,u).
1014d763cef2SBarry Smith 
10153f9fe445SBarry Smith     Logically Collective on TS
1016d763cef2SBarry Smith 
1017d763cef2SBarry Smith     Input Parameters:
1018d763cef2SBarry Smith +   ts - the TS context obtained from TSCreate()
10190298fd71SBarry Smith .   r - vector to put the computed right hand side (or NULL to have it created)
1020d763cef2SBarry Smith .   f - routine for evaluating the right-hand-side function
1021d763cef2SBarry Smith -   ctx - [optional] user-defined context for private data for the
10220298fd71SBarry Smith           function evaluation routine (may be NULL)
1023d763cef2SBarry Smith 
1024a96d6ef6SBarry Smith     Calling sequence of f:
1025a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec F,void *ctx);
1026d763cef2SBarry Smith 
1027a96d6ef6SBarry Smith +   ts - timestep context
1028a96d6ef6SBarry Smith .   t - current timestep
1029d763cef2SBarry Smith .   u - input vector
1030d763cef2SBarry Smith .   F - function vector
1031d763cef2SBarry Smith -   ctx - [optional] user-defined function context
1032d763cef2SBarry Smith 
1033d763cef2SBarry Smith     Level: beginner
1034d763cef2SBarry Smith 
103595452b02SPatrick Sanan     Notes:
103695452b02SPatrick Sanan     You must call this function or TSSetIFunction() to define your ODE. You cannot use this function when solving a DAE.
10372bbac0d3SBarry Smith 
1038db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSSetIFunction()`
1039d763cef2SBarry Smith @*/
1040089b2837SJed Brown PetscErrorCode  TSSetRHSFunction(TS ts,Vec r,PetscErrorCode (*f)(TS,PetscReal,Vec,Vec,void*),void *ctx)
1041d763cef2SBarry Smith {
1042089b2837SJed Brown   SNES           snes;
10430298fd71SBarry Smith   Vec            ralloc = NULL;
104424989b8cSPeter Brune   DM             dm;
1045d763cef2SBarry Smith 
1046089b2837SJed Brown   PetscFunctionBegin;
10470700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1048ca94891dSJed Brown   if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2);
104924989b8cSPeter Brune 
10509566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
10519566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSFunction(dm,f,ctx));
10529566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
1053e856ceecSJed Brown   if (!r && !ts->dm && ts->vec_sol) {
10549566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol,&ralloc));
1055e856ceecSJed Brown     r = ralloc;
1056e856ceecSJed Brown   }
10579566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes,r,SNESTSFormFunction,ts));
10589566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
1059d763cef2SBarry Smith   PetscFunctionReturn(0);
1060d763cef2SBarry Smith }
1061d763cef2SBarry Smith 
1062ef20d060SBarry Smith /*@C
1063abd5a294SJed Brown     TSSetSolutionFunction - Provide a function that computes the solution of the ODE or DAE
1064ef20d060SBarry Smith 
1065ef20d060SBarry Smith     Logically Collective on TS
1066ef20d060SBarry Smith 
1067ef20d060SBarry Smith     Input Parameters:
1068ef20d060SBarry Smith +   ts - the TS context obtained from TSCreate()
1069ef20d060SBarry Smith .   f - routine for evaluating the solution
1070ef20d060SBarry Smith -   ctx - [optional] user-defined context for private data for the
10710298fd71SBarry Smith           function evaluation routine (may be NULL)
1072ef20d060SBarry Smith 
1073a96d6ef6SBarry Smith     Calling sequence of f:
1074a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,void *ctx);
1075ef20d060SBarry Smith 
1076ef20d060SBarry Smith +   t - current timestep
1077ef20d060SBarry Smith .   u - output vector
1078ef20d060SBarry Smith -   ctx - [optional] user-defined function context
1079ef20d060SBarry Smith 
10800ed3bfb6SBarry Smith     Options Database:
10810ed3bfb6SBarry Smith +  -ts_monitor_lg_error - create a graphical monitor of error history, requires user to have provided TSSetSolutionFunction()
10820ed3bfb6SBarry Smith -  -ts_monitor_draw_error - Monitor error graphically, requires user to have provided TSSetSolutionFunction()
10830ed3bfb6SBarry Smith 
1084abd5a294SJed Brown     Notes:
1085abd5a294SJed Brown     This routine is used for testing accuracy of time integration schemes when you already know the solution.
1086abd5a294SJed Brown     If analytic solutions are not known for your system, consider using the Method of Manufactured Solutions to
1087abd5a294SJed Brown     create closed-form solutions with non-physical forcing terms.
1088abd5a294SJed Brown 
10894f09c107SBarry Smith     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
1090abd5a294SJed Brown 
1091ef20d060SBarry Smith     Level: beginner
1092ef20d060SBarry Smith 
1093db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSComputeSolutionFunction()`, `TSSetForcingFunction()`, `TSSetSolution()`, `TSGetSolution()`, `TSMonitorLGError()`, `TSMonitorDrawError()`
1094ef20d060SBarry Smith @*/
1095ef20d060SBarry Smith PetscErrorCode  TSSetSolutionFunction(TS ts,PetscErrorCode (*f)(TS,PetscReal,Vec,void*),void *ctx)
1096ef20d060SBarry Smith {
1097ef20d060SBarry Smith   DM             dm;
1098ef20d060SBarry Smith 
1099ef20d060SBarry Smith   PetscFunctionBegin;
1100ef20d060SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
11019566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
11029566063dSJacob Faibussowitsch   PetscCall(DMTSSetSolutionFunction(dm,f,ctx));
1103ef20d060SBarry Smith   PetscFunctionReturn(0);
1104ef20d060SBarry Smith }
1105ef20d060SBarry Smith 
11069b7cd975SBarry Smith /*@C
11079b7cd975SBarry Smith     TSSetForcingFunction - Provide a function that computes a forcing term for a ODE or PDE
11089b7cd975SBarry Smith 
11099b7cd975SBarry Smith     Logically Collective on TS
11109b7cd975SBarry Smith 
11119b7cd975SBarry Smith     Input Parameters:
11129b7cd975SBarry Smith +   ts - the TS context obtained from TSCreate()
1113e162b725SBarry Smith .   func - routine for evaluating the forcing function
11149b7cd975SBarry Smith -   ctx - [optional] user-defined context for private data for the
11150298fd71SBarry Smith           function evaluation routine (may be NULL)
11169b7cd975SBarry Smith 
11179b7cd975SBarry Smith     Calling sequence of func:
11186bc98fa9SBarry Smith $     PetscErrorCode func (TS ts,PetscReal t,Vec f,void *ctx);
11199b7cd975SBarry Smith 
11209b7cd975SBarry Smith +   t - current timestep
1121e162b725SBarry Smith .   f - output vector
11229b7cd975SBarry Smith -   ctx - [optional] user-defined function context
11239b7cd975SBarry Smith 
11249b7cd975SBarry Smith     Notes:
11259b7cd975SBarry Smith     This routine is useful for testing accuracy of time integration schemes when using the Method of Manufactured Solutions to
1126e162b725SBarry 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
1127e162b725SBarry Smith     definition of the problem you are solving and hence possibly introducing bugs.
1128e162b725SBarry Smith 
1129e162b725SBarry Smith     This replaces the ODE F(u,u_t,t) = 0 the TS is solving with F(u,u_t,t) - func(t) = 0
1130e162b725SBarry Smith 
1131e162b725SBarry 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
1132e162b725SBarry Smith     parameters can be passed in the ctx variable.
11339b7cd975SBarry Smith 
11349b7cd975SBarry Smith     For low-dimensional problems solved in serial, such as small discrete systems, TSMonitorLGError() can be used to monitor the error history.
11359b7cd975SBarry Smith 
11369b7cd975SBarry Smith     Level: beginner
11379b7cd975SBarry Smith 
1138db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetIJacobian()`, `TSComputeSolutionFunction()`, `TSSetSolutionFunction()`
11399b7cd975SBarry Smith @*/
1140e162b725SBarry Smith PetscErrorCode  TSSetForcingFunction(TS ts,TSForcingFunction func,void *ctx)
11419b7cd975SBarry Smith {
11429b7cd975SBarry Smith   DM             dm;
11439b7cd975SBarry Smith 
11449b7cd975SBarry Smith   PetscFunctionBegin;
11459b7cd975SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
11469566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
11479566063dSJacob Faibussowitsch   PetscCall(DMTSSetForcingFunction(dm,func,ctx));
11489b7cd975SBarry Smith   PetscFunctionReturn(0);
11499b7cd975SBarry Smith }
11509b7cd975SBarry Smith 
1151d763cef2SBarry Smith /*@C
1152f7ab8db6SBarry Smith    TSSetRHSJacobian - Sets the function to compute the Jacobian of G,
1153b5abc632SBarry Smith    where U_t = G(U,t), as well as the location to store the matrix.
1154d763cef2SBarry Smith 
11553f9fe445SBarry Smith    Logically Collective on TS
1156d763cef2SBarry Smith 
1157d763cef2SBarry Smith    Input Parameters:
1158d763cef2SBarry Smith +  ts  - the TS context obtained from TSCreate()
1159e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1160e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1161d763cef2SBarry Smith .  f   - the Jacobian evaluation routine
1162d763cef2SBarry Smith -  ctx - [optional] user-defined context for private data for the
11630298fd71SBarry Smith          Jacobian evaluation routine (may be NULL)
1164d763cef2SBarry Smith 
1165f7ab8db6SBarry Smith    Calling sequence of f:
1166a96d6ef6SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Mat A,Mat B,void *ctx);
1167d763cef2SBarry Smith 
1168d763cef2SBarry Smith +  t - current timestep
1169d763cef2SBarry Smith .  u - input vector
1170e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1171e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is to be constructed (usually the same as Amat)
1172d763cef2SBarry Smith -  ctx - [optional] user-defined context for matrix evaluation routine
1173d763cef2SBarry Smith 
11746cd88445SBarry Smith    Notes:
11756cd88445SBarry Smith    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
11766cd88445SBarry Smith 
11776cd88445SBarry Smith    The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1178ca5f011dSBarry Smith    You should not assume the values are the same in the next call to f() as you set them in the previous call.
1179d763cef2SBarry Smith 
1180d763cef2SBarry Smith    Level: beginner
1181d763cef2SBarry Smith 
1182db781477SPatrick Sanan .seealso: `SNESComputeJacobianDefaultColor()`, `TSSetRHSFunction()`, `TSRHSJacobianSetReuse()`, `TSSetIJacobian()`
1183d763cef2SBarry Smith 
1184d763cef2SBarry Smith @*/
1185e5d3d808SBarry Smith PetscErrorCode  TSSetRHSJacobian(TS ts,Mat Amat,Mat Pmat,TSRHSJacobian f,void *ctx)
1186d763cef2SBarry Smith {
1187089b2837SJed Brown   SNES           snes;
118824989b8cSPeter Brune   DM             dm;
118924989b8cSPeter Brune   TSIJacobian    ijacobian;
1190277b19d0SLisandro Dalcin 
1191d763cef2SBarry Smith   PetscFunctionBegin;
11920700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1193e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
1194e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
1195e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts,1,Amat,2);
1196e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts,1,Pmat,3);
1197d763cef2SBarry Smith 
11989566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
11999566063dSJacob Faibussowitsch   PetscCall(DMTSSetRHSJacobian(dm,f,ctx));
12009566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm,&ijacobian,NULL));
12019566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
12025f659677SPeter Brune   if (!ijacobian) {
12039566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts));
12040e4ef248SJed Brown   }
1205e5d3d808SBarry Smith   if (Amat) {
12069566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Amat));
12079566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Arhs));
1208e5d3d808SBarry Smith     ts->Arhs = Amat;
12090e4ef248SJed Brown   }
1210e5d3d808SBarry Smith   if (Pmat) {
12119566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Pmat));
12129566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&ts->Brhs));
1213e5d3d808SBarry Smith     ts->Brhs = Pmat;
12140e4ef248SJed Brown   }
1215d763cef2SBarry Smith   PetscFunctionReturn(0);
1216d763cef2SBarry Smith }
1217d763cef2SBarry Smith 
1218316643e7SJed Brown /*@C
1219b5abc632SBarry Smith    TSSetIFunction - Set the function to compute F(t,U,U_t) where F() = 0 is the DAE to be solved.
1220316643e7SJed Brown 
12213f9fe445SBarry Smith    Logically Collective on TS
1222316643e7SJed Brown 
1223316643e7SJed Brown    Input Parameters:
1224316643e7SJed Brown +  ts  - the TS context obtained from TSCreate()
12250298fd71SBarry Smith .  r   - vector to hold the residual (or NULL to have it created internally)
1226316643e7SJed Brown .  f   - the function evaluation routine
12270298fd71SBarry Smith -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1228316643e7SJed Brown 
1229316643e7SJed Brown    Calling sequence of f:
12306bc98fa9SBarry Smith $     PetscErrorCode f(TS ts,PetscReal t,Vec u,Vec u_t,Vec F,ctx);
1231316643e7SJed Brown 
1232316643e7SJed Brown +  t   - time at step/stage being solved
1233316643e7SJed Brown .  u   - state vector
1234316643e7SJed Brown .  u_t - time derivative of state vector
1235316643e7SJed Brown .  F   - function vector
1236316643e7SJed Brown -  ctx - [optional] user-defined context for matrix evaluation routine
1237316643e7SJed Brown 
1238316643e7SJed Brown    Important:
12392bbac0d3SBarry Smith    The user MUST call either this routine or TSSetRHSFunction() to define the ODE.  When solving DAEs you must use this function.
1240316643e7SJed Brown 
1241316643e7SJed Brown    Level: beginner
1242316643e7SJed Brown 
1243db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSSetRHSFunction()`, `TSSetIJacobian()`
1244316643e7SJed Brown @*/
124551699248SLisandro Dalcin PetscErrorCode  TSSetIFunction(TS ts,Vec r,TSIFunction f,void *ctx)
1246316643e7SJed Brown {
1247089b2837SJed Brown   SNES           snes;
124851699248SLisandro Dalcin   Vec            ralloc = NULL;
124924989b8cSPeter Brune   DM             dm;
1250316643e7SJed Brown 
1251316643e7SJed Brown   PetscFunctionBegin;
12520700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
125351699248SLisandro Dalcin   if (r) PetscValidHeaderSpecific(r,VEC_CLASSID,2);
125424989b8cSPeter Brune 
12559566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
12569566063dSJacob Faibussowitsch   PetscCall(DMTSSetIFunction(dm,f,ctx));
125724989b8cSPeter Brune 
12589566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
125951699248SLisandro Dalcin   if (!r && !ts->dm && ts->vec_sol) {
12609566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->vec_sol,&ralloc));
126151699248SLisandro Dalcin     r  = ralloc;
1262e856ceecSJed Brown   }
12639566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes,r,SNESTSFormFunction,ts));
12649566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ralloc));
1265089b2837SJed Brown   PetscFunctionReturn(0);
1266089b2837SJed Brown }
1267089b2837SJed Brown 
1268089b2837SJed Brown /*@C
1269a5b23f4aSJose E. Roman    TSGetIFunction - Returns the vector where the implicit residual is stored and the function/context to compute it.
1270089b2837SJed Brown 
1271089b2837SJed Brown    Not Collective
1272089b2837SJed Brown 
1273089b2837SJed Brown    Input Parameter:
1274089b2837SJed Brown .  ts - the TS context
1275089b2837SJed Brown 
1276d8d19677SJose E. Roman    Output Parameters:
12770298fd71SBarry Smith +  r - vector to hold residual (or NULL)
12780298fd71SBarry Smith .  func - the function to compute residual (or NULL)
12790298fd71SBarry Smith -  ctx - the function context (or NULL)
1280089b2837SJed Brown 
1281089b2837SJed Brown    Level: advanced
1282089b2837SJed Brown 
1283db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `SNESGetFunction()`
1284089b2837SJed Brown @*/
1285089b2837SJed Brown PetscErrorCode TSGetIFunction(TS ts,Vec *r,TSIFunction *func,void **ctx)
1286089b2837SJed Brown {
1287089b2837SJed Brown   SNES           snes;
128824989b8cSPeter Brune   DM             dm;
1289089b2837SJed Brown 
1290089b2837SJed Brown   PetscFunctionBegin;
1291089b2837SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
12929566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
12939566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,r,NULL,NULL));
12949566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
12959566063dSJacob Faibussowitsch   PetscCall(DMTSGetIFunction(dm,func,ctx));
1296089b2837SJed Brown   PetscFunctionReturn(0);
1297089b2837SJed Brown }
1298089b2837SJed Brown 
1299089b2837SJed Brown /*@C
1300089b2837SJed Brown    TSGetRHSFunction - Returns the vector where the right hand side is stored and the function/context to compute it.
1301089b2837SJed Brown 
1302089b2837SJed Brown    Not Collective
1303089b2837SJed Brown 
1304089b2837SJed Brown    Input Parameter:
1305089b2837SJed Brown .  ts - the TS context
1306089b2837SJed Brown 
1307d8d19677SJose E. Roman    Output Parameters:
13080298fd71SBarry Smith +  r - vector to hold computed right hand side (or NULL)
13090298fd71SBarry Smith .  func - the function to compute right hand side (or NULL)
13100298fd71SBarry Smith -  ctx - the function context (or NULL)
1311089b2837SJed Brown 
1312089b2837SJed Brown    Level: advanced
1313089b2837SJed Brown 
1314db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `SNESGetFunction()`
1315089b2837SJed Brown @*/
1316089b2837SJed Brown PetscErrorCode TSGetRHSFunction(TS ts,Vec *r,TSRHSFunction *func,void **ctx)
1317089b2837SJed Brown {
1318089b2837SJed Brown   SNES           snes;
131924989b8cSPeter Brune   DM             dm;
1320089b2837SJed Brown 
1321089b2837SJed Brown   PetscFunctionBegin;
1322089b2837SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
13239566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
13249566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,r,NULL,NULL));
13259566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
13269566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm,func,ctx));
1327316643e7SJed Brown   PetscFunctionReturn(0);
1328316643e7SJed Brown }
1329316643e7SJed Brown 
1330316643e7SJed Brown /*@C
1331a4f0a591SBarry Smith    TSSetIJacobian - Set the function to compute the matrix dF/dU + a*dF/dU_t where F(t,U,U_t) is the function
1332ae8867d6SBarry Smith         provided with TSSetIFunction().
1333316643e7SJed Brown 
13343f9fe445SBarry Smith    Logically Collective on TS
1335316643e7SJed Brown 
1336316643e7SJed Brown    Input Parameters:
1337316643e7SJed Brown +  ts  - the TS context obtained from TSCreate()
1338e5d3d808SBarry Smith .  Amat - (approximate) Jacobian matrix
1339e5d3d808SBarry Smith .  Pmat - matrix used to compute preconditioner (usually the same as Amat)
1340316643e7SJed Brown .  f   - the Jacobian evaluation routine
13410298fd71SBarry Smith -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1342316643e7SJed Brown 
1343316643e7SJed Brown    Calling sequence of f:
13446bc98fa9SBarry Smith $    PetscErrorCode f(TS ts,PetscReal t,Vec U,Vec U_t,PetscReal a,Mat Amat,Mat Pmat,void *ctx);
1345316643e7SJed Brown 
1346316643e7SJed Brown +  t    - time at step/stage being solved
13471b4a444bSJed Brown .  U    - state vector
13481b4a444bSJed Brown .  U_t  - time derivative of state vector
1349316643e7SJed Brown .  a    - shift
1350e5d3d808SBarry Smith .  Amat - (approximate) Jacobian of F(t,U,W+a*U), equivalent to dF/dU + a*dF/dU_t
1351e5d3d808SBarry Smith .  Pmat - matrix used for constructing preconditioner, usually the same as Amat
1352316643e7SJed Brown -  ctx  - [optional] user-defined context for matrix evaluation routine
1353316643e7SJed Brown 
1354316643e7SJed Brown    Notes:
1355e5d3d808SBarry Smith    The matrices Amat and Pmat are exactly the matrices that are used by SNES for the nonlinear solve.
1356316643e7SJed Brown 
1357895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
1358895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
1359895c21f2SBarry Smith 
1360a4f0a591SBarry Smith    The matrix dF/dU + a*dF/dU_t you provide turns out to be
1361b5abc632SBarry Smith    the Jacobian of F(t,U,W+a*U) where F(t,U,U_t) = 0 is the DAE to be solved.
1362a4f0a591SBarry Smith    The time integrator internally approximates U_t by W+a*U where the positive "shift"
1363a4f0a591SBarry Smith    a and vector W depend on the integration method, step size, and past states. For example with
1364a4f0a591SBarry Smith    the backward Euler method a = 1/dt and W = -a*U(previous timestep) so
1365a4f0a591SBarry Smith    W + a*U = a*(U - U(previous timestep)) = (U - U(previous timestep))/dt
1366a4f0a591SBarry Smith 
13676cd88445SBarry Smith    You must set all the diagonal entries of the matrices, if they are zero you must still set them with a zero value
13686cd88445SBarry Smith 
13696cd88445SBarry Smith    The TS solver may modify the nonzero structure and the entries of the matrices Amat and Pmat between the calls to f()
1370ca5f011dSBarry Smith    You should not assume the values are the same in the next call to f() as you set them in the previous call.
1371ca5f011dSBarry Smith 
1372316643e7SJed Brown    Level: beginner
1373316643e7SJed Brown 
1374db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSSetRHSJacobian()`, `SNESComputeJacobianDefaultColor()`, `SNESComputeJacobianDefault()`, `TSSetRHSFunction()`
1375316643e7SJed Brown 
1376316643e7SJed Brown @*/
1377e5d3d808SBarry Smith PetscErrorCode  TSSetIJacobian(TS ts,Mat Amat,Mat Pmat,TSIJacobian f,void *ctx)
1378316643e7SJed Brown {
1379089b2837SJed Brown   SNES           snes;
138024989b8cSPeter Brune   DM             dm;
1381316643e7SJed Brown 
1382316643e7SJed Brown   PetscFunctionBegin;
13830700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1384e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
1385e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
1386e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(ts,1,Amat,2);
1387e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(ts,1,Pmat,3);
138824989b8cSPeter Brune 
13899566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
13909566063dSJacob Faibussowitsch   PetscCall(DMTSSetIJacobian(dm,f,ctx));
139124989b8cSPeter Brune 
13929566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
13939566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes,Amat,Pmat,SNESTSFormJacobian,ts));
1394316643e7SJed Brown   PetscFunctionReturn(0);
1395316643e7SJed Brown }
1396316643e7SJed Brown 
1397e1244c69SJed Brown /*@
1398e1244c69SJed Brown    TSRHSJacobianSetReuse - restore RHS Jacobian before re-evaluating.  Without this flag, TS will change the sign and
1399e1244c69SJed Brown    shift the RHS Jacobian for a finite-time-step implicit solve, in which case the user function will need to recompute
1400e1244c69SJed Brown    the entire Jacobian.  The reuse flag must be set if the evaluation function will assume that the matrix entries have
1401e1244c69SJed Brown    not been changed by the TS.
1402e1244c69SJed Brown 
1403e1244c69SJed Brown    Logically Collective
1404e1244c69SJed Brown 
14054165533cSJose E. Roman    Input Parameters:
1406e1244c69SJed Brown +  ts - TS context obtained from TSCreate()
1407e1244c69SJed Brown -  reuse - PETSC_TRUE if the RHS Jacobian
1408e1244c69SJed Brown 
1409e1244c69SJed Brown    Level: intermediate
1410e1244c69SJed Brown 
1411db781477SPatrick Sanan .seealso: `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
1412e1244c69SJed Brown @*/
1413e1244c69SJed Brown PetscErrorCode TSRHSJacobianSetReuse(TS ts,PetscBool reuse)
1414e1244c69SJed Brown {
1415e1244c69SJed Brown   PetscFunctionBegin;
1416e1244c69SJed Brown   ts->rhsjacobian.reuse = reuse;
1417e1244c69SJed Brown   PetscFunctionReturn(0);
1418e1244c69SJed Brown }
1419e1244c69SJed Brown 
1420efe9872eSLisandro Dalcin /*@C
1421efe9872eSLisandro Dalcin    TSSetI2Function - Set the function to compute F(t,U,U_t,U_tt) where F = 0 is the DAE to be solved.
1422efe9872eSLisandro Dalcin 
1423efe9872eSLisandro Dalcin    Logically Collective on TS
1424efe9872eSLisandro Dalcin 
1425efe9872eSLisandro Dalcin    Input Parameters:
1426efe9872eSLisandro Dalcin +  ts  - the TS context obtained from TSCreate()
1427efe9872eSLisandro Dalcin .  F   - vector to hold the residual (or NULL to have it created internally)
1428efe9872eSLisandro Dalcin .  fun - the function evaluation routine
1429efe9872eSLisandro Dalcin -  ctx - user-defined context for private data for the function evaluation routine (may be NULL)
1430efe9872eSLisandro Dalcin 
1431efe9872eSLisandro Dalcin    Calling sequence of fun:
14326bc98fa9SBarry Smith $     PetscErrorCode fun(TS ts,PetscReal t,Vec U,Vec U_t,Vec U_tt,Vec F,ctx);
1433efe9872eSLisandro Dalcin 
1434efe9872eSLisandro Dalcin +  t    - time at step/stage being solved
1435efe9872eSLisandro Dalcin .  U    - state vector
1436efe9872eSLisandro Dalcin .  U_t  - time derivative of state vector
1437efe9872eSLisandro Dalcin .  U_tt - second time derivative of state vector
1438efe9872eSLisandro Dalcin .  F    - function vector
1439efe9872eSLisandro Dalcin -  ctx  - [optional] user-defined context for matrix evaluation routine (may be NULL)
1440efe9872eSLisandro Dalcin 
1441efe9872eSLisandro Dalcin    Level: beginner
1442efe9872eSLisandro Dalcin 
1443db781477SPatrick Sanan .seealso: `TSSetI2Jacobian()`, `TSSetIFunction()`, `TSCreate()`, `TSSetRHSFunction()`
1444efe9872eSLisandro Dalcin @*/
1445efe9872eSLisandro Dalcin PetscErrorCode TSSetI2Function(TS ts,Vec F,TSI2Function fun,void *ctx)
1446efe9872eSLisandro Dalcin {
1447efe9872eSLisandro Dalcin   DM             dm;
1448efe9872eSLisandro Dalcin 
1449efe9872eSLisandro Dalcin   PetscFunctionBegin;
1450efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1451efe9872eSLisandro Dalcin   if (F) PetscValidHeaderSpecific(F,VEC_CLASSID,2);
14529566063dSJacob Faibussowitsch   PetscCall(TSSetIFunction(ts,F,NULL,NULL));
14539566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
14549566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Function(dm,fun,ctx));
1455efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1456efe9872eSLisandro Dalcin }
1457efe9872eSLisandro Dalcin 
1458efe9872eSLisandro Dalcin /*@C
1459a5b23f4aSJose E. Roman   TSGetI2Function - Returns the vector where the implicit residual is stored and the function/context to compute it.
1460efe9872eSLisandro Dalcin 
1461efe9872eSLisandro Dalcin   Not Collective
1462efe9872eSLisandro Dalcin 
1463efe9872eSLisandro Dalcin   Input Parameter:
1464efe9872eSLisandro Dalcin . ts - the TS context
1465efe9872eSLisandro Dalcin 
1466d8d19677SJose E. Roman   Output Parameters:
1467efe9872eSLisandro Dalcin + r - vector to hold residual (or NULL)
1468efe9872eSLisandro Dalcin . fun - the function to compute residual (or NULL)
1469efe9872eSLisandro Dalcin - ctx - the function context (or NULL)
1470efe9872eSLisandro Dalcin 
1471efe9872eSLisandro Dalcin   Level: advanced
1472efe9872eSLisandro Dalcin 
1473db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `SNESGetFunction()`, `TSCreate()`
1474efe9872eSLisandro Dalcin @*/
1475efe9872eSLisandro Dalcin PetscErrorCode TSGetI2Function(TS ts,Vec *r,TSI2Function *fun,void **ctx)
1476efe9872eSLisandro Dalcin {
1477efe9872eSLisandro Dalcin   SNES           snes;
1478efe9872eSLisandro Dalcin   DM             dm;
1479efe9872eSLisandro Dalcin 
1480efe9872eSLisandro Dalcin   PetscFunctionBegin;
1481efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
14829566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
14839566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,r,NULL,NULL));
14849566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
14859566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm,fun,ctx));
1486efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1487efe9872eSLisandro Dalcin }
1488efe9872eSLisandro Dalcin 
1489efe9872eSLisandro Dalcin /*@C
1490bc77d74cSLisandro Dalcin    TSSetI2Jacobian - Set the function to compute the matrix dF/dU + v*dF/dU_t  + a*dF/dU_tt
1491efe9872eSLisandro Dalcin         where F(t,U,U_t,U_tt) is the function you provided with TSSetI2Function().
1492efe9872eSLisandro Dalcin 
1493efe9872eSLisandro Dalcin    Logically Collective on TS
1494efe9872eSLisandro Dalcin 
1495efe9872eSLisandro Dalcin    Input Parameters:
1496efe9872eSLisandro Dalcin +  ts  - the TS context obtained from TSCreate()
1497efe9872eSLisandro Dalcin .  J   - Jacobian matrix
1498efe9872eSLisandro Dalcin .  P   - preconditioning matrix for J (may be same as J)
1499efe9872eSLisandro Dalcin .  jac - the Jacobian evaluation routine
1500efe9872eSLisandro Dalcin -  ctx - user-defined context for private data for the Jacobian evaluation routine (may be NULL)
1501efe9872eSLisandro Dalcin 
1502efe9872eSLisandro Dalcin    Calling sequence of jac:
15036bc98fa9SBarry 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);
1504efe9872eSLisandro Dalcin 
1505efe9872eSLisandro Dalcin +  t    - time at step/stage being solved
1506efe9872eSLisandro Dalcin .  U    - state vector
1507efe9872eSLisandro Dalcin .  U_t  - time derivative of state vector
1508efe9872eSLisandro Dalcin .  U_tt - second time derivative of state vector
1509efe9872eSLisandro Dalcin .  v    - shift for U_t
1510efe9872eSLisandro Dalcin .  a    - shift for U_tt
1511efe9872eSLisandro 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
1512efe9872eSLisandro Dalcin .  P    - preconditioning matrix for J, may be same as J
1513efe9872eSLisandro Dalcin -  ctx  - [optional] user-defined context for matrix evaluation routine
1514efe9872eSLisandro Dalcin 
1515efe9872eSLisandro Dalcin    Notes:
1516efe9872eSLisandro Dalcin    The matrices J and P are exactly the matrices that are used by SNES for the nonlinear solve.
1517efe9872eSLisandro Dalcin 
1518efe9872eSLisandro Dalcin    The matrix dF/dU + v*dF/dU_t + a*dF/dU_tt you provide turns out to be
1519efe9872eSLisandro 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.
1520efe9872eSLisandro Dalcin    The time integrator internally approximates U_t by W+v*U and U_tt by W'+a*U  where the positive "shift"
1521bc77d74cSLisandro Dalcin    parameters 'v' and 'a' and vectors W, W' depend on the integration method, step size, and past states.
1522efe9872eSLisandro Dalcin 
1523efe9872eSLisandro Dalcin    Level: beginner
1524efe9872eSLisandro Dalcin 
1525db781477SPatrick Sanan .seealso: `TSSetI2Function()`, `TSGetI2Jacobian()`
1526efe9872eSLisandro Dalcin @*/
1527efe9872eSLisandro Dalcin PetscErrorCode TSSetI2Jacobian(TS ts,Mat J,Mat P,TSI2Jacobian jac,void *ctx)
1528efe9872eSLisandro Dalcin {
1529efe9872eSLisandro Dalcin   DM             dm;
1530efe9872eSLisandro Dalcin 
1531efe9872eSLisandro Dalcin   PetscFunctionBegin;
1532efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1533efe9872eSLisandro Dalcin   if (J) PetscValidHeaderSpecific(J,MAT_CLASSID,2);
1534efe9872eSLisandro Dalcin   if (P) PetscValidHeaderSpecific(P,MAT_CLASSID,3);
15359566063dSJacob Faibussowitsch   PetscCall(TSSetIJacobian(ts,J,P,NULL,NULL));
15369566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
15379566063dSJacob Faibussowitsch   PetscCall(DMTSSetI2Jacobian(dm,jac,ctx));
1538efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1539efe9872eSLisandro Dalcin }
1540efe9872eSLisandro Dalcin 
1541efe9872eSLisandro Dalcin /*@C
1542efe9872eSLisandro Dalcin   TSGetI2Jacobian - Returns the implicit Jacobian at the present timestep.
1543efe9872eSLisandro Dalcin 
1544efe9872eSLisandro Dalcin   Not Collective, but parallel objects are returned if TS is parallel
1545efe9872eSLisandro Dalcin 
1546efe9872eSLisandro Dalcin   Input Parameter:
1547efe9872eSLisandro Dalcin . ts  - The TS context obtained from TSCreate()
1548efe9872eSLisandro Dalcin 
1549efe9872eSLisandro Dalcin   Output Parameters:
1550efe9872eSLisandro Dalcin + J  - The (approximate) Jacobian of F(t,U,U_t,U_tt)
1551efe9872eSLisandro Dalcin . P - The matrix from which the preconditioner is constructed, often the same as J
1552efe9872eSLisandro Dalcin . jac - The function to compute the Jacobian matrices
1553efe9872eSLisandro Dalcin - ctx - User-defined context for Jacobian evaluation routine
1554efe9872eSLisandro Dalcin 
155595452b02SPatrick Sanan   Notes:
155695452b02SPatrick Sanan     You can pass in NULL for any return argument you do not need.
1557efe9872eSLisandro Dalcin 
1558efe9872eSLisandro Dalcin   Level: advanced
1559efe9872eSLisandro Dalcin 
1560db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`, `TSSetI2Jacobian()`, `TSGetI2Function()`, `TSCreate()`
1561efe9872eSLisandro Dalcin 
1562efe9872eSLisandro Dalcin @*/
1563efe9872eSLisandro Dalcin PetscErrorCode  TSGetI2Jacobian(TS ts,Mat *J,Mat *P,TSI2Jacobian *jac,void **ctx)
1564efe9872eSLisandro Dalcin {
1565efe9872eSLisandro Dalcin   SNES           snes;
1566efe9872eSLisandro Dalcin   DM             dm;
1567efe9872eSLisandro Dalcin 
1568efe9872eSLisandro Dalcin   PetscFunctionBegin;
15699566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
15709566063dSJacob Faibussowitsch   PetscCall(SNESSetUpMatrices(snes));
15719566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes,J,P,NULL,NULL));
15729566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
15739566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm,jac,ctx));
1574efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1575efe9872eSLisandro Dalcin }
1576efe9872eSLisandro Dalcin 
1577efe9872eSLisandro Dalcin /*@
1578efe9872eSLisandro Dalcin   TSComputeI2Function - Evaluates the DAE residual written in implicit form F(t,U,U_t,U_tt) = 0
1579efe9872eSLisandro Dalcin 
1580d083f849SBarry Smith   Collective on TS
1581efe9872eSLisandro Dalcin 
1582efe9872eSLisandro Dalcin   Input Parameters:
1583efe9872eSLisandro Dalcin + ts - the TS context
1584efe9872eSLisandro Dalcin . t - current time
1585efe9872eSLisandro Dalcin . U - state vector
1586efe9872eSLisandro Dalcin . V - time derivative of state vector (U_t)
1587efe9872eSLisandro Dalcin - A - second time derivative of state vector (U_tt)
1588efe9872eSLisandro Dalcin 
1589efe9872eSLisandro Dalcin   Output Parameter:
1590efe9872eSLisandro Dalcin . F - the residual vector
1591efe9872eSLisandro Dalcin 
1592efe9872eSLisandro Dalcin   Note:
1593efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
1594efe9872eSLisandro Dalcin   is used internally within the nonlinear solvers.
1595efe9872eSLisandro Dalcin 
1596efe9872eSLisandro Dalcin   Level: developer
1597efe9872eSLisandro Dalcin 
1598db781477SPatrick Sanan .seealso: `TSSetI2Function()`, `TSGetI2Function()`
1599efe9872eSLisandro Dalcin @*/
1600efe9872eSLisandro Dalcin PetscErrorCode TSComputeI2Function(TS ts,PetscReal t,Vec U,Vec V,Vec A,Vec F)
1601efe9872eSLisandro Dalcin {
1602efe9872eSLisandro Dalcin   DM             dm;
1603efe9872eSLisandro Dalcin   TSI2Function   I2Function;
1604efe9872eSLisandro Dalcin   void           *ctx;
1605efe9872eSLisandro Dalcin   TSRHSFunction  rhsfunction;
1606efe9872eSLisandro Dalcin 
1607efe9872eSLisandro Dalcin   PetscFunctionBegin;
1608efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1609efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
1610efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V,VEC_CLASSID,4);
1611efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A,VEC_CLASSID,5);
1612efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(F,VEC_CLASSID,6);
1613efe9872eSLisandro Dalcin 
16149566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
16159566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Function(dm,&I2Function,&ctx));
16169566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSFunction(dm,&rhsfunction,NULL));
1617efe9872eSLisandro Dalcin 
1618efe9872eSLisandro Dalcin   if (!I2Function) {
16199566063dSJacob Faibussowitsch     PetscCall(TSComputeIFunction(ts,t,U,A,F,PETSC_FALSE));
1620efe9872eSLisandro Dalcin     PetscFunctionReturn(0);
1621efe9872eSLisandro Dalcin   }
1622efe9872eSLisandro Dalcin 
16239566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_FunctionEval,ts,U,V,F));
1624efe9872eSLisandro Dalcin 
1625*792fecdfSBarry Smith   PetscCallBack("TS callback implicit function",I2Function(ts,t,U,V,A,F,ctx));
1626efe9872eSLisandro Dalcin 
1627efe9872eSLisandro Dalcin   if (rhsfunction) {
1628efe9872eSLisandro Dalcin     Vec Frhs;
16299566063dSJacob Faibussowitsch     PetscCall(TSGetRHSVec_Private(ts,&Frhs));
16309566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSFunction(ts,t,U,Frhs));
16319566063dSJacob Faibussowitsch     PetscCall(VecAXPY(F,-1,Frhs));
1632efe9872eSLisandro Dalcin   }
1633efe9872eSLisandro Dalcin 
16349566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_FunctionEval,ts,U,V,F));
1635efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1636efe9872eSLisandro Dalcin }
1637efe9872eSLisandro Dalcin 
1638efe9872eSLisandro Dalcin /*@
1639efe9872eSLisandro Dalcin   TSComputeI2Jacobian - Evaluates the Jacobian of the DAE
1640efe9872eSLisandro Dalcin 
1641d083f849SBarry Smith   Collective on TS
1642efe9872eSLisandro Dalcin 
1643efe9872eSLisandro Dalcin   Input Parameters:
1644efe9872eSLisandro Dalcin + ts - the TS context
1645efe9872eSLisandro Dalcin . t - current timestep
1646efe9872eSLisandro Dalcin . U - state vector
1647efe9872eSLisandro Dalcin . V - time derivative of state vector
1648efe9872eSLisandro Dalcin . A - second time derivative of state vector
1649efe9872eSLisandro Dalcin . shiftV - shift to apply, see note below
1650efe9872eSLisandro Dalcin - shiftA - shift to apply, see note below
1651efe9872eSLisandro Dalcin 
1652efe9872eSLisandro Dalcin   Output Parameters:
1653efe9872eSLisandro Dalcin + J - Jacobian matrix
1654efe9872eSLisandro Dalcin - P - optional preconditioning matrix
1655efe9872eSLisandro Dalcin 
1656efe9872eSLisandro Dalcin   Notes:
1657efe9872eSLisandro Dalcin   If F(t,U,V,A)=0 is the DAE, the required Jacobian is
1658efe9872eSLisandro Dalcin 
1659efe9872eSLisandro Dalcin   dF/dU + shiftV*dF/dV + shiftA*dF/dA
1660efe9872eSLisandro Dalcin 
1661efe9872eSLisandro Dalcin   Most users should not need to explicitly call this routine, as it
1662efe9872eSLisandro Dalcin   is used internally within the nonlinear solvers.
1663efe9872eSLisandro Dalcin 
1664efe9872eSLisandro Dalcin   Level: developer
1665efe9872eSLisandro Dalcin 
1666db781477SPatrick Sanan .seealso: `TSSetI2Jacobian()`
1667efe9872eSLisandro Dalcin @*/
1668efe9872eSLisandro Dalcin PetscErrorCode TSComputeI2Jacobian(TS ts,PetscReal t,Vec U,Vec V,Vec A,PetscReal shiftV,PetscReal shiftA,Mat J,Mat P)
1669efe9872eSLisandro Dalcin {
1670efe9872eSLisandro Dalcin   DM             dm;
1671efe9872eSLisandro Dalcin   TSI2Jacobian   I2Jacobian;
1672efe9872eSLisandro Dalcin   void           *ctx;
1673efe9872eSLisandro Dalcin   TSRHSJacobian  rhsjacobian;
1674efe9872eSLisandro Dalcin 
1675efe9872eSLisandro Dalcin   PetscFunctionBegin;
1676efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1677efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
1678efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(V,VEC_CLASSID,4);
1679efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(A,VEC_CLASSID,5);
1680efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(J,MAT_CLASSID,8);
1681efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(P,MAT_CLASSID,9);
1682efe9872eSLisandro Dalcin 
16839566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
16849566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm,&I2Jacobian,&ctx));
16859566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm,&rhsjacobian,NULL));
1686efe9872eSLisandro Dalcin 
1687efe9872eSLisandro Dalcin   if (!I2Jacobian) {
16889566063dSJacob Faibussowitsch     PetscCall(TSComputeIJacobian(ts,t,U,A,shiftA,J,P,PETSC_FALSE));
1689efe9872eSLisandro Dalcin     PetscFunctionReturn(0);
1690efe9872eSLisandro Dalcin   }
1691efe9872eSLisandro Dalcin 
16929566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_JacobianEval,ts,U,J,P));
1693*792fecdfSBarry Smith   PetscCallBack("TS callback implicit Jacobian",I2Jacobian(ts,t,U,V,A,shiftV,shiftA,J,P,ctx));
1694efe9872eSLisandro Dalcin   if (rhsjacobian) {
1695d60b7d5cSBarry Smith     Mat Jrhs,Prhs;
16969566063dSJacob Faibussowitsch     PetscCall(TSGetRHSMats_Private(ts,&Jrhs,&Prhs));
16979566063dSJacob Faibussowitsch     PetscCall(TSComputeRHSJacobian(ts,t,U,Jrhs,Prhs));
16989566063dSJacob Faibussowitsch     PetscCall(MatAXPY(J,-1,Jrhs,ts->axpy_pattern));
16999566063dSJacob Faibussowitsch     if (P != J) PetscCall(MatAXPY(P,-1,Prhs,ts->axpy_pattern));
1700efe9872eSLisandro Dalcin   }
1701efe9872eSLisandro Dalcin 
17029566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_JacobianEval,ts,U,J,P));
1703efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1704efe9872eSLisandro Dalcin }
1705efe9872eSLisandro Dalcin 
1706438f35afSJed Brown /*@C
1707438f35afSJed Brown    TSSetTransientVariable - sets function to transform from state to transient variables
1708438f35afSJed Brown 
1709438f35afSJed Brown    Logically Collective
1710438f35afSJed Brown 
17114165533cSJose E. Roman    Input Parameters:
1712438f35afSJed Brown +  ts - time stepping context on which to change the transient variable
1713a96d6ef6SBarry Smith .  tvar - a function that transforms to transient variables
1714438f35afSJed Brown -  ctx - a context for tvar
1715438f35afSJed Brown 
1716a96d6ef6SBarry Smith     Calling sequence of tvar:
1717a96d6ef6SBarry Smith $     PetscErrorCode tvar(TS ts,Vec p,Vec c,void *ctx);
1718a96d6ef6SBarry Smith 
1719a96d6ef6SBarry Smith +   ts - timestep context
17206aad120cSJose E. Roman .   p - input vector (primitive form)
1721a96d6ef6SBarry Smith .   c - output vector, transient variables (conservative form)
1722a96d6ef6SBarry Smith -   ctx - [optional] user-defined function context
1723a96d6ef6SBarry Smith 
1724438f35afSJed Brown    Level: advanced
1725438f35afSJed Brown 
1726438f35afSJed Brown    Notes:
1727438f35afSJed Brown    This is typically used to transform from primitive to conservative variables so that a time integrator (e.g., TSBDF)
1728438f35afSJed Brown    can be conservative.  In this context, primitive variables P are used to model the state (e.g., because they lead to
1729438f35afSJed Brown    well-conditioned formulations even in limiting cases such as low-Mach or zero porosity).  The transient variable is
1730438f35afSJed Brown    C(P), specified by calling this function.  An IFunction thus receives arguments (P, Cdot) and the IJacobian must be
1731438f35afSJed Brown    evaluated via the chain rule, as in
1732438f35afSJed Brown 
1733438f35afSJed Brown      dF/dP + shift * dF/dCdot dC/dP.
1734438f35afSJed Brown 
1735db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `DMTSGetTransientVariable()`, `TSSetIFunction()`, `TSSetIJacobian()`
1736438f35afSJed Brown @*/
1737438f35afSJed Brown PetscErrorCode TSSetTransientVariable(TS ts,TSTransientVariable tvar,void *ctx)
1738438f35afSJed Brown {
1739438f35afSJed Brown   DM             dm;
1740438f35afSJed Brown 
1741438f35afSJed Brown   PetscFunctionBegin;
1742438f35afSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
17439566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
17449566063dSJacob Faibussowitsch   PetscCall(DMTSSetTransientVariable(dm,tvar,ctx));
1745438f35afSJed Brown   PetscFunctionReturn(0);
1746438f35afSJed Brown }
1747438f35afSJed Brown 
1748efe9872eSLisandro Dalcin /*@
1749e3c11fc1SJed Brown    TSComputeTransientVariable - transforms state (primitive) variables to transient (conservative) variables
1750e3c11fc1SJed Brown 
1751e3c11fc1SJed Brown    Logically Collective
1752e3c11fc1SJed Brown 
1753e3c11fc1SJed Brown    Input Parameters:
1754e3c11fc1SJed Brown +  ts - TS on which to compute
1755e3c11fc1SJed Brown -  U - state vector to be transformed to transient variables
1756e3c11fc1SJed Brown 
1757e3c11fc1SJed Brown    Output Parameters:
1758e3c11fc1SJed Brown .  C - transient (conservative) variable
1759e3c11fc1SJed Brown 
1760e3c11fc1SJed Brown    Developer Notes:
1761e3c11fc1SJed Brown    If DMTSSetTransientVariable() has not been called, then C is not modified in this routine and C=NULL is allowed.
1762e3c11fc1SJed Brown    This makes it safe to call without a guard.  One can use TSHasTransientVariable() to check if transient variables are
1763e3c11fc1SJed Brown    being used.
1764e3c11fc1SJed Brown 
1765e3c11fc1SJed Brown    Level: developer
1766e3c11fc1SJed Brown 
1767db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `TSComputeIFunction()`, `TSComputeIJacobian()`
1768e3c11fc1SJed Brown @*/
1769e3c11fc1SJed Brown PetscErrorCode TSComputeTransientVariable(TS ts,Vec U,Vec C)
1770e3c11fc1SJed Brown {
1771e3c11fc1SJed Brown   DM             dm;
1772e3c11fc1SJed Brown   DMTS           dmts;
1773e3c11fc1SJed Brown 
1774e3c11fc1SJed Brown   PetscFunctionBegin;
1775e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1776e3c11fc1SJed Brown   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
17779566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
17789566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&dmts));
1779e3c11fc1SJed Brown   if (dmts->ops->transientvar) {
1780e3c11fc1SJed Brown     PetscValidHeaderSpecific(C,VEC_CLASSID,3);
17819566063dSJacob Faibussowitsch     PetscCall((*dmts->ops->transientvar)(ts,U,C,dmts->transientvarctx));
1782e3c11fc1SJed Brown   }
1783e3c11fc1SJed Brown   PetscFunctionReturn(0);
1784e3c11fc1SJed Brown }
1785e3c11fc1SJed Brown 
1786e3c11fc1SJed Brown /*@
1787e3c11fc1SJed Brown    TSHasTransientVariable - determine whether transient variables have been set
1788e3c11fc1SJed Brown 
1789e3c11fc1SJed Brown    Logically Collective
1790e3c11fc1SJed Brown 
1791e3c11fc1SJed Brown    Input Parameters:
1792e3c11fc1SJed Brown .  ts - TS on which to compute
1793e3c11fc1SJed Brown 
1794e3c11fc1SJed Brown    Output Parameters:
1795e3c11fc1SJed Brown .  has - PETSC_TRUE if transient variables have been set
1796e3c11fc1SJed Brown 
1797e3c11fc1SJed Brown    Level: developer
1798e3c11fc1SJed Brown 
1799db781477SPatrick Sanan .seealso: `DMTSSetTransientVariable()`, `TSComputeTransientVariable()`
1800e3c11fc1SJed Brown @*/
1801e3c11fc1SJed Brown PetscErrorCode TSHasTransientVariable(TS ts,PetscBool *has)
1802e3c11fc1SJed Brown {
1803e3c11fc1SJed Brown   DM             dm;
1804e3c11fc1SJed Brown   DMTS           dmts;
1805e3c11fc1SJed Brown 
1806e3c11fc1SJed Brown   PetscFunctionBegin;
1807e3c11fc1SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
18089566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
18099566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(dm,&dmts));
1810e3c11fc1SJed Brown   *has = dmts->ops->transientvar ? PETSC_TRUE : PETSC_FALSE;
1811e3c11fc1SJed Brown   PetscFunctionReturn(0);
1812e3c11fc1SJed Brown }
1813e3c11fc1SJed Brown 
1814e3c11fc1SJed Brown /*@
1815efe9872eSLisandro Dalcin    TS2SetSolution - Sets the initial solution and time derivative vectors
1816efe9872eSLisandro Dalcin    for use by the TS routines handling second order equations.
1817efe9872eSLisandro Dalcin 
1818d083f849SBarry Smith    Logically Collective on TS
1819efe9872eSLisandro Dalcin 
1820efe9872eSLisandro Dalcin    Input Parameters:
1821efe9872eSLisandro Dalcin +  ts - the TS context obtained from TSCreate()
1822efe9872eSLisandro Dalcin .  u - the solution vector
1823efe9872eSLisandro Dalcin -  v - the time derivative vector
1824efe9872eSLisandro Dalcin 
1825efe9872eSLisandro Dalcin    Level: beginner
1826efe9872eSLisandro Dalcin 
1827efe9872eSLisandro Dalcin @*/
1828efe9872eSLisandro Dalcin PetscErrorCode  TS2SetSolution(TS ts,Vec u,Vec v)
1829efe9872eSLisandro Dalcin {
1830efe9872eSLisandro Dalcin   PetscFunctionBegin;
1831efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1832efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
1833efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(v,VEC_CLASSID,3);
18349566063dSJacob Faibussowitsch   PetscCall(TSSetSolution(ts,u));
18359566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)v));
18369566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
1837efe9872eSLisandro Dalcin   ts->vec_dot = v;
1838efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1839efe9872eSLisandro Dalcin }
1840efe9872eSLisandro Dalcin 
1841efe9872eSLisandro Dalcin /*@
1842efe9872eSLisandro Dalcin    TS2GetSolution - Returns the solution and time derivative at the present timestep
1843efe9872eSLisandro Dalcin    for second order equations. It is valid to call this routine inside the function
1844efe9872eSLisandro Dalcin    that you are evaluating in order to move to the new timestep. This vector not
1845efe9872eSLisandro Dalcin    changed until the solution at the next timestep has been calculated.
1846efe9872eSLisandro Dalcin 
1847efe9872eSLisandro Dalcin    Not Collective, but Vec returned is parallel if TS is parallel
1848efe9872eSLisandro Dalcin 
1849efe9872eSLisandro Dalcin    Input Parameter:
1850efe9872eSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
1851efe9872eSLisandro Dalcin 
1852d8d19677SJose E. Roman    Output Parameters:
1853efe9872eSLisandro Dalcin +  u - the vector containing the solution
1854efe9872eSLisandro Dalcin -  v - the vector containing the time derivative
1855efe9872eSLisandro Dalcin 
1856efe9872eSLisandro Dalcin    Level: intermediate
1857efe9872eSLisandro Dalcin 
1858db781477SPatrick Sanan .seealso: `TS2SetSolution()`, `TSGetTimeStep()`, `TSGetTime()`
1859efe9872eSLisandro Dalcin 
1860efe9872eSLisandro Dalcin @*/
1861efe9872eSLisandro Dalcin PetscErrorCode  TS2GetSolution(TS ts,Vec *u,Vec *v)
1862efe9872eSLisandro Dalcin {
1863efe9872eSLisandro Dalcin   PetscFunctionBegin;
1864efe9872eSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
1865efe9872eSLisandro Dalcin   if (u) PetscValidPointer(u,2);
1866efe9872eSLisandro Dalcin   if (v) PetscValidPointer(v,3);
1867efe9872eSLisandro Dalcin   if (u) *u = ts->vec_sol;
1868efe9872eSLisandro Dalcin   if (v) *v = ts->vec_dot;
1869efe9872eSLisandro Dalcin   PetscFunctionReturn(0);
1870efe9872eSLisandro Dalcin }
1871efe9872eSLisandro Dalcin 
187255849f57SBarry Smith /*@C
187355849f57SBarry Smith   TSLoad - Loads a KSP that has been stored in binary  with KSPView().
187455849f57SBarry Smith 
187555849f57SBarry Smith   Collective on PetscViewer
187655849f57SBarry Smith 
187755849f57SBarry Smith   Input Parameters:
187855849f57SBarry Smith + newdm - the newly loaded TS, this needs to have been created with TSCreate() or
187955849f57SBarry Smith            some related function before a call to TSLoad().
188055849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
188155849f57SBarry Smith 
188255849f57SBarry Smith    Level: intermediate
188355849f57SBarry Smith 
188455849f57SBarry Smith   Notes:
188555849f57SBarry Smith    The type is determined by the data in the file, any type set into the TS before this call is ignored.
188655849f57SBarry Smith 
188755849f57SBarry Smith   Notes for advanced users:
188855849f57SBarry Smith   Most users should not need to know the details of the binary storage
188955849f57SBarry Smith   format, since TSLoad() and TSView() completely hide these details.
189055849f57SBarry Smith   But for anyone who's interested, the standard binary matrix storage
189155849f57SBarry Smith   format is
189255849f57SBarry Smith .vb
189355849f57SBarry Smith      has not yet been determined
189455849f57SBarry Smith .ve
189555849f57SBarry Smith 
1896db781477SPatrick Sanan .seealso: `PetscViewerBinaryOpen()`, `TSView()`, `MatLoad()`, `VecLoad()`
189755849f57SBarry Smith @*/
1898f2c2a1b9SBarry Smith PetscErrorCode  TSLoad(TS ts, PetscViewer viewer)
189955849f57SBarry Smith {
190055849f57SBarry Smith   PetscBool      isbinary;
190155849f57SBarry Smith   PetscInt       classid;
190255849f57SBarry Smith   char           type[256];
19032d53ad75SBarry Smith   DMTS           sdm;
1904ad6bc421SBarry Smith   DM             dm;
190555849f57SBarry Smith 
190655849f57SBarry Smith   PetscFunctionBegin;
1907f2c2a1b9SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
190855849f57SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
19099566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
19103c633725SBarry Smith   PetscCheck(isbinary,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
191155849f57SBarry Smith 
19129566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT));
19133c633725SBarry Smith   PetscCheck(classid == TS_FILE_CLASSID,PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Not TS next in file");
19149566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR));
19159566063dSJacob Faibussowitsch   PetscCall(TSSetType(ts, type));
19161baa6e33SBarry Smith   if (ts->ops->load) PetscCall((*ts->ops->load)(ts,viewer));
19179566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)ts),&dm));
19189566063dSJacob Faibussowitsch   PetscCall(DMLoad(dm,viewer));
19199566063dSJacob Faibussowitsch   PetscCall(TSSetDM(ts,dm));
19209566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(ts->dm,&ts->vec_sol));
19219566063dSJacob Faibussowitsch   PetscCall(VecLoad(ts->vec_sol,viewer));
19229566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm,&sdm));
19239566063dSJacob Faibussowitsch   PetscCall(DMTSLoad(sdm,viewer));
192455849f57SBarry Smith   PetscFunctionReturn(0);
192555849f57SBarry Smith }
192655849f57SBarry Smith 
19279804daf3SBarry Smith #include <petscdraw.h>
1928e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1929e04113cfSBarry Smith #include <petscviewersaws.h>
1930f05ece33SBarry Smith #endif
1931fe2efc57SMark 
1932fe2efc57SMark /*@C
1933fe2efc57SMark    TSViewFromOptions - View from Options
1934fe2efc57SMark 
1935fe2efc57SMark    Collective on TS
1936fe2efc57SMark 
1937fe2efc57SMark    Input Parameters:
1938fe2efc57SMark +  A - the application ordering context
1939736c3998SJose E. Roman .  obj - Optional object
1940736c3998SJose E. Roman -  name - command line option
1941fe2efc57SMark 
1942fe2efc57SMark    Level: intermediate
1943db781477SPatrick Sanan .seealso: `TS`, `TSView`, `PetscObjectViewFromOptions()`, `TSCreate()`
1944fe2efc57SMark @*/
1945fe2efc57SMark PetscErrorCode  TSViewFromOptions(TS A,PetscObject obj,const char name[])
1946fe2efc57SMark {
1947fe2efc57SMark   PetscFunctionBegin;
1948fe2efc57SMark   PetscValidHeaderSpecific(A,TS_CLASSID,1);
19499566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
1950fe2efc57SMark   PetscFunctionReturn(0);
1951fe2efc57SMark }
1952fe2efc57SMark 
19537e2c5f70SBarry Smith /*@C
1954d763cef2SBarry Smith     TSView - Prints the TS data structure.
1955d763cef2SBarry Smith 
19564c49b128SBarry Smith     Collective on TS
1957d763cef2SBarry Smith 
1958d763cef2SBarry Smith     Input Parameters:
1959d763cef2SBarry Smith +   ts - the TS context obtained from TSCreate()
1960d763cef2SBarry Smith -   viewer - visualization context
1961d763cef2SBarry Smith 
1962d763cef2SBarry Smith     Options Database Key:
1963d763cef2SBarry Smith .   -ts_view - calls TSView() at end of TSStep()
1964d763cef2SBarry Smith 
1965d763cef2SBarry Smith     Notes:
1966d763cef2SBarry Smith     The available visualization contexts include
1967b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
1968b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
1969d763cef2SBarry Smith          output where only the first processor opens
1970d763cef2SBarry Smith          the file.  All other processors send their
1971d763cef2SBarry Smith          data to the first processor to print.
1972d763cef2SBarry Smith 
1973d763cef2SBarry Smith     The user can open an alternative visualization context with
1974b0a32e0cSBarry Smith     PetscViewerASCIIOpen() - output to a specified file.
1975d763cef2SBarry Smith 
1976595c91d4SBarry Smith     In the debugger you can do "call TSView(ts,0)" to display the TS solver. (The same holds for any PETSc object viewer).
1977595c91d4SBarry Smith 
1978d763cef2SBarry Smith     Level: beginner
1979d763cef2SBarry Smith 
1980db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`
1981d763cef2SBarry Smith @*/
19827087cfbeSBarry Smith PetscErrorCode  TSView(TS ts,PetscViewer viewer)
1983d763cef2SBarry Smith {
198419fd82e9SBarry Smith   TSType         type;
19852b0a91c0SBarry Smith   PetscBool      iascii,isstring,isundials,isbinary,isdraw;
19862d53ad75SBarry Smith   DMTS           sdm;
1987e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
1988536b137fSBarry Smith   PetscBool      issaws;
1989f05ece33SBarry Smith #endif
1990d763cef2SBarry Smith 
1991d763cef2SBarry Smith   PetscFunctionBegin;
19920700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
19933050cee2SBarry Smith   if (!viewer) {
19949566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ts),&viewer));
19953050cee2SBarry Smith   }
19960700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1997c9780b6fSBarry Smith   PetscCheckSameComm(ts,1,viewer,2);
1998fd16b177SBarry Smith 
19999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
20009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
20019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
20029566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
2003e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
20049566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws));
2005f05ece33SBarry Smith #endif
200632077d6dSBarry Smith   if (iascii) {
20079566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ts,viewer));
2008efd4aadfSBarry Smith     if (ts->ops->view) {
20099566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
20109566063dSJacob Faibussowitsch       PetscCall((*ts->ops->view)(ts,viewer));
20119566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
2012efd4aadfSBarry Smith     }
2013ef85077eSLisandro Dalcin     if (ts->max_steps < PETSC_MAX_INT) {
201463a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  maximum steps=%" PetscInt_FMT "\n",ts->max_steps));
2015ef85077eSLisandro Dalcin     }
2016ef85077eSLisandro Dalcin     if (ts->max_time < PETSC_MAX_REAL) {
20179566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  maximum time=%g\n",(double)ts->max_time));
2018ef85077eSLisandro Dalcin     }
2019a6ab3590SBarry Smith     if (ts->ifuncs) {
202063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of I function evaluations=%" PetscInt_FMT "\n",ts->ifuncs));
2021a6ab3590SBarry Smith     }
2022a6ab3590SBarry Smith     if (ts->ijacs) {
202363a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of I Jacobian evaluations=%" PetscInt_FMT "\n",ts->ijacs));
2024a6ab3590SBarry Smith     }
2025a6ab3590SBarry Smith     if (ts->rhsfuncs) {
202663a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of RHS function evaluations=%" PetscInt_FMT "\n",ts->rhsfuncs));
2027a6ab3590SBarry Smith     }
2028a6ab3590SBarry Smith     if (ts->rhsjacs) {
202963a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of RHS Jacobian evaluations=%" PetscInt_FMT "\n",ts->rhsjacs));
2030a6ab3590SBarry Smith     }
2031efd4aadfSBarry Smith     if (ts->usessnes) {
2032efd4aadfSBarry Smith       PetscBool lin;
2033d763cef2SBarry Smith       if (ts->problem_type == TS_NONLINEAR) {
203463a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of nonlinear solver iterations=%" PetscInt_FMT "\n",ts->snes_its));
2035d763cef2SBarry Smith       }
203663a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%" PetscInt_FMT "\n",ts->ksp_its));
20379566063dSJacob Faibussowitsch       PetscCall(PetscObjectTypeCompareAny((PetscObject)ts->snes,&lin,SNESKSPONLY,SNESKSPTRANSPOSEONLY,""));
203863a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of %slinear solve failures=%" PetscInt_FMT "\n",lin ? "" : "non",ts->num_snes_failures));
2039efd4aadfSBarry Smith     }
204063a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of rejected steps=%" PetscInt_FMT "\n",ts->reject));
2041a0af407cSBarry Smith     if (ts->vrtol) {
20429566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  using vector of relative error tolerances, "));
2043a0af407cSBarry Smith     } else {
20449566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  using relative error tolerance of %g, ",(double)ts->rtol));
2045a0af407cSBarry Smith     }
2046a0af407cSBarry Smith     if (ts->vatol) {
20479566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  using vector of absolute error tolerances\n"));
2048a0af407cSBarry Smith     } else {
20499566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  using absolute error tolerance of %g\n",(double)ts->atol));
2050a0af407cSBarry Smith     }
20519566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
20529566063dSJacob Faibussowitsch     PetscCall(TSAdaptView(ts->adapt,viewer));
20539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
20540f5bd95cSBarry Smith   } else if (isstring) {
20559566063dSJacob Faibussowitsch     PetscCall(TSGetType(ts,&type));
20569566063dSJacob Faibussowitsch     PetscCall(PetscViewerStringSPrintf(viewer," TSType: %-7.7s",type));
20579566063dSJacob Faibussowitsch     if (ts->ops->view) PetscCall((*ts->ops->view)(ts,viewer));
205855849f57SBarry Smith   } else if (isbinary) {
205955849f57SBarry Smith     PetscInt    classid = TS_FILE_CLASSID;
206055849f57SBarry Smith     MPI_Comm    comm;
206155849f57SBarry Smith     PetscMPIInt rank;
206255849f57SBarry Smith     char        type[256];
206355849f57SBarry Smith 
20649566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)ts,&comm));
20659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm,&rank));
2066dd400576SPatrick Sanan     if (rank == 0) {
20679566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT));
20689566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(type,((PetscObject)ts)->type_name,256));
20699566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR));
207055849f57SBarry Smith     }
20711baa6e33SBarry Smith     if (ts->ops->view) PetscCall((*ts->ops->view)(ts,viewer));
20729566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt,viewer));
20739566063dSJacob Faibussowitsch     PetscCall(DMView(ts->dm,viewer));
20749566063dSJacob Faibussowitsch     PetscCall(VecView(ts->vec_sol,viewer));
20759566063dSJacob Faibussowitsch     PetscCall(DMGetDMTS(ts->dm,&sdm));
20769566063dSJacob Faibussowitsch     PetscCall(DMTSView(sdm,viewer));
20772b0a91c0SBarry Smith   } else if (isdraw) {
20782b0a91c0SBarry Smith     PetscDraw draw;
20792b0a91c0SBarry Smith     char      str[36];
208089fd9fafSBarry Smith     PetscReal x,y,bottom,h;
20812b0a91c0SBarry Smith 
20829566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
20839566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCurrentPoint(draw,&x,&y));
20849566063dSJacob Faibussowitsch     PetscCall(PetscStrcpy(str,"TS: "));
20859566063dSJacob Faibussowitsch     PetscCall(PetscStrcat(str,((PetscObject)ts)->type_name));
20869566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLACK,PETSC_DRAW_BLACK,str,NULL,&h));
208789fd9fafSBarry Smith     bottom = y - h;
20889566063dSJacob Faibussowitsch     PetscCall(PetscDrawPushCurrentPoint(draw,x,bottom));
20891baa6e33SBarry Smith     if (ts->ops->view) PetscCall((*ts->ops->view)(ts,viewer));
20909566063dSJacob Faibussowitsch     if (ts->adapt) PetscCall(TSAdaptView(ts->adapt,viewer));
20919566063dSJacob Faibussowitsch     if (ts->snes)  PetscCall(SNESView(ts->snes,viewer));
20929566063dSJacob Faibussowitsch     PetscCall(PetscDrawPopCurrentPoint(draw));
2093e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
2094536b137fSBarry Smith   } else if (issaws) {
2095d45a07a7SBarry Smith     PetscMPIInt rank;
20962657e9d9SBarry Smith     const char  *name;
20972657e9d9SBarry Smith 
20989566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)ts,&name));
20999566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
2100dd400576SPatrick Sanan     if (!((PetscObject)ts)->amsmem && rank == 0) {
2101d45a07a7SBarry Smith       char       dir[1024];
2102d45a07a7SBarry Smith 
21039566063dSJacob Faibussowitsch       PetscCall(PetscObjectViewSAWs((PetscObject)ts,viewer));
21049566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time_step",name));
2105*792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register,(dir,&ts->steps,1,SAWs_READ,SAWs_INT));
21069566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/time",name));
2107*792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register,(dir,&ts->ptime,1,SAWs_READ,SAWs_DOUBLE));
2108d763cef2SBarry Smith     }
21091baa6e33SBarry Smith     if (ts->ops->view) PetscCall((*ts->ops->view)(ts,viewer));
2110f05ece33SBarry Smith #endif
2111f05ece33SBarry Smith   }
211236a9e3b9SBarry Smith   if (ts->snes && ts->usessnes)  {
21139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
21149566063dSJacob Faibussowitsch     PetscCall(SNESView(ts->snes,viewer));
21159566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
211636a9e3b9SBarry Smith   }
21179566063dSJacob Faibussowitsch   PetscCall(DMGetDMTS(ts->dm,&sdm));
21189566063dSJacob Faibussowitsch   PetscCall(DMTSView(sdm,viewer));
2119f05ece33SBarry Smith 
21209566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
21219566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ts,TSSUNDIALS,&isundials));
21229566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
2123d763cef2SBarry Smith   PetscFunctionReturn(0);
2124d763cef2SBarry Smith }
2125d763cef2SBarry Smith 
2126b07ff414SBarry Smith /*@
2127d763cef2SBarry Smith    TSSetApplicationContext - Sets an optional user-defined context for
2128d763cef2SBarry Smith    the timesteppers.
2129d763cef2SBarry Smith 
21303f9fe445SBarry Smith    Logically Collective on TS
2131d763cef2SBarry Smith 
2132d763cef2SBarry Smith    Input Parameters:
2133d763cef2SBarry Smith +  ts - the TS context obtained from TSCreate()
2134d763cef2SBarry Smith -  usrP - optional user context
2135d763cef2SBarry Smith 
213695452b02SPatrick Sanan    Fortran Notes:
213795452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
2138daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2139daf670e6SBarry Smith 
2140d763cef2SBarry Smith    Level: intermediate
2141d763cef2SBarry Smith 
2142db781477SPatrick Sanan .seealso: `TSGetApplicationContext()`
2143d763cef2SBarry Smith @*/
21447087cfbeSBarry Smith PetscErrorCode  TSSetApplicationContext(TS ts,void *usrP)
2145d763cef2SBarry Smith {
2146d763cef2SBarry Smith   PetscFunctionBegin;
21470700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2148d763cef2SBarry Smith   ts->user = usrP;
2149d763cef2SBarry Smith   PetscFunctionReturn(0);
2150d763cef2SBarry Smith }
2151d763cef2SBarry Smith 
2152b07ff414SBarry Smith /*@
2153d763cef2SBarry Smith     TSGetApplicationContext - Gets the user-defined context for the
2154d763cef2SBarry Smith     timestepper.
2155d763cef2SBarry Smith 
2156d763cef2SBarry Smith     Not Collective
2157d763cef2SBarry Smith 
2158d763cef2SBarry Smith     Input Parameter:
2159d763cef2SBarry Smith .   ts - the TS context obtained from TSCreate()
2160d763cef2SBarry Smith 
2161d763cef2SBarry Smith     Output Parameter:
2162d763cef2SBarry Smith .   usrP - user context
2163d763cef2SBarry Smith 
216495452b02SPatrick Sanan    Fortran Notes:
216595452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
2166daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
2167daf670e6SBarry Smith 
2168d763cef2SBarry Smith     Level: intermediate
2169d763cef2SBarry Smith 
2170db781477SPatrick Sanan .seealso: `TSSetApplicationContext()`
2171d763cef2SBarry Smith @*/
2172e71120c6SJed Brown PetscErrorCode  TSGetApplicationContext(TS ts,void *usrP)
2173d763cef2SBarry Smith {
2174d763cef2SBarry Smith   PetscFunctionBegin;
21750700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2176e71120c6SJed Brown   *(void**)usrP = ts->user;
2177d763cef2SBarry Smith   PetscFunctionReturn(0);
2178d763cef2SBarry Smith }
2179d763cef2SBarry Smith 
2180d763cef2SBarry Smith /*@
218180275a0aSLisandro Dalcin    TSGetStepNumber - Gets the number of steps completed.
2182d763cef2SBarry Smith 
2183d763cef2SBarry Smith    Not Collective
2184d763cef2SBarry Smith 
2185d763cef2SBarry Smith    Input Parameter:
2186d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2187d763cef2SBarry Smith 
2188d763cef2SBarry Smith    Output Parameter:
218980275a0aSLisandro Dalcin .  steps - number of steps completed so far
2190d763cef2SBarry Smith 
2191d763cef2SBarry Smith    Level: intermediate
2192d763cef2SBarry Smith 
2193db781477SPatrick Sanan .seealso: `TSGetTime()`, `TSGetTimeStep()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`
2194d763cef2SBarry Smith @*/
219580275a0aSLisandro Dalcin PetscErrorCode TSGetStepNumber(TS ts,PetscInt *steps)
2196d763cef2SBarry Smith {
2197d763cef2SBarry Smith   PetscFunctionBegin;
21980700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
219980275a0aSLisandro Dalcin   PetscValidIntPointer(steps,2);
220080275a0aSLisandro Dalcin   *steps = ts->steps;
220180275a0aSLisandro Dalcin   PetscFunctionReturn(0);
220280275a0aSLisandro Dalcin }
220380275a0aSLisandro Dalcin 
220480275a0aSLisandro Dalcin /*@
220580275a0aSLisandro Dalcin    TSSetStepNumber - Sets the number of steps completed.
220680275a0aSLisandro Dalcin 
220780275a0aSLisandro Dalcin    Logically Collective on TS
220880275a0aSLisandro Dalcin 
220980275a0aSLisandro Dalcin    Input Parameters:
221080275a0aSLisandro Dalcin +  ts - the TS context
221180275a0aSLisandro Dalcin -  steps - number of steps completed so far
221280275a0aSLisandro Dalcin 
221380275a0aSLisandro Dalcin    Notes:
221480275a0aSLisandro Dalcin    For most uses of the TS solvers the user need not explicitly call
221580275a0aSLisandro Dalcin    TSSetStepNumber(), as the step counter is appropriately updated in
221680275a0aSLisandro Dalcin    TSSolve()/TSStep()/TSRollBack(). Power users may call this routine to
221780275a0aSLisandro Dalcin    reinitialize timestepping by setting the step counter to zero (and time
221880275a0aSLisandro Dalcin    to the initial time) to solve a similar problem with different initial
221980275a0aSLisandro Dalcin    conditions or parameters. Other possible use case is to continue
222080275a0aSLisandro Dalcin    timestepping from a previously interrupted run in such a way that TS
222180275a0aSLisandro Dalcin    monitors will be called with a initial nonzero step counter.
222280275a0aSLisandro Dalcin 
222380275a0aSLisandro Dalcin    Level: advanced
222480275a0aSLisandro Dalcin 
2225db781477SPatrick Sanan .seealso: `TSGetStepNumber()`, `TSSetTime()`, `TSSetTimeStep()`, `TSSetSolution()`
222680275a0aSLisandro Dalcin @*/
222780275a0aSLisandro Dalcin PetscErrorCode TSSetStepNumber(TS ts,PetscInt steps)
222880275a0aSLisandro Dalcin {
222980275a0aSLisandro Dalcin   PetscFunctionBegin;
223080275a0aSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
223180275a0aSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts,steps,2);
22323c633725SBarry Smith   PetscCheck(steps >= 0,PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Step number must be non-negative");
223380275a0aSLisandro Dalcin   ts->steps = steps;
2234d763cef2SBarry Smith   PetscFunctionReturn(0);
2235d763cef2SBarry Smith }
2236d763cef2SBarry Smith 
2237d763cef2SBarry Smith /*@
2238d763cef2SBarry Smith    TSSetTimeStep - Allows one to reset the timestep at any time,
2239d763cef2SBarry Smith    useful for simple pseudo-timestepping codes.
2240d763cef2SBarry Smith 
22413f9fe445SBarry Smith    Logically Collective on TS
2242d763cef2SBarry Smith 
2243d763cef2SBarry Smith    Input Parameters:
2244d763cef2SBarry Smith +  ts - the TS context obtained from TSCreate()
2245d763cef2SBarry Smith -  time_step - the size of the timestep
2246d763cef2SBarry Smith 
2247d763cef2SBarry Smith    Level: intermediate
2248d763cef2SBarry Smith 
2249db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSSetTime()`
2250d763cef2SBarry Smith 
2251d763cef2SBarry Smith @*/
22527087cfbeSBarry Smith PetscErrorCode  TSSetTimeStep(TS ts,PetscReal time_step)
2253d763cef2SBarry Smith {
2254d763cef2SBarry Smith   PetscFunctionBegin;
22550700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2256c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts,time_step,2);
2257d763cef2SBarry Smith   ts->time_step = time_step;
2258d763cef2SBarry Smith   PetscFunctionReturn(0);
2259d763cef2SBarry Smith }
2260d763cef2SBarry Smith 
2261a43b19c4SJed Brown /*@
226249354f04SShri Abhyankar    TSSetExactFinalTime - Determines whether to adapt the final time step to
226349354f04SShri Abhyankar      match the exact final time, interpolate solution to the exact final time,
226449354f04SShri Abhyankar      or just return at the final time TS computed.
2265a43b19c4SJed Brown 
2266a43b19c4SJed Brown   Logically Collective on TS
2267a43b19c4SJed Brown 
2268d8d19677SJose E. Roman    Input Parameters:
2269a43b19c4SJed Brown +   ts - the time-step context
227049354f04SShri Abhyankar -   eftopt - exact final time option
2271a43b19c4SJed Brown 
2272feed9e9dSBarry Smith $  TS_EXACTFINALTIME_STEPOVER    - Don't do anything if final time is exceeded
2273feed9e9dSBarry Smith $  TS_EXACTFINALTIME_INTERPOLATE - Interpolate back to final time
2274feed9e9dSBarry Smith $  TS_EXACTFINALTIME_MATCHSTEP - Adapt final time step to match the final time
2275feed9e9dSBarry Smith 
2276feed9e9dSBarry Smith    Options Database:
2277feed9e9dSBarry Smith .   -ts_exact_final_time <stepover,interpolate,matchstep> - select the final step at runtime
2278feed9e9dSBarry Smith 
2279ee346746SBarry Smith    Warning: If you use the option TS_EXACTFINALTIME_STEPOVER the solution may be at a very different time
2280ee346746SBarry Smith     then the final time you selected.
2281ee346746SBarry Smith 
2282a43b19c4SJed Brown    Level: beginner
2283a43b19c4SJed Brown 
2284db781477SPatrick Sanan .seealso: `TSExactFinalTimeOption`, `TSGetExactFinalTime()`
2285a43b19c4SJed Brown @*/
228649354f04SShri Abhyankar PetscErrorCode TSSetExactFinalTime(TS ts,TSExactFinalTimeOption eftopt)
2287a43b19c4SJed Brown {
2288a43b19c4SJed Brown   PetscFunctionBegin;
2289a43b19c4SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
229049354f04SShri Abhyankar   PetscValidLogicalCollectiveEnum(ts,eftopt,2);
229149354f04SShri Abhyankar   ts->exact_final_time = eftopt;
2292a43b19c4SJed Brown   PetscFunctionReturn(0);
2293a43b19c4SJed Brown }
2294a43b19c4SJed Brown 
2295d763cef2SBarry Smith /*@
2296f6953c82SLisandro Dalcin    TSGetExactFinalTime - Gets the exact final time option.
2297f6953c82SLisandro Dalcin 
2298f6953c82SLisandro Dalcin    Not Collective
2299f6953c82SLisandro Dalcin 
2300f6953c82SLisandro Dalcin    Input Parameter:
2301f6953c82SLisandro Dalcin .  ts - the TS context
2302f6953c82SLisandro Dalcin 
2303f6953c82SLisandro Dalcin    Output Parameter:
2304f6953c82SLisandro Dalcin .  eftopt - exact final time option
2305f6953c82SLisandro Dalcin 
2306f6953c82SLisandro Dalcin    Level: beginner
2307f6953c82SLisandro Dalcin 
2308db781477SPatrick Sanan .seealso: `TSExactFinalTimeOption`, `TSSetExactFinalTime()`
2309f6953c82SLisandro Dalcin @*/
2310f6953c82SLisandro Dalcin PetscErrorCode TSGetExactFinalTime(TS ts,TSExactFinalTimeOption *eftopt)
2311f6953c82SLisandro Dalcin {
2312f6953c82SLisandro Dalcin   PetscFunctionBegin;
2313f6953c82SLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2314f6953c82SLisandro Dalcin   PetscValidPointer(eftopt,2);
2315f6953c82SLisandro Dalcin   *eftopt = ts->exact_final_time;
2316f6953c82SLisandro Dalcin   PetscFunctionReturn(0);
2317f6953c82SLisandro Dalcin }
2318f6953c82SLisandro Dalcin 
2319f6953c82SLisandro Dalcin /*@
2320d763cef2SBarry Smith    TSGetTimeStep - Gets the current timestep size.
2321d763cef2SBarry Smith 
2322d763cef2SBarry Smith    Not Collective
2323d763cef2SBarry Smith 
2324d763cef2SBarry Smith    Input Parameter:
2325d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2326d763cef2SBarry Smith 
2327d763cef2SBarry Smith    Output Parameter:
2328d763cef2SBarry Smith .  dt - the current timestep size
2329d763cef2SBarry Smith 
2330d763cef2SBarry Smith    Level: intermediate
2331d763cef2SBarry Smith 
2332db781477SPatrick Sanan .seealso: `TSSetTimeStep()`, `TSGetTime()`
2333d763cef2SBarry Smith 
2334d763cef2SBarry Smith @*/
23357087cfbeSBarry Smith PetscErrorCode  TSGetTimeStep(TS ts,PetscReal *dt)
2336d763cef2SBarry Smith {
2337d763cef2SBarry Smith   PetscFunctionBegin;
23380700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2339f7cf8827SBarry Smith   PetscValidRealPointer(dt,2);
2340d763cef2SBarry Smith   *dt = ts->time_step;
2341d763cef2SBarry Smith   PetscFunctionReturn(0);
2342d763cef2SBarry Smith }
2343d763cef2SBarry Smith 
2344d8e5e3e6SSatish Balay /*@
2345d763cef2SBarry Smith    TSGetSolution - Returns the solution at the present timestep. It
2346d763cef2SBarry Smith    is valid to call this routine inside the function that you are evaluating
2347d763cef2SBarry Smith    in order to move to the new timestep. This vector not changed until
2348d763cef2SBarry Smith    the solution at the next timestep has been calculated.
2349d763cef2SBarry Smith 
2350d763cef2SBarry Smith    Not Collective, but Vec returned is parallel if TS is parallel
2351d763cef2SBarry Smith 
2352d763cef2SBarry Smith    Input Parameter:
2353d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2354d763cef2SBarry Smith 
2355d763cef2SBarry Smith    Output Parameter:
2356d763cef2SBarry Smith .  v - the vector containing the solution
2357d763cef2SBarry Smith 
235863e21af5SBarry Smith    Note: If you used TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); this does not return the solution at the requested
235963e21af5SBarry Smith    final time. It returns the solution at the next timestep.
236063e21af5SBarry Smith 
2361d763cef2SBarry Smith    Level: intermediate
2362d763cef2SBarry Smith 
2363db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetTime()`, `TSGetSolveTime()`, `TSGetSolutionComponents()`, `TSSetSolutionFunction()`
2364d763cef2SBarry Smith 
2365d763cef2SBarry Smith @*/
23667087cfbeSBarry Smith PetscErrorCode  TSGetSolution(TS ts,Vec *v)
2367d763cef2SBarry Smith {
2368d763cef2SBarry Smith   PetscFunctionBegin;
23690700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
23704482741eSBarry Smith   PetscValidPointer(v,2);
23718737fe31SLisandro Dalcin   *v = ts->vec_sol;
2372d763cef2SBarry Smith   PetscFunctionReturn(0);
2373d763cef2SBarry Smith }
2374d763cef2SBarry Smith 
237503fe5f5eSDebojyoti Ghosh /*@
2376b2bf4f3aSDebojyoti Ghosh    TSGetSolutionComponents - Returns any solution components at the present
237703fe5f5eSDebojyoti Ghosh    timestep, if available for the time integration method being used.
2378b2bf4f3aSDebojyoti Ghosh    Solution components are quantities that share the same size and
237903fe5f5eSDebojyoti Ghosh    structure as the solution vector.
238003fe5f5eSDebojyoti Ghosh 
238103fe5f5eSDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
238203fe5f5eSDebojyoti Ghosh 
238303fe5f5eSDebojyoti Ghosh    Parameters :
2384a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2385b2bf4f3aSDebojyoti Ghosh .  n - If v is PETSC_NULL, then the number of solution components is
2386b2bf4f3aSDebojyoti Ghosh        returned through n, else the n-th solution component is
238703fe5f5eSDebojyoti Ghosh        returned in v.
2388a2b725a8SWilliam Gropp -  v - the vector containing the n-th solution component
238903fe5f5eSDebojyoti Ghosh        (may be PETSC_NULL to use this function to find out
2390b2bf4f3aSDebojyoti Ghosh         the number of solutions components).
239103fe5f5eSDebojyoti Ghosh 
23924cdd57e5SDebojyoti Ghosh    Level: advanced
239303fe5f5eSDebojyoti Ghosh 
2394db781477SPatrick Sanan .seealso: `TSGetSolution()`
239503fe5f5eSDebojyoti Ghosh 
239603fe5f5eSDebojyoti Ghosh @*/
2397b2bf4f3aSDebojyoti Ghosh PetscErrorCode  TSGetSolutionComponents(TS ts,PetscInt *n,Vec *v)
239803fe5f5eSDebojyoti Ghosh {
239903fe5f5eSDebojyoti Ghosh   PetscFunctionBegin;
240003fe5f5eSDebojyoti Ghosh   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2401b2bf4f3aSDebojyoti Ghosh   if (!ts->ops->getsolutioncomponents) *n = 0;
240203fe5f5eSDebojyoti Ghosh   else {
24039566063dSJacob Faibussowitsch     PetscCall((*ts->ops->getsolutioncomponents)(ts,n,v));
240403fe5f5eSDebojyoti Ghosh   }
240503fe5f5eSDebojyoti Ghosh   PetscFunctionReturn(0);
240603fe5f5eSDebojyoti Ghosh }
240703fe5f5eSDebojyoti Ghosh 
24084cdd57e5SDebojyoti Ghosh /*@
24094cdd57e5SDebojyoti Ghosh    TSGetAuxSolution - Returns an auxiliary solution at the present
24104cdd57e5SDebojyoti Ghosh    timestep, if available for the time integration method being used.
24114cdd57e5SDebojyoti Ghosh 
24124cdd57e5SDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
24134cdd57e5SDebojyoti Ghosh 
24144cdd57e5SDebojyoti Ghosh    Parameters :
2415a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2416a2b725a8SWilliam Gropp -  v - the vector containing the auxiliary solution
24174cdd57e5SDebojyoti Ghosh 
24184cdd57e5SDebojyoti Ghosh    Level: intermediate
24194cdd57e5SDebojyoti Ghosh 
2420db781477SPatrick Sanan .seealso: `TSGetSolution()`
24214cdd57e5SDebojyoti Ghosh 
24224cdd57e5SDebojyoti Ghosh @*/
24234cdd57e5SDebojyoti Ghosh PetscErrorCode  TSGetAuxSolution(TS ts,Vec *v)
24244cdd57e5SDebojyoti Ghosh {
24254cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
24264cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2427f6356ec7SDebojyoti Ghosh   if (ts->ops->getauxsolution) {
24289566063dSJacob Faibussowitsch     PetscCall((*ts->ops->getauxsolution)(ts,v));
2429f6356ec7SDebojyoti Ghosh   } else {
24309566063dSJacob Faibussowitsch     PetscCall(VecZeroEntries(*v));
2431f6356ec7SDebojyoti Ghosh   }
24324cdd57e5SDebojyoti Ghosh   PetscFunctionReturn(0);
24334cdd57e5SDebojyoti Ghosh }
24344cdd57e5SDebojyoti Ghosh 
24354cdd57e5SDebojyoti Ghosh /*@
24364cdd57e5SDebojyoti Ghosh    TSGetTimeError - Returns the estimated error vector, if the chosen
24374cdd57e5SDebojyoti Ghosh    TSType has an error estimation functionality.
24384cdd57e5SDebojyoti Ghosh 
24394cdd57e5SDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
24404cdd57e5SDebojyoti Ghosh 
24419657682dSDebojyoti Ghosh    Note: MUST call after TSSetUp()
24429657682dSDebojyoti Ghosh 
24434cdd57e5SDebojyoti Ghosh    Parameters :
2444a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2445657c1e31SEmil Constantinescu .  n - current estimate (n=0) or previous one (n=-1)
2446a2b725a8SWilliam Gropp -  v - the vector containing the error (same size as the solution).
24474cdd57e5SDebojyoti Ghosh 
24484cdd57e5SDebojyoti Ghosh    Level: intermediate
24494cdd57e5SDebojyoti Ghosh 
2450db781477SPatrick Sanan .seealso: `TSGetSolution()`, `TSSetTimeError()`
24514cdd57e5SDebojyoti Ghosh 
24524cdd57e5SDebojyoti Ghosh @*/
24530a01e1b2SEmil Constantinescu PetscErrorCode  TSGetTimeError(TS ts,PetscInt n,Vec *v)
24544cdd57e5SDebojyoti Ghosh {
24554cdd57e5SDebojyoti Ghosh   PetscFunctionBegin;
24564cdd57e5SDebojyoti Ghosh   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2457f6356ec7SDebojyoti Ghosh   if (ts->ops->gettimeerror) {
24589566063dSJacob Faibussowitsch     PetscCall((*ts->ops->gettimeerror)(ts,n,v));
2459f6356ec7SDebojyoti Ghosh   } else {
24609566063dSJacob Faibussowitsch     PetscCall(VecZeroEntries(*v));
2461f6356ec7SDebojyoti Ghosh   }
24624cdd57e5SDebojyoti Ghosh   PetscFunctionReturn(0);
24634cdd57e5SDebojyoti Ghosh }
24644cdd57e5SDebojyoti Ghosh 
246557df6a1bSDebojyoti Ghosh /*@
246657df6a1bSDebojyoti Ghosh    TSSetTimeError - Sets the estimated error vector, if the chosen
246757df6a1bSDebojyoti Ghosh    TSType has an error estimation functionality. This can be used
246857df6a1bSDebojyoti Ghosh    to restart such a time integrator with a given error vector.
246957df6a1bSDebojyoti Ghosh 
247057df6a1bSDebojyoti Ghosh    Not Collective, but Vec returned is parallel if TS is parallel
247157df6a1bSDebojyoti Ghosh 
247257df6a1bSDebojyoti Ghosh    Parameters :
2473a2b725a8SWilliam Gropp +  ts - the TS context obtained from TSCreate() (input parameter).
2474a2b725a8SWilliam Gropp -  v - the vector containing the error (same size as the solution).
247557df6a1bSDebojyoti Ghosh 
247657df6a1bSDebojyoti Ghosh    Level: intermediate
247757df6a1bSDebojyoti Ghosh 
2478db781477SPatrick Sanan .seealso: `TSSetSolution()`, `TSGetTimeError)`
247957df6a1bSDebojyoti Ghosh 
248057df6a1bSDebojyoti Ghosh @*/
248157df6a1bSDebojyoti Ghosh PetscErrorCode  TSSetTimeError(TS ts,Vec v)
248257df6a1bSDebojyoti Ghosh {
248357df6a1bSDebojyoti Ghosh   PetscFunctionBegin;
248457df6a1bSDebojyoti Ghosh   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
24853c633725SBarry Smith   PetscCheck(ts->setupcalled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetUp() first");
24861baa6e33SBarry Smith   if (ts->ops->settimeerror) PetscCall((*ts->ops->settimeerror)(ts,v));
248757df6a1bSDebojyoti Ghosh   PetscFunctionReturn(0);
248857df6a1bSDebojyoti Ghosh }
248957df6a1bSDebojyoti Ghosh 
2490bdad233fSMatthew Knepley /* ----- Routines to initialize and destroy a timestepper ---- */
2491d8e5e3e6SSatish Balay /*@
2492bdad233fSMatthew Knepley   TSSetProblemType - Sets the type of problem to be solved.
2493d763cef2SBarry Smith 
2494bdad233fSMatthew Knepley   Not collective
2495d763cef2SBarry Smith 
2496bdad233fSMatthew Knepley   Input Parameters:
2497bdad233fSMatthew Knepley + ts   - The TS
2498bdad233fSMatthew Knepley - type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2499d763cef2SBarry Smith .vb
25000910c330SBarry Smith          U_t - A U = 0      (linear)
25010910c330SBarry Smith          U_t - A(t) U = 0   (linear)
25020910c330SBarry Smith          F(t,U,U_t) = 0     (nonlinear)
2503d763cef2SBarry Smith .ve
2504d763cef2SBarry Smith 
2505d763cef2SBarry Smith    Level: beginner
2506d763cef2SBarry Smith 
2507db781477SPatrick Sanan .seealso: `TSSetUp()`, `TSProblemType`, `TS`
2508d763cef2SBarry Smith @*/
25097087cfbeSBarry Smith PetscErrorCode  TSSetProblemType(TS ts, TSProblemType type)
2510a7cc72afSBarry Smith {
2511d763cef2SBarry Smith   PetscFunctionBegin;
25120700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
2513bdad233fSMatthew Knepley   ts->problem_type = type;
25149e2a6581SJed Brown   if (type == TS_LINEAR) {
25159e2a6581SJed Brown     SNES snes;
25169566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts,&snes));
25179566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes,SNESKSPONLY));
25189e2a6581SJed Brown   }
2519d763cef2SBarry Smith   PetscFunctionReturn(0);
2520d763cef2SBarry Smith }
2521d763cef2SBarry Smith 
2522bdad233fSMatthew Knepley /*@C
2523bdad233fSMatthew Knepley   TSGetProblemType - Gets the type of problem to be solved.
2524bdad233fSMatthew Knepley 
2525bdad233fSMatthew Knepley   Not collective
2526bdad233fSMatthew Knepley 
2527bdad233fSMatthew Knepley   Input Parameter:
2528bdad233fSMatthew Knepley . ts   - The TS
2529bdad233fSMatthew Knepley 
2530bdad233fSMatthew Knepley   Output Parameter:
2531bdad233fSMatthew Knepley . type - One of TS_LINEAR, TS_NONLINEAR where these types refer to problems of the forms
2532bdad233fSMatthew Knepley .vb
2533089b2837SJed Brown          M U_t = A U
2534089b2837SJed Brown          M(t) U_t = A(t) U
2535b5abc632SBarry Smith          F(t,U,U_t)
2536bdad233fSMatthew Knepley .ve
2537bdad233fSMatthew Knepley 
2538bdad233fSMatthew Knepley    Level: beginner
2539bdad233fSMatthew Knepley 
2540db781477SPatrick Sanan .seealso: `TSSetUp()`, `TSProblemType`, `TS`
2541bdad233fSMatthew Knepley @*/
25427087cfbeSBarry Smith PetscErrorCode  TSGetProblemType(TS ts, TSProblemType *type)
2543a7cc72afSBarry Smith {
2544bdad233fSMatthew Knepley   PetscFunctionBegin;
25450700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
25464482741eSBarry Smith   PetscValidIntPointer(type,2);
2547bdad233fSMatthew Knepley   *type = ts->problem_type;
2548bdad233fSMatthew Knepley   PetscFunctionReturn(0);
2549bdad233fSMatthew Knepley }
2550d763cef2SBarry Smith 
2551303a5415SBarry Smith /*
2552303a5415SBarry 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()
2553303a5415SBarry Smith */
2554303a5415SBarry Smith static PetscErrorCode TSSetExactFinalTimeDefault(TS ts)
2555303a5415SBarry Smith {
2556303a5415SBarry Smith   PetscBool      isnone;
2557303a5415SBarry Smith 
2558303a5415SBarry Smith   PetscFunctionBegin;
25599566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts,&ts->adapt));
25609566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type));
2561303a5415SBarry Smith 
25629566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ts->adapt,TSADAPTNONE,&isnone));
2563303a5415SBarry Smith   if (!isnone && ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) {
2564303a5415SBarry Smith     ts->exact_final_time = TS_EXACTFINALTIME_MATCHSTEP;
2565303a5415SBarry Smith   } else if (ts->exact_final_time == TS_EXACTFINALTIME_UNSPECIFIED) {
2566303a5415SBarry Smith     ts->exact_final_time = TS_EXACTFINALTIME_INTERPOLATE;
2567303a5415SBarry Smith   }
2568303a5415SBarry Smith   PetscFunctionReturn(0);
2569303a5415SBarry Smith }
2570303a5415SBarry Smith 
2571d763cef2SBarry Smith /*@
2572303a5415SBarry Smith    TSSetUp - Sets up the internal data structures for the later use of a timestepper.
2573d763cef2SBarry Smith 
2574d763cef2SBarry Smith    Collective on TS
2575d763cef2SBarry Smith 
2576d763cef2SBarry Smith    Input Parameter:
2577d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2578d763cef2SBarry Smith 
2579d763cef2SBarry Smith    Notes:
2580d763cef2SBarry Smith    For basic use of the TS solvers the user need not explicitly call
2581d763cef2SBarry Smith    TSSetUp(), since these actions will automatically occur during
2582141bd67dSStefano Zampini    the call to TSStep() or TSSolve().  However, if one wishes to control this
2583d763cef2SBarry Smith    phase separately, TSSetUp() should be called after TSCreate()
2584141bd67dSStefano Zampini    and optional routines of the form TSSetXXX(), but before TSStep() and TSSolve().
2585d763cef2SBarry Smith 
2586d763cef2SBarry Smith    Level: advanced
2587d763cef2SBarry Smith 
2588db781477SPatrick Sanan .seealso: `TSCreate()`, `TSStep()`, `TSDestroy()`, `TSSolve()`
2589d763cef2SBarry Smith @*/
25907087cfbeSBarry Smith PetscErrorCode  TSSetUp(TS ts)
2591d763cef2SBarry Smith {
25926c6b9e74SPeter Brune   DM             dm;
25936c6b9e74SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
2594d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
2595cd11d68dSLisandro Dalcin   TSIFunction    ifun;
25966c6b9e74SPeter Brune   TSIJacobian    ijac;
2597efe9872eSLisandro Dalcin   TSI2Jacobian   i2jac;
25986c6b9e74SPeter Brune   TSRHSJacobian  rhsjac;
2599d763cef2SBarry Smith 
2600d763cef2SBarry Smith   PetscFunctionBegin;
26010700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2602277b19d0SLisandro Dalcin   if (ts->setupcalled) PetscFunctionReturn(0);
2603277b19d0SLisandro Dalcin 
26047adad957SLisandro Dalcin   if (!((PetscObject)ts)->type_name) {
26059566063dSJacob Faibussowitsch     PetscCall(TSGetIFunction(ts,NULL,&ifun,NULL));
26069566063dSJacob Faibussowitsch     PetscCall(TSSetType(ts,ifun ? TSBEULER : TSEULER));
2607d763cef2SBarry Smith   }
2608277b19d0SLisandro Dalcin 
26091a638600SStefano Zampini   if (!ts->vec_sol) {
26101a638600SStefano Zampini     if (ts->dm) {
26119566063dSJacob Faibussowitsch       PetscCall(DMCreateGlobalVector(ts->dm,&ts->vec_sol));
26121a638600SStefano Zampini     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call TSSetSolution() first");
26131a638600SStefano Zampini   }
2614277b19d0SLisandro Dalcin 
26154a658b32SHong Zhang   if (ts->tspan) {
26164a658b32SHong Zhang     if (!ts->tspan->vecs_sol) {
26174a658b32SHong Zhang       PetscCall(VecDuplicateVecs(ts->vec_sol,ts->tspan->num_span_times,&ts->tspan->vecs_sol));
26184a658b32SHong Zhang     }
26194a658b32SHong Zhang   }
2620298bade4SHong Zhang   if (!ts->Jacp && ts->Jacprhs) { /* IJacobianP shares the same matrix with RHSJacobianP if only RHSJacobianP is provided */
26219566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)ts->Jacprhs));
2622298bade4SHong Zhang     ts->Jacp = ts->Jacprhs;
2623298bade4SHong Zhang   }
2624298bade4SHong Zhang 
2625cd4cee2dSHong Zhang   if (ts->quadraturets) {
26269566063dSJacob Faibussowitsch     PetscCall(TSSetUp(ts->quadraturets));
26279566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
26289566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(ts->quadraturets->vec_sol,&ts->vec_costintegrand));
2629cd4cee2dSHong Zhang   }
2630cd4cee2dSHong Zhang 
26319566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts,NULL,NULL,&rhsjac,NULL));
2632f23ba4b3SHong Zhang   if (rhsjac == TSComputeRHSJacobianConstant) {
2633e1244c69SJed Brown     Mat Amat,Pmat;
2634e1244c69SJed Brown     SNES snes;
26359566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts,&snes));
26369566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes,&Amat,&Pmat,NULL,NULL));
2637e1244c69SJed Brown     /* Matching matrices implies that an IJacobian is NOT set, because if it had been set, the IJacobian's matrix would
2638e1244c69SJed Brown      * have displaced the RHS matrix */
2639971015bcSStefano Zampini     if (Amat && Amat == ts->Arhs) {
2640abc0d4abSBarry 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 */
26419566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Arhs,MAT_COPY_VALUES,&Amat));
26429566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes,Amat,NULL,NULL,NULL));
26439566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Amat));
2644e1244c69SJed Brown     }
2645971015bcSStefano Zampini     if (Pmat && Pmat == ts->Brhs) {
26469566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(ts->Brhs,MAT_COPY_VALUES,&Pmat));
26479566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes,NULL,Pmat,NULL,NULL));
26489566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Pmat));
2649e1244c69SJed Brown     }
2650e1244c69SJed Brown   }
26512ffb9264SLisandro Dalcin 
26529566063dSJacob Faibussowitsch   PetscCall(TSGetAdapt(ts,&ts->adapt));
26539566063dSJacob Faibussowitsch   PetscCall(TSAdaptSetDefaultType(ts->adapt,ts->default_adapt_type));
26542ffb9264SLisandro Dalcin 
26551baa6e33SBarry Smith   if (ts->ops->setup) PetscCall((*ts->ops->setup)(ts));
2656277b19d0SLisandro Dalcin 
26579566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
26582ffb9264SLisandro Dalcin 
2659a6772fa2SLisandro Dalcin   /* In the case where we've set a DMTSFunction or what have you, we need the default SNESFunction
26606c6b9e74SPeter Brune      to be set right but can't do it elsewhere due to the overreliance on ctx=ts.
26616c6b9e74SPeter Brune    */
26629566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
26639566063dSJacob Faibussowitsch   PetscCall(DMSNESGetFunction(dm,&func,NULL));
26646c6b9e74SPeter Brune   if (!func) {
26659566063dSJacob Faibussowitsch     PetscCall(DMSNESSetFunction(dm,SNESTSFormFunction,ts));
26666c6b9e74SPeter Brune   }
2667a6772fa2SLisandro 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.
26686c6b9e74SPeter Brune      Otherwise, the SNES will use coloring internally to form the Jacobian.
26696c6b9e74SPeter Brune    */
26709566063dSJacob Faibussowitsch   PetscCall(DMSNESGetJacobian(dm,&jac,NULL));
26719566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm,&ijac,NULL));
26729566063dSJacob Faibussowitsch   PetscCall(DMTSGetI2Jacobian(dm,&i2jac,NULL));
26739566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm,&rhsjac,NULL));
2674efe9872eSLisandro Dalcin   if (!jac && (ijac || i2jac || rhsjac)) {
26759566063dSJacob Faibussowitsch     PetscCall(DMSNESSetJacobian(dm,SNESTSFormJacobian,ts));
26766c6b9e74SPeter Brune   }
2677c0517034SDebojyoti Ghosh 
2678c0517034SDebojyoti Ghosh   /* if time integration scheme has a starting method, call it */
26791baa6e33SBarry Smith   if (ts->ops->startingmethod) PetscCall((*ts->ops->startingmethod)(ts));
2680c0517034SDebojyoti Ghosh 
2681277b19d0SLisandro Dalcin   ts->setupcalled = PETSC_TRUE;
2682277b19d0SLisandro Dalcin   PetscFunctionReturn(0);
2683277b19d0SLisandro Dalcin }
2684277b19d0SLisandro Dalcin 
2685f6a906c0SBarry Smith /*@
2686277b19d0SLisandro Dalcin    TSReset - Resets a TS context and removes any allocated Vecs and Mats.
2687277b19d0SLisandro Dalcin 
2688277b19d0SLisandro Dalcin    Collective on TS
2689277b19d0SLisandro Dalcin 
2690277b19d0SLisandro Dalcin    Input Parameter:
2691277b19d0SLisandro Dalcin .  ts - the TS context obtained from TSCreate()
2692277b19d0SLisandro Dalcin 
2693277b19d0SLisandro Dalcin    Level: beginner
2694277b19d0SLisandro Dalcin 
2695db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetup()`, `TSDestroy()`
2696277b19d0SLisandro Dalcin @*/
2697277b19d0SLisandro Dalcin PetscErrorCode  TSReset(TS ts)
2698277b19d0SLisandro Dalcin {
26991d06f6b3SHong Zhang   TS_RHSSplitLink ilink = ts->tsrhssplit,next;
2700277b19d0SLisandro Dalcin 
2701277b19d0SLisandro Dalcin   PetscFunctionBegin;
2702277b19d0SLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2703b18ea86cSHong Zhang 
27041baa6e33SBarry Smith   if (ts->ops->reset) PetscCall((*ts->ops->reset)(ts));
27059566063dSJacob Faibussowitsch   if (ts->snes) PetscCall(SNESReset(ts->snes));
27069566063dSJacob Faibussowitsch   if (ts->adapt) PetscCall(TSAdaptReset(ts->adapt));
2707bbd56ea5SKarl Rupp 
27089566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Arhs));
27099566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Brhs));
27109566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->Frhs));
27119566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
27129566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_dot));
27139566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vatol));
27149566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vrtol));
27159566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(ts->nwork,&ts->work));
2716bbd56ea5SKarl Rupp 
27179566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacprhs));
27189566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&ts->Jacp));
27191baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardReset(ts));
2720cd4cee2dSHong Zhang   if (ts->quadraturets) {
27219566063dSJacob Faibussowitsch     PetscCall(TSReset(ts->quadraturets));
27229566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vec_costintegrand));
2723cd4cee2dSHong Zhang   }
27241d06f6b3SHong Zhang   while (ilink) {
27251d06f6b3SHong Zhang     next = ilink->next;
27269566063dSJacob Faibussowitsch     PetscCall(TSDestroy(&ilink->ts));
27279566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink->splitname));
27289566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ilink->is));
27299566063dSJacob Faibussowitsch     PetscCall(PetscFree(ilink));
27301d06f6b3SHong Zhang     ilink = next;
273187f4e208SHong Zhang   }
27326bf673ebSJoe Pusztay   ts->tsrhssplit = NULL;
2733545aaa6fSHong Zhang   ts->num_rhs_splits = 0;
27344a658b32SHong Zhang   if (ts->tspan) {
27354a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan->span_times));
27364a658b32SHong Zhang     PetscCall(VecDestroyVecs(ts->tspan->num_span_times,&ts->tspan->vecs_sol));
27374a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan));
27384a658b32SHong Zhang   }
2739277b19d0SLisandro Dalcin   ts->setupcalled = PETSC_FALSE;
2740d763cef2SBarry Smith   PetscFunctionReturn(0);
2741d763cef2SBarry Smith }
2742d763cef2SBarry Smith 
27431fb7b255SJunchao Zhang /*@C
2744d763cef2SBarry Smith    TSDestroy - Destroys the timestepper context that was created
2745d763cef2SBarry Smith    with TSCreate().
2746d763cef2SBarry Smith 
2747d763cef2SBarry Smith    Collective on TS
2748d763cef2SBarry Smith 
2749d763cef2SBarry Smith    Input Parameter:
2750d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2751d763cef2SBarry Smith 
2752d763cef2SBarry Smith    Level: beginner
2753d763cef2SBarry Smith 
2754db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetUp()`, `TSSolve()`
2755d763cef2SBarry Smith @*/
27566bf464f9SBarry Smith PetscErrorCode  TSDestroy(TS *ts)
2757d763cef2SBarry Smith {
2758d763cef2SBarry Smith   PetscFunctionBegin;
27596bf464f9SBarry Smith   if (!*ts) PetscFunctionReturn(0);
2760ecf68647SHong Zhang   PetscValidHeaderSpecific(*ts,TS_CLASSID,1);
2761c793f718SLisandro Dalcin   if (--((PetscObject)(*ts))->refct > 0) {*ts = NULL; PetscFunctionReturn(0);}
2762d763cef2SBarry Smith 
27639566063dSJacob Faibussowitsch   PetscCall(TSReset(*ts));
27649566063dSJacob Faibussowitsch   PetscCall(TSAdjointReset(*ts));
2765ecf68647SHong Zhang   if ((*ts)->forward_solve) {
27669566063dSJacob Faibussowitsch     PetscCall(TSForwardReset(*ts));
2767ecf68647SHong Zhang   }
2768e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
27699566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*ts));
27709566063dSJacob Faibussowitsch   if ((*ts)->ops->destroy) PetscCall((*(*ts)->ops->destroy)((*ts)));
27716d4c513bSLisandro Dalcin 
27729566063dSJacob Faibussowitsch   PetscCall(TSTrajectoryDestroy(&(*ts)->trajectory));
2773bc952696SBarry Smith 
27749566063dSJacob Faibussowitsch   PetscCall(TSAdaptDestroy(&(*ts)->adapt));
27759566063dSJacob Faibussowitsch   PetscCall(TSEventDestroy(&(*ts)->event));
27766427ac75SLisandro Dalcin 
27779566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&(*ts)->snes));
27789566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&(*ts)->dm));
27799566063dSJacob Faibussowitsch   PetscCall(TSMonitorCancel((*ts)));
27809566063dSJacob Faibussowitsch   PetscCall(TSAdjointMonitorCancel((*ts)));
27816d4c513bSLisandro Dalcin 
27829566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&(*ts)->quadraturets));
27839566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(ts));
2784d763cef2SBarry Smith   PetscFunctionReturn(0);
2785d763cef2SBarry Smith }
2786d763cef2SBarry Smith 
2787d8e5e3e6SSatish Balay /*@
2788d763cef2SBarry Smith    TSGetSNES - Returns the SNES (nonlinear solver) associated with
2789d763cef2SBarry Smith    a TS (timestepper) context. Valid only for nonlinear problems.
2790d763cef2SBarry Smith 
2791d763cef2SBarry Smith    Not Collective, but SNES is parallel if TS is parallel
2792d763cef2SBarry Smith 
2793d763cef2SBarry Smith    Input Parameter:
2794d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2795d763cef2SBarry Smith 
2796d763cef2SBarry Smith    Output Parameter:
2797d763cef2SBarry Smith .  snes - the nonlinear solver context
2798d763cef2SBarry Smith 
2799d763cef2SBarry Smith    Notes:
2800d763cef2SBarry Smith    The user can then directly manipulate the SNES context to set various
2801d763cef2SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
280294b7f48cSBarry Smith    KSP, KSP, and PC contexts as well.
2803d763cef2SBarry Smith 
2804d763cef2SBarry Smith    TSGetSNES() does not work for integrators that do not use SNES; in
28050298fd71SBarry Smith    this case TSGetSNES() returns NULL in snes.
2806d763cef2SBarry Smith 
2807d763cef2SBarry Smith    Level: beginner
2808d763cef2SBarry Smith 
2809d763cef2SBarry Smith @*/
28107087cfbeSBarry Smith PetscErrorCode  TSGetSNES(TS ts,SNES *snes)
2811d763cef2SBarry Smith {
2812d763cef2SBarry Smith   PetscFunctionBegin;
28130700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
28144482741eSBarry Smith   PetscValidPointer(snes,2);
2815d372ba47SLisandro Dalcin   if (!ts->snes) {
28169566063dSJacob Faibussowitsch     PetscCall(SNESCreate(PetscObjectComm((PetscObject)ts),&ts->snes));
28179566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)ts->snes,((PetscObject)ts)->options));
28189566063dSJacob Faibussowitsch     PetscCall(SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts));
28199566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->snes));
28209566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->snes,(PetscObject)ts,1));
28219566063dSJacob Faibussowitsch     if (ts->dm) PetscCall(SNESSetDM(ts->snes,ts->dm));
28229e2a6581SJed Brown     if (ts->problem_type == TS_LINEAR) {
28239566063dSJacob Faibussowitsch       PetscCall(SNESSetType(ts->snes,SNESKSPONLY));
28249e2a6581SJed Brown     }
2825d372ba47SLisandro Dalcin   }
2826d763cef2SBarry Smith   *snes = ts->snes;
2827d763cef2SBarry Smith   PetscFunctionReturn(0);
2828d763cef2SBarry Smith }
2829d763cef2SBarry Smith 
2830deb2cd25SJed Brown /*@
2831deb2cd25SJed Brown    TSSetSNES - Set the SNES (nonlinear solver) to be used by the timestepping context
2832deb2cd25SJed Brown 
2833deb2cd25SJed Brown    Collective
2834deb2cd25SJed Brown 
2835d8d19677SJose E. Roman    Input Parameters:
2836deb2cd25SJed Brown +  ts - the TS context obtained from TSCreate()
2837deb2cd25SJed Brown -  snes - the nonlinear solver context
2838deb2cd25SJed Brown 
2839deb2cd25SJed Brown    Notes:
2840deb2cd25SJed Brown    Most users should have the TS created by calling TSGetSNES()
2841deb2cd25SJed Brown 
2842deb2cd25SJed Brown    Level: developer
2843deb2cd25SJed Brown 
2844deb2cd25SJed Brown @*/
2845deb2cd25SJed Brown PetscErrorCode TSSetSNES(TS ts,SNES snes)
2846deb2cd25SJed Brown {
2847d1e9a80fSBarry Smith   PetscErrorCode (*func)(SNES,Vec,Mat,Mat,void*);
2848deb2cd25SJed Brown 
2849deb2cd25SJed Brown   PetscFunctionBegin;
2850deb2cd25SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2851deb2cd25SJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,2);
28529566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)snes));
28539566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&ts->snes));
2854bbd56ea5SKarl Rupp 
2855deb2cd25SJed Brown   ts->snes = snes;
2856bbd56ea5SKarl Rupp 
28579566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(ts->snes,NULL,SNESTSFormFunction,ts));
28589566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(ts->snes,NULL,NULL,&func,NULL));
2859740132f1SEmil Constantinescu   if (func == SNESTSFormJacobian) {
28609566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(ts->snes,NULL,NULL,SNESTSFormJacobian,ts));
2861740132f1SEmil Constantinescu   }
2862deb2cd25SJed Brown   PetscFunctionReturn(0);
2863deb2cd25SJed Brown }
2864deb2cd25SJed Brown 
2865d8e5e3e6SSatish Balay /*@
286694b7f48cSBarry Smith    TSGetKSP - Returns the KSP (linear solver) associated with
2867d763cef2SBarry Smith    a TS (timestepper) context.
2868d763cef2SBarry Smith 
286994b7f48cSBarry Smith    Not Collective, but KSP is parallel if TS is parallel
2870d763cef2SBarry Smith 
2871d763cef2SBarry Smith    Input Parameter:
2872d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
2873d763cef2SBarry Smith 
2874d763cef2SBarry Smith    Output Parameter:
287594b7f48cSBarry Smith .  ksp - the nonlinear solver context
2876d763cef2SBarry Smith 
2877d763cef2SBarry Smith    Notes:
287894b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
2879d763cef2SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
2880d763cef2SBarry Smith    KSP and PC contexts as well.
2881d763cef2SBarry Smith 
288294b7f48cSBarry Smith    TSGetKSP() does not work for integrators that do not use KSP;
28830298fd71SBarry Smith    in this case TSGetKSP() returns NULL in ksp.
2884d763cef2SBarry Smith 
2885d763cef2SBarry Smith    Level: beginner
2886d763cef2SBarry Smith 
2887d763cef2SBarry Smith @*/
28887087cfbeSBarry Smith PetscErrorCode  TSGetKSP(TS ts,KSP *ksp)
2889d763cef2SBarry Smith {
2890089b2837SJed Brown   SNES           snes;
2891d372ba47SLisandro Dalcin 
2892d763cef2SBarry Smith   PetscFunctionBegin;
28930700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
28944482741eSBarry Smith   PetscValidPointer(ksp,2);
28953c633725SBarry Smith   PetscCheck(((PetscObject)ts)->type_name,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"KSP is not created yet. Call TSSetType() first");
28963c633725SBarry Smith   PetscCheck(ts->problem_type == TS_LINEAR,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Linear only; use TSGetSNES()");
28979566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
28989566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes,ksp));
2899d763cef2SBarry Smith   PetscFunctionReturn(0);
2900d763cef2SBarry Smith }
2901d763cef2SBarry Smith 
2902d763cef2SBarry Smith /* ----------- Routines to set solver parameters ---------- */
2903d763cef2SBarry Smith 
2904adb62b0dSMatthew Knepley /*@
2905618ce8baSLisandro Dalcin    TSSetMaxSteps - Sets the maximum number of steps to use.
2906618ce8baSLisandro Dalcin 
2907618ce8baSLisandro Dalcin    Logically Collective on TS
2908618ce8baSLisandro Dalcin 
2909618ce8baSLisandro Dalcin    Input Parameters:
2910618ce8baSLisandro Dalcin +  ts - the TS context obtained from TSCreate()
2911618ce8baSLisandro Dalcin -  maxsteps - maximum number of steps to use
2912618ce8baSLisandro Dalcin 
2913618ce8baSLisandro Dalcin    Options Database Keys:
2914618ce8baSLisandro Dalcin .  -ts_max_steps <maxsteps> - Sets maxsteps
2915618ce8baSLisandro Dalcin 
2916618ce8baSLisandro Dalcin    Notes:
2917618ce8baSLisandro Dalcin    The default maximum number of steps is 5000
2918618ce8baSLisandro Dalcin 
2919618ce8baSLisandro Dalcin    Level: intermediate
2920618ce8baSLisandro Dalcin 
2921db781477SPatrick Sanan .seealso: `TSGetMaxSteps()`, `TSSetMaxTime()`, `TSSetExactFinalTime()`
2922618ce8baSLisandro Dalcin @*/
2923618ce8baSLisandro Dalcin PetscErrorCode TSSetMaxSteps(TS ts,PetscInt maxsteps)
2924618ce8baSLisandro Dalcin {
2925618ce8baSLisandro Dalcin   PetscFunctionBegin;
2926618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2927618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
29283c633725SBarry Smith   PetscCheck(maxsteps >= 0,PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of steps must be non-negative");
2929618ce8baSLisandro Dalcin   ts->max_steps = maxsteps;
2930618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
2931618ce8baSLisandro Dalcin }
2932618ce8baSLisandro Dalcin 
2933618ce8baSLisandro Dalcin /*@
2934618ce8baSLisandro Dalcin    TSGetMaxSteps - Gets the maximum number of steps to use.
2935618ce8baSLisandro Dalcin 
2936618ce8baSLisandro Dalcin    Not Collective
2937618ce8baSLisandro Dalcin 
2938618ce8baSLisandro Dalcin    Input Parameters:
2939618ce8baSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
2940618ce8baSLisandro Dalcin 
2941618ce8baSLisandro Dalcin    Output Parameter:
2942618ce8baSLisandro Dalcin .  maxsteps - maximum number of steps to use
2943618ce8baSLisandro Dalcin 
2944618ce8baSLisandro Dalcin    Level: advanced
2945618ce8baSLisandro Dalcin 
2946db781477SPatrick Sanan .seealso: `TSSetMaxSteps()`, `TSGetMaxTime()`, `TSSetMaxTime()`
2947618ce8baSLisandro Dalcin @*/
2948618ce8baSLisandro Dalcin PetscErrorCode TSGetMaxSteps(TS ts,PetscInt *maxsteps)
2949618ce8baSLisandro Dalcin {
2950618ce8baSLisandro Dalcin   PetscFunctionBegin;
2951618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2952618ce8baSLisandro Dalcin   PetscValidIntPointer(maxsteps,2);
2953618ce8baSLisandro Dalcin   *maxsteps = ts->max_steps;
2954618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
2955618ce8baSLisandro Dalcin }
2956618ce8baSLisandro Dalcin 
2957618ce8baSLisandro Dalcin /*@
2958618ce8baSLisandro Dalcin    TSSetMaxTime - Sets the maximum (or final) time for timestepping.
2959618ce8baSLisandro Dalcin 
2960618ce8baSLisandro Dalcin    Logically Collective on TS
2961618ce8baSLisandro Dalcin 
2962618ce8baSLisandro Dalcin    Input Parameters:
2963618ce8baSLisandro Dalcin +  ts - the TS context obtained from TSCreate()
2964618ce8baSLisandro Dalcin -  maxtime - final time to step to
2965618ce8baSLisandro Dalcin 
2966618ce8baSLisandro Dalcin    Options Database Keys:
2967ef85077eSLisandro Dalcin .  -ts_max_time <maxtime> - Sets maxtime
2968618ce8baSLisandro Dalcin 
2969618ce8baSLisandro Dalcin    Notes:
2970618ce8baSLisandro Dalcin    The default maximum time is 5.0
2971618ce8baSLisandro Dalcin 
2972618ce8baSLisandro Dalcin    Level: intermediate
2973618ce8baSLisandro Dalcin 
2974db781477SPatrick Sanan .seealso: `TSGetMaxTime()`, `TSSetMaxSteps()`, `TSSetExactFinalTime()`
2975618ce8baSLisandro Dalcin @*/
2976618ce8baSLisandro Dalcin PetscErrorCode TSSetMaxTime(TS ts,PetscReal maxtime)
2977618ce8baSLisandro Dalcin {
2978618ce8baSLisandro Dalcin   PetscFunctionBegin;
2979618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
2980618ce8baSLisandro Dalcin   PetscValidLogicalCollectiveReal(ts,maxtime,2);
2981618ce8baSLisandro Dalcin   ts->max_time = maxtime;
2982618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
2983618ce8baSLisandro Dalcin }
2984618ce8baSLisandro Dalcin 
2985618ce8baSLisandro Dalcin /*@
2986618ce8baSLisandro Dalcin    TSGetMaxTime - Gets the maximum (or final) time for timestepping.
2987618ce8baSLisandro Dalcin 
2988618ce8baSLisandro Dalcin    Not Collective
2989618ce8baSLisandro Dalcin 
2990618ce8baSLisandro Dalcin    Input Parameters:
2991618ce8baSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
2992618ce8baSLisandro Dalcin 
2993618ce8baSLisandro Dalcin    Output Parameter:
2994618ce8baSLisandro Dalcin .  maxtime - final time to step to
2995618ce8baSLisandro Dalcin 
2996618ce8baSLisandro Dalcin    Level: advanced
2997618ce8baSLisandro Dalcin 
2998db781477SPatrick Sanan .seealso: `TSSetMaxTime()`, `TSGetMaxSteps()`, `TSSetMaxSteps()`
2999618ce8baSLisandro Dalcin @*/
3000618ce8baSLisandro Dalcin PetscErrorCode TSGetMaxTime(TS ts,PetscReal *maxtime)
3001618ce8baSLisandro Dalcin {
3002618ce8baSLisandro Dalcin   PetscFunctionBegin;
3003618ce8baSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3004618ce8baSLisandro Dalcin   PetscValidRealPointer(maxtime,2);
3005618ce8baSLisandro Dalcin   *maxtime = ts->max_time;
3006618ce8baSLisandro Dalcin   PetscFunctionReturn(0);
3007618ce8baSLisandro Dalcin }
3008618ce8baSLisandro Dalcin 
3009618ce8baSLisandro Dalcin /*@
3010aaa6c58dSLisandro Dalcin    TSSetInitialTimeStep - Deprecated, use TSSetTime() and TSSetTimeStep().
3011edc382c3SSatish Balay 
3012edc382c3SSatish Balay    Level: deprecated
3013edc382c3SSatish Balay 
3014aaa6c58dSLisandro Dalcin @*/
3015aaa6c58dSLisandro Dalcin PetscErrorCode  TSSetInitialTimeStep(TS ts,PetscReal initial_time,PetscReal time_step)
3016aaa6c58dSLisandro Dalcin {
3017aaa6c58dSLisandro Dalcin   PetscFunctionBegin;
3018aaa6c58dSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
30199566063dSJacob Faibussowitsch   PetscCall(TSSetTime(ts,initial_time));
30209566063dSJacob Faibussowitsch   PetscCall(TSSetTimeStep(ts,time_step));
3021aaa6c58dSLisandro Dalcin   PetscFunctionReturn(0);
3022aaa6c58dSLisandro Dalcin }
3023aaa6c58dSLisandro Dalcin 
3024aaa6c58dSLisandro Dalcin /*@
302519eac22cSLisandro Dalcin    TSGetDuration - Deprecated, use TSGetMaxSteps() and TSGetMaxTime().
3026edc382c3SSatish Balay 
3027edc382c3SSatish Balay    Level: deprecated
3028edc382c3SSatish Balay 
3029adb62b0dSMatthew Knepley @*/
30307087cfbeSBarry Smith PetscErrorCode TSGetDuration(TS ts, PetscInt *maxsteps, PetscReal *maxtime)
3031adb62b0dSMatthew Knepley {
3032adb62b0dSMatthew Knepley   PetscFunctionBegin;
30330700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3034abc0a331SBarry Smith   if (maxsteps) {
30354482741eSBarry Smith     PetscValidIntPointer(maxsteps,2);
3036adb62b0dSMatthew Knepley     *maxsteps = ts->max_steps;
3037adb62b0dSMatthew Knepley   }
3038abc0a331SBarry Smith   if (maxtime) {
3039064a246eSJacob Faibussowitsch     PetscValidRealPointer(maxtime,3);
3040adb62b0dSMatthew Knepley     *maxtime = ts->max_time;
3041adb62b0dSMatthew Knepley   }
3042adb62b0dSMatthew Knepley   PetscFunctionReturn(0);
3043adb62b0dSMatthew Knepley }
3044adb62b0dSMatthew Knepley 
3045d763cef2SBarry Smith /*@
304619eac22cSLisandro Dalcin    TSSetDuration - Deprecated, use TSSetMaxSteps() and TSSetMaxTime().
3047edc382c3SSatish Balay 
3048edc382c3SSatish Balay    Level: deprecated
3049edc382c3SSatish Balay 
3050d763cef2SBarry Smith @*/
30517087cfbeSBarry Smith PetscErrorCode TSSetDuration(TS ts,PetscInt maxsteps,PetscReal maxtime)
3052d763cef2SBarry Smith {
3053d763cef2SBarry Smith   PetscFunctionBegin;
30540700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3055c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(ts,maxsteps,2);
3056064a246eSJacob Faibussowitsch   PetscValidLogicalCollectiveReal(ts,maxtime,3);
305739b7ec4bSSean Farley   if (maxsteps >= 0) ts->max_steps = maxsteps;
305839b7ec4bSSean Farley   if (maxtime != PETSC_DEFAULT) ts->max_time = maxtime;
3059d763cef2SBarry Smith   PetscFunctionReturn(0);
3060d763cef2SBarry Smith }
3061d763cef2SBarry Smith 
3062d763cef2SBarry Smith /*@
30635c5f5948SLisandro Dalcin    TSGetTimeStepNumber - Deprecated, use TSGetStepNumber().
3064edc382c3SSatish Balay 
3065edc382c3SSatish Balay    Level: deprecated
3066edc382c3SSatish Balay 
30675c5f5948SLisandro Dalcin @*/
3068e193eaafSLisandro Dalcin PetscErrorCode TSGetTimeStepNumber(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); }
30695c5f5948SLisandro Dalcin 
307019eac22cSLisandro Dalcin /*@
30714f4e0956SLisandro Dalcin    TSGetTotalSteps - Deprecated, use TSGetStepNumber().
3072edc382c3SSatish Balay 
3073edc382c3SSatish Balay    Level: deprecated
3074edc382c3SSatish Balay 
30754f4e0956SLisandro Dalcin @*/
30764f4e0956SLisandro Dalcin PetscErrorCode TSGetTotalSteps(TS ts,PetscInt *steps) { return TSGetStepNumber(ts,steps); }
30774f4e0956SLisandro Dalcin 
30784f4e0956SLisandro Dalcin /*@
3079d763cef2SBarry Smith    TSSetSolution - Sets the initial solution vector
3080d763cef2SBarry Smith    for use by the TS routines.
3081d763cef2SBarry Smith 
3082d083f849SBarry Smith    Logically Collective on TS
3083d763cef2SBarry Smith 
3084d763cef2SBarry Smith    Input Parameters:
3085d763cef2SBarry Smith +  ts - the TS context obtained from TSCreate()
30860910c330SBarry Smith -  u - the solution vector
3087d763cef2SBarry Smith 
3088d763cef2SBarry Smith    Level: beginner
3089d763cef2SBarry Smith 
3090db781477SPatrick Sanan .seealso: `TSSetSolutionFunction()`, `TSGetSolution()`, `TSCreate()`
3091d763cef2SBarry Smith @*/
30920910c330SBarry Smith PetscErrorCode  TSSetSolution(TS ts,Vec u)
3093d763cef2SBarry Smith {
3094496e6a7aSJed Brown   DM             dm;
30958737fe31SLisandro Dalcin 
3096d763cef2SBarry Smith   PetscFunctionBegin;
30970700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
30980910c330SBarry Smith   PetscValidHeaderSpecific(u,VEC_CLASSID,2);
30999566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)u));
31009566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ts->vec_sol));
31010910c330SBarry Smith   ts->vec_sol = u;
3102bbd56ea5SKarl Rupp 
31039566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
31049566063dSJacob Faibussowitsch   PetscCall(DMShellSetGlobalVector(dm,u));
3105d763cef2SBarry Smith   PetscFunctionReturn(0);
3106d763cef2SBarry Smith }
3107d763cef2SBarry Smith 
3108ac226902SBarry Smith /*@C
3109000e7ae3SMatthew Knepley   TSSetPreStep - Sets the general-purpose function
31103f2090d5SJed Brown   called once at the beginning of each time step.
3111000e7ae3SMatthew Knepley 
31123f9fe445SBarry Smith   Logically Collective on TS
3113000e7ae3SMatthew Knepley 
3114000e7ae3SMatthew Knepley   Input Parameters:
3115000e7ae3SMatthew Knepley + ts   - The TS context obtained from TSCreate()
3116000e7ae3SMatthew Knepley - func - The function
3117000e7ae3SMatthew Knepley 
3118000e7ae3SMatthew Knepley   Calling sequence of func:
311967b8a455SSatish Balay .vb
312067b8a455SSatish Balay   PetscErrorCode func (TS ts);
312167b8a455SSatish Balay .ve
3122000e7ae3SMatthew Knepley 
3123000e7ae3SMatthew Knepley   Level: intermediate
3124000e7ae3SMatthew Knepley 
3125db781477SPatrick Sanan .seealso: `TSSetPreStage()`, `TSSetPostStage()`, `TSSetPostStep()`, `TSStep()`, `TSRestartStep()`
3126000e7ae3SMatthew Knepley @*/
31277087cfbeSBarry Smith PetscErrorCode  TSSetPreStep(TS ts, PetscErrorCode (*func)(TS))
3128000e7ae3SMatthew Knepley {
3129000e7ae3SMatthew Knepley   PetscFunctionBegin;
31300700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3131ae60f76fSBarry Smith   ts->prestep = func;
3132000e7ae3SMatthew Knepley   PetscFunctionReturn(0);
3133000e7ae3SMatthew Knepley }
3134000e7ae3SMatthew Knepley 
313509ee8438SJed Brown /*@
31363f2090d5SJed Brown   TSPreStep - Runs the user-defined pre-step function.
31373f2090d5SJed Brown 
31383f2090d5SJed Brown   Collective on TS
31393f2090d5SJed Brown 
31403f2090d5SJed Brown   Input Parameters:
31413f2090d5SJed Brown . ts   - The TS context obtained from TSCreate()
31423f2090d5SJed Brown 
31433f2090d5SJed Brown   Notes:
31443f2090d5SJed Brown   TSPreStep() is typically used within time stepping implementations,
31453f2090d5SJed Brown   so most users would not generally call this routine themselves.
31463f2090d5SJed Brown 
31473f2090d5SJed Brown   Level: developer
31483f2090d5SJed Brown 
3149db781477SPatrick Sanan .seealso: `TSSetPreStep()`, `TSPreStage()`, `TSPostStage()`, `TSPostStep()`
31503f2090d5SJed Brown @*/
31517087cfbeSBarry Smith PetscErrorCode  TSPreStep(TS ts)
31523f2090d5SJed Brown {
31533f2090d5SJed Brown   PetscFunctionBegin;
31540700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3155ae60f76fSBarry Smith   if (ts->prestep) {
31565efd42a4SStefano Zampini     Vec              U;
3157ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3158ef8d1ce0SJohann Rudi     PetscBool        sameObject;
31595efd42a4SStefano Zampini     PetscObjectState sprev,spost;
31605efd42a4SStefano Zampini 
31619566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts,&U));
31629566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U,&idprev));
31639566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U,&sprev));
3164*792fecdfSBarry Smith     PetscCallExternal((*ts->prestep),ts);
31659566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts,&U));
31669566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U,idprev,&sameObject));
31679566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U,&spost));
31689566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
3169312ce896SJed Brown   }
31703f2090d5SJed Brown   PetscFunctionReturn(0);
31713f2090d5SJed Brown }
31723f2090d5SJed Brown 
3173b8123daeSJed Brown /*@C
3174b8123daeSJed Brown   TSSetPreStage - Sets the general-purpose function
3175b8123daeSJed Brown   called once at the beginning of each stage.
3176b8123daeSJed Brown 
3177b8123daeSJed Brown   Logically Collective on TS
3178b8123daeSJed Brown 
3179b8123daeSJed Brown   Input Parameters:
3180b8123daeSJed Brown + ts   - The TS context obtained from TSCreate()
3181b8123daeSJed Brown - func - The function
3182b8123daeSJed Brown 
3183b8123daeSJed Brown   Calling sequence of func:
318467b8a455SSatish Balay .vb
318567b8a455SSatish Balay   PetscErrorCode func(TS ts, PetscReal stagetime);
318667b8a455SSatish Balay .ve
3187b8123daeSJed Brown 
3188b8123daeSJed Brown   Level: intermediate
3189b8123daeSJed Brown 
3190b8123daeSJed Brown   Note:
3191b8123daeSJed Brown   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
319280275a0aSLisandro Dalcin   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
3193b8123daeSJed Brown   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
3194b8123daeSJed Brown 
3195db781477SPatrick Sanan .seealso: `TSSetPostStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3196b8123daeSJed Brown @*/
3197b8123daeSJed Brown PetscErrorCode  TSSetPreStage(TS ts, PetscErrorCode (*func)(TS,PetscReal))
3198b8123daeSJed Brown {
3199b8123daeSJed Brown   PetscFunctionBegin;
3200b8123daeSJed Brown   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3201ae60f76fSBarry Smith   ts->prestage = func;
3202b8123daeSJed Brown   PetscFunctionReturn(0);
3203b8123daeSJed Brown }
3204b8123daeSJed Brown 
32059be3e283SDebojyoti Ghosh /*@C
32069be3e283SDebojyoti Ghosh   TSSetPostStage - Sets the general-purpose function
32079be3e283SDebojyoti Ghosh   called once at the end of each stage.
32089be3e283SDebojyoti Ghosh 
32099be3e283SDebojyoti Ghosh   Logically Collective on TS
32109be3e283SDebojyoti Ghosh 
32119be3e283SDebojyoti Ghosh   Input Parameters:
32129be3e283SDebojyoti Ghosh + ts   - The TS context obtained from TSCreate()
32139be3e283SDebojyoti Ghosh - func - The function
32149be3e283SDebojyoti Ghosh 
32159be3e283SDebojyoti Ghosh   Calling sequence of func:
321667b8a455SSatish Balay .vb
321767b8a455SSatish Balay   PetscErrorCode func(TS ts, PetscReal stagetime, PetscInt stageindex, Vec* Y);
321867b8a455SSatish Balay .ve
32199be3e283SDebojyoti Ghosh 
32209be3e283SDebojyoti Ghosh   Level: intermediate
32219be3e283SDebojyoti Ghosh 
32229be3e283SDebojyoti Ghosh   Note:
32239be3e283SDebojyoti Ghosh   There may be several stages per time step. If the solve for a given stage fails, the step may be rejected and retried.
322480275a0aSLisandro Dalcin   The time step number being computed can be queried using TSGetStepNumber() and the total size of the step being
32259be3e283SDebojyoti Ghosh   attempted can be obtained using TSGetTimeStep(). The time at the start of the step is available via TSGetTime().
32269be3e283SDebojyoti Ghosh 
3227db781477SPatrick Sanan .seealso: `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
32289be3e283SDebojyoti Ghosh @*/
32299be3e283SDebojyoti Ghosh PetscErrorCode  TSSetPostStage(TS ts, PetscErrorCode (*func)(TS,PetscReal,PetscInt,Vec*))
32309be3e283SDebojyoti Ghosh {
32319be3e283SDebojyoti Ghosh   PetscFunctionBegin;
32329be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
32339be3e283SDebojyoti Ghosh   ts->poststage = func;
32349be3e283SDebojyoti Ghosh   PetscFunctionReturn(0);
32359be3e283SDebojyoti Ghosh }
32369be3e283SDebojyoti Ghosh 
3237c688d042SShri Abhyankar /*@C
3238c688d042SShri Abhyankar   TSSetPostEvaluate - Sets the general-purpose function
3239c688d042SShri Abhyankar   called once at the end of each step evaluation.
3240c688d042SShri Abhyankar 
3241c688d042SShri Abhyankar   Logically Collective on TS
3242c688d042SShri Abhyankar 
3243c688d042SShri Abhyankar   Input Parameters:
3244c688d042SShri Abhyankar + ts   - The TS context obtained from TSCreate()
3245c688d042SShri Abhyankar - func - The function
3246c688d042SShri Abhyankar 
3247c688d042SShri Abhyankar   Calling sequence of func:
324867b8a455SSatish Balay .vb
324967b8a455SSatish Balay   PetscErrorCode func(TS ts);
325067b8a455SSatish Balay .ve
3251c688d042SShri Abhyankar 
3252c688d042SShri Abhyankar   Level: intermediate
3253c688d042SShri Abhyankar 
3254c688d042SShri Abhyankar   Note:
32551785ff2aSShri Abhyankar   Semantically, TSSetPostEvaluate() differs from TSSetPostStep() since the function it sets is called before event-handling
32561785ff2aSShri Abhyankar   thus guaranteeing the same solution (computed by the time-stepper) will be passed to it. On the other hand, TSPostStep()
3257e7e94ed4SShri Abhyankar   may be passed a different solution, possibly changed by the event handler. TSPostEvaluate() is called after the next step
3258e7e94ed4SShri Abhyankar   solution is evaluated allowing to modify it, if need be. The solution can be obtained with TSGetSolution(), the time step
3259e7e94ed4SShri Abhyankar   with TSGetTimeStep(), and the time at the start of the step is available via TSGetTime()
3260c688d042SShri Abhyankar 
3261db781477SPatrick Sanan .seealso: `TSSetPreStage()`, `TSSetPreStep()`, `TSSetPostStep()`, `TSGetApplicationContext()`
3262c688d042SShri Abhyankar @*/
3263c688d042SShri Abhyankar PetscErrorCode  TSSetPostEvaluate(TS ts, PetscErrorCode (*func)(TS))
3264c688d042SShri Abhyankar {
3265c688d042SShri Abhyankar   PetscFunctionBegin;
3266c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3267c688d042SShri Abhyankar   ts->postevaluate = func;
3268c688d042SShri Abhyankar   PetscFunctionReturn(0);
3269c688d042SShri Abhyankar }
3270c688d042SShri Abhyankar 
3271b8123daeSJed Brown /*@
3272b8123daeSJed Brown   TSPreStage - Runs the user-defined pre-stage function set using TSSetPreStage()
3273b8123daeSJed Brown 
3274b8123daeSJed Brown   Collective on TS
3275b8123daeSJed Brown 
3276b8123daeSJed Brown   Input Parameters:
3277b8123daeSJed Brown . ts          - The TS context obtained from TSCreate()
32789be3e283SDebojyoti Ghosh   stagetime   - The absolute time of the current stage
3279b8123daeSJed Brown 
3280b8123daeSJed Brown   Notes:
3281b8123daeSJed Brown   TSPreStage() is typically used within time stepping implementations,
3282b8123daeSJed Brown   most users would not generally call this routine themselves.
3283b8123daeSJed Brown 
3284b8123daeSJed Brown   Level: developer
3285b8123daeSJed Brown 
3286db781477SPatrick Sanan .seealso: `TSPostStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3287b8123daeSJed Brown @*/
3288b8123daeSJed Brown PetscErrorCode  TSPreStage(TS ts, PetscReal stagetime)
3289b8123daeSJed Brown {
3290b8123daeSJed Brown   PetscFunctionBegin;
3291b8123daeSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3292ae60f76fSBarry Smith   if (ts->prestage) {
3293*792fecdfSBarry Smith     PetscCallExternal((*ts->prestage),ts,stagetime);
3294b8123daeSJed Brown   }
3295b8123daeSJed Brown   PetscFunctionReturn(0);
3296b8123daeSJed Brown }
3297b8123daeSJed Brown 
32989be3e283SDebojyoti Ghosh /*@
32999be3e283SDebojyoti Ghosh   TSPostStage - Runs the user-defined post-stage function set using TSSetPostStage()
33009be3e283SDebojyoti Ghosh 
33019be3e283SDebojyoti Ghosh   Collective on TS
33029be3e283SDebojyoti Ghosh 
33039be3e283SDebojyoti Ghosh   Input Parameters:
33049be3e283SDebojyoti Ghosh . ts          - The TS context obtained from TSCreate()
33059be3e283SDebojyoti Ghosh   stagetime   - The absolute time of the current stage
33069be3e283SDebojyoti Ghosh   stageindex  - Stage number
33079be3e283SDebojyoti Ghosh   Y           - Array of vectors (of size = total number
33089be3e283SDebojyoti Ghosh                 of stages) with the stage solutions
33099be3e283SDebojyoti Ghosh 
33109be3e283SDebojyoti Ghosh   Notes:
33119be3e283SDebojyoti Ghosh   TSPostStage() is typically used within time stepping implementations,
33129be3e283SDebojyoti Ghosh   most users would not generally call this routine themselves.
33139be3e283SDebojyoti Ghosh 
33149be3e283SDebojyoti Ghosh   Level: developer
33159be3e283SDebojyoti Ghosh 
3316db781477SPatrick Sanan .seealso: `TSPreStage()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
33179be3e283SDebojyoti Ghosh @*/
33189be3e283SDebojyoti Ghosh PetscErrorCode  TSPostStage(TS ts, PetscReal stagetime, PetscInt stageindex, Vec *Y)
33199be3e283SDebojyoti Ghosh {
33209be3e283SDebojyoti Ghosh   PetscFunctionBegin;
33219be3e283SDebojyoti Ghosh   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
33224beae5d8SLisandro Dalcin   if (ts->poststage) {
3323*792fecdfSBarry Smith     PetscCallExternal((*ts->poststage),ts,stagetime,stageindex,Y);
33249be3e283SDebojyoti Ghosh   }
33259be3e283SDebojyoti Ghosh   PetscFunctionReturn(0);
33269be3e283SDebojyoti Ghosh }
33279be3e283SDebojyoti Ghosh 
3328c688d042SShri Abhyankar /*@
3329c688d042SShri Abhyankar   TSPostEvaluate - Runs the user-defined post-evaluate function set using TSSetPostEvaluate()
3330c688d042SShri Abhyankar 
3331c688d042SShri Abhyankar   Collective on TS
3332c688d042SShri Abhyankar 
3333c688d042SShri Abhyankar   Input Parameters:
3334c688d042SShri Abhyankar . ts          - The TS context obtained from TSCreate()
3335c688d042SShri Abhyankar 
3336c688d042SShri Abhyankar   Notes:
3337c688d042SShri Abhyankar   TSPostEvaluate() is typically used within time stepping implementations,
3338c688d042SShri Abhyankar   most users would not generally call this routine themselves.
3339c688d042SShri Abhyankar 
3340c688d042SShri Abhyankar   Level: developer
3341c688d042SShri Abhyankar 
3342db781477SPatrick Sanan .seealso: `TSSetPostEvaluate()`, `TSSetPreStep()`, `TSPreStep()`, `TSPostStep()`
3343c688d042SShri Abhyankar @*/
3344c688d042SShri Abhyankar PetscErrorCode  TSPostEvaluate(TS ts)
3345c688d042SShri Abhyankar {
3346c688d042SShri Abhyankar   PetscFunctionBegin;
3347c688d042SShri Abhyankar   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3348c688d042SShri Abhyankar   if (ts->postevaluate) {
3349dcb233daSLisandro Dalcin     Vec              U;
3350dcb233daSLisandro Dalcin     PetscObjectState sprev,spost;
3351dcb233daSLisandro Dalcin 
33529566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts,&U));
33539566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U,&sprev));
3354*792fecdfSBarry Smith     PetscCallExternal((*ts->postevaluate),ts);
33559566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U,&spost));
33569566063dSJacob Faibussowitsch     if (sprev != spost) PetscCall(TSRestartStep(ts));
3357c688d042SShri Abhyankar   }
3358c688d042SShri Abhyankar   PetscFunctionReturn(0);
3359c688d042SShri Abhyankar }
3360c688d042SShri Abhyankar 
3361ac226902SBarry Smith /*@C
3362000e7ae3SMatthew Knepley   TSSetPostStep - Sets the general-purpose function
33633f2090d5SJed Brown   called once at the end of each time step.
3364000e7ae3SMatthew Knepley 
33653f9fe445SBarry Smith   Logically Collective on TS
3366000e7ae3SMatthew Knepley 
3367000e7ae3SMatthew Knepley   Input Parameters:
3368000e7ae3SMatthew Knepley + ts   - The TS context obtained from TSCreate()
3369000e7ae3SMatthew Knepley - func - The function
3370000e7ae3SMatthew Knepley 
3371000e7ae3SMatthew Knepley   Calling sequence of func:
3372b8123daeSJed Brown $ func (TS ts);
3373000e7ae3SMatthew Knepley 
33741785ff2aSShri Abhyankar   Notes:
33751785ff2aSShri Abhyankar   The function set by TSSetPostStep() is called after each successful step. The solution vector X
33761785ff2aSShri Abhyankar   obtained by TSGetSolution() may be different than that computed at the step end if the event handler
33771785ff2aSShri Abhyankar   locates an event and TSPostEvent() modifies it. Use TSSetPostEvaluate() if an unmodified solution is needed instead.
33781785ff2aSShri Abhyankar 
3379000e7ae3SMatthew Knepley   Level: intermediate
3380000e7ae3SMatthew Knepley 
3381db781477SPatrick Sanan .seealso: `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostEvaluate()`, `TSGetTimeStep()`, `TSGetStepNumber()`, `TSGetTime()`, `TSRestartStep()`
3382000e7ae3SMatthew Knepley @*/
33837087cfbeSBarry Smith PetscErrorCode  TSSetPostStep(TS ts, PetscErrorCode (*func)(TS))
3384000e7ae3SMatthew Knepley {
3385000e7ae3SMatthew Knepley   PetscFunctionBegin;
33860700a824SBarry Smith   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
3387ae60f76fSBarry Smith   ts->poststep = func;
3388000e7ae3SMatthew Knepley   PetscFunctionReturn(0);
3389000e7ae3SMatthew Knepley }
3390000e7ae3SMatthew Knepley 
339109ee8438SJed Brown /*@
33923f2090d5SJed Brown   TSPostStep - Runs the user-defined post-step function.
33933f2090d5SJed Brown 
33943f2090d5SJed Brown   Collective on TS
33953f2090d5SJed Brown 
33963f2090d5SJed Brown   Input Parameters:
33973f2090d5SJed Brown . ts   - The TS context obtained from TSCreate()
33983f2090d5SJed Brown 
33993f2090d5SJed Brown   Notes:
34003f2090d5SJed Brown   TSPostStep() is typically used within time stepping implementations,
34013f2090d5SJed Brown   so most users would not generally call this routine themselves.
34023f2090d5SJed Brown 
34033f2090d5SJed Brown   Level: developer
34043f2090d5SJed Brown 
34053f2090d5SJed Brown @*/
34067087cfbeSBarry Smith PetscErrorCode  TSPostStep(TS ts)
34073f2090d5SJed Brown {
34083f2090d5SJed Brown   PetscFunctionBegin;
34090700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3410ae60f76fSBarry Smith   if (ts->poststep) {
34115efd42a4SStefano Zampini     Vec              U;
3412ef8d1ce0SJohann Rudi     PetscObjectId    idprev;
3413ef8d1ce0SJohann Rudi     PetscBool        sameObject;
34145efd42a4SStefano Zampini     PetscObjectState sprev,spost;
34155efd42a4SStefano Zampini 
34169566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts,&U));
34179566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetId((PetscObject)U,&idprev));
34189566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U,&sprev));
3419*792fecdfSBarry Smith     PetscCallExternal((*ts->poststep),ts);
34209566063dSJacob Faibussowitsch     PetscCall(TSGetSolution(ts,&U));
34219566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompareId((PetscObject)U,idprev,&sameObject));
34229566063dSJacob Faibussowitsch     PetscCall(PetscObjectStateGet((PetscObject)U,&spost));
34239566063dSJacob Faibussowitsch     if (!sameObject || sprev != spost) PetscCall(TSRestartStep(ts));
342472ac3e02SJed Brown   }
34253f2090d5SJed Brown   PetscFunctionReturn(0);
34263f2090d5SJed Brown }
34273f2090d5SJed Brown 
3428cd652676SJed Brown /*@
3429cd652676SJed Brown    TSInterpolate - Interpolate the solution computed during the previous step to an arbitrary location in the interval
3430cd652676SJed Brown 
3431cd652676SJed Brown    Collective on TS
3432cd652676SJed Brown 
34334165533cSJose E. Roman    Input Parameters:
3434cd652676SJed Brown +  ts - time stepping context
3435cd652676SJed Brown -  t - time to interpolate to
3436cd652676SJed Brown 
34374165533cSJose E. Roman    Output Parameter:
34380910c330SBarry Smith .  U - state at given time
3439cd652676SJed Brown 
3440cd652676SJed Brown    Level: intermediate
3441cd652676SJed Brown 
3442cd652676SJed Brown    Developer Notes:
3443cd652676SJed Brown    TSInterpolate() and the storing of previous steps/stages should be generalized to support delay differential equations and continuous adjoints.
3444cd652676SJed Brown 
3445db781477SPatrick Sanan .seealso: `TSSetExactFinalTime()`, `TSSolve()`
3446cd652676SJed Brown @*/
34470910c330SBarry Smith PetscErrorCode TSInterpolate(TS ts,PetscReal t,Vec U)
3448cd652676SJed Brown {
3449cd652676SJed Brown   PetscFunctionBegin;
3450cd652676SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3451b06615a5SLisandro Dalcin   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
345263a3b9bcSJacob 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);
34533c633725SBarry Smith   PetscCheck(ts->ops->interpolate,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"%s does not provide interpolation",((PetscObject)ts)->type_name);
34549566063dSJacob Faibussowitsch   PetscCall((*ts->ops->interpolate)(ts,t,U));
3455cd652676SJed Brown   PetscFunctionReturn(0);
3456cd652676SJed Brown }
3457cd652676SJed Brown 
3458d763cef2SBarry Smith /*@
34596d9e5789SSean Farley    TSStep - Steps one time step
3460d763cef2SBarry Smith 
3461d763cef2SBarry Smith    Collective on TS
3462d763cef2SBarry Smith 
3463d763cef2SBarry Smith    Input Parameter:
3464d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
3465d763cef2SBarry Smith 
346627829d71SBarry Smith    Level: developer
3467d763cef2SBarry Smith 
3468b8123daeSJed Brown    Notes:
346927829d71SBarry Smith    The public interface for the ODE/DAE solvers is TSSolve(), you should almost for sure be using that routine and not this routine.
347027829d71SBarry Smith 
3471b8123daeSJed Brown    The hook set using TSSetPreStep() is called before each attempt to take the step. In general, the time step size may
3472b8123daeSJed Brown    be changed due to adaptive error controller or solve failures. Note that steps may contain multiple stages.
3473b8123daeSJed Brown 
347419eac22cSLisandro Dalcin    This may over-step the final time provided in TSSetMaxTime() depending on the time-step used. TSSolve() interpolates to exactly the
347519eac22cSLisandro Dalcin    time provided in TSSetMaxTime(). One can use TSInterpolate() to determine an interpolated solution within the final timestep.
347625cb2221SBarry Smith 
3477db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSSetPostStage()`, `TSInterpolate()`
3478d763cef2SBarry Smith @*/
3479193ac0bcSJed Brown PetscErrorCode  TSStep(TS ts)
3480d763cef2SBarry Smith {
3481fffbeea8SBarry Smith   static PetscBool cite = PETSC_FALSE;
3482be5899b3SLisandro Dalcin   PetscReal        ptime;
3483d763cef2SBarry Smith 
3484d763cef2SBarry Smith   PetscFunctionBegin;
34850700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3486d0609cedSBarry Smith   PetscCall(PetscCitationsRegister("@article{tspaper,\n"
3487fffbeea8SBarry Smith                                    "  title         = {{PETSc/TS}: A Modern Scalable {DAE/ODE} Solver Library},\n"
3488f1d62c27SHong Zhang                                    "  author        = {Abhyankar, Shrirang and Brown, Jed and Constantinescu, Emil and Ghosh, Debojyoti and Smith, Barry F. and Zhang, Hong},\n"
3489f1d62c27SHong Zhang                                    "  journal       = {arXiv e-preprints},\n"
3490f1d62c27SHong Zhang                                    "  eprint        = {1806.01437},\n"
3491f1d62c27SHong Zhang                                    "  archivePrefix = {arXiv},\n"
3492d0609cedSBarry Smith                                    "  year          = {2018}\n}\n",&cite));
34939566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
34949566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory,ts));
3495d405a339SMatthew Knepley 
34963c633725SBarry Smith   PetscCheck(ts->ops->step,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSStep not implemented for type '%s'",((PetscObject)ts)->type_name);
34973c633725SBarry 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>");
34983c633725SBarry 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()");
34993c633725SBarry 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");
3500a6772fa2SLisandro Dalcin 
3501be5899b3SLisandro Dalcin   if (!ts->steps) ts->ptime_prev = ts->ptime;
3502be5899b3SLisandro Dalcin   ptime = ts->ptime; ts->ptime_prev_rollback = ts->ptime_prev;
35032808aa04SLisandro Dalcin   ts->reason = TS_CONVERGED_ITERATING;
3504fc8dbba5SLisandro Dalcin 
35059566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(TS_Step,ts,0,0,0));
35069566063dSJacob Faibussowitsch   PetscCall((*ts->ops->step)(ts));
35079566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(TS_Step,ts,0,0,0));
3508fc8dbba5SLisandro Dalcin 
3509fc8dbba5SLisandro Dalcin   if (ts->reason >= 0) {
3510be5899b3SLisandro Dalcin     ts->ptime_prev = ptime;
35112808aa04SLisandro Dalcin     ts->steps++;
3512be5899b3SLisandro Dalcin     ts->steprollback = PETSC_FALSE;
351328d5b5d6SLisandro Dalcin     ts->steprestart  = PETSC_FALSE;
3514e1db57b0SHong Zhang     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) PetscCall(VecCopy(ts->vec_sol,ts->tspan->vecs_sol[ts->tspan->spanctr++]));
3515d2daff3dSHong Zhang   }
3516fc8dbba5SLisandro Dalcin 
3517fc8dbba5SLisandro Dalcin   if (!ts->reason) {
351808c7845fSBarry Smith     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
351908c7845fSBarry Smith     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
352008c7845fSBarry Smith   }
3521fc8dbba5SLisandro Dalcin 
35223c633725SBarry 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]);
35233c633725SBarry Smith   PetscCheck(ts->reason >= 0 || !ts->errorifstepfailed,PetscObjectComm((PetscObject)ts),PETSC_ERR_NOT_CONVERGED,"TSStep has failed due to %s",TSConvergedReasons[ts->reason]);
352408c7845fSBarry Smith   PetscFunctionReturn(0);
352508c7845fSBarry Smith }
352608c7845fSBarry Smith 
352708c7845fSBarry Smith /*@
35287cbde773SLisandro Dalcin    TSEvaluateWLTE - Evaluate the weighted local truncation error norm
35297cbde773SLisandro Dalcin    at the end of a time step with a given order of accuracy.
35307cbde773SLisandro Dalcin 
35317cbde773SLisandro Dalcin    Collective on TS
35327cbde773SLisandro Dalcin 
35334165533cSJose E. Roman    Input Parameters:
35347cbde773SLisandro Dalcin +  ts - time stepping context
353597bb3fdcSJose E. Roman -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
35367cbde773SLisandro Dalcin 
353797bb3fdcSJose E. Roman    Input/Output Parameter:
353897bb3fdcSJose E. Roman .  order - optional, desired order for the error evaluation or PETSC_DECIDE;
353997bb3fdcSJose E. Roman            on output, the actual order of the error evaluation
354097bb3fdcSJose E. Roman 
354197bb3fdcSJose E. Roman    Output Parameter:
354297bb3fdcSJose E. Roman .  wlte - the weighted local truncation error norm
35437cbde773SLisandro Dalcin 
35447cbde773SLisandro Dalcin    Level: advanced
35457cbde773SLisandro Dalcin 
35467cbde773SLisandro Dalcin    Notes:
35477cbde773SLisandro Dalcin    If the timestepper cannot evaluate the error in a particular step
35487cbde773SLisandro Dalcin    (eg. in the first step or restart steps after event handling),
35497cbde773SLisandro Dalcin    this routine returns wlte=-1.0 .
35507cbde773SLisandro Dalcin 
3551db781477SPatrick Sanan .seealso: `TSStep()`, `TSAdapt`, `TSErrorWeightedNorm()`
35527cbde773SLisandro Dalcin @*/
35537cbde773SLisandro Dalcin PetscErrorCode TSEvaluateWLTE(TS ts,NormType wnormtype,PetscInt *order,PetscReal *wlte)
35547cbde773SLisandro Dalcin {
35557cbde773SLisandro Dalcin   PetscFunctionBegin;
35567cbde773SLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
35577cbde773SLisandro Dalcin   PetscValidType(ts,1);
3558064a246eSJacob Faibussowitsch   PetscValidLogicalCollectiveEnum(ts,wnormtype,2);
35597cbde773SLisandro Dalcin   if (order) PetscValidIntPointer(order,3);
35607cbde773SLisandro Dalcin   if (order) PetscValidLogicalCollectiveInt(ts,*order,3);
35617cbde773SLisandro Dalcin   PetscValidRealPointer(wlte,4);
35623c633725SBarry Smith   PetscCheck(wnormtype == NORM_2 || wnormtype == NORM_INFINITY,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
35633c633725SBarry Smith   PetscCheck(ts->ops->evaluatewlte,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateWLTE not implemented for type '%s'",((PetscObject)ts)->type_name);
35649566063dSJacob Faibussowitsch   PetscCall((*ts->ops->evaluatewlte)(ts,wnormtype,order,wlte));
35657cbde773SLisandro Dalcin   PetscFunctionReturn(0);
35667cbde773SLisandro Dalcin }
35677cbde773SLisandro Dalcin 
356805175c85SJed Brown /*@
356905175c85SJed Brown    TSEvaluateStep - Evaluate the solution at the end of a time step with a given order of accuracy.
357005175c85SJed Brown 
35711c3436cfSJed Brown    Collective on TS
357205175c85SJed Brown 
35734165533cSJose E. Roman    Input Parameters:
35741c3436cfSJed Brown +  ts - time stepping context
35751c3436cfSJed Brown .  order - desired order of accuracy
35760298fd71SBarry Smith -  done - whether the step was evaluated at this order (pass NULL to generate an error if not available)
357705175c85SJed Brown 
35784165533cSJose E. Roman    Output Parameter:
35790910c330SBarry Smith .  U - state at the end of the current step
358005175c85SJed Brown 
358105175c85SJed Brown    Level: advanced
358205175c85SJed Brown 
3583108c343cSJed Brown    Notes:
3584108c343cSJed Brown    This function cannot be called until all stages have been evaluated.
3585108c343cSJed 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.
3586108c343cSJed Brown 
3587db781477SPatrick Sanan .seealso: `TSStep()`, `TSAdapt`
358805175c85SJed Brown @*/
35890910c330SBarry Smith PetscErrorCode TSEvaluateStep(TS ts,PetscInt order,Vec U,PetscBool *done)
359005175c85SJed Brown {
359105175c85SJed Brown   PetscFunctionBegin;
359205175c85SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
359305175c85SJed Brown   PetscValidType(ts,1);
35940910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
35953c633725SBarry Smith   PetscCheck(ts->ops->evaluatestep,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSEvaluateStep not implemented for type '%s'",((PetscObject)ts)->type_name);
35969566063dSJacob Faibussowitsch   PetscCall((*ts->ops->evaluatestep)(ts,order,U,done));
359705175c85SJed Brown   PetscFunctionReturn(0);
359805175c85SJed Brown }
359905175c85SJed Brown 
3600aad739acSMatthew G. Knepley /*@C
36012e61be88SMatthew G. Knepley   TSGetComputeInitialCondition - Get the function used to automatically compute an initial condition for the timestepping.
3602aad739acSMatthew G. Knepley 
3603aad739acSMatthew G. Knepley   Not collective
3604aad739acSMatthew G. Knepley 
36054165533cSJose E. Roman   Input Parameter:
3606aad739acSMatthew G. Knepley . ts        - time stepping context
3607aad739acSMatthew G. Knepley 
36084165533cSJose E. Roman   Output Parameter:
36092e61be88SMatthew G. Knepley . initConditions - The function which computes an initial condition
3610aad739acSMatthew G. Knepley 
3611aad739acSMatthew G. Knepley    Level: advanced
3612aad739acSMatthew G. Knepley 
3613aad739acSMatthew G. Knepley    Notes:
3614aad739acSMatthew G. Knepley    The calling sequence for the function is
36152e61be88SMatthew G. Knepley $ initCondition(TS ts, Vec u)
3616aad739acSMatthew G. Knepley $ ts - The timestepping context
36172e61be88SMatthew G. Knepley $ u  - The input vector in which the initial condition is stored
3618aad739acSMatthew G. Knepley 
3619db781477SPatrick Sanan .seealso: `TSSetComputeInitialCondition()`, `TSComputeInitialCondition()`
3620aad739acSMatthew G. Knepley @*/
36212e61be88SMatthew G. Knepley PetscErrorCode TSGetComputeInitialCondition(TS ts, PetscErrorCode (**initCondition)(TS, Vec))
3622aad739acSMatthew G. Knepley {
3623aad739acSMatthew G. Knepley   PetscFunctionBegin;
3624aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
36252e61be88SMatthew G. Knepley   PetscValidPointer(initCondition, 2);
36262e61be88SMatthew G. Knepley   *initCondition = ts->ops->initcondition;
3627aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3628aad739acSMatthew G. Knepley }
3629aad739acSMatthew G. Knepley 
3630aad739acSMatthew G. Knepley /*@C
36312e61be88SMatthew G. Knepley   TSSetComputeInitialCondition - Set the function used to automatically compute an initial condition for the timestepping.
3632aad739acSMatthew G. Knepley 
3633aad739acSMatthew G. Knepley   Logically collective on ts
3634aad739acSMatthew G. Knepley 
36354165533cSJose E. Roman   Input Parameters:
3636aad739acSMatthew G. Knepley + ts        - time stepping context
36372e61be88SMatthew G. Knepley - initCondition - The function which computes an initial condition
3638aad739acSMatthew G. Knepley 
3639aad739acSMatthew G. Knepley   Level: advanced
3640aad739acSMatthew G. Knepley 
3641a96d6ef6SBarry Smith   Calling sequence for initCondition:
3642a96d6ef6SBarry Smith $ PetscErrorCode initCondition(TS ts, Vec u)
3643a96d6ef6SBarry Smith 
3644a96d6ef6SBarry Smith + ts - The timestepping context
3645a96d6ef6SBarry Smith - u  - The input vector in which the initial condition is to be stored
3646aad739acSMatthew G. Knepley 
3647db781477SPatrick Sanan .seealso: `TSGetComputeInitialCondition()`, `TSComputeInitialCondition()`
3648aad739acSMatthew G. Knepley @*/
36492e61be88SMatthew G. Knepley PetscErrorCode TSSetComputeInitialCondition(TS ts, PetscErrorCode (*initCondition)(TS, Vec))
3650aad739acSMatthew G. Knepley {
3651aad739acSMatthew G. Knepley   PetscFunctionBegin;
3652aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
36532e61be88SMatthew G. Knepley   PetscValidFunction(initCondition, 2);
36542e61be88SMatthew G. Knepley   ts->ops->initcondition = initCondition;
3655aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3656aad739acSMatthew G. Knepley }
3657aad739acSMatthew G. Knepley 
3658aad739acSMatthew G. Knepley /*@
36592e61be88SMatthew G. Knepley   TSComputeInitialCondition - Compute an initial condition for the timestepping using the function previously set.
3660aad739acSMatthew G. Knepley 
3661aad739acSMatthew G. Knepley   Collective on ts
3662aad739acSMatthew G. Knepley 
36634165533cSJose E. Roman   Input Parameters:
3664aad739acSMatthew G. Knepley + ts - time stepping context
36652e61be88SMatthew G. Knepley - u  - The Vec to store the condition in which will be used in TSSolve()
3666aad739acSMatthew G. Knepley 
3667aad739acSMatthew G. Knepley   Level: advanced
3668aad739acSMatthew G. Knepley 
3669db781477SPatrick Sanan .seealso: `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3670aad739acSMatthew G. Knepley @*/
36712e61be88SMatthew G. Knepley PetscErrorCode TSComputeInitialCondition(TS ts, Vec u)
3672aad739acSMatthew G. Knepley {
3673aad739acSMatthew G. Knepley   PetscFunctionBegin;
3674aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3675aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
36769566063dSJacob Faibussowitsch   if (ts->ops->initcondition) PetscCall((*ts->ops->initcondition)(ts, u));
3677aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3678aad739acSMatthew G. Knepley }
3679aad739acSMatthew G. Knepley 
3680aad739acSMatthew G. Knepley /*@C
3681aad739acSMatthew G. Knepley   TSGetComputeExactError - Get the function used to automatically compute the exact error for the timestepping.
3682aad739acSMatthew G. Knepley 
3683aad739acSMatthew G. Knepley   Not collective
3684aad739acSMatthew G. Knepley 
36854165533cSJose E. Roman   Input Parameter:
3686aad739acSMatthew G. Knepley . ts         - time stepping context
3687aad739acSMatthew G. Knepley 
36884165533cSJose E. Roman   Output Parameter:
3689aad739acSMatthew G. Knepley . exactError - The function which computes the solution error
3690aad739acSMatthew G. Knepley 
3691aad739acSMatthew G. Knepley   Level: advanced
3692aad739acSMatthew G. Knepley 
3693a96d6ef6SBarry Smith   Calling sequence for exactError:
3694a96d6ef6SBarry Smith $ PetscErrorCode exactError(TS ts, Vec u)
3695a96d6ef6SBarry Smith 
3696a96d6ef6SBarry Smith + ts - The timestepping context
3697a96d6ef6SBarry Smith . u  - The approximate solution vector
3698a96d6ef6SBarry Smith - e  - The input vector in which the error is stored
3699aad739acSMatthew G. Knepley 
3700db781477SPatrick Sanan .seealso: `TSGetComputeExactError()`, `TSComputeExactError()`
3701aad739acSMatthew G. Knepley @*/
3702aad739acSMatthew G. Knepley PetscErrorCode TSGetComputeExactError(TS ts, PetscErrorCode (**exactError)(TS, Vec, Vec))
3703aad739acSMatthew G. Knepley {
3704aad739acSMatthew G. Knepley   PetscFunctionBegin;
3705aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3706aad739acSMatthew G. Knepley   PetscValidPointer(exactError, 2);
3707aad739acSMatthew G. Knepley   *exactError = ts->ops->exacterror;
3708aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3709aad739acSMatthew G. Knepley }
3710aad739acSMatthew G. Knepley 
3711aad739acSMatthew G. Knepley /*@C
3712aad739acSMatthew G. Knepley   TSSetComputeExactError - Set the function used to automatically compute the exact error for the timestepping.
3713aad739acSMatthew G. Knepley 
3714aad739acSMatthew G. Knepley   Logically collective on ts
3715aad739acSMatthew G. Knepley 
37164165533cSJose E. Roman   Input Parameters:
3717aad739acSMatthew G. Knepley + ts         - time stepping context
3718aad739acSMatthew G. Knepley - exactError - The function which computes the solution error
3719aad739acSMatthew G. Knepley 
3720aad739acSMatthew G. Knepley   Level: advanced
3721aad739acSMatthew G. Knepley 
3722a96d6ef6SBarry Smith   Calling sequence for exactError:
3723a96d6ef6SBarry Smith $ PetscErrorCode exactError(TS ts, Vec u)
3724a96d6ef6SBarry Smith 
3725a96d6ef6SBarry Smith + ts - The timestepping context
3726a96d6ef6SBarry Smith . u  - The approximate solution vector
3727a96d6ef6SBarry Smith - e  - The input vector in which the error is stored
3728aad739acSMatthew G. Knepley 
3729db781477SPatrick Sanan .seealso: `TSGetComputeExactError()`, `TSComputeExactError()`
3730aad739acSMatthew G. Knepley @*/
3731aad739acSMatthew G. Knepley PetscErrorCode TSSetComputeExactError(TS ts, PetscErrorCode (*exactError)(TS, Vec, Vec))
3732aad739acSMatthew G. Knepley {
3733aad739acSMatthew G. Knepley   PetscFunctionBegin;
3734aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3735f907fdbfSMatthew G. Knepley   PetscValidFunction(exactError, 2);
3736aad739acSMatthew G. Knepley   ts->ops->exacterror = exactError;
3737aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3738aad739acSMatthew G. Knepley }
3739aad739acSMatthew G. Knepley 
3740aad739acSMatthew G. Knepley /*@
3741aad739acSMatthew G. Knepley   TSComputeExactError - Compute the solution error for the timestepping using the function previously set.
3742aad739acSMatthew G. Knepley 
3743aad739acSMatthew G. Knepley   Collective on ts
3744aad739acSMatthew G. Knepley 
37454165533cSJose E. Roman   Input Parameters:
3746aad739acSMatthew G. Knepley + ts - time stepping context
3747aad739acSMatthew G. Knepley . u  - The approximate solution
3748aad739acSMatthew G. Knepley - e  - The Vec used to store the error
3749aad739acSMatthew G. Knepley 
3750aad739acSMatthew G. Knepley   Level: advanced
3751aad739acSMatthew G. Knepley 
3752db781477SPatrick Sanan .seealso: `TSGetComputeInitialCondition()`, `TSSetComputeInitialCondition()`, `TSSolve()`
3753aad739acSMatthew G. Knepley @*/
3754aad739acSMatthew G. Knepley PetscErrorCode TSComputeExactError(TS ts, Vec u, Vec e)
3755aad739acSMatthew G. Knepley {
3756aad739acSMatthew G. Knepley   PetscFunctionBegin;
3757aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(ts, TS_CLASSID, 1);
3758aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
3759aad739acSMatthew G. Knepley   PetscValidHeaderSpecific(e, VEC_CLASSID, 3);
37609566063dSJacob Faibussowitsch   if (ts->ops->exacterror) PetscCall((*ts->ops->exacterror)(ts, u, e));
3761aad739acSMatthew G. Knepley   PetscFunctionReturn(0);
3762aad739acSMatthew G. Knepley }
3763aad739acSMatthew G. Knepley 
3764b1cb36f3SHong Zhang /*@
37656a4d4014SLisandro Dalcin    TSSolve - Steps the requested number of timesteps.
37666a4d4014SLisandro Dalcin 
37676a4d4014SLisandro Dalcin    Collective on TS
37686a4d4014SLisandro Dalcin 
3769d8d19677SJose E. Roman    Input Parameters:
37706a4d4014SLisandro Dalcin +  ts - the TS context obtained from TSCreate()
377163e21af5SBarry Smith -  u - the solution vector  (can be null if TSSetSolution() was used and TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP) was not used,
377263e21af5SBarry Smith                              otherwise must contain the initial conditions and will contain the solution at the final requested time
37735a3a76d0SJed Brown 
37746a4d4014SLisandro Dalcin    Level: beginner
37756a4d4014SLisandro Dalcin 
37765a3a76d0SJed Brown    Notes:
37775a3a76d0SJed Brown    The final time returned by this function may be different from the time of the internally
37785a3a76d0SJed Brown    held state accessible by TSGetSolution() and TSGetTime() because the method may have
37795a3a76d0SJed Brown    stepped over the final time.
37805a3a76d0SJed Brown 
3781db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetSolution()`, `TSStep()`, `TSGetTime()`, `TSGetSolveTime()`
37826a4d4014SLisandro Dalcin @*/
3783cc708dedSBarry Smith PetscErrorCode TSSolve(TS ts,Vec u)
37846a4d4014SLisandro Dalcin {
3785b06615a5SLisandro Dalcin   Vec               solution;
3786f22f69f0SBarry Smith 
37876a4d4014SLisandro Dalcin   PetscFunctionBegin;
37880700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3789f2c2a1b9SBarry Smith   if (u) PetscValidHeaderSpecific(u,VEC_CLASSID,2);
3790303a5415SBarry Smith 
37919566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTimeDefault(ts));
3792ee41a567SStefano 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 */
37930910c330SBarry Smith     if (!ts->vec_sol || u == ts->vec_sol) {
37949566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(u,&solution));
37959566063dSJacob Faibussowitsch       PetscCall(TSSetSolution(ts,solution));
37969566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&solution)); /* grant ownership */
37975a3a76d0SJed Brown     }
37989566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,ts->vec_sol));
37993c633725SBarry Smith     PetscCheck(!ts->forward_solve,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Sensitivity analysis does not support the mode TS_EXACTFINALTIME_INTERPOLATE");
38001baa6e33SBarry Smith   } else if (u) PetscCall(TSSetSolution(ts,u));
38019566063dSJacob Faibussowitsch   PetscCall(TSSetUp(ts));
38029566063dSJacob Faibussowitsch   PetscCall(TSTrajectorySetUp(ts->trajectory,ts));
3803a6772fa2SLisandro Dalcin 
38043c633725SBarry 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>");
38053c633725SBarry 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()");
38063c633725SBarry 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");
38074a658b32SHong 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");
38084a658b32SHong Zhang 
3809e1db57b0SHong 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 */
38104a658b32SHong Zhang     PetscCall(VecCopy(ts->vec_sol,ts->tspan->vecs_sol[0]));
38114a658b32SHong Zhang     ts->tspan->spanctr = 1;
38124a658b32SHong Zhang   }
3813a6772fa2SLisandro Dalcin 
38141baa6e33SBarry Smith   if (ts->forward_solve) PetscCall(TSForwardSetUp(ts));
3815715f1b00SHong Zhang 
3816e7069c78SShri   /* reset number of steps only when the step is not restarted. ARKIMEX
3817715f1b00SHong Zhang      restarts the step after an event. Resetting these counters in such case causes
3818e7069c78SShri      TSTrajectory to incorrectly save the output files
3819e7069c78SShri   */
3820715f1b00SHong Zhang   /* reset time step and iteration counters */
38212808aa04SLisandro Dalcin   if (!ts->steps) {
38225ef26d82SJed Brown     ts->ksp_its           = 0;
38235ef26d82SJed Brown     ts->snes_its          = 0;
3824c610991cSLisandro Dalcin     ts->num_snes_failures = 0;
3825c610991cSLisandro Dalcin     ts->reject            = 0;
38262808aa04SLisandro Dalcin     ts->steprestart       = PETSC_TRUE;
38272808aa04SLisandro Dalcin     ts->steprollback      = PETSC_FALSE;
38287d51462cSStefano Zampini     ts->rhsjacobian.time  = PETSC_MIN_REAL;
38292808aa04SLisandro Dalcin   }
3830e97c63d7SStefano Zampini 
38314a658b32SHong Zhang   /* make sure initial time step does not overshoot final time or the next point in tspan */
3832e97c63d7SStefano Zampini   if (ts->exact_final_time == TS_EXACTFINALTIME_MATCHSTEP) {
38334a658b32SHong Zhang     PetscReal maxdt;
3834e97c63d7SStefano Zampini     PetscReal dt = ts->time_step;
3835e97c63d7SStefano Zampini 
38364a658b32SHong Zhang     if (ts->tspan) maxdt = ts->tspan->span_times[ts->tspan->spanctr] - ts->ptime;
38374a658b32SHong Zhang     else maxdt = ts->max_time - ts->ptime;
3838e97c63d7SStefano Zampini     ts->time_step = dt >= maxdt ? maxdt : (PetscIsCloseAtTol(dt,maxdt,10*PETSC_MACHINE_EPSILON,0) ? maxdt : dt);
3839e97c63d7SStefano Zampini   }
3840193ac0bcSJed Brown   ts->reason = TS_CONVERGED_ITERATING;
3841193ac0bcSJed Brown 
3842900f6b5bSMatthew G. Knepley   {
3843900f6b5bSMatthew G. Knepley     PetscViewer       viewer;
3844900f6b5bSMatthew G. Knepley     PetscViewerFormat format;
3845900f6b5bSMatthew G. Knepley     PetscBool         flg;
3846900f6b5bSMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
3847900f6b5bSMatthew G. Knepley 
3848900f6b5bSMatthew G. Knepley     if (!incall) {
3849900f6b5bSMatthew G. Knepley       /* Estimate the convergence rate of the time discretization */
38509566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject) ts),((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_estimate", &viewer, &format, &flg));
3851900f6b5bSMatthew G. Knepley       if (flg) {
3852900f6b5bSMatthew G. Knepley         PetscConvEst conv;
3853900f6b5bSMatthew G. Knepley         DM           dm;
3854900f6b5bSMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
3855900f6b5bSMatthew G. Knepley         PetscInt     Nf;
3856f2ed2dc7SMatthew G. Knepley         PetscBool    checkTemporal = PETSC_TRUE;
3857900f6b5bSMatthew G. Knepley 
3858900f6b5bSMatthew G. Knepley         incall = PETSC_TRUE;
38599566063dSJacob Faibussowitsch         PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options, ((PetscObject) ts)->prefix, "-ts_convergence_temporal", &checkTemporal, &flg));
38609566063dSJacob Faibussowitsch         PetscCall(TSGetDM(ts, &dm));
38619566063dSJacob Faibussowitsch         PetscCall(DMGetNumFields(dm, &Nf));
38629566063dSJacob Faibussowitsch         PetscCall(PetscCalloc1(PetscMax(Nf, 1), &alpha));
38639566063dSJacob Faibussowitsch         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject) ts), &conv));
38649566063dSJacob Faibussowitsch         PetscCall(PetscConvEstUseTS(conv, checkTemporal));
38659566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetSolver(conv, (PetscObject) ts));
38669566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetFromOptions(conv));
38679566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetUp(conv));
38689566063dSJacob Faibussowitsch         PetscCall(PetscConvEstGetConvRate(conv, alpha));
38699566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(viewer, format));
38709566063dSJacob Faibussowitsch         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
38719566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(viewer));
38729566063dSJacob Faibussowitsch         PetscCall(PetscViewerDestroy(&viewer));
38739566063dSJacob Faibussowitsch         PetscCall(PetscConvEstDestroy(&conv));
38749566063dSJacob Faibussowitsch         PetscCall(PetscFree(alpha));
3875900f6b5bSMatthew G. Knepley         incall = PETSC_FALSE;
3876900f6b5bSMatthew G. Knepley       }
3877900f6b5bSMatthew G. Knepley     }
3878900f6b5bSMatthew G. Knepley   }
3879900f6b5bSMatthew G. Knepley 
38809566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts,NULL,"-ts_view_pre"));
3881f05ece33SBarry Smith 
3882193ac0bcSJed Brown   if (ts->ops->solve) { /* This private interface is transitional and should be removed when all implementations are updated. */
38839566063dSJacob Faibussowitsch     PetscCall((*ts->ops->solve)(ts));
38849566063dSJacob Faibussowitsch     if (u) PetscCall(VecCopy(ts->vec_sol,u));
3885cc708dedSBarry Smith     ts->solvetime = ts->ptime;
3886a6772fa2SLisandro Dalcin     solution = ts->vec_sol;
3887be5899b3SLisandro Dalcin   } else { /* Step the requested number of timesteps. */
3888db4deed7SKarl Rupp     if (ts->steps >= ts->max_steps) ts->reason = TS_CONVERGED_ITS;
3889db4deed7SKarl Rupp     else if (ts->ptime >= ts->max_time) ts->reason = TS_CONVERGED_TIME;
3890e7069c78SShri 
38912808aa04SLisandro Dalcin     if (!ts->steps) {
38929566063dSJacob Faibussowitsch       PetscCall(TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol));
38939566063dSJacob Faibussowitsch       PetscCall(TSEventInitialize(ts->event,ts,ts->ptime,ts->vec_sol));
38942808aa04SLisandro Dalcin     }
38956427ac75SLisandro Dalcin 
3896e1a7a14fSJed Brown     while (!ts->reason) {
38979566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol));
38989687d888SLisandro Dalcin       if (!ts->steprollback) {
38999566063dSJacob Faibussowitsch         PetscCall(TSPreStep(ts));
39009687d888SLisandro Dalcin       }
39019566063dSJacob Faibussowitsch       PetscCall(TSStep(ts));
39021baa6e33SBarry Smith       if (ts->testjacobian) PetscCall(TSRHSJacobianTest(ts,NULL));
39031baa6e33SBarry Smith       if (ts->testjacobiantranspose) PetscCall(TSRHSJacobianTestTranspose(ts,NULL));
3904cd4cee2dSHong Zhang       if (ts->quadraturets && ts->costintegralfwd) { /* Must evaluate the cost integral before event is handled. The cost integral value can also be rolled back. */
39057b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */
39069566063dSJacob Faibussowitsch         PetscCall(TSForwardCostIntegral(ts));
39077b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
3908b1cb36f3SHong Zhang       }
390958818c2dSLisandro Dalcin       if (ts->forward_solve) { /* compute forward sensitivities before event handling because postevent() may change RHS and jump conditions may have to be applied */
39107b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps--; /* Revert the step number changed by TSStep() */
39119566063dSJacob Faibussowitsch         PetscCall(TSForwardStep(ts));
39127b0e2f17SHong Zhang         if (ts->reason >= 0) ts->steps++;
3913715f1b00SHong Zhang       }
39149566063dSJacob Faibussowitsch       PetscCall(TSPostEvaluate(ts));
39159566063dSJacob 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. */
39161baa6e33SBarry Smith       if (ts->steprollback) PetscCall(TSPostEvaluate(ts));
3917e783b05fSHong Zhang       if (!ts->steprollback) {
39189566063dSJacob Faibussowitsch         PetscCall(TSTrajectorySet(ts->trajectory,ts,ts->steps,ts->ptime,ts->vec_sol));
39199566063dSJacob Faibussowitsch         PetscCall(TSPostStep(ts));
3920aeb4809dSShri Abhyankar       }
3921193ac0bcSJed Brown     }
39229566063dSJacob Faibussowitsch     PetscCall(TSMonitor(ts,ts->steps,ts->ptime,ts->vec_sol));
39236427ac75SLisandro Dalcin 
392449354f04SShri Abhyankar     if (ts->exact_final_time == TS_EXACTFINALTIME_INTERPOLATE && ts->ptime > ts->max_time) {
39259566063dSJacob Faibussowitsch       PetscCall(TSInterpolate(ts,ts->max_time,u));
3926cc708dedSBarry Smith       ts->solvetime = ts->max_time;
3927b06615a5SLisandro Dalcin       solution = u;
39289566063dSJacob Faibussowitsch       PetscCall(TSMonitor(ts,-1,ts->solvetime,solution));
39290574a7fbSJed Brown     } else {
39309566063dSJacob Faibussowitsch       if (u) PetscCall(VecCopy(ts->vec_sol,u));
3931cc708dedSBarry Smith       ts->solvetime = ts->ptime;
3932b06615a5SLisandro Dalcin       solution = ts->vec_sol;
39330574a7fbSJed Brown     }
3934193ac0bcSJed Brown   }
3935d2daff3dSHong Zhang 
39369566063dSJacob Faibussowitsch   PetscCall(TSViewFromOptions(ts,NULL,"-ts_view"));
39379566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(solution,(PetscObject)ts,"-ts_view_solution"));
39389566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsBlock((PetscObject)ts));
39391baa6e33SBarry Smith   if (ts->adjoint_solve) PetscCall(TSAdjointSolve(ts));
39406a4d4014SLisandro Dalcin   PetscFunctionReturn(0);
39416a4d4014SLisandro Dalcin }
39426a4d4014SLisandro Dalcin 
3943d763cef2SBarry Smith /*@
3944b8123daeSJed Brown    TSGetTime - Gets the time of the most recently completed step.
3945d763cef2SBarry Smith 
3946d763cef2SBarry Smith    Not Collective
3947d763cef2SBarry Smith 
3948d763cef2SBarry Smith    Input Parameter:
3949d763cef2SBarry Smith .  ts - the TS context obtained from TSCreate()
3950d763cef2SBarry Smith 
3951d763cef2SBarry Smith    Output Parameter:
395219eac22cSLisandro Dalcin .  t  - the current time. This time may not corresponds to the final time set with TSSetMaxTime(), use TSGetSolveTime().
3953d763cef2SBarry Smith 
3954d763cef2SBarry Smith    Level: beginner
3955d763cef2SBarry Smith 
3956b8123daeSJed Brown    Note:
3957b8123daeSJed Brown    When called during time step evaluation (e.g. during residual evaluation or via hooks set using TSSetPreStep(),
39589be3e283SDebojyoti Ghosh    TSSetPreStage(), TSSetPostStage(), or TSSetPostStep()), the time is the time at the start of the step being evaluated.
3959b8123daeSJed Brown 
3960db781477SPatrick Sanan .seealso: `TSGetSolveTime()`, `TSSetTime()`, `TSGetTimeStep()`, `TSGetStepNumber()`
3961d763cef2SBarry Smith 
3962d763cef2SBarry Smith @*/
39637087cfbeSBarry Smith PetscErrorCode  TSGetTime(TS ts,PetscReal *t)
3964d763cef2SBarry Smith {
3965d763cef2SBarry Smith   PetscFunctionBegin;
39660700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3967f7cf8827SBarry Smith   PetscValidRealPointer(t,2);
3968d763cef2SBarry Smith   *t = ts->ptime;
3969d763cef2SBarry Smith   PetscFunctionReturn(0);
3970d763cef2SBarry Smith }
3971d763cef2SBarry Smith 
3972e5e524a1SHong Zhang /*@
3973e5e524a1SHong Zhang    TSGetPrevTime - Gets the starting time of the previously completed step.
3974e5e524a1SHong Zhang 
3975e5e524a1SHong Zhang    Not Collective
3976e5e524a1SHong Zhang 
3977e5e524a1SHong Zhang    Input Parameter:
3978e5e524a1SHong Zhang .  ts - the TS context obtained from TSCreate()
3979e5e524a1SHong Zhang 
3980e5e524a1SHong Zhang    Output Parameter:
3981e5e524a1SHong Zhang .  t  - the previous time
3982e5e524a1SHong Zhang 
3983e5e524a1SHong Zhang    Level: beginner
3984e5e524a1SHong Zhang 
3985db781477SPatrick Sanan .seealso: `TSGetTime()`, `TSGetSolveTime()`, `TSGetTimeStep()`
3986e5e524a1SHong Zhang 
3987e5e524a1SHong Zhang @*/
3988e5e524a1SHong Zhang PetscErrorCode  TSGetPrevTime(TS ts,PetscReal *t)
3989e5e524a1SHong Zhang {
3990e5e524a1SHong Zhang   PetscFunctionBegin;
3991e5e524a1SHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
3992e5e524a1SHong Zhang   PetscValidRealPointer(t,2);
3993e5e524a1SHong Zhang   *t = ts->ptime_prev;
3994e5e524a1SHong Zhang   PetscFunctionReturn(0);
3995e5e524a1SHong Zhang }
3996e5e524a1SHong Zhang 
39976a4d4014SLisandro Dalcin /*@
39986a4d4014SLisandro Dalcin    TSSetTime - Allows one to reset the time.
39996a4d4014SLisandro Dalcin 
40003f9fe445SBarry Smith    Logically Collective on TS
40016a4d4014SLisandro Dalcin 
40026a4d4014SLisandro Dalcin    Input Parameters:
40036a4d4014SLisandro Dalcin +  ts - the TS context obtained from TSCreate()
40046a4d4014SLisandro Dalcin -  time - the time
40056a4d4014SLisandro Dalcin 
40066a4d4014SLisandro Dalcin    Level: intermediate
40076a4d4014SLisandro Dalcin 
4008db781477SPatrick Sanan .seealso: `TSGetTime()`, `TSSetMaxSteps()`
40096a4d4014SLisandro Dalcin 
40106a4d4014SLisandro Dalcin @*/
40117087cfbeSBarry Smith PetscErrorCode  TSSetTime(TS ts, PetscReal t)
40126a4d4014SLisandro Dalcin {
40136a4d4014SLisandro Dalcin   PetscFunctionBegin;
40140700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4015c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(ts,t,2);
40166a4d4014SLisandro Dalcin   ts->ptime = t;
40176a4d4014SLisandro Dalcin   PetscFunctionReturn(0);
40186a4d4014SLisandro Dalcin }
40196a4d4014SLisandro Dalcin 
4020d763cef2SBarry Smith /*@C
4021d763cef2SBarry Smith    TSSetOptionsPrefix - Sets the prefix used for searching for all
4022d763cef2SBarry Smith    TS options in the database.
4023d763cef2SBarry Smith 
40243f9fe445SBarry Smith    Logically Collective on TS
4025d763cef2SBarry Smith 
4026d8d19677SJose E. Roman    Input Parameters:
4027d763cef2SBarry Smith +  ts     - The TS context
4028d763cef2SBarry Smith -  prefix - The prefix to prepend to all option names
4029d763cef2SBarry Smith 
4030d763cef2SBarry Smith    Notes:
4031d763cef2SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
4032d763cef2SBarry Smith    The first character of all runtime options is AUTOMATICALLY the
4033d763cef2SBarry Smith    hyphen.
4034d763cef2SBarry Smith 
4035d763cef2SBarry Smith    Level: advanced
4036d763cef2SBarry Smith 
4037db781477SPatrick Sanan .seealso: `TSSetFromOptions()`
4038d763cef2SBarry Smith 
4039d763cef2SBarry Smith @*/
40407087cfbeSBarry Smith PetscErrorCode  TSSetOptionsPrefix(TS ts,const char prefix[])
4041d763cef2SBarry Smith {
4042089b2837SJed Brown   SNES           snes;
4043d763cef2SBarry Smith 
4044d763cef2SBarry Smith   PetscFunctionBegin;
40450700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
40469566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ts,prefix));
40479566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
40489566063dSJacob Faibussowitsch   PetscCall(SNESSetOptionsPrefix(snes,prefix));
4049d763cef2SBarry Smith   PetscFunctionReturn(0);
4050d763cef2SBarry Smith }
4051d763cef2SBarry Smith 
4052d763cef2SBarry Smith /*@C
4053d763cef2SBarry Smith    TSAppendOptionsPrefix - Appends to the prefix used for searching for all
4054d763cef2SBarry Smith    TS options in the database.
4055d763cef2SBarry Smith 
40563f9fe445SBarry Smith    Logically Collective on TS
4057d763cef2SBarry Smith 
4058d8d19677SJose E. Roman    Input Parameters:
4059d763cef2SBarry Smith +  ts     - The TS context
4060d763cef2SBarry Smith -  prefix - The prefix to prepend to all option names
4061d763cef2SBarry Smith 
4062d763cef2SBarry Smith    Notes:
4063d763cef2SBarry Smith    A hyphen (-) must NOT be given at the beginning of the prefix name.
4064d763cef2SBarry Smith    The first character of all runtime options is AUTOMATICALLY the
4065d763cef2SBarry Smith    hyphen.
4066d763cef2SBarry Smith 
4067d763cef2SBarry Smith    Level: advanced
4068d763cef2SBarry Smith 
4069db781477SPatrick Sanan .seealso: `TSGetOptionsPrefix()`
4070d763cef2SBarry Smith 
4071d763cef2SBarry Smith @*/
40727087cfbeSBarry Smith PetscErrorCode  TSAppendOptionsPrefix(TS ts,const char prefix[])
4073d763cef2SBarry Smith {
4074089b2837SJed Brown   SNES           snes;
4075d763cef2SBarry Smith 
4076d763cef2SBarry Smith   PetscFunctionBegin;
40770700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
40789566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)ts,prefix));
40799566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
40809566063dSJacob Faibussowitsch   PetscCall(SNESAppendOptionsPrefix(snes,prefix));
4081d763cef2SBarry Smith   PetscFunctionReturn(0);
4082d763cef2SBarry Smith }
4083d763cef2SBarry Smith 
4084d763cef2SBarry Smith /*@C
4085d763cef2SBarry Smith    TSGetOptionsPrefix - Sets the prefix used for searching for all
4086d763cef2SBarry Smith    TS options in the database.
4087d763cef2SBarry Smith 
4088d763cef2SBarry Smith    Not Collective
4089d763cef2SBarry Smith 
4090d763cef2SBarry Smith    Input Parameter:
4091d763cef2SBarry Smith .  ts - The TS context
4092d763cef2SBarry Smith 
4093d763cef2SBarry Smith    Output Parameter:
4094d763cef2SBarry Smith .  prefix - A pointer to the prefix string used
4095d763cef2SBarry Smith 
409695452b02SPatrick Sanan    Notes:
409795452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prifix' of
4098d763cef2SBarry Smith    sufficient length to hold the prefix.
4099d763cef2SBarry Smith 
4100d763cef2SBarry Smith    Level: intermediate
4101d763cef2SBarry Smith 
4102db781477SPatrick Sanan .seealso: `TSAppendOptionsPrefix()`
4103d763cef2SBarry Smith @*/
41047087cfbeSBarry Smith PetscErrorCode  TSGetOptionsPrefix(TS ts,const char *prefix[])
4105d763cef2SBarry Smith {
4106d763cef2SBarry Smith   PetscFunctionBegin;
41070700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
41084482741eSBarry Smith   PetscValidPointer(prefix,2);
41099566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ts,prefix));
4110d763cef2SBarry Smith   PetscFunctionReturn(0);
4111d763cef2SBarry Smith }
4112d763cef2SBarry Smith 
4113d763cef2SBarry Smith /*@C
4114d763cef2SBarry Smith    TSGetRHSJacobian - Returns the Jacobian J at the present timestep.
4115d763cef2SBarry Smith 
4116d763cef2SBarry Smith    Not Collective, but parallel objects are returned if TS is parallel
4117d763cef2SBarry Smith 
4118d763cef2SBarry Smith    Input Parameter:
4119d763cef2SBarry Smith .  ts  - The TS context obtained from TSCreate()
4120d763cef2SBarry Smith 
4121d763cef2SBarry Smith    Output Parameters:
4122e4357dc4SBarry Smith +  Amat - The (approximate) Jacobian J of G, where U_t = G(U,t)  (or NULL)
4123e4357dc4SBarry Smith .  Pmat - The matrix from which the preconditioner is constructed, usually the same as Amat  (or NULL)
4124e4357dc4SBarry Smith .  func - Function to compute the Jacobian of the RHS  (or NULL)
4125e4357dc4SBarry Smith -  ctx - User-defined context for Jacobian evaluation routine  (or NULL)
4126d763cef2SBarry Smith 
412795452b02SPatrick Sanan    Notes:
412895452b02SPatrick Sanan     You can pass in NULL for any return argument you do not need.
4129d763cef2SBarry Smith 
4130d763cef2SBarry Smith    Level: intermediate
4131d763cef2SBarry Smith 
4132db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
4133d763cef2SBarry Smith 
4134d763cef2SBarry Smith @*/
4135e4357dc4SBarry Smith PetscErrorCode  TSGetRHSJacobian(TS ts,Mat *Amat,Mat *Pmat,TSRHSJacobian *func,void **ctx)
4136d763cef2SBarry Smith {
413724989b8cSPeter Brune   DM             dm;
4138089b2837SJed Brown 
4139d763cef2SBarry Smith   PetscFunctionBegin;
414023a57915SBarry Smith   if (Amat || Pmat) {
414123a57915SBarry Smith     SNES snes;
41429566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts,&snes));
41439566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
41449566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes,Amat,Pmat,NULL,NULL));
414523a57915SBarry Smith   }
41469566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
41479566063dSJacob Faibussowitsch   PetscCall(DMTSGetRHSJacobian(dm,func,ctx));
4148d763cef2SBarry Smith   PetscFunctionReturn(0);
4149d763cef2SBarry Smith }
4150d763cef2SBarry Smith 
41512eca1d9cSJed Brown /*@C
41522eca1d9cSJed Brown    TSGetIJacobian - Returns the implicit Jacobian at the present timestep.
41532eca1d9cSJed Brown 
41542eca1d9cSJed Brown    Not Collective, but parallel objects are returned if TS is parallel
41552eca1d9cSJed Brown 
41562eca1d9cSJed Brown    Input Parameter:
41572eca1d9cSJed Brown .  ts  - The TS context obtained from TSCreate()
41582eca1d9cSJed Brown 
41592eca1d9cSJed Brown    Output Parameters:
4160e4357dc4SBarry Smith +  Amat  - The (approximate) Jacobian of F(t,U,U_t)
4161e4357dc4SBarry Smith .  Pmat - The matrix from which the preconditioner is constructed, often the same as Amat
41622eca1d9cSJed Brown .  f   - The function to compute the matrices
41632eca1d9cSJed Brown - ctx - User-defined context for Jacobian evaluation routine
41642eca1d9cSJed Brown 
416595452b02SPatrick Sanan    Notes:
416695452b02SPatrick Sanan     You can pass in NULL for any return argument you do not need.
41672eca1d9cSJed Brown 
41682eca1d9cSJed Brown    Level: advanced
41692eca1d9cSJed Brown 
4170db781477SPatrick Sanan .seealso: `TSGetTimeStep()`, `TSGetRHSJacobian()`, `TSGetMatrices()`, `TSGetTime()`, `TSGetStepNumber()`
41712eca1d9cSJed Brown 
41722eca1d9cSJed Brown @*/
4173e4357dc4SBarry Smith PetscErrorCode  TSGetIJacobian(TS ts,Mat *Amat,Mat *Pmat,TSIJacobian *f,void **ctx)
41742eca1d9cSJed Brown {
417524989b8cSPeter Brune   DM             dm;
41760910c330SBarry Smith 
41772eca1d9cSJed Brown   PetscFunctionBegin;
4178c0aab802Sstefano_zampini   if (Amat || Pmat) {
4179c0aab802Sstefano_zampini     SNES snes;
41809566063dSJacob Faibussowitsch     PetscCall(TSGetSNES(ts,&snes));
41819566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrices(snes));
41829566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes,Amat,Pmat,NULL,NULL));
4183c0aab802Sstefano_zampini   }
41849566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts,&dm));
41859566063dSJacob Faibussowitsch   PetscCall(DMTSGetIJacobian(dm,f,ctx));
41862eca1d9cSJed Brown   PetscFunctionReturn(0);
41872eca1d9cSJed Brown }
41882eca1d9cSJed Brown 
4189af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
41906c699258SBarry Smith /*@
41912a808120SBarry Smith    TSSetDM - Sets the DM that may be used by some nonlinear solvers or preconditioners under the TS
41926c699258SBarry Smith 
4193d083f849SBarry Smith    Logically Collective on ts
41946c699258SBarry Smith 
41956c699258SBarry Smith    Input Parameters:
41962a808120SBarry Smith +  ts - the ODE integrator object
41972a808120SBarry Smith -  dm - the dm, cannot be NULL
41986c699258SBarry Smith 
4199e03a659cSJed Brown    Notes:
4200e03a659cSJed Brown    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
4201e03a659cSJed Brown    even when not using interfaces like DMTSSetIFunction().  Use DMClone() to get a distinct DM when solving
4202e03a659cSJed Brown    different problems using the same function space.
4203e03a659cSJed Brown 
42046c699258SBarry Smith    Level: intermediate
42056c699258SBarry Smith 
4206db781477SPatrick Sanan .seealso: `TSGetDM()`, `SNESSetDM()`, `SNESGetDM()`
42076c699258SBarry Smith @*/
42087087cfbeSBarry Smith PetscErrorCode  TSSetDM(TS ts,DM dm)
42096c699258SBarry Smith {
4210089b2837SJed Brown   SNES           snes;
4211942e3340SBarry Smith   DMTS           tsdm;
42126c699258SBarry Smith 
42136c699258SBarry Smith   PetscFunctionBegin;
42140700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
42152a808120SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
42169566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)dm));
4217942e3340SBarry Smith   if (ts->dm) {               /* Move the DMTS context over to the new DM unless the new DM already has one */
42182a34c10cSBarry Smith     if (ts->dm->dmts && !dm->dmts) {
42199566063dSJacob Faibussowitsch       PetscCall(DMCopyDMTS(ts->dm,dm));
42209566063dSJacob Faibussowitsch       PetscCall(DMGetDMTS(ts->dm,&tsdm));
422124989b8cSPeter Brune       if (tsdm->originaldm == ts->dm) { /* Grant write privileges to the replacement DM */
422224989b8cSPeter Brune         tsdm->originaldm = dm;
422324989b8cSPeter Brune       }
422424989b8cSPeter Brune     }
42259566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&ts->dm));
422624989b8cSPeter Brune   }
42276c699258SBarry Smith   ts->dm = dm;
4228bbd56ea5SKarl Rupp 
42299566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
42309566063dSJacob Faibussowitsch   PetscCall(SNESSetDM(snes,dm));
42316c699258SBarry Smith   PetscFunctionReturn(0);
42326c699258SBarry Smith }
42336c699258SBarry Smith 
42346c699258SBarry Smith /*@
42356c699258SBarry Smith    TSGetDM - Gets the DM that may be used by some preconditioners
42366c699258SBarry Smith 
42373f9fe445SBarry Smith    Not Collective
42386c699258SBarry Smith 
42396c699258SBarry Smith    Input Parameter:
42406c699258SBarry Smith . ts - the preconditioner context
42416c699258SBarry Smith 
42426c699258SBarry Smith    Output Parameter:
42436c699258SBarry Smith .  dm - the dm
42446c699258SBarry Smith 
42456c699258SBarry Smith    Level: intermediate
42466c699258SBarry Smith 
4247db781477SPatrick Sanan .seealso: `TSSetDM()`, `SNESSetDM()`, `SNESGetDM()`
42486c699258SBarry Smith @*/
42497087cfbeSBarry Smith PetscErrorCode  TSGetDM(TS ts,DM *dm)
42506c699258SBarry Smith {
42516c699258SBarry Smith   PetscFunctionBegin;
42520700a824SBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4253496e6a7aSJed Brown   if (!ts->dm) {
42549566063dSJacob Faibussowitsch     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)ts),&ts->dm));
42559566063dSJacob Faibussowitsch     if (ts->snes) PetscCall(SNESSetDM(ts->snes,ts->dm));
4256496e6a7aSJed Brown   }
42576c699258SBarry Smith   *dm = ts->dm;
42586c699258SBarry Smith   PetscFunctionReturn(0);
42596c699258SBarry Smith }
42601713a123SBarry Smith 
42610f5c6efeSJed Brown /*@
42620f5c6efeSJed Brown    SNESTSFormFunction - Function to evaluate nonlinear residual
42630f5c6efeSJed Brown 
42643f9fe445SBarry Smith    Logically Collective on SNES
42650f5c6efeSJed Brown 
4266d8d19677SJose E. Roman    Input Parameters:
4267d42a1c89SJed Brown + snes - nonlinear solver
42680910c330SBarry Smith . U - the current state at which to evaluate the residual
4269d42a1c89SJed Brown - ctx - user context, must be a TS
42700f5c6efeSJed Brown 
42710f5c6efeSJed Brown    Output Parameter:
42720f5c6efeSJed Brown . F - the nonlinear residual
42730f5c6efeSJed Brown 
42740f5c6efeSJed Brown    Notes:
42750f5c6efeSJed Brown    This function is not normally called by users and is automatically registered with the SNES used by TS.
42760f5c6efeSJed Brown    It is most frequently passed to MatFDColoringSetFunction().
42770f5c6efeSJed Brown 
42780f5c6efeSJed Brown    Level: advanced
42790f5c6efeSJed Brown 
4280db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `MatFDColoringSetFunction()`
42810f5c6efeSJed Brown @*/
42820910c330SBarry Smith PetscErrorCode  SNESTSFormFunction(SNES snes,Vec U,Vec F,void *ctx)
42830f5c6efeSJed Brown {
42840f5c6efeSJed Brown   TS             ts = (TS)ctx;
42850f5c6efeSJed Brown 
42860f5c6efeSJed Brown   PetscFunctionBegin;
42870f5c6efeSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42880910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
42890f5c6efeSJed Brown   PetscValidHeaderSpecific(F,VEC_CLASSID,3);
42900f5c6efeSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,4);
42919566063dSJacob Faibussowitsch   PetscCall((ts->ops->snesfunction)(snes,U,F,ts));
42920f5c6efeSJed Brown   PetscFunctionReturn(0);
42930f5c6efeSJed Brown }
42940f5c6efeSJed Brown 
42950f5c6efeSJed Brown /*@
42960f5c6efeSJed Brown    SNESTSFormJacobian - Function to evaluate the Jacobian
42970f5c6efeSJed Brown 
42980f5c6efeSJed Brown    Collective on SNES
42990f5c6efeSJed Brown 
4300d8d19677SJose E. Roman    Input Parameters:
43010f5c6efeSJed Brown + snes - nonlinear solver
43020910c330SBarry Smith . U - the current state at which to evaluate the residual
43030f5c6efeSJed Brown - ctx - user context, must be a TS
43040f5c6efeSJed Brown 
4305d8d19677SJose E. Roman    Output Parameters:
43060f5c6efeSJed Brown + A - the Jacobian
43076b867d5aSJose E. Roman - B - the preconditioning matrix (may be the same as A)
43080f5c6efeSJed Brown 
43090f5c6efeSJed Brown    Notes:
43100f5c6efeSJed Brown    This function is not normally called by users and is automatically registered with the SNES used by TS.
43110f5c6efeSJed Brown 
43120f5c6efeSJed Brown    Level: developer
43130f5c6efeSJed Brown 
4314db781477SPatrick Sanan .seealso: `SNESSetJacobian()`
43150f5c6efeSJed Brown @*/
4316d1e9a80fSBarry Smith PetscErrorCode  SNESTSFormJacobian(SNES snes,Vec U,Mat A,Mat B,void *ctx)
43170f5c6efeSJed Brown {
43180f5c6efeSJed Brown   TS             ts = (TS)ctx;
43190f5c6efeSJed Brown 
43200f5c6efeSJed Brown   PetscFunctionBegin;
43210f5c6efeSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43220910c330SBarry Smith   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
43230f5c6efeSJed Brown   PetscValidPointer(A,3);
432494ab13aaSBarry Smith   PetscValidHeaderSpecific(A,MAT_CLASSID,3);
43250f5c6efeSJed Brown   PetscValidPointer(B,4);
432694ab13aaSBarry Smith   PetscValidHeaderSpecific(B,MAT_CLASSID,4);
4327064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(ts,TS_CLASSID,5);
43289566063dSJacob Faibussowitsch   PetscCall((ts->ops->snesjacobian)(snes,U,A,B,ts));
43290f5c6efeSJed Brown   PetscFunctionReturn(0);
43300f5c6efeSJed Brown }
4331325fc9f4SBarry Smith 
43320e4ef248SJed Brown /*@C
43339ae8fd06SBarry Smith    TSComputeRHSFunctionLinear - Evaluate the right hand side via the user-provided Jacobian, for linear problems Udot = A U only
43340e4ef248SJed Brown 
43350e4ef248SJed Brown    Collective on TS
43360e4ef248SJed Brown 
43374165533cSJose E. Roman    Input Parameters:
43380e4ef248SJed Brown +  ts - time stepping context
43390e4ef248SJed Brown .  t - time at which to evaluate
43400910c330SBarry Smith .  U - state at which to evaluate
43410e4ef248SJed Brown -  ctx - context
43420e4ef248SJed Brown 
43434165533cSJose E. Roman    Output Parameter:
43440e4ef248SJed Brown .  F - right hand side
43450e4ef248SJed Brown 
43460e4ef248SJed Brown    Level: intermediate
43470e4ef248SJed Brown 
43480e4ef248SJed Brown    Notes:
43490e4ef248SJed Brown    This function is intended to be passed to TSSetRHSFunction() to evaluate the right hand side for linear problems.
43500e4ef248SJed Brown    The matrix (and optionally the evaluation context) should be passed to TSSetRHSJacobian().
43510e4ef248SJed Brown 
4352db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSJacobianConstant()`
43530e4ef248SJed Brown @*/
43540910c330SBarry Smith PetscErrorCode TSComputeRHSFunctionLinear(TS ts,PetscReal t,Vec U,Vec F,void *ctx)
43550e4ef248SJed Brown {
43560e4ef248SJed Brown   Mat            Arhs,Brhs;
43570e4ef248SJed Brown 
43580e4ef248SJed Brown   PetscFunctionBegin;
43599566063dSJacob Faibussowitsch   PetscCall(TSGetRHSMats_Private(ts,&Arhs,&Brhs));
43602663174eSHong Zhang   /* undo the damage caused by shifting */
43619566063dSJacob Faibussowitsch   PetscCall(TSRecoverRHSJacobian(ts,Arhs,Brhs));
43629566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSJacobian(ts,t,U,Arhs,Brhs));
43639566063dSJacob Faibussowitsch   PetscCall(MatMult(Arhs,U,F));
43640e4ef248SJed Brown   PetscFunctionReturn(0);
43650e4ef248SJed Brown }
43660e4ef248SJed Brown 
43670e4ef248SJed Brown /*@C
43680e4ef248SJed Brown    TSComputeRHSJacobianConstant - Reuses a Jacobian that is time-independent.
43690e4ef248SJed Brown 
43700e4ef248SJed Brown    Collective on TS
43710e4ef248SJed Brown 
43724165533cSJose E. Roman    Input Parameters:
43730e4ef248SJed Brown +  ts - time stepping context
43740e4ef248SJed Brown .  t - time at which to evaluate
43750910c330SBarry Smith .  U - state at which to evaluate
43760e4ef248SJed Brown -  ctx - context
43770e4ef248SJed Brown 
43784165533cSJose E. Roman    Output Parameters:
43790e4ef248SJed Brown +  A - pointer to operator
438097bb3fdcSJose E. Roman -  B - pointer to preconditioning matrix
43810e4ef248SJed Brown 
43820e4ef248SJed Brown    Level: intermediate
43830e4ef248SJed Brown 
43840e4ef248SJed Brown    Notes:
43850e4ef248SJed Brown    This function is intended to be passed to TSSetRHSJacobian() to evaluate the Jacobian for linear time-independent problems.
43860e4ef248SJed Brown 
4387db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSSetRHSJacobian()`, `TSComputeRHSFunctionLinear()`
43880e4ef248SJed Brown @*/
4389d1e9a80fSBarry Smith PetscErrorCode TSComputeRHSJacobianConstant(TS ts,PetscReal t,Vec U,Mat A,Mat B,void *ctx)
43900e4ef248SJed Brown {
43910e4ef248SJed Brown   PetscFunctionBegin;
43920e4ef248SJed Brown   PetscFunctionReturn(0);
43930e4ef248SJed Brown }
43940e4ef248SJed Brown 
43950026cea9SSean Farley /*@C
43960026cea9SSean Farley    TSComputeIFunctionLinear - Evaluate the left hand side via the user-provided Jacobian, for linear problems only
43970026cea9SSean Farley 
43980026cea9SSean Farley    Collective on TS
43990026cea9SSean Farley 
44004165533cSJose E. Roman    Input Parameters:
44010026cea9SSean Farley +  ts - time stepping context
44020026cea9SSean Farley .  t - time at which to evaluate
44030910c330SBarry Smith .  U - state at which to evaluate
44040910c330SBarry Smith .  Udot - time derivative of state vector
44050026cea9SSean Farley -  ctx - context
44060026cea9SSean Farley 
44074165533cSJose E. Roman    Output Parameter:
44080026cea9SSean Farley .  F - left hand side
44090026cea9SSean Farley 
44100026cea9SSean Farley    Level: intermediate
44110026cea9SSean Farley 
44120026cea9SSean Farley    Notes:
44130910c330SBarry 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
44140026cea9SSean Farley    user is required to write their own TSComputeIFunction.
44150026cea9SSean Farley    This function is intended to be passed to TSSetIFunction() to evaluate the left hand side for linear problems.
44160026cea9SSean Farley    The matrix (and optionally the evaluation context) should be passed to TSSetIJacobian().
44170026cea9SSean Farley 
44189ae8fd06SBarry Smith    Note that using this function is NOT equivalent to using TSComputeRHSFunctionLinear() since that solves Udot = A U
44199ae8fd06SBarry Smith 
4420db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIJacobianConstant()`, `TSComputeRHSFunctionLinear()`
44210026cea9SSean Farley @*/
44220910c330SBarry Smith PetscErrorCode TSComputeIFunctionLinear(TS ts,PetscReal t,Vec U,Vec Udot,Vec F,void *ctx)
44230026cea9SSean Farley {
44240026cea9SSean Farley   Mat            A,B;
44250026cea9SSean Farley 
44260026cea9SSean Farley   PetscFunctionBegin;
44279566063dSJacob Faibussowitsch   PetscCall(TSGetIJacobian(ts,&A,&B,NULL,NULL));
44289566063dSJacob Faibussowitsch   PetscCall(TSComputeIJacobian(ts,t,U,Udot,1.0,A,B,PETSC_TRUE));
44299566063dSJacob Faibussowitsch   PetscCall(MatMult(A,Udot,F));
44300026cea9SSean Farley   PetscFunctionReturn(0);
44310026cea9SSean Farley }
44320026cea9SSean Farley 
44330026cea9SSean Farley /*@C
4434b41af12eSJed Brown    TSComputeIJacobianConstant - Reuses a time-independent for a semi-implicit DAE or ODE
44350026cea9SSean Farley 
44360026cea9SSean Farley    Collective on TS
44370026cea9SSean Farley 
44384165533cSJose E. Roman    Input Parameters:
44390026cea9SSean Farley +  ts - time stepping context
44400026cea9SSean Farley .  t - time at which to evaluate
44410910c330SBarry Smith .  U - state at which to evaluate
44420910c330SBarry Smith .  Udot - time derivative of state vector
44430026cea9SSean Farley .  shift - shift to apply
44440026cea9SSean Farley -  ctx - context
44450026cea9SSean Farley 
44464165533cSJose E. Roman    Output Parameters:
44470026cea9SSean Farley +  A - pointer to operator
444897bb3fdcSJose E. Roman -  B - pointer to preconditioning matrix
44490026cea9SSean Farley 
4450b41af12eSJed Brown    Level: advanced
44510026cea9SSean Farley 
44520026cea9SSean Farley    Notes:
44530026cea9SSean Farley    This function is intended to be passed to TSSetIJacobian() to evaluate the Jacobian for linear time-independent problems.
44540026cea9SSean Farley 
4455b41af12eSJed Brown    It is only appropriate for problems of the form
4456b41af12eSJed Brown 
4457b41af12eSJed Brown $     M Udot = F(U,t)
4458b41af12eSJed Brown 
4459b41af12eSJed Brown   where M is constant and F is non-stiff.  The user must pass M to TSSetIJacobian().  The current implementation only
4460b41af12eSJed Brown   works with IMEX time integration methods such as TSROSW and TSARKIMEX, since there is no support for de-constructing
4461b41af12eSJed Brown   an implicit operator of the form
4462b41af12eSJed Brown 
4463b41af12eSJed Brown $    shift*M + J
4464b41af12eSJed Brown 
4465b41af12eSJed 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
4466b41af12eSJed Brown   a copy of M or reassemble it when requested.
4467b41af12eSJed Brown 
4468db781477SPatrick Sanan .seealso: `TSSetIFunction()`, `TSSetIJacobian()`, `TSComputeIFunctionLinear()`
44690026cea9SSean Farley @*/
4470d1e9a80fSBarry Smith PetscErrorCode TSComputeIJacobianConstant(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat A,Mat B,void *ctx)
44710026cea9SSean Farley {
44720026cea9SSean Farley   PetscFunctionBegin;
44739566063dSJacob Faibussowitsch   PetscCall(MatScale(A, shift / ts->ijacobian.shift));
4474b41af12eSJed Brown   ts->ijacobian.shift = shift;
44750026cea9SSean Farley   PetscFunctionReturn(0);
44760026cea9SSean Farley }
4477b41af12eSJed Brown 
4478e817cc15SEmil Constantinescu /*@
4479e817cc15SEmil Constantinescu    TSGetEquationType - Gets the type of the equation that TS is solving.
4480e817cc15SEmil Constantinescu 
4481e817cc15SEmil Constantinescu    Not Collective
4482e817cc15SEmil Constantinescu 
4483e817cc15SEmil Constantinescu    Input Parameter:
4484e817cc15SEmil Constantinescu .  ts - the TS context
4485e817cc15SEmil Constantinescu 
4486e817cc15SEmil Constantinescu    Output Parameter:
44874e6b9ce4SEmil Constantinescu .  equation_type - see TSEquationType
4488e817cc15SEmil Constantinescu 
4489e817cc15SEmil Constantinescu    Level: beginner
4490e817cc15SEmil Constantinescu 
4491db781477SPatrick Sanan .seealso: `TSSetEquationType()`, `TSEquationType`
4492e817cc15SEmil Constantinescu @*/
4493e817cc15SEmil Constantinescu PetscErrorCode  TSGetEquationType(TS ts,TSEquationType *equation_type)
4494e817cc15SEmil Constantinescu {
4495e817cc15SEmil Constantinescu   PetscFunctionBegin;
4496e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4497e817cc15SEmil Constantinescu   PetscValidPointer(equation_type,2);
4498e817cc15SEmil Constantinescu   *equation_type = ts->equation_type;
4499e817cc15SEmil Constantinescu   PetscFunctionReturn(0);
4500e817cc15SEmil Constantinescu }
4501e817cc15SEmil Constantinescu 
4502e817cc15SEmil Constantinescu /*@
4503e817cc15SEmil Constantinescu    TSSetEquationType - Sets the type of the equation that TS is solving.
4504e817cc15SEmil Constantinescu 
4505e817cc15SEmil Constantinescu    Not Collective
4506e817cc15SEmil Constantinescu 
4507d8d19677SJose E. Roman    Input Parameters:
4508e817cc15SEmil Constantinescu +  ts - the TS context
45091297b224SEmil Constantinescu -  equation_type - see TSEquationType
4510e817cc15SEmil Constantinescu 
4511e817cc15SEmil Constantinescu    Level: advanced
4512e817cc15SEmil Constantinescu 
4513db781477SPatrick Sanan .seealso: `TSGetEquationType()`, `TSEquationType`
4514e817cc15SEmil Constantinescu @*/
4515e817cc15SEmil Constantinescu PetscErrorCode  TSSetEquationType(TS ts,TSEquationType equation_type)
4516e817cc15SEmil Constantinescu {
4517e817cc15SEmil Constantinescu   PetscFunctionBegin;
4518e817cc15SEmil Constantinescu   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4519e817cc15SEmil Constantinescu   ts->equation_type = equation_type;
4520e817cc15SEmil Constantinescu   PetscFunctionReturn(0);
4521e817cc15SEmil Constantinescu }
45220026cea9SSean Farley 
45234af1b03aSJed Brown /*@
45244af1b03aSJed Brown    TSGetConvergedReason - Gets the reason the TS iteration was stopped.
45254af1b03aSJed Brown 
45264af1b03aSJed Brown    Not Collective
45274af1b03aSJed Brown 
45284af1b03aSJed Brown    Input Parameter:
45294af1b03aSJed Brown .  ts - the TS context
45304af1b03aSJed Brown 
45314af1b03aSJed Brown    Output Parameter:
45324af1b03aSJed Brown .  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
45334af1b03aSJed Brown             manual pages for the individual convergence tests for complete lists
45344af1b03aSJed Brown 
4535487e0bb9SJed Brown    Level: beginner
45364af1b03aSJed Brown 
4537cd652676SJed Brown    Notes:
4538cd652676SJed Brown    Can only be called after the call to TSSolve() is complete.
45394af1b03aSJed Brown 
4540db781477SPatrick Sanan .seealso: `TSSetConvergenceTest()`, `TSConvergedReason`
45414af1b03aSJed Brown @*/
45424af1b03aSJed Brown PetscErrorCode  TSGetConvergedReason(TS ts,TSConvergedReason *reason)
45434af1b03aSJed Brown {
45444af1b03aSJed Brown   PetscFunctionBegin;
45454af1b03aSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
45464af1b03aSJed Brown   PetscValidPointer(reason,2);
45474af1b03aSJed Brown   *reason = ts->reason;
45484af1b03aSJed Brown   PetscFunctionReturn(0);
45494af1b03aSJed Brown }
45504af1b03aSJed Brown 
4551d6ad946cSShri Abhyankar /*@
4552d6ad946cSShri Abhyankar    TSSetConvergedReason - Sets the reason for handling the convergence of TSSolve.
4553d6ad946cSShri Abhyankar 
45546b221cbeSPatrick Sanan    Logically Collective; reason must contain common value
4555d6ad946cSShri Abhyankar 
45566b221cbeSPatrick Sanan    Input Parameters:
4557d6ad946cSShri Abhyankar +  ts - the TS context
45586b221cbeSPatrick Sanan -  reason - negative value indicates diverged, positive value converged, see TSConvergedReason or the
4559d6ad946cSShri Abhyankar             manual pages for the individual convergence tests for complete lists
4560d6ad946cSShri Abhyankar 
4561f5abba47SShri Abhyankar    Level: advanced
4562d6ad946cSShri Abhyankar 
4563d6ad946cSShri Abhyankar    Notes:
45646b221cbeSPatrick Sanan    Can only be called while TSSolve() is active.
4565d6ad946cSShri Abhyankar 
4566db781477SPatrick Sanan .seealso: `TSConvergedReason`
4567d6ad946cSShri Abhyankar @*/
4568d6ad946cSShri Abhyankar PetscErrorCode  TSSetConvergedReason(TS ts,TSConvergedReason reason)
4569d6ad946cSShri Abhyankar {
4570d6ad946cSShri Abhyankar   PetscFunctionBegin;
4571d6ad946cSShri Abhyankar   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4572d6ad946cSShri Abhyankar   ts->reason = reason;
4573d6ad946cSShri Abhyankar   PetscFunctionReturn(0);
4574d6ad946cSShri Abhyankar }
4575d6ad946cSShri Abhyankar 
4576cc708dedSBarry Smith /*@
4577cc708dedSBarry Smith    TSGetSolveTime - Gets the time after a call to TSSolve()
4578cc708dedSBarry Smith 
4579cc708dedSBarry Smith    Not Collective
4580cc708dedSBarry Smith 
4581cc708dedSBarry Smith    Input Parameter:
4582cc708dedSBarry Smith .  ts - the TS context
4583cc708dedSBarry Smith 
4584cc708dedSBarry Smith    Output Parameter:
458519eac22cSLisandro Dalcin .  ftime - the final time. This time corresponds to the final time set with TSSetMaxTime()
4586cc708dedSBarry Smith 
4587487e0bb9SJed Brown    Level: beginner
4588cc708dedSBarry Smith 
4589cc708dedSBarry Smith    Notes:
4590cc708dedSBarry Smith    Can only be called after the call to TSSolve() is complete.
4591cc708dedSBarry Smith 
4592db781477SPatrick Sanan .seealso: `TSSetConvergenceTest()`, `TSConvergedReason`
4593cc708dedSBarry Smith @*/
4594cc708dedSBarry Smith PetscErrorCode  TSGetSolveTime(TS ts,PetscReal *ftime)
4595cc708dedSBarry Smith {
4596cc708dedSBarry Smith   PetscFunctionBegin;
4597cc708dedSBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4598dadcf809SJacob Faibussowitsch   PetscValidRealPointer(ftime,2);
4599cc708dedSBarry Smith   *ftime = ts->solvetime;
4600cc708dedSBarry Smith   PetscFunctionReturn(0);
4601cc708dedSBarry Smith }
4602cc708dedSBarry Smith 
46032c18e0fdSBarry Smith /*@
46045ef26d82SJed Brown    TSGetSNESIterations - Gets the total number of nonlinear iterations
46059f67acb7SJed Brown    used by the time integrator.
46069f67acb7SJed Brown 
46079f67acb7SJed Brown    Not Collective
46089f67acb7SJed Brown 
46099f67acb7SJed Brown    Input Parameter:
46109f67acb7SJed Brown .  ts - TS context
46119f67acb7SJed Brown 
46129f67acb7SJed Brown    Output Parameter:
46139f67acb7SJed Brown .  nits - number of nonlinear iterations
46149f67acb7SJed Brown 
46159f67acb7SJed Brown    Notes:
46169f67acb7SJed Brown    This counter is reset to zero for each successive call to TSSolve().
46179f67acb7SJed Brown 
46189f67acb7SJed Brown    Level: intermediate
46199f67acb7SJed Brown 
4620db781477SPatrick Sanan .seealso: `TSGetKSPIterations()`
46219f67acb7SJed Brown @*/
46225ef26d82SJed Brown PetscErrorCode TSGetSNESIterations(TS ts,PetscInt *nits)
46239f67acb7SJed Brown {
46249f67acb7SJed Brown   PetscFunctionBegin;
46259f67acb7SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
46269f67acb7SJed Brown   PetscValidIntPointer(nits,2);
46275ef26d82SJed Brown   *nits = ts->snes_its;
46289f67acb7SJed Brown   PetscFunctionReturn(0);
46299f67acb7SJed Brown }
46309f67acb7SJed Brown 
46319f67acb7SJed Brown /*@
46325ef26d82SJed Brown    TSGetKSPIterations - Gets the total number of linear iterations
46339f67acb7SJed Brown    used by the time integrator.
46349f67acb7SJed Brown 
46359f67acb7SJed Brown    Not Collective
46369f67acb7SJed Brown 
46379f67acb7SJed Brown    Input Parameter:
46389f67acb7SJed Brown .  ts - TS context
46399f67acb7SJed Brown 
46409f67acb7SJed Brown    Output Parameter:
46419f67acb7SJed Brown .  lits - number of linear iterations
46429f67acb7SJed Brown 
46439f67acb7SJed Brown    Notes:
46449f67acb7SJed Brown    This counter is reset to zero for each successive call to TSSolve().
46459f67acb7SJed Brown 
46469f67acb7SJed Brown    Level: intermediate
46479f67acb7SJed Brown 
4648db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `SNESGetKSPIterations()`
46499f67acb7SJed Brown @*/
46505ef26d82SJed Brown PetscErrorCode TSGetKSPIterations(TS ts,PetscInt *lits)
46519f67acb7SJed Brown {
46529f67acb7SJed Brown   PetscFunctionBegin;
46539f67acb7SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
46549f67acb7SJed Brown   PetscValidIntPointer(lits,2);
46555ef26d82SJed Brown   *lits = ts->ksp_its;
46569f67acb7SJed Brown   PetscFunctionReturn(0);
46579f67acb7SJed Brown }
46589f67acb7SJed Brown 
4659cef5090cSJed Brown /*@
4660cef5090cSJed Brown    TSGetStepRejections - Gets the total number of rejected steps.
4661cef5090cSJed Brown 
4662cef5090cSJed Brown    Not Collective
4663cef5090cSJed Brown 
4664cef5090cSJed Brown    Input Parameter:
4665cef5090cSJed Brown .  ts - TS context
4666cef5090cSJed Brown 
4667cef5090cSJed Brown    Output Parameter:
4668cef5090cSJed Brown .  rejects - number of steps rejected
4669cef5090cSJed Brown 
4670cef5090cSJed Brown    Notes:
4671cef5090cSJed Brown    This counter is reset to zero for each successive call to TSSolve().
4672cef5090cSJed Brown 
4673cef5090cSJed Brown    Level: intermediate
4674cef5090cSJed Brown 
4675db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetSNESFailures()`, `TSSetMaxSNESFailures()`, `TSSetErrorIfStepFails()`
4676cef5090cSJed Brown @*/
4677cef5090cSJed Brown PetscErrorCode TSGetStepRejections(TS ts,PetscInt *rejects)
4678cef5090cSJed Brown {
4679cef5090cSJed Brown   PetscFunctionBegin;
4680cef5090cSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4681cef5090cSJed Brown   PetscValidIntPointer(rejects,2);
4682cef5090cSJed Brown   *rejects = ts->reject;
4683cef5090cSJed Brown   PetscFunctionReturn(0);
4684cef5090cSJed Brown }
4685cef5090cSJed Brown 
4686cef5090cSJed Brown /*@
4687cef5090cSJed Brown    TSGetSNESFailures - Gets the total number of failed SNES solves
4688cef5090cSJed Brown 
4689cef5090cSJed Brown    Not Collective
4690cef5090cSJed Brown 
4691cef5090cSJed Brown    Input Parameter:
4692cef5090cSJed Brown .  ts - TS context
4693cef5090cSJed Brown 
4694cef5090cSJed Brown    Output Parameter:
4695cef5090cSJed Brown .  fails - number of failed nonlinear solves
4696cef5090cSJed Brown 
4697cef5090cSJed Brown    Notes:
4698cef5090cSJed Brown    This counter is reset to zero for each successive call to TSSolve().
4699cef5090cSJed Brown 
4700cef5090cSJed Brown    Level: intermediate
4701cef5090cSJed Brown 
4702db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSSetMaxSNESFailures()`
4703cef5090cSJed Brown @*/
4704cef5090cSJed Brown PetscErrorCode TSGetSNESFailures(TS ts,PetscInt *fails)
4705cef5090cSJed Brown {
4706cef5090cSJed Brown   PetscFunctionBegin;
4707cef5090cSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4708cef5090cSJed Brown   PetscValidIntPointer(fails,2);
4709cef5090cSJed Brown   *fails = ts->num_snes_failures;
4710cef5090cSJed Brown   PetscFunctionReturn(0);
4711cef5090cSJed Brown }
4712cef5090cSJed Brown 
4713cef5090cSJed Brown /*@
4714cef5090cSJed Brown    TSSetMaxStepRejections - Sets the maximum number of step rejections before a step fails
4715cef5090cSJed Brown 
4716cef5090cSJed Brown    Not Collective
4717cef5090cSJed Brown 
4718d8d19677SJose E. Roman    Input Parameters:
4719cef5090cSJed Brown +  ts - TS context
4720cef5090cSJed Brown -  rejects - maximum number of rejected steps, pass -1 for unlimited
4721cef5090cSJed Brown 
4722cef5090cSJed Brown    Notes:
4723cef5090cSJed Brown    The counter is reset to zero for each step
4724cef5090cSJed Brown 
4725cef5090cSJed Brown    Options Database Key:
4726cef5090cSJed Brown .  -ts_max_reject - Maximum number of step rejections before a step fails
4727cef5090cSJed Brown 
4728cef5090cSJed Brown    Level: intermediate
4729cef5090cSJed Brown 
4730db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxSNESFailures()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSSetErrorIfStepFails()`, `TSGetConvergedReason()`
4731cef5090cSJed Brown @*/
4732cef5090cSJed Brown PetscErrorCode TSSetMaxStepRejections(TS ts,PetscInt rejects)
4733cef5090cSJed Brown {
4734cef5090cSJed Brown   PetscFunctionBegin;
4735cef5090cSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4736cef5090cSJed Brown   ts->max_reject = rejects;
4737cef5090cSJed Brown   PetscFunctionReturn(0);
4738cef5090cSJed Brown }
4739cef5090cSJed Brown 
4740cef5090cSJed Brown /*@
4741cef5090cSJed Brown    TSSetMaxSNESFailures - Sets the maximum number of failed SNES solves
4742cef5090cSJed Brown 
4743cef5090cSJed Brown    Not Collective
4744cef5090cSJed Brown 
4745d8d19677SJose E. Roman    Input Parameters:
4746cef5090cSJed Brown +  ts - TS context
4747cef5090cSJed Brown -  fails - maximum number of failed nonlinear solves, pass -1 for unlimited
4748cef5090cSJed Brown 
4749cef5090cSJed Brown    Notes:
4750cef5090cSJed Brown    The counter is reset to zero for each successive call to TSSolve().
4751cef5090cSJed Brown 
4752cef5090cSJed Brown    Options Database Key:
4753cef5090cSJed Brown .  -ts_max_snes_failures - Maximum number of nonlinear solve failures
4754cef5090cSJed Brown 
4755cef5090cSJed Brown    Level: intermediate
4756cef5090cSJed Brown 
4757db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `SNESGetConvergedReason()`, `TSGetConvergedReason()`
4758cef5090cSJed Brown @*/
4759cef5090cSJed Brown PetscErrorCode TSSetMaxSNESFailures(TS ts,PetscInt fails)
4760cef5090cSJed Brown {
4761cef5090cSJed Brown   PetscFunctionBegin;
4762cef5090cSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4763cef5090cSJed Brown   ts->max_snes_failures = fails;
4764cef5090cSJed Brown   PetscFunctionReturn(0);
4765cef5090cSJed Brown }
4766cef5090cSJed Brown 
4767cef5090cSJed Brown /*@
4768cef5090cSJed Brown    TSSetErrorIfStepFails - Error if no step succeeds
4769cef5090cSJed Brown 
4770cef5090cSJed Brown    Not Collective
4771cef5090cSJed Brown 
4772d8d19677SJose E. Roman    Input Parameters:
4773cef5090cSJed Brown +  ts - TS context
4774cef5090cSJed Brown -  err - PETSC_TRUE to error if no step succeeds, PETSC_FALSE to return without failure
4775cef5090cSJed Brown 
4776cef5090cSJed Brown    Options Database Key:
4777cef5090cSJed Brown .  -ts_error_if_step_fails - Error if no step succeeds
4778cef5090cSJed Brown 
4779cef5090cSJed Brown    Level: intermediate
4780cef5090cSJed Brown 
4781db781477SPatrick Sanan .seealso: `TSGetSNESIterations()`, `TSGetKSPIterations()`, `TSSetMaxStepRejections()`, `TSGetStepRejections()`, `TSGetSNESFailures()`, `TSSetErrorIfStepFails()`, `TSGetConvergedReason()`
4782cef5090cSJed Brown @*/
4783cef5090cSJed Brown PetscErrorCode TSSetErrorIfStepFails(TS ts,PetscBool err)
4784cef5090cSJed Brown {
4785cef5090cSJed Brown   PetscFunctionBegin;
4786cef5090cSJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4787cef5090cSJed Brown   ts->errorifstepfailed = err;
4788cef5090cSJed Brown   PetscFunctionReturn(0);
4789cef5090cSJed Brown }
4790cef5090cSJed Brown 
479184df9cb4SJed Brown /*@
4792552698daSJed Brown    TSGetAdapt - Get the adaptive controller context for the current method
479384df9cb4SJed Brown 
4794ed81e22dSJed Brown    Collective on TS if controller has not been created yet
479584df9cb4SJed Brown 
47964165533cSJose E. Roman    Input Parameter:
4797ed81e22dSJed Brown .  ts - time stepping context
479884df9cb4SJed Brown 
47994165533cSJose E. Roman    Output Parameter:
4800ed81e22dSJed Brown .  adapt - adaptive controller
480184df9cb4SJed Brown 
480284df9cb4SJed Brown    Level: intermediate
480384df9cb4SJed Brown 
4804db781477SPatrick Sanan .seealso: `TSAdapt`, `TSAdaptSetType()`, `TSAdaptChoose()`
480584df9cb4SJed Brown @*/
4806552698daSJed Brown PetscErrorCode TSGetAdapt(TS ts,TSAdapt *adapt)
480784df9cb4SJed Brown {
480884df9cb4SJed Brown   PetscFunctionBegin;
480984df9cb4SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4810bec58848SLisandro Dalcin   PetscValidPointer(adapt,2);
481184df9cb4SJed Brown   if (!ts->adapt) {
48129566063dSJacob Faibussowitsch     PetscCall(TSAdaptCreate(PetscObjectComm((PetscObject)ts),&ts->adapt));
48139566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)ts,(PetscObject)ts->adapt));
48149566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)ts->adapt,(PetscObject)ts,1));
481584df9cb4SJed Brown   }
4816bec58848SLisandro Dalcin   *adapt = ts->adapt;
481784df9cb4SJed Brown   PetscFunctionReturn(0);
481884df9cb4SJed Brown }
4819d6ebe24aSShri Abhyankar 
48201c3436cfSJed Brown /*@
48211c3436cfSJed Brown    TSSetTolerances - Set tolerances for local truncation error when using adaptive controller
48221c3436cfSJed Brown 
48231c3436cfSJed Brown    Logically Collective
48241c3436cfSJed Brown 
48254165533cSJose E. Roman    Input Parameters:
48261c3436cfSJed Brown +  ts - time integration context
48271c3436cfSJed Brown .  atol - scalar absolute tolerances, PETSC_DECIDE to leave current value
48280298fd71SBarry Smith .  vatol - vector of absolute tolerances or NULL, used in preference to atol if present
48291c3436cfSJed Brown .  rtol - scalar relative tolerances, PETSC_DECIDE to leave current value
48300298fd71SBarry Smith -  vrtol - vector of relative tolerances or NULL, used in preference to atol if present
48311c3436cfSJed Brown 
4832a3cdaa26SBarry Smith    Options Database keys:
4833a3cdaa26SBarry Smith +  -ts_rtol <rtol> - relative tolerance for local truncation error
483467b8a455SSatish Balay -  -ts_atol <atol> - Absolute tolerance for local truncation error
4835a3cdaa26SBarry Smith 
48363ff766beSShri Abhyankar    Notes:
48373ff766beSShri Abhyankar    With PETSc's implicit schemes for DAE problems, the calculation of the local truncation error
48383ff766beSShri Abhyankar    (LTE) includes both the differential and the algebraic variables. If one wants the LTE to be
48393ff766beSShri Abhyankar    computed only for the differential or the algebraic part then this can be done using the vector of
48403ff766beSShri Abhyankar    tolerances vatol. For example, by setting the tolerance vector with the desired tolerance for the
48413ff766beSShri Abhyankar    differential part and infinity for the algebraic part, the LTE calculation will include only the
48423ff766beSShri Abhyankar    differential variables.
48433ff766beSShri Abhyankar 
48441c3436cfSJed Brown    Level: beginner
48451c3436cfSJed Brown 
4846db781477SPatrick Sanan .seealso: `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSGetTolerances()`
48471c3436cfSJed Brown @*/
48481c3436cfSJed Brown PetscErrorCode TSSetTolerances(TS ts,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol)
48491c3436cfSJed Brown {
48501c3436cfSJed Brown   PetscFunctionBegin;
4851c5033834SJed Brown   if (atol != PETSC_DECIDE && atol != PETSC_DEFAULT) ts->atol = atol;
48521c3436cfSJed Brown   if (vatol) {
48539566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vatol));
48549566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vatol));
48551c3436cfSJed Brown     ts->vatol = vatol;
48561c3436cfSJed Brown   }
4857c5033834SJed Brown   if (rtol != PETSC_DECIDE && rtol != PETSC_DEFAULT) ts->rtol = rtol;
48581c3436cfSJed Brown   if (vrtol) {
48599566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)vrtol));
48609566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&ts->vrtol));
48611c3436cfSJed Brown     ts->vrtol = vrtol;
48621c3436cfSJed Brown   }
48631c3436cfSJed Brown   PetscFunctionReturn(0);
48641c3436cfSJed Brown }
48651c3436cfSJed Brown 
4866c5033834SJed Brown /*@
4867c5033834SJed Brown    TSGetTolerances - Get tolerances for local truncation error when using adaptive controller
4868c5033834SJed Brown 
4869c5033834SJed Brown    Logically Collective
4870c5033834SJed Brown 
48714165533cSJose E. Roman    Input Parameter:
4872c5033834SJed Brown .  ts - time integration context
4873c5033834SJed Brown 
48744165533cSJose E. Roman    Output Parameters:
48750298fd71SBarry Smith +  atol - scalar absolute tolerances, NULL to ignore
48760298fd71SBarry Smith .  vatol - vector of absolute tolerances, NULL to ignore
48770298fd71SBarry Smith .  rtol - scalar relative tolerances, NULL to ignore
48780298fd71SBarry Smith -  vrtol - vector of relative tolerances, NULL to ignore
4879c5033834SJed Brown 
4880c5033834SJed Brown    Level: beginner
4881c5033834SJed Brown 
4882db781477SPatrick Sanan .seealso: `TS`, `TSAdapt`, `TSErrorWeightedNorm()`, `TSSetTolerances()`
4883c5033834SJed Brown @*/
4884c5033834SJed Brown PetscErrorCode TSGetTolerances(TS ts,PetscReal *atol,Vec *vatol,PetscReal *rtol,Vec *vrtol)
4885c5033834SJed Brown {
4886c5033834SJed Brown   PetscFunctionBegin;
4887c5033834SJed Brown   if (atol)  *atol  = ts->atol;
4888c5033834SJed Brown   if (vatol) *vatol = ts->vatol;
4889c5033834SJed Brown   if (rtol)  *rtol  = ts->rtol;
4890c5033834SJed Brown   if (vrtol) *vrtol = ts->vrtol;
4891c5033834SJed Brown   PetscFunctionReturn(0);
4892c5033834SJed Brown }
4893c5033834SJed Brown 
48949c6b16b5SShri Abhyankar /*@
4895a4868fbcSLisandro Dalcin    TSErrorWeightedNorm2 - compute a weighted 2-norm of the difference between two state vectors
48969c6b16b5SShri Abhyankar 
48979c6b16b5SShri Abhyankar    Collective on TS
48989c6b16b5SShri Abhyankar 
48994165533cSJose E. Roman    Input Parameters:
49009c6b16b5SShri Abhyankar +  ts - time stepping context
4901a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
4902a4868fbcSLisandro Dalcin -  Y - state vector to be compared to U
49039c6b16b5SShri Abhyankar 
49044165533cSJose E. Roman    Output Parameters:
4905a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
49067453f775SEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
4907a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
49089c6b16b5SShri Abhyankar 
49099c6b16b5SShri Abhyankar    Level: developer
49109c6b16b5SShri Abhyankar 
4911db781477SPatrick Sanan .seealso: `TSErrorWeightedNorm()`, `TSErrorWeightedNormInfinity()`
49129c6b16b5SShri Abhyankar @*/
49137453f775SEmil Constantinescu PetscErrorCode TSErrorWeightedNorm2(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
49149c6b16b5SShri Abhyankar {
49159c6b16b5SShri Abhyankar   PetscInt          i,n,N,rstart;
49167453f775SEmil Constantinescu   PetscInt          n_loc,na_loc,nr_loc;
49177453f775SEmil Constantinescu   PetscReal         n_glb,na_glb,nr_glb;
49189c6b16b5SShri Abhyankar   const PetscScalar *u,*y;
49197453f775SEmil Constantinescu   PetscReal         sum,suma,sumr,gsum,gsuma,gsumr,diff;
49207453f775SEmil Constantinescu   PetscReal         tol,tola,tolr;
49217453f775SEmil Constantinescu   PetscReal         err_loc[6],err_glb[6];
49229c6b16b5SShri Abhyankar 
49239c6b16b5SShri Abhyankar   PetscFunctionBegin;
49249c6b16b5SShri Abhyankar   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
4925a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
4926a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
4927a4868fbcSLisandro Dalcin   PetscValidType(U,2);
4928a4868fbcSLisandro Dalcin   PetscValidType(Y,3);
4929a4868fbcSLisandro Dalcin   PetscCheckSameComm(U,2,Y,3);
4930dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm,4);
4931dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma,5);
4932dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr,6);
49333c633725SBarry Smith   PetscCheck(U != Y,PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
49349c6b16b5SShri Abhyankar 
49359566063dSJacob Faibussowitsch   PetscCall(VecGetSize(U,&N));
49369566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U,&n));
49379566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(U,&rstart,NULL));
49389566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U,&u));
49399566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y,&y));
49407453f775SEmil Constantinescu   sum  = 0.; n_loc  = 0;
49417453f775SEmil Constantinescu   suma = 0.; na_loc = 0;
49427453f775SEmil Constantinescu   sumr = 0.; nr_loc = 0;
49439c6b16b5SShri Abhyankar   if (ts->vatol && ts->vrtol) {
49449c6b16b5SShri Abhyankar     const PetscScalar *atol,*rtol;
49459566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
49469566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
49479c6b16b5SShri Abhyankar     for (i=0; i<n; i++) {
494876cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
49497453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49507453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
49517453f775SEmil Constantinescu       if (tola>0.) {
49527453f775SEmil Constantinescu         suma  += PetscSqr(diff/tola);
49537453f775SEmil Constantinescu         na_loc++;
49547453f775SEmil Constantinescu       }
49557453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
49567453f775SEmil Constantinescu       if (tolr>0.) {
49577453f775SEmil Constantinescu         sumr  += PetscSqr(diff/tolr);
49587453f775SEmil Constantinescu         nr_loc++;
49597453f775SEmil Constantinescu       }
49607453f775SEmil Constantinescu       tol=tola+tolr;
49617453f775SEmil Constantinescu       if (tol>0.) {
49627453f775SEmil Constantinescu         sum  += PetscSqr(diff/tol);
49637453f775SEmil Constantinescu         n_loc++;
49647453f775SEmil Constantinescu       }
49659c6b16b5SShri Abhyankar     }
49669566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
49679566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
49689c6b16b5SShri Abhyankar   } else if (ts->vatol) {       /* vector atol, scalar rtol */
49699c6b16b5SShri Abhyankar     const PetscScalar *atol;
49709566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
49719c6b16b5SShri Abhyankar     for (i=0; i<n; i++) {
497276cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
49737453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49747453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
49757453f775SEmil Constantinescu       if (tola>0.) {
49767453f775SEmil Constantinescu         suma  += PetscSqr(diff/tola);
49777453f775SEmil Constantinescu         na_loc++;
49787453f775SEmil Constantinescu       }
49797453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
49807453f775SEmil Constantinescu       if (tolr>0.) {
49817453f775SEmil Constantinescu         sumr  += PetscSqr(diff/tolr);
49827453f775SEmil Constantinescu         nr_loc++;
49837453f775SEmil Constantinescu       }
49847453f775SEmil Constantinescu       tol=tola+tolr;
49857453f775SEmil Constantinescu       if (tol>0.) {
49867453f775SEmil Constantinescu         sum  += PetscSqr(diff/tol);
49877453f775SEmil Constantinescu         n_loc++;
49887453f775SEmil Constantinescu       }
49899c6b16b5SShri Abhyankar     }
49909566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
49919c6b16b5SShri Abhyankar   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
49929c6b16b5SShri Abhyankar     const PetscScalar *rtol;
49939566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
49949c6b16b5SShri Abhyankar     for (i=0; i<n; i++) {
499576cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
49967453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
49977453f775SEmil Constantinescu       tola = ts->atol;
49987453f775SEmil Constantinescu       if (tola>0.) {
49997453f775SEmil Constantinescu         suma  += PetscSqr(diff/tola);
50007453f775SEmil Constantinescu         na_loc++;
50017453f775SEmil Constantinescu       }
50027453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
50037453f775SEmil Constantinescu       if (tolr>0.) {
50047453f775SEmil Constantinescu         sumr  += PetscSqr(diff/tolr);
50057453f775SEmil Constantinescu         nr_loc++;
50067453f775SEmil Constantinescu       }
50077453f775SEmil Constantinescu       tol=tola+tolr;
50087453f775SEmil Constantinescu       if (tol>0.) {
50097453f775SEmil Constantinescu         sum  += PetscSqr(diff/tol);
50107453f775SEmil Constantinescu         n_loc++;
50117453f775SEmil Constantinescu       }
50129c6b16b5SShri Abhyankar     }
50139566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
50149c6b16b5SShri Abhyankar   } else {                      /* scalar atol, scalar rtol */
50159c6b16b5SShri Abhyankar     for (i=0; i<n; i++) {
501676cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
50177453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
50187453f775SEmil Constantinescu       tola = ts->atol;
50197453f775SEmil Constantinescu       if (tola>0.) {
50207453f775SEmil Constantinescu         suma  += PetscSqr(diff/tola);
50217453f775SEmil Constantinescu         na_loc++;
50227453f775SEmil Constantinescu       }
50237453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
50247453f775SEmil Constantinescu       if (tolr>0.) {
50257453f775SEmil Constantinescu         sumr  += PetscSqr(diff/tolr);
50267453f775SEmil Constantinescu         nr_loc++;
50277453f775SEmil Constantinescu       }
50287453f775SEmil Constantinescu       tol=tola+tolr;
50297453f775SEmil Constantinescu       if (tol>0.) {
50307453f775SEmil Constantinescu         sum  += PetscSqr(diff/tol);
50317453f775SEmil Constantinescu         n_loc++;
50327453f775SEmil Constantinescu       }
50339c6b16b5SShri Abhyankar     }
50349c6b16b5SShri Abhyankar   }
50359566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U,&u));
50369566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y,&y));
50379c6b16b5SShri Abhyankar 
50387453f775SEmil Constantinescu   err_loc[0] = sum;
50397453f775SEmil Constantinescu   err_loc[1] = suma;
50407453f775SEmil Constantinescu   err_loc[2] = sumr;
50417453f775SEmil Constantinescu   err_loc[3] = (PetscReal)n_loc;
50427453f775SEmil Constantinescu   err_loc[4] = (PetscReal)na_loc;
50437453f775SEmil Constantinescu   err_loc[5] = (PetscReal)nr_loc;
50447453f775SEmil Constantinescu 
50451c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts)));
50467453f775SEmil Constantinescu 
50477453f775SEmil Constantinescu   gsum   = err_glb[0];
50487453f775SEmil Constantinescu   gsuma  = err_glb[1];
50497453f775SEmil Constantinescu   gsumr  = err_glb[2];
50507453f775SEmil Constantinescu   n_glb  = err_glb[3];
50517453f775SEmil Constantinescu   na_glb = err_glb[4];
50527453f775SEmil Constantinescu   nr_glb = err_glb[5];
50537453f775SEmil Constantinescu 
5054b1316ef9SEmil Constantinescu   *norm  = 0.;
5055b1316ef9SEmil Constantinescu   if (n_glb>0.) {*norm  = PetscSqrtReal(gsum  / n_glb);}
5056b1316ef9SEmil Constantinescu   *norma = 0.;
5057b1316ef9SEmil Constantinescu   if (na_glb>0.) {*norma = PetscSqrtReal(gsuma / na_glb);}
5058b1316ef9SEmil Constantinescu   *normr = 0.;
5059b1316ef9SEmil Constantinescu   if (nr_glb>0.) {*normr = PetscSqrtReal(gsumr / nr_glb);}
50609c6b16b5SShri Abhyankar 
50613c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
50623c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
50633c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
50649c6b16b5SShri Abhyankar   PetscFunctionReturn(0);
50659c6b16b5SShri Abhyankar }
50669c6b16b5SShri Abhyankar 
50679c6b16b5SShri Abhyankar /*@
5068a4868fbcSLisandro Dalcin    TSErrorWeightedNormInfinity - compute a weighted infinity-norm of the difference between two state vectors
50699c6b16b5SShri Abhyankar 
50709c6b16b5SShri Abhyankar    Collective on TS
50719c6b16b5SShri Abhyankar 
50724165533cSJose E. Roman    Input Parameters:
50739c6b16b5SShri Abhyankar +  ts - time stepping context
5074a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
5075a4868fbcSLisandro Dalcin -  Y - state vector to be compared to U
50769c6b16b5SShri Abhyankar 
50774165533cSJose E. Roman    Output Parameters:
5078a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
50797453f775SEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5080a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
50819c6b16b5SShri Abhyankar 
50829c6b16b5SShri Abhyankar    Level: developer
50839c6b16b5SShri Abhyankar 
5084db781477SPatrick Sanan .seealso: `TSErrorWeightedNorm()`, `TSErrorWeightedNorm2()`
50859c6b16b5SShri Abhyankar @*/
50867453f775SEmil Constantinescu PetscErrorCode TSErrorWeightedNormInfinity(TS ts,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
50879c6b16b5SShri Abhyankar {
50887453f775SEmil Constantinescu   PetscInt          i,n,N,rstart;
50899c6b16b5SShri Abhyankar   const PetscScalar *u,*y;
50907453f775SEmil Constantinescu   PetscReal         max,gmax,maxa,gmaxa,maxr,gmaxr;
50917453f775SEmil Constantinescu   PetscReal         tol,tola,tolr,diff;
50927453f775SEmil Constantinescu   PetscReal         err_loc[3],err_glb[3];
50939c6b16b5SShri Abhyankar 
50949c6b16b5SShri Abhyankar   PetscFunctionBegin;
50959c6b16b5SShri Abhyankar   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5096a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(U,VEC_CLASSID,2);
5097a4868fbcSLisandro Dalcin   PetscValidHeaderSpecific(Y,VEC_CLASSID,3);
5098a4868fbcSLisandro Dalcin   PetscValidType(U,2);
5099a4868fbcSLisandro Dalcin   PetscValidType(Y,3);
5100a4868fbcSLisandro Dalcin   PetscCheckSameComm(U,2,Y,3);
5101dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm,4);
5102dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma,5);
5103dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr,6);
51043c633725SBarry Smith   PetscCheck(U != Y,PetscObjectComm((PetscObject)U),PETSC_ERR_ARG_IDN,"U and Y cannot be the same vector");
51059c6b16b5SShri Abhyankar 
51069566063dSJacob Faibussowitsch   PetscCall(VecGetSize(U,&N));
51079566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(U,&n));
51089566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(U,&rstart,NULL));
51099566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U,&u));
51109566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y,&y));
51117453f775SEmil Constantinescu 
51127453f775SEmil Constantinescu   max=0.;
51137453f775SEmil Constantinescu   maxa=0.;
51147453f775SEmil Constantinescu   maxr=0.;
51157453f775SEmil Constantinescu 
51167453f775SEmil Constantinescu   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
51179c6b16b5SShri Abhyankar     const PetscScalar *atol,*rtol;
51189566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
51199566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
51207453f775SEmil Constantinescu 
51217453f775SEmil Constantinescu     for (i=0; i<n; i++) {
512276cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
51237453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
51247453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
51257453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
51267453f775SEmil Constantinescu       tol  = tola+tolr;
51277453f775SEmil Constantinescu       if (tola>0.) {
51287453f775SEmil Constantinescu         maxa = PetscMax(maxa,diff / tola);
51297453f775SEmil Constantinescu       }
51307453f775SEmil Constantinescu       if (tolr>0.) {
51317453f775SEmil Constantinescu         maxr = PetscMax(maxr,diff / tolr);
51327453f775SEmil Constantinescu       }
51337453f775SEmil Constantinescu       if (tol>0.) {
51347453f775SEmil Constantinescu         max = PetscMax(max,diff / tol);
51357453f775SEmil Constantinescu       }
51369c6b16b5SShri Abhyankar     }
51379566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
51389566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
51399c6b16b5SShri Abhyankar   } else if (ts->vatol) {       /* vector atol, scalar rtol */
51409c6b16b5SShri Abhyankar     const PetscScalar *atol;
51419566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
51427453f775SEmil Constantinescu     for (i=0; i<n; i++) {
514376cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
51447453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
51457453f775SEmil Constantinescu       tola = PetscRealPart(atol[i]);
51467453f775SEmil Constantinescu       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
51477453f775SEmil Constantinescu       tol  = tola+tolr;
51487453f775SEmil Constantinescu       if (tola>0.) {
51497453f775SEmil Constantinescu         maxa = PetscMax(maxa,diff / tola);
51507453f775SEmil Constantinescu       }
51517453f775SEmil Constantinescu       if (tolr>0.) {
51527453f775SEmil Constantinescu         maxr = PetscMax(maxr,diff / tolr);
51537453f775SEmil Constantinescu       }
51547453f775SEmil Constantinescu       if (tol>0.) {
51557453f775SEmil Constantinescu         max = PetscMax(max,diff / tol);
51567453f775SEmil Constantinescu       }
51579c6b16b5SShri Abhyankar     }
51589566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
51599c6b16b5SShri Abhyankar   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
51609c6b16b5SShri Abhyankar     const PetscScalar *rtol;
51619566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
51627453f775SEmil Constantinescu 
51637453f775SEmil Constantinescu     for (i=0; i<n; i++) {
516476cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
51657453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
51667453f775SEmil Constantinescu       tola = ts->atol;
51677453f775SEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
51687453f775SEmil Constantinescu       tol  = tola+tolr;
51697453f775SEmil Constantinescu       if (tola>0.) {
51707453f775SEmil Constantinescu         maxa = PetscMax(maxa,diff / tola);
51717453f775SEmil Constantinescu       }
51727453f775SEmil Constantinescu       if (tolr>0.) {
51737453f775SEmil Constantinescu         maxr = PetscMax(maxr,diff / tolr);
51747453f775SEmil Constantinescu       }
51757453f775SEmil Constantinescu       if (tol>0.) {
51767453f775SEmil Constantinescu         max = PetscMax(max,diff / tol);
51777453f775SEmil Constantinescu       }
51789c6b16b5SShri Abhyankar     }
51799566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
51809c6b16b5SShri Abhyankar   } else {                      /* scalar atol, scalar rtol */
51817453f775SEmil Constantinescu 
51827453f775SEmil Constantinescu     for (i=0; i<n; i++) {
518376cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
51847453f775SEmil Constantinescu       diff = PetscAbsScalar(y[i] - u[i]);
51857453f775SEmil Constantinescu       tola = ts->atol;
51867453f775SEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
51877453f775SEmil Constantinescu       tol  = tola+tolr;
51887453f775SEmil Constantinescu       if (tola>0.) {
51897453f775SEmil Constantinescu         maxa = PetscMax(maxa,diff / tola);
51907453f775SEmil Constantinescu       }
51917453f775SEmil Constantinescu       if (tolr>0.) {
51927453f775SEmil Constantinescu         maxr = PetscMax(maxr,diff / tolr);
51937453f775SEmil Constantinescu       }
51947453f775SEmil Constantinescu       if (tol>0.) {
51957453f775SEmil Constantinescu         max = PetscMax(max,diff / tol);
51967453f775SEmil Constantinescu       }
51979c6b16b5SShri Abhyankar     }
51989c6b16b5SShri Abhyankar   }
51999566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U,&u));
52009566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y,&y));
52017453f775SEmil Constantinescu   err_loc[0] = max;
52027453f775SEmil Constantinescu   err_loc[1] = maxa;
52037453f775SEmil Constantinescu   err_loc[2] = maxr;
52041c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts)));
52057453f775SEmil Constantinescu   gmax   = err_glb[0];
52067453f775SEmil Constantinescu   gmaxa  = err_glb[1];
52077453f775SEmil Constantinescu   gmaxr  = err_glb[2];
52089c6b16b5SShri Abhyankar 
52099c6b16b5SShri Abhyankar   *norm = gmax;
52107453f775SEmil Constantinescu   *norma = gmaxa;
52117453f775SEmil Constantinescu   *normr = gmaxr;
52123c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
52133c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
52143c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
52159c6b16b5SShri Abhyankar   PetscFunctionReturn(0);
52169c6b16b5SShri Abhyankar }
52179c6b16b5SShri Abhyankar 
52181c3436cfSJed Brown /*@
52198a175baeSEmil Constantinescu    TSErrorWeightedNorm - compute a weighted norm of the difference between two state vectors based on supplied absolute and relative tolerances
52201c3436cfSJed Brown 
52211c3436cfSJed Brown    Collective on TS
52221c3436cfSJed Brown 
52234165533cSJose E. Roman    Input Parameters:
52241c3436cfSJed Brown +  ts - time stepping context
5225a4868fbcSLisandro Dalcin .  U - state vector, usually ts->vec_sol
5226a4868fbcSLisandro Dalcin .  Y - state vector to be compared to U
5227a4868fbcSLisandro Dalcin -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
52287619abb3SShri 
52294165533cSJose E. Roman    Output Parameters:
5230a2b725a8SWilliam Gropp +  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
52318a175baeSEmil Constantinescu .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5232a2b725a8SWilliam Gropp -  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
5233a4868fbcSLisandro Dalcin 
5234a4868fbcSLisandro Dalcin    Options Database Keys:
5235a4868fbcSLisandro Dalcin .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
5236a4868fbcSLisandro Dalcin 
52371c3436cfSJed Brown    Level: developer
52381c3436cfSJed Brown 
5239db781477SPatrick Sanan .seealso: `TSErrorWeightedNormInfinity()`, `TSErrorWeightedNorm2()`, `TSErrorWeightedENorm`
52401c3436cfSJed Brown @*/
52417453f775SEmil Constantinescu PetscErrorCode TSErrorWeightedNorm(TS ts,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
52421c3436cfSJed Brown {
52431c3436cfSJed Brown   PetscFunctionBegin;
5244a4868fbcSLisandro Dalcin   if (wnormtype == NORM_2) {
52459566063dSJacob Faibussowitsch     PetscCall(TSErrorWeightedNorm2(ts,U,Y,norm,norma,normr));
5246a4868fbcSLisandro Dalcin   } else if (wnormtype == NORM_INFINITY) {
52479566063dSJacob Faibussowitsch     PetscCall(TSErrorWeightedNormInfinity(ts,U,Y,norm,norma,normr));
524898921bdaSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
52491c3436cfSJed Brown   PetscFunctionReturn(0);
52501c3436cfSJed Brown }
52511c3436cfSJed Brown 
52528a175baeSEmil Constantinescu /*@
52538a175baeSEmil Constantinescu    TSErrorWeightedENorm2 - compute a weighted 2 error norm based on supplied absolute and relative tolerances
52548a175baeSEmil Constantinescu 
52558a175baeSEmil Constantinescu    Collective on TS
52568a175baeSEmil Constantinescu 
52574165533cSJose E. Roman    Input Parameters:
52588a175baeSEmil Constantinescu +  ts - time stepping context
52598a175baeSEmil Constantinescu .  E - error vector
52608a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
52618a175baeSEmil Constantinescu -  Y - state vector, previous time step
52628a175baeSEmil Constantinescu 
52634165533cSJose E. Roman    Output Parameters:
5264a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
52658a175baeSEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5266a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
52678a175baeSEmil Constantinescu 
52688a175baeSEmil Constantinescu    Level: developer
52698a175baeSEmil Constantinescu 
5270db781477SPatrick Sanan .seealso: `TSErrorWeightedENorm()`, `TSErrorWeightedENormInfinity()`
52718a175baeSEmil Constantinescu @*/
52728a175baeSEmil Constantinescu PetscErrorCode TSErrorWeightedENorm2(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
52738a175baeSEmil Constantinescu {
52748a175baeSEmil Constantinescu   PetscInt          i,n,N,rstart;
52758a175baeSEmil Constantinescu   PetscInt          n_loc,na_loc,nr_loc;
52768a175baeSEmil Constantinescu   PetscReal         n_glb,na_glb,nr_glb;
52778a175baeSEmil Constantinescu   const PetscScalar *e,*u,*y;
52788a175baeSEmil Constantinescu   PetscReal         err,sum,suma,sumr,gsum,gsuma,gsumr;
52798a175baeSEmil Constantinescu   PetscReal         tol,tola,tolr;
52808a175baeSEmil Constantinescu   PetscReal         err_loc[6],err_glb[6];
52818a175baeSEmil Constantinescu 
52828a175baeSEmil Constantinescu   PetscFunctionBegin;
52838a175baeSEmil Constantinescu   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
52848a175baeSEmil Constantinescu   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
52858a175baeSEmil Constantinescu   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
52868a175baeSEmil Constantinescu   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
52878a175baeSEmil Constantinescu   PetscValidType(E,2);
52888a175baeSEmil Constantinescu   PetscValidType(U,3);
52898a175baeSEmil Constantinescu   PetscValidType(Y,4);
52908a175baeSEmil Constantinescu   PetscCheckSameComm(E,2,U,3);
5291064a246eSJacob Faibussowitsch   PetscCheckSameComm(U,3,Y,4);
5292dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm,5);
5293dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma,6);
5294dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr,7);
52958a175baeSEmil Constantinescu 
52969566063dSJacob Faibussowitsch   PetscCall(VecGetSize(E,&N));
52979566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(E,&n));
52989566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(E,&rstart,NULL));
52999566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(E,&e));
53009566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U,&u));
53019566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y,&y));
53028a175baeSEmil Constantinescu   sum  = 0.; n_loc  = 0;
53038a175baeSEmil Constantinescu   suma = 0.; na_loc = 0;
53048a175baeSEmil Constantinescu   sumr = 0.; nr_loc = 0;
53058a175baeSEmil Constantinescu   if (ts->vatol && ts->vrtol) {
53068a175baeSEmil Constantinescu     const PetscScalar *atol,*rtol;
53079566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
53089566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
53098a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
531076cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
53118a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
53128a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
53138a175baeSEmil Constantinescu       if (tola>0.) {
53148a175baeSEmil Constantinescu         suma  += PetscSqr(err/tola);
53158a175baeSEmil Constantinescu         na_loc++;
53168a175baeSEmil Constantinescu       }
53178a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
53188a175baeSEmil Constantinescu       if (tolr>0.) {
53198a175baeSEmil Constantinescu         sumr  += PetscSqr(err/tolr);
53208a175baeSEmil Constantinescu         nr_loc++;
53218a175baeSEmil Constantinescu       }
53228a175baeSEmil Constantinescu       tol=tola+tolr;
53238a175baeSEmil Constantinescu       if (tol>0.) {
53248a175baeSEmil Constantinescu         sum  += PetscSqr(err/tol);
53258a175baeSEmil Constantinescu         n_loc++;
53268a175baeSEmil Constantinescu       }
53278a175baeSEmil Constantinescu     }
53289566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
53299566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
53308a175baeSEmil Constantinescu   } else if (ts->vatol) {       /* vector atol, scalar rtol */
53318a175baeSEmil Constantinescu     const PetscScalar *atol;
53329566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
53338a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
533476cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
53358a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
53368a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
53378a175baeSEmil Constantinescu       if (tola>0.) {
53388a175baeSEmil Constantinescu         suma  += PetscSqr(err/tola);
53398a175baeSEmil Constantinescu         na_loc++;
53408a175baeSEmil Constantinescu       }
53418a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
53428a175baeSEmil Constantinescu       if (tolr>0.) {
53438a175baeSEmil Constantinescu         sumr  += PetscSqr(err/tolr);
53448a175baeSEmil Constantinescu         nr_loc++;
53458a175baeSEmil Constantinescu       }
53468a175baeSEmil Constantinescu       tol=tola+tolr;
53478a175baeSEmil Constantinescu       if (tol>0.) {
53488a175baeSEmil Constantinescu         sum  += PetscSqr(err/tol);
53498a175baeSEmil Constantinescu         n_loc++;
53508a175baeSEmil Constantinescu       }
53518a175baeSEmil Constantinescu     }
53529566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
53538a175baeSEmil Constantinescu   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
53548a175baeSEmil Constantinescu     const PetscScalar *rtol;
53559566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
53568a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
535776cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
53588a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
53598a175baeSEmil Constantinescu       tola = ts->atol;
53608a175baeSEmil Constantinescu       if (tola>0.) {
53618a175baeSEmil Constantinescu         suma  += PetscSqr(err/tola);
53628a175baeSEmil Constantinescu         na_loc++;
53638a175baeSEmil Constantinescu       }
53648a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
53658a175baeSEmil Constantinescu       if (tolr>0.) {
53668a175baeSEmil Constantinescu         sumr  += PetscSqr(err/tolr);
53678a175baeSEmil Constantinescu         nr_loc++;
53688a175baeSEmil Constantinescu       }
53698a175baeSEmil Constantinescu       tol=tola+tolr;
53708a175baeSEmil Constantinescu       if (tol>0.) {
53718a175baeSEmil Constantinescu         sum  += PetscSqr(err/tol);
53728a175baeSEmil Constantinescu         n_loc++;
53738a175baeSEmil Constantinescu       }
53748a175baeSEmil Constantinescu     }
53759566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
53768a175baeSEmil Constantinescu   } else {                      /* scalar atol, scalar rtol */
53778a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
537876cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
53798a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
53808a175baeSEmil Constantinescu       tola = ts->atol;
53818a175baeSEmil Constantinescu       if (tola>0.) {
53828a175baeSEmil Constantinescu         suma  += PetscSqr(err/tola);
53838a175baeSEmil Constantinescu         na_loc++;
53848a175baeSEmil Constantinescu       }
53858a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
53868a175baeSEmil Constantinescu       if (tolr>0.) {
53878a175baeSEmil Constantinescu         sumr  += PetscSqr(err/tolr);
53888a175baeSEmil Constantinescu         nr_loc++;
53898a175baeSEmil Constantinescu       }
53908a175baeSEmil Constantinescu       tol=tola+tolr;
53918a175baeSEmil Constantinescu       if (tol>0.) {
53928a175baeSEmil Constantinescu         sum  += PetscSqr(err/tol);
53938a175baeSEmil Constantinescu         n_loc++;
53948a175baeSEmil Constantinescu       }
53958a175baeSEmil Constantinescu     }
53968a175baeSEmil Constantinescu   }
53979566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(E,&e));
53989566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U,&u));
53999566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y,&y));
54008a175baeSEmil Constantinescu 
54018a175baeSEmil Constantinescu   err_loc[0] = sum;
54028a175baeSEmil Constantinescu   err_loc[1] = suma;
54038a175baeSEmil Constantinescu   err_loc[2] = sumr;
54048a175baeSEmil Constantinescu   err_loc[3] = (PetscReal)n_loc;
54058a175baeSEmil Constantinescu   err_loc[4] = (PetscReal)na_loc;
54068a175baeSEmil Constantinescu   err_loc[5] = (PetscReal)nr_loc;
54078a175baeSEmil Constantinescu 
54081c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc,err_glb,6,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)ts)));
54098a175baeSEmil Constantinescu 
54108a175baeSEmil Constantinescu   gsum   = err_glb[0];
54118a175baeSEmil Constantinescu   gsuma  = err_glb[1];
54128a175baeSEmil Constantinescu   gsumr  = err_glb[2];
54138a175baeSEmil Constantinescu   n_glb  = err_glb[3];
54148a175baeSEmil Constantinescu   na_glb = err_glb[4];
54158a175baeSEmil Constantinescu   nr_glb = err_glb[5];
54168a175baeSEmil Constantinescu 
54178a175baeSEmil Constantinescu   *norm  = 0.;
54188a175baeSEmil Constantinescu   if (n_glb>0.) {*norm  = PetscSqrtReal(gsum  / n_glb);}
54198a175baeSEmil Constantinescu   *norma = 0.;
54208a175baeSEmil Constantinescu   if (na_glb>0.) {*norma = PetscSqrtReal(gsuma / na_glb);}
54218a175baeSEmil Constantinescu   *normr = 0.;
54228a175baeSEmil Constantinescu   if (nr_glb>0.) {*normr = PetscSqrtReal(gsumr / nr_glb);}
54238a175baeSEmil Constantinescu 
54243c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
54253c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
54263c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
54278a175baeSEmil Constantinescu   PetscFunctionReturn(0);
54288a175baeSEmil Constantinescu }
54298a175baeSEmil Constantinescu 
54308a175baeSEmil Constantinescu /*@
54318a175baeSEmil Constantinescu    TSErrorWeightedENormInfinity - compute a weighted infinity error norm based on supplied absolute and relative tolerances
54328a175baeSEmil Constantinescu    Collective on TS
54338a175baeSEmil Constantinescu 
54344165533cSJose E. Roman    Input Parameters:
54358a175baeSEmil Constantinescu +  ts - time stepping context
54368a175baeSEmil Constantinescu .  E - error vector
54378a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
54388a175baeSEmil Constantinescu -  Y - state vector, previous time step
54398a175baeSEmil Constantinescu 
54404165533cSJose E. Roman    Output Parameters:
5441a2b725a8SWilliam Gropp +  norm - weighted norm, a value of 1.0 means that the error matches the tolerances
54428a175baeSEmil Constantinescu .  norma - weighted norm based on the absolute tolerance, a value of 1.0 means that the error matches the tolerances
5443a2b725a8SWilliam Gropp -  normr - weighted norm based on the relative tolerance, a value of 1.0 means that the error matches the tolerances
54448a175baeSEmil Constantinescu 
54458a175baeSEmil Constantinescu    Level: developer
54468a175baeSEmil Constantinescu 
5447db781477SPatrick Sanan .seealso: `TSErrorWeightedENorm()`, `TSErrorWeightedENorm2()`
54488a175baeSEmil Constantinescu @*/
54498a175baeSEmil Constantinescu PetscErrorCode TSErrorWeightedENormInfinity(TS ts,Vec E,Vec U,Vec Y,PetscReal *norm,PetscReal *norma,PetscReal *normr)
54508a175baeSEmil Constantinescu {
54518a175baeSEmil Constantinescu   PetscInt          i,n,N,rstart;
54528a175baeSEmil Constantinescu   const PetscScalar *e,*u,*y;
54538a175baeSEmil Constantinescu   PetscReal         err,max,gmax,maxa,gmaxa,maxr,gmaxr;
54548a175baeSEmil Constantinescu   PetscReal         tol,tola,tolr;
54558a175baeSEmil Constantinescu   PetscReal         err_loc[3],err_glb[3];
54568a175baeSEmil Constantinescu 
54578a175baeSEmil Constantinescu   PetscFunctionBegin;
54588a175baeSEmil Constantinescu   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
54598a175baeSEmil Constantinescu   PetscValidHeaderSpecific(E,VEC_CLASSID,2);
54608a175baeSEmil Constantinescu   PetscValidHeaderSpecific(U,VEC_CLASSID,3);
54618a175baeSEmil Constantinescu   PetscValidHeaderSpecific(Y,VEC_CLASSID,4);
54628a175baeSEmil Constantinescu   PetscValidType(E,2);
54638a175baeSEmil Constantinescu   PetscValidType(U,3);
54648a175baeSEmil Constantinescu   PetscValidType(Y,4);
54658a175baeSEmil Constantinescu   PetscCheckSameComm(E,2,U,3);
5466064a246eSJacob Faibussowitsch   PetscCheckSameComm(U,3,Y,4);
5467dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm,5);
5468dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norma,6);
5469dadcf809SJacob Faibussowitsch   PetscValidRealPointer(normr,7);
54708a175baeSEmil Constantinescu 
54719566063dSJacob Faibussowitsch   PetscCall(VecGetSize(E,&N));
54729566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(E,&n));
54739566063dSJacob Faibussowitsch   PetscCall(VecGetOwnershipRange(E,&rstart,NULL));
54749566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(E,&e));
54759566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(U,&u));
54769566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(Y,&y));
54778a175baeSEmil Constantinescu 
54788a175baeSEmil Constantinescu   max=0.;
54798a175baeSEmil Constantinescu   maxa=0.;
54808a175baeSEmil Constantinescu   maxr=0.;
54818a175baeSEmil Constantinescu 
54828a175baeSEmil Constantinescu   if (ts->vatol && ts->vrtol) {     /* vector atol, vector rtol */
54838a175baeSEmil Constantinescu     const PetscScalar *atol,*rtol;
54849566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
54859566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
54868a175baeSEmil Constantinescu 
54878a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
548876cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
54898a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
54908a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
54918a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
54928a175baeSEmil Constantinescu       tol  = tola+tolr;
54938a175baeSEmil Constantinescu       if (tola>0.) {
54948a175baeSEmil Constantinescu         maxa = PetscMax(maxa,err / tola);
54958a175baeSEmil Constantinescu       }
54968a175baeSEmil Constantinescu       if (tolr>0.) {
54978a175baeSEmil Constantinescu         maxr = PetscMax(maxr,err / tolr);
54988a175baeSEmil Constantinescu       }
54998a175baeSEmil Constantinescu       if (tol>0.) {
55008a175baeSEmil Constantinescu         max = PetscMax(max,err / tol);
55018a175baeSEmil Constantinescu       }
55028a175baeSEmil Constantinescu     }
55039566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
55049566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
55058a175baeSEmil Constantinescu   } else if (ts->vatol) {       /* vector atol, scalar rtol */
55068a175baeSEmil Constantinescu     const PetscScalar *atol;
55079566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vatol,&atol));
55088a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
550976cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
55108a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
55118a175baeSEmil Constantinescu       tola = PetscRealPart(atol[i]);
55128a175baeSEmil Constantinescu       tolr = ts->rtol  * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
55138a175baeSEmil Constantinescu       tol  = tola+tolr;
55148a175baeSEmil Constantinescu       if (tola>0.) {
55158a175baeSEmil Constantinescu         maxa = PetscMax(maxa,err / tola);
55168a175baeSEmil Constantinescu       }
55178a175baeSEmil Constantinescu       if (tolr>0.) {
55188a175baeSEmil Constantinescu         maxr = PetscMax(maxr,err / tolr);
55198a175baeSEmil Constantinescu       }
55208a175baeSEmil Constantinescu       if (tol>0.) {
55218a175baeSEmil Constantinescu         max = PetscMax(max,err / tol);
55228a175baeSEmil Constantinescu       }
55238a175baeSEmil Constantinescu     }
55249566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vatol,&atol));
55258a175baeSEmil Constantinescu   } else if (ts->vrtol) {       /* scalar atol, vector rtol */
55268a175baeSEmil Constantinescu     const PetscScalar *rtol;
55279566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ts->vrtol,&rtol));
55288a175baeSEmil Constantinescu 
55298a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
553076cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
55318a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
55328a175baeSEmil Constantinescu       tola = ts->atol;
55338a175baeSEmil Constantinescu       tolr = PetscRealPart(rtol[i]) * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
55348a175baeSEmil Constantinescu       tol  = tola+tolr;
55358a175baeSEmil Constantinescu       if (tola>0.) {
55368a175baeSEmil Constantinescu         maxa = PetscMax(maxa,err / tola);
55378a175baeSEmil Constantinescu       }
55388a175baeSEmil Constantinescu       if (tolr>0.) {
55398a175baeSEmil Constantinescu         maxr = PetscMax(maxr,err / tolr);
55408a175baeSEmil Constantinescu       }
55418a175baeSEmil Constantinescu       if (tol>0.) {
55428a175baeSEmil Constantinescu         max = PetscMax(max,err / tol);
55438a175baeSEmil Constantinescu       }
55448a175baeSEmil Constantinescu     }
55459566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ts->vrtol,&rtol));
55468a175baeSEmil Constantinescu   } else {                      /* scalar atol, scalar rtol */
55478a175baeSEmil Constantinescu 
55488a175baeSEmil Constantinescu     for (i=0; i<n; i++) {
554976cddca1SEmil Constantinescu       SkipSmallValue(y[i],u[i],ts->adapt->ignore_max);
55508a175baeSEmil Constantinescu       err = PetscAbsScalar(e[i]);
55518a175baeSEmil Constantinescu       tola = ts->atol;
55528a175baeSEmil Constantinescu       tolr = ts->rtol * PetscMax(PetscAbsScalar(u[i]),PetscAbsScalar(y[i]));
55538a175baeSEmil Constantinescu       tol  = tola+tolr;
55548a175baeSEmil Constantinescu       if (tola>0.) {
55558a175baeSEmil Constantinescu         maxa = PetscMax(maxa,err / tola);
55568a175baeSEmil Constantinescu       }
55578a175baeSEmil Constantinescu       if (tolr>0.) {
55588a175baeSEmil Constantinescu         maxr = PetscMax(maxr,err / tolr);
55598a175baeSEmil Constantinescu       }
55608a175baeSEmil Constantinescu       if (tol>0.) {
55618a175baeSEmil Constantinescu         max = PetscMax(max,err / tol);
55628a175baeSEmil Constantinescu       }
55638a175baeSEmil Constantinescu     }
55648a175baeSEmil Constantinescu   }
55659566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(E,&e));
55669566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(U,&u));
55679566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(Y,&y));
55688a175baeSEmil Constantinescu   err_loc[0] = max;
55698a175baeSEmil Constantinescu   err_loc[1] = maxa;
55708a175baeSEmil Constantinescu   err_loc[2] = maxr;
55711c2dc1cbSBarry Smith   PetscCall(MPIU_Allreduce(err_loc,err_glb,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)ts)));
55728a175baeSEmil Constantinescu   gmax   = err_glb[0];
55738a175baeSEmil Constantinescu   gmaxa  = err_glb[1];
55748a175baeSEmil Constantinescu   gmaxr  = err_glb[2];
55758a175baeSEmil Constantinescu 
55768a175baeSEmil Constantinescu   *norm = gmax;
55778a175baeSEmil Constantinescu   *norma = gmaxa;
55788a175baeSEmil Constantinescu   *normr = gmaxr;
55793c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norm),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
55803c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*norma),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in norma");
55813c633725SBarry Smith   PetscCheck(!PetscIsInfOrNanScalar(*normr),PetscObjectComm((PetscObject)ts),PETSC_ERR_FP,"Infinite or not-a-number generated in normr");
55828a175baeSEmil Constantinescu   PetscFunctionReturn(0);
55838a175baeSEmil Constantinescu }
55848a175baeSEmil Constantinescu 
55858a175baeSEmil Constantinescu /*@
55868a175baeSEmil Constantinescu    TSErrorWeightedENorm - compute a weighted error norm based on supplied absolute and relative tolerances
55878a175baeSEmil Constantinescu 
55888a175baeSEmil Constantinescu    Collective on TS
55898a175baeSEmil Constantinescu 
55904165533cSJose E. Roman    Input Parameters:
55918a175baeSEmil Constantinescu +  ts - time stepping context
55928a175baeSEmil Constantinescu .  E - error vector
55938a175baeSEmil Constantinescu .  U - state vector, usually ts->vec_sol
55948a175baeSEmil Constantinescu .  Y - state vector, previous time step
55958a175baeSEmil Constantinescu -  wnormtype - norm type, either NORM_2 or NORM_INFINITY
55968a175baeSEmil Constantinescu 
55974165533cSJose E. Roman    Output Parameters:
5598a2b725a8SWilliam Gropp +  norm  - weighted norm, a value of 1.0 achieves a balance between absolute and relative tolerances
55998a175baeSEmil Constantinescu .  norma - weighted norm, a value of 1.0 means that the error meets the absolute tolerance set by the user
5600a2b725a8SWilliam Gropp -  normr - weighted norm, a value of 1.0 means that the error meets the relative tolerance set by the user
56018a175baeSEmil Constantinescu 
56028a175baeSEmil Constantinescu    Options Database Keys:
56038a175baeSEmil Constantinescu .  -ts_adapt_wnormtype <wnormtype> - 2, INFINITY
56048a175baeSEmil Constantinescu 
56058a175baeSEmil Constantinescu    Level: developer
56068a175baeSEmil Constantinescu 
5607db781477SPatrick Sanan .seealso: `TSErrorWeightedENormInfinity()`, `TSErrorWeightedENorm2()`, `TSErrorWeightedNormInfinity()`, `TSErrorWeightedNorm2()`
56088a175baeSEmil Constantinescu @*/
56098a175baeSEmil Constantinescu PetscErrorCode TSErrorWeightedENorm(TS ts,Vec E,Vec U,Vec Y,NormType wnormtype,PetscReal *norm,PetscReal *norma,PetscReal *normr)
56108a175baeSEmil Constantinescu {
56118a175baeSEmil Constantinescu   PetscFunctionBegin;
56128a175baeSEmil Constantinescu   if (wnormtype == NORM_2) {
56139566063dSJacob Faibussowitsch     PetscCall(TSErrorWeightedENorm2(ts,E,U,Y,norm,norma,normr));
56148a175baeSEmil Constantinescu   } else if (wnormtype == NORM_INFINITY) {
56159566063dSJacob Faibussowitsch     PetscCall(TSErrorWeightedENormInfinity(ts,E,U,Y,norm,norma,normr));
561698921bdaSJacob Faibussowitsch   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for norm type %s",NormTypes[wnormtype]);
56178a175baeSEmil Constantinescu   PetscFunctionReturn(0);
56188a175baeSEmil Constantinescu }
56198a175baeSEmil Constantinescu 
56208d59e960SJed Brown /*@
56218d59e960SJed Brown    TSSetCFLTimeLocal - Set the local CFL constraint relative to forward Euler
56228d59e960SJed Brown 
56238d59e960SJed Brown    Logically Collective on TS
56248d59e960SJed Brown 
56254165533cSJose E. Roman    Input Parameters:
56268d59e960SJed Brown +  ts - time stepping context
56278d59e960SJed Brown -  cfltime - maximum stable time step if using forward Euler (value can be different on each process)
56288d59e960SJed Brown 
56298d59e960SJed Brown    Note:
56308d59e960SJed Brown    After calling this function, the global CFL time can be obtained by calling TSGetCFLTime()
56318d59e960SJed Brown 
56328d59e960SJed Brown    Level: intermediate
56338d59e960SJed Brown 
5634db781477SPatrick Sanan .seealso: `TSGetCFLTime()`, `TSADAPTCFL`
56358d59e960SJed Brown @*/
56368d59e960SJed Brown PetscErrorCode TSSetCFLTimeLocal(TS ts,PetscReal cfltime)
56378d59e960SJed Brown {
56388d59e960SJed Brown   PetscFunctionBegin;
56398d59e960SJed Brown   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
56408d59e960SJed Brown   ts->cfltime_local = cfltime;
56418d59e960SJed Brown   ts->cfltime       = -1.;
56428d59e960SJed Brown   PetscFunctionReturn(0);
56438d59e960SJed Brown }
56448d59e960SJed Brown 
56458d59e960SJed Brown /*@
56468d59e960SJed Brown    TSGetCFLTime - Get the maximum stable time step according to CFL criteria applied to forward Euler
56478d59e960SJed Brown 
56488d59e960SJed Brown    Collective on TS
56498d59e960SJed Brown 
56504165533cSJose E. Roman    Input Parameter:
56518d59e960SJed Brown .  ts - time stepping context
56528d59e960SJed Brown 
56534165533cSJose E. Roman    Output Parameter:
56548d59e960SJed Brown .  cfltime - maximum stable time step for forward Euler
56558d59e960SJed Brown 
56568d59e960SJed Brown    Level: advanced
56578d59e960SJed Brown 
5658db781477SPatrick Sanan .seealso: `TSSetCFLTimeLocal()`
56598d59e960SJed Brown @*/
56608d59e960SJed Brown PetscErrorCode TSGetCFLTime(TS ts,PetscReal *cfltime)
56618d59e960SJed Brown {
56628d59e960SJed Brown   PetscFunctionBegin;
56638d59e960SJed Brown   if (ts->cfltime < 0) {
56641c2dc1cbSBarry Smith     PetscCall(MPIU_Allreduce(&ts->cfltime_local,&ts->cfltime,1,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)ts)));
56658d59e960SJed Brown   }
56668d59e960SJed Brown   *cfltime = ts->cfltime;
56678d59e960SJed Brown   PetscFunctionReturn(0);
56688d59e960SJed Brown }
56698d59e960SJed Brown 
5670d6ebe24aSShri Abhyankar /*@
5671d6ebe24aSShri Abhyankar    TSVISetVariableBounds - Sets the lower and upper bounds for the solution vector. xl <= x <= xu
5672d6ebe24aSShri Abhyankar 
5673d6ebe24aSShri Abhyankar    Input Parameters:
5674a2b725a8SWilliam Gropp +  ts   - the TS context.
5675d6ebe24aSShri Abhyankar .  xl   - lower bound.
5676a2b725a8SWilliam Gropp -  xu   - upper bound.
5677d6ebe24aSShri Abhyankar 
5678d6ebe24aSShri Abhyankar    Notes:
5679d6ebe24aSShri Abhyankar    If this routine is not called then the lower and upper bounds are set to
5680e270355aSBarry Smith    PETSC_NINFINITY and PETSC_INFINITY respectively during SNESSetUp().
5681d6ebe24aSShri Abhyankar 
56822bd2b0e6SSatish Balay    Level: advanced
56832bd2b0e6SSatish Balay 
5684d6ebe24aSShri Abhyankar @*/
5685d6ebe24aSShri Abhyankar PetscErrorCode TSVISetVariableBounds(TS ts, Vec xl, Vec xu)
5686d6ebe24aSShri Abhyankar {
5687d6ebe24aSShri Abhyankar   SNES           snes;
5688d6ebe24aSShri Abhyankar 
5689d6ebe24aSShri Abhyankar   PetscFunctionBegin;
56909566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts,&snes));
56919566063dSJacob Faibussowitsch   PetscCall(SNESVISetVariableBounds(snes,xl,xu));
5692d6ebe24aSShri Abhyankar   PetscFunctionReturn(0);
5693d6ebe24aSShri Abhyankar }
5694d6ebe24aSShri Abhyankar 
5695f9c1d6abSBarry Smith /*@
5696f9c1d6abSBarry Smith    TSComputeLinearStability - computes the linear stability function at a point
5697f9c1d6abSBarry Smith 
5698d083f849SBarry Smith    Collective on TS
5699f9c1d6abSBarry Smith 
5700f9c1d6abSBarry Smith    Input Parameters:
5701f9c1d6abSBarry Smith +  ts - the TS context
5702f9c1d6abSBarry Smith -  xr,xi - real and imaginary part of input arguments
5703f9c1d6abSBarry Smith 
5704f9c1d6abSBarry Smith    Output Parameters:
5705f9c1d6abSBarry Smith .  yr,yi - real and imaginary part of function value
5706f9c1d6abSBarry Smith 
5707f9c1d6abSBarry Smith    Level: developer
5708f9c1d6abSBarry Smith 
5709db781477SPatrick Sanan .seealso: `TSSetRHSFunction()`, `TSComputeIFunction()`
5710f9c1d6abSBarry Smith @*/
5711f9c1d6abSBarry Smith PetscErrorCode TSComputeLinearStability(TS ts,PetscReal xr,PetscReal xi,PetscReal *yr,PetscReal *yi)
5712f9c1d6abSBarry Smith {
5713f9c1d6abSBarry Smith   PetscFunctionBegin;
5714f9c1d6abSBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
57153c633725SBarry Smith   PetscCheck(ts->ops->linearstability,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"Linearized stability function not provided for this method");
57169566063dSJacob Faibussowitsch   PetscCall((*ts->ops->linearstability)(ts,xr,xi,yr,yi));
5717f9c1d6abSBarry Smith   PetscFunctionReturn(0);
5718f9c1d6abSBarry Smith }
571924655328SShri 
572024655328SShri /*@
5721dcb233daSLisandro Dalcin    TSRestartStep - Flags the solver to restart the next step
5722dcb233daSLisandro Dalcin 
5723dcb233daSLisandro Dalcin    Collective on TS
5724dcb233daSLisandro Dalcin 
5725dcb233daSLisandro Dalcin    Input Parameter:
5726dcb233daSLisandro Dalcin .  ts - the TS context obtained from TSCreate()
5727dcb233daSLisandro Dalcin 
5728dcb233daSLisandro Dalcin    Level: advanced
5729dcb233daSLisandro Dalcin 
5730dcb233daSLisandro Dalcin    Notes:
5731dcb233daSLisandro Dalcin    Multistep methods like BDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of
5732dcb233daSLisandro Dalcin    discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution
5733dcb233daSLisandro Dalcin    vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For
5734dcb233daSLisandro Dalcin    the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce
5735dcb233daSLisandro Dalcin    discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with
5736dcb233daSLisandro Dalcin    discontinuous source terms).
5737dcb233daSLisandro Dalcin 
5738db781477SPatrick Sanan .seealso: `TSSolve()`, `TSSetPreStep()`, `TSSetPostStep()`
5739dcb233daSLisandro Dalcin @*/
5740dcb233daSLisandro Dalcin PetscErrorCode TSRestartStep(TS ts)
5741dcb233daSLisandro Dalcin {
5742dcb233daSLisandro Dalcin   PetscFunctionBegin;
5743dcb233daSLisandro Dalcin   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5744dcb233daSLisandro Dalcin   ts->steprestart = PETSC_TRUE;
5745dcb233daSLisandro Dalcin   PetscFunctionReturn(0);
5746dcb233daSLisandro Dalcin }
5747dcb233daSLisandro Dalcin 
5748dcb233daSLisandro Dalcin /*@
574924655328SShri    TSRollBack - Rolls back one time step
575024655328SShri 
575124655328SShri    Collective on TS
575224655328SShri 
575324655328SShri    Input Parameter:
575424655328SShri .  ts - the TS context obtained from TSCreate()
575524655328SShri 
575624655328SShri    Level: advanced
575724655328SShri 
5758db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetUp()`, `TSDestroy()`, `TSSolve()`, `TSSetPreStep()`, `TSSetPreStage()`, `TSInterpolate()`
575924655328SShri @*/
576024655328SShri PetscErrorCode  TSRollBack(TS ts)
576124655328SShri {
576224655328SShri   PetscFunctionBegin;
576324655328SShri   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
57643c633725SBarry Smith   PetscCheck(!ts->steprollback,PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONGSTATE,"TSRollBack already called");
57653c633725SBarry Smith   PetscCheck(ts->ops->rollback,PetscObjectComm((PetscObject)ts),PETSC_ERR_SUP,"TSRollBack not implemented for type '%s'",((PetscObject)ts)->type_name);
57669566063dSJacob Faibussowitsch   PetscCall((*ts->ops->rollback)(ts));
576724655328SShri   ts->time_step = ts->ptime - ts->ptime_prev;
576824655328SShri   ts->ptime = ts->ptime_prev;
5769be5899b3SLisandro Dalcin   ts->ptime_prev = ts->ptime_prev_rollback;
57702808aa04SLisandro Dalcin   ts->steps--;
5771b3de5cdeSLisandro Dalcin   ts->steprollback = PETSC_TRUE;
577224655328SShri   PetscFunctionReturn(0);
577324655328SShri }
5774aeb4809dSShri Abhyankar 
5775ff22ae23SHong Zhang /*@
5776ff22ae23SHong Zhang    TSGetStages - Get the number of stages and stage values
5777ff22ae23SHong Zhang 
5778ff22ae23SHong Zhang    Input Parameter:
5779ff22ae23SHong Zhang .  ts - the TS context obtained from TSCreate()
5780ff22ae23SHong Zhang 
57810429704eSStefano Zampini    Output Parameters:
57820429704eSStefano Zampini +  ns - the number of stages
57830429704eSStefano Zampini -  Y - the current stage vectors
57840429704eSStefano Zampini 
5785ff22ae23SHong Zhang    Level: advanced
5786ff22ae23SHong Zhang 
57870429704eSStefano Zampini    Notes: Both ns and Y can be NULL.
57880429704eSStefano Zampini 
5789db781477SPatrick Sanan .seealso: `TSCreate()`
5790ff22ae23SHong Zhang @*/
5791ff22ae23SHong Zhang PetscErrorCode  TSGetStages(TS ts,PetscInt *ns,Vec **Y)
5792ff22ae23SHong Zhang {
5793ff22ae23SHong Zhang   PetscFunctionBegin;
5794ff22ae23SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
5795dadcf809SJacob Faibussowitsch   if (ns) PetscValidIntPointer(ns,2);
57960429704eSStefano Zampini   if (Y) PetscValidPointer(Y,3);
57970429704eSStefano Zampini   if (!ts->ops->getstages) {
57980429704eSStefano Zampini     if (ns) *ns = 0;
57990429704eSStefano Zampini     if (Y) *Y = NULL;
58000429704eSStefano Zampini   } else {
58019566063dSJacob Faibussowitsch     PetscCall((*ts->ops->getstages)(ts,ns,Y));
5802ff22ae23SHong Zhang   }
5803ff22ae23SHong Zhang   PetscFunctionReturn(0);
5804ff22ae23SHong Zhang }
5805ff22ae23SHong Zhang 
5806847ff0e1SMatthew G. Knepley /*@C
5807847ff0e1SMatthew G. Knepley   TSComputeIJacobianDefaultColor - Computes the Jacobian using finite differences and coloring to exploit matrix sparsity.
5808847ff0e1SMatthew G. Knepley 
5809847ff0e1SMatthew G. Knepley   Collective on SNES
5810847ff0e1SMatthew G. Knepley 
5811847ff0e1SMatthew G. Knepley   Input Parameters:
5812847ff0e1SMatthew G. Knepley + ts - the TS context
5813847ff0e1SMatthew G. Knepley . t - current timestep
5814847ff0e1SMatthew G. Knepley . U - state vector
5815847ff0e1SMatthew G. Knepley . Udot - time derivative of state vector
5816847ff0e1SMatthew G. Knepley . shift - shift to apply, see note below
5817847ff0e1SMatthew G. Knepley - ctx - an optional user context
5818847ff0e1SMatthew G. Knepley 
5819847ff0e1SMatthew G. Knepley   Output Parameters:
5820847ff0e1SMatthew G. Knepley + J - Jacobian matrix (not altered in this routine)
5821847ff0e1SMatthew G. Knepley - B - newly computed Jacobian matrix to use with preconditioner (generally the same as J)
5822847ff0e1SMatthew G. Knepley 
5823847ff0e1SMatthew G. Knepley   Level: intermediate
5824847ff0e1SMatthew G. Knepley 
5825847ff0e1SMatthew G. Knepley   Notes:
5826847ff0e1SMatthew G. Knepley   If F(t,U,Udot)=0 is the DAE, the required Jacobian is
5827847ff0e1SMatthew G. Knepley 
5828847ff0e1SMatthew G. Knepley   dF/dU + shift*dF/dUdot
5829847ff0e1SMatthew G. Knepley 
5830847ff0e1SMatthew G. Knepley   Most users should not need to explicitly call this routine, as it
5831847ff0e1SMatthew G. Knepley   is used internally within the nonlinear solvers.
5832847ff0e1SMatthew G. Knepley 
5833847ff0e1SMatthew G. Knepley   This will first try to get the coloring from the DM.  If the DM type has no coloring
5834847ff0e1SMatthew G. Knepley   routine, then it will try to get the coloring from the matrix.  This requires that the
5835847ff0e1SMatthew G. Knepley   matrix have nonzero entries precomputed.
5836847ff0e1SMatthew G. Knepley 
5837db781477SPatrick Sanan .seealso: `TSSetIJacobian()`, `MatFDColoringCreate()`, `MatFDColoringSetFunction()`
5838847ff0e1SMatthew G. Knepley @*/
5839847ff0e1SMatthew G. Knepley PetscErrorCode TSComputeIJacobianDefaultColor(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal shift,Mat J,Mat B,void *ctx)
5840847ff0e1SMatthew G. Knepley {
5841847ff0e1SMatthew G. Knepley   SNES           snes;
5842847ff0e1SMatthew G. Knepley   MatFDColoring  color;
5843847ff0e1SMatthew G. Knepley   PetscBool      hascolor, matcolor = PETSC_FALSE;
5844847ff0e1SMatthew G. Knepley 
5845847ff0e1SMatthew G. Knepley   PetscFunctionBegin;
58469566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)ts)->options,((PetscObject) ts)->prefix, "-ts_fd_color_use_mat", &matcolor, NULL));
58479566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject) B, "TSMatFDColoring", (PetscObject *) &color));
5848847ff0e1SMatthew G. Knepley   if (!color) {
5849847ff0e1SMatthew G. Knepley     DM         dm;
5850847ff0e1SMatthew G. Knepley     ISColoring iscoloring;
5851847ff0e1SMatthew G. Knepley 
58529566063dSJacob Faibussowitsch     PetscCall(TSGetDM(ts, &dm));
58539566063dSJacob Faibussowitsch     PetscCall(DMHasColoring(dm, &hascolor));
5854847ff0e1SMatthew G. Knepley     if (hascolor && !matcolor) {
58559566063dSJacob Faibussowitsch       PetscCall(DMCreateColoring(dm, IS_COLORING_GLOBAL, &iscoloring));
58569566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
58579566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts));
58589566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
58599566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
58609566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5861847ff0e1SMatthew G. Knepley     } else {
5862847ff0e1SMatthew G. Knepley       MatColoring mc;
5863847ff0e1SMatthew G. Knepley 
58649566063dSJacob Faibussowitsch       PetscCall(MatColoringCreate(B, &mc));
58659566063dSJacob Faibussowitsch       PetscCall(MatColoringSetDistance(mc, 2));
58669566063dSJacob Faibussowitsch       PetscCall(MatColoringSetType(mc, MATCOLORINGSL));
58679566063dSJacob Faibussowitsch       PetscCall(MatColoringSetFromOptions(mc));
58689566063dSJacob Faibussowitsch       PetscCall(MatColoringApply(mc, &iscoloring));
58699566063dSJacob Faibussowitsch       PetscCall(MatColoringDestroy(&mc));
58709566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(B, iscoloring, &color));
58719566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(color, (PetscErrorCode (*)(void)) SNESTSFormFunction, (void *) ts));
58729566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(color));
58739566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(B, iscoloring, color));
58749566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
5875847ff0e1SMatthew G. Knepley     }
58769566063dSJacob Faibussowitsch     PetscCall(PetscObjectCompose((PetscObject) B, "TSMatFDColoring", (PetscObject) color));
58779566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject) color));
5878847ff0e1SMatthew G. Knepley   }
58799566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
58809566063dSJacob Faibussowitsch   PetscCall(MatFDColoringApply(B, color, U, snes));
5881847ff0e1SMatthew G. Knepley   if (J != B) {
58829566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
58839566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
5884847ff0e1SMatthew G. Knepley   }
5885847ff0e1SMatthew G. Knepley   PetscFunctionReturn(0);
5886847ff0e1SMatthew G. Knepley }
588793b34091SDebojyoti Ghosh 
5888cb9d8021SPierre Barbier de Reuille /*@
58896bc98fa9SBarry Smith     TSSetFunctionDomainError - Set a function that tests if the current state vector is valid
5890cb9d8021SPierre Barbier de Reuille 
5891cb9d8021SPierre Barbier de Reuille     Input Parameters:
58926bc98fa9SBarry Smith +    ts - the TS context
58936bc98fa9SBarry Smith -    func - function called within TSFunctionDomainError
58946bc98fa9SBarry Smith 
58956bc98fa9SBarry Smith     Calling sequence of func:
58966bc98fa9SBarry Smith $     PetscErrorCode func(TS ts,PetscReal time,Vec state,PetscBool reject)
58976bc98fa9SBarry Smith 
58986bc98fa9SBarry Smith +   ts - the TS context
58996bc98fa9SBarry Smith .   time - the current time (of the stage)
59006bc98fa9SBarry Smith .   state - the state to check if it is valid
59016bc98fa9SBarry Smith -   reject - (output parameter) PETSC_FALSE if the state is acceptable, PETSC_TRUE if not acceptable
5902cb9d8021SPierre Barbier de Reuille 
5903cb9d8021SPierre Barbier de Reuille     Level: intermediate
5904cb9d8021SPierre Barbier de Reuille 
59056bc98fa9SBarry Smith     Notes:
59066bc98fa9SBarry Smith       If an implicit ODE solver is being used then, in addition to providing this routine, the
59076bc98fa9SBarry Smith       user's code should call SNESSetFunctionDomainError() when domain errors occur during
59086bc98fa9SBarry Smith       function evaluations where the functions are provided by TSSetIFunction() or TSSetRHSFunction().
59096bc98fa9SBarry Smith       Use TSGetSNES() to obtain the SNES object
59106bc98fa9SBarry Smith 
59116bc98fa9SBarry Smith     Developer Notes:
59126bc98fa9SBarry Smith       The naming of this function is inconsistent with the SNESSetFunctionDomainError()
59136bc98fa9SBarry Smith       since one takes a function pointer and the other does not.
59146bc98fa9SBarry Smith 
5915db781477SPatrick Sanan .seealso: `TSAdaptCheckStage()`, `TSFunctionDomainError()`, `SNESSetFunctionDomainError()`, `TSGetSNES()`
5916cb9d8021SPierre Barbier de Reuille @*/
5917cb9d8021SPierre Barbier de Reuille 
5918d183316bSPierre Barbier de Reuille PetscErrorCode TSSetFunctionDomainError(TS ts, PetscErrorCode (*func)(TS,PetscReal,Vec,PetscBool*))
5919cb9d8021SPierre Barbier de Reuille {
5920cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5921cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
5922cb9d8021SPierre Barbier de Reuille   ts->functiondomainerror = func;
5923cb9d8021SPierre Barbier de Reuille   PetscFunctionReturn(0);
5924cb9d8021SPierre Barbier de Reuille }
5925cb9d8021SPierre Barbier de Reuille 
5926cb9d8021SPierre Barbier de Reuille /*@
59276bc98fa9SBarry Smith     TSFunctionDomainError - Checks if the current state is valid
5928cb9d8021SPierre Barbier de Reuille 
5929cb9d8021SPierre Barbier de Reuille     Input Parameters:
59306bc98fa9SBarry Smith +    ts - the TS context
59316bc98fa9SBarry Smith .    stagetime - time of the simulation
59326bc98fa9SBarry Smith -    Y - state vector to check.
5933cb9d8021SPierre Barbier de Reuille 
5934cb9d8021SPierre Barbier de Reuille     Output Parameter:
59356bc98fa9SBarry Smith .    accept - Set to PETSC_FALSE if the current state vector is valid.
5936cb9d8021SPierre Barbier de Reuille 
5937cb9d8021SPierre Barbier de Reuille     Note:
59386bc98fa9SBarry Smith     This function is called by the TS integration routines and calls the user provided function (set with TSSetFunctionDomainError())
59396bc98fa9SBarry Smith     to check if the current state is valid.
594096a0c994SBarry Smith 
59416bc98fa9SBarry Smith     Level: developer
59426bc98fa9SBarry Smith 
5943db781477SPatrick Sanan .seealso: `TSSetFunctionDomainError()`
5944cb9d8021SPierre Barbier de Reuille @*/
5945d183316bSPierre Barbier de Reuille PetscErrorCode TSFunctionDomainError(TS ts,PetscReal stagetime,Vec Y,PetscBool* accept)
5946cb9d8021SPierre Barbier de Reuille {
5947cb9d8021SPierre Barbier de Reuille   PetscFunctionBegin;
5948cb9d8021SPierre Barbier de Reuille   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
5949cb9d8021SPierre Barbier de Reuille   *accept = PETSC_TRUE;
5950cb9d8021SPierre Barbier de Reuille   if (ts->functiondomainerror) {
5951*792fecdfSBarry Smith     PetscCallExternal((*ts->functiondomainerror),ts,stagetime,Y,accept);
5952cb9d8021SPierre Barbier de Reuille   }
5953cb9d8021SPierre Barbier de Reuille   PetscFunctionReturn(0);
5954cb9d8021SPierre Barbier de Reuille }
59551ceb14c0SBarry Smith 
595693b34091SDebojyoti Ghosh /*@C
5957e5168f73SEmil Constantinescu   TSClone - This function clones a time step object.
595893b34091SDebojyoti Ghosh 
5959d083f849SBarry Smith   Collective
596093b34091SDebojyoti Ghosh 
596193b34091SDebojyoti Ghosh   Input Parameter:
596293b34091SDebojyoti Ghosh . tsin    - The input TS
596393b34091SDebojyoti Ghosh 
596493b34091SDebojyoti Ghosh   Output Parameter:
5965e5168f73SEmil Constantinescu . tsout   - The output TS (cloned)
596693b34091SDebojyoti Ghosh 
59675eca1a21SEmil Constantinescu   Notes:
59685eca1a21SEmil 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.
59695eca1a21SEmil Constantinescu 
5970928bb9adSStefano 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);
59715eca1a21SEmil Constantinescu 
59725eca1a21SEmil Constantinescu   Level: developer
597393b34091SDebojyoti Ghosh 
5974db781477SPatrick Sanan .seealso: `TSCreate()`, `TSSetType()`, `TSSetUp()`, `TSDestroy()`, `TSSetProblemType()`
597593b34091SDebojyoti Ghosh @*/
5976baa10174SEmil Constantinescu PetscErrorCode  TSClone(TS tsin, TS *tsout)
597793b34091SDebojyoti Ghosh {
597893b34091SDebojyoti Ghosh   TS             t;
5979dc846ba4SSatish Balay   SNES           snes_start;
5980dc846ba4SSatish Balay   DM             dm;
5981dc846ba4SSatish Balay   TSType         type;
598293b34091SDebojyoti Ghosh 
598393b34091SDebojyoti Ghosh   PetscFunctionBegin;
598493b34091SDebojyoti Ghosh   PetscValidPointer(tsin,1);
598593b34091SDebojyoti Ghosh   *tsout = NULL;
598693b34091SDebojyoti Ghosh 
59879566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(t, TS_CLASSID, "TS", "Time stepping", "TS", PetscObjectComm((PetscObject)tsin), TSDestroy, TSView));
598893b34091SDebojyoti Ghosh 
598993b34091SDebojyoti Ghosh   /* General TS description */
599093b34091SDebojyoti Ghosh   t->numbermonitors    = 0;
5991d0c080abSJoseph Pusztay   t->monitorFrequency  = 1;
599293b34091SDebojyoti Ghosh   t->setupcalled       = 0;
599393b34091SDebojyoti Ghosh   t->ksp_its           = 0;
599493b34091SDebojyoti Ghosh   t->snes_its          = 0;
599593b34091SDebojyoti Ghosh   t->nwork             = 0;
59967d51462cSStefano Zampini   t->rhsjacobian.time  = PETSC_MIN_REAL;
599793b34091SDebojyoti Ghosh   t->rhsjacobian.scale = 1.;
599893b34091SDebojyoti Ghosh   t->ijacobian.shift   = 1.;
599993b34091SDebojyoti Ghosh 
60009566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(tsin,&snes_start));
60019566063dSJacob Faibussowitsch   PetscCall(TSSetSNES(t,snes_start));
6002d15a3a53SEmil Constantinescu 
60039566063dSJacob Faibussowitsch   PetscCall(TSGetDM(tsin,&dm));
60049566063dSJacob Faibussowitsch   PetscCall(TSSetDM(t,dm));
600593b34091SDebojyoti Ghosh 
600693b34091SDebojyoti Ghosh   t->adapt = tsin->adapt;
60079566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->adapt));
600893b34091SDebojyoti Ghosh 
6009e7069c78SShri   t->trajectory = tsin->trajectory;
60109566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)t->trajectory));
6011e7069c78SShri 
6012e7069c78SShri   t->event = tsin->event;
60136b10a48eSSatish Balay   if (t->event) t->event->refct++;
6014e7069c78SShri 
601593b34091SDebojyoti Ghosh   t->problem_type      = tsin->problem_type;
601693b34091SDebojyoti Ghosh   t->ptime             = tsin->ptime;
6017e7069c78SShri   t->ptime_prev        = tsin->ptime_prev;
601893b34091SDebojyoti Ghosh   t->time_step         = tsin->time_step;
601993b34091SDebojyoti Ghosh   t->max_time          = tsin->max_time;
602093b34091SDebojyoti Ghosh   t->steps             = tsin->steps;
602193b34091SDebojyoti Ghosh   t->max_steps         = tsin->max_steps;
602293b34091SDebojyoti Ghosh   t->equation_type     = tsin->equation_type;
602393b34091SDebojyoti Ghosh   t->atol              = tsin->atol;
602493b34091SDebojyoti Ghosh   t->rtol              = tsin->rtol;
602593b34091SDebojyoti Ghosh   t->max_snes_failures = tsin->max_snes_failures;
602693b34091SDebojyoti Ghosh   t->max_reject        = tsin->max_reject;
602793b34091SDebojyoti Ghosh   t->errorifstepfailed = tsin->errorifstepfailed;
602893b34091SDebojyoti Ghosh 
60299566063dSJacob Faibussowitsch   PetscCall(TSGetType(tsin,&type));
60309566063dSJacob Faibussowitsch   PetscCall(TSSetType(t,type));
603193b34091SDebojyoti Ghosh 
603293b34091SDebojyoti Ghosh   t->vec_sol           = NULL;
603393b34091SDebojyoti Ghosh 
603493b34091SDebojyoti Ghosh   t->cfltime          = tsin->cfltime;
603593b34091SDebojyoti Ghosh   t->cfltime_local    = tsin->cfltime_local;
603693b34091SDebojyoti Ghosh   t->exact_final_time = tsin->exact_final_time;
603793b34091SDebojyoti Ghosh 
60389566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(t->ops,tsin->ops,sizeof(struct _TSOps)));
603993b34091SDebojyoti Ghosh 
60400d4fed19SBarry Smith   if (((PetscObject)tsin)->fortran_func_pointers) {
60410d4fed19SBarry Smith     PetscInt i;
60429566063dSJacob Faibussowitsch     PetscCall(PetscMalloc((10)*sizeof(void(*)(void)),&((PetscObject)t)->fortran_func_pointers));
60430d4fed19SBarry Smith     for (i=0; i<10; i++) {
60440d4fed19SBarry Smith       ((PetscObject)t)->fortran_func_pointers[i] = ((PetscObject)tsin)->fortran_func_pointers[i];
60450d4fed19SBarry Smith     }
60460d4fed19SBarry Smith   }
604793b34091SDebojyoti Ghosh   *tsout = t;
604893b34091SDebojyoti Ghosh   PetscFunctionReturn(0);
604993b34091SDebojyoti Ghosh }
6050f3b1f45cSBarry Smith 
6051f3b1f45cSBarry Smith static PetscErrorCode RHSWrapperFunction_TSRHSJacobianTest(void* ctx,Vec x,Vec y)
6052f3b1f45cSBarry Smith {
6053f3b1f45cSBarry Smith   TS             ts = (TS) ctx;
6054f3b1f45cSBarry Smith 
6055f3b1f45cSBarry Smith   PetscFunctionBegin;
60569566063dSJacob Faibussowitsch   PetscCall(TSComputeRHSFunction(ts,0,x,y));
6057f3b1f45cSBarry Smith   PetscFunctionReturn(0);
6058f3b1f45cSBarry Smith }
6059f3b1f45cSBarry Smith 
6060f3b1f45cSBarry Smith /*@
6061f3b1f45cSBarry Smith     TSRHSJacobianTest - Compares the multiply routine provided to the MATSHELL with differencing on the TS given RHS function.
6062f3b1f45cSBarry Smith 
6063d083f849SBarry Smith    Logically Collective on TS
6064f3b1f45cSBarry Smith 
6065f3b1f45cSBarry Smith     Input Parameters:
6066f3b1f45cSBarry Smith     TS - the time stepping routine
6067f3b1f45cSBarry Smith 
6068f3b1f45cSBarry Smith    Output Parameter:
6069f3b1f45cSBarry Smith .   flg - PETSC_TRUE if the multiply is likely correct
6070f3b1f45cSBarry Smith 
6071f3b1f45cSBarry Smith    Options Database:
6072f3b1f45cSBarry Smith  .   -ts_rhs_jacobian_test_mult -mat_shell_test_mult_view - run the test at each timestep of the integrator
6073f3b1f45cSBarry Smith 
6074f3b1f45cSBarry Smith    Level: advanced
6075f3b1f45cSBarry Smith 
607695452b02SPatrick Sanan    Notes:
607795452b02SPatrick Sanan     This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
6078f3b1f45cSBarry Smith 
6079db781477SPatrick Sanan .seealso: `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTestTranspose()`
6080f3b1f45cSBarry Smith @*/
6081f3b1f45cSBarry Smith PetscErrorCode  TSRHSJacobianTest(TS ts,PetscBool *flg)
6082f3b1f45cSBarry Smith {
6083f3b1f45cSBarry Smith   Mat            J,B;
6084f3b1f45cSBarry Smith   TSRHSJacobian  func;
6085f3b1f45cSBarry Smith   void*          ctx;
6086f3b1f45cSBarry Smith 
6087f3b1f45cSBarry Smith   PetscFunctionBegin;
60889566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts,&J,&B,&func,&ctx));
60899566063dSJacob Faibussowitsch   PetscCall((*func)(ts,0.0,ts->vec_sol,J,B,ctx));
60909566063dSJacob Faibussowitsch   PetscCall(MatShellTestMult(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg));
6091f3b1f45cSBarry Smith   PetscFunctionReturn(0);
6092f3b1f45cSBarry Smith }
6093f3b1f45cSBarry Smith 
6094f3b1f45cSBarry Smith /*@C
6095f3b1f45cSBarry Smith     TSRHSJacobianTestTranspose - Compares the multiply transpose routine provided to the MATSHELL with differencing on the TS given RHS function.
6096f3b1f45cSBarry Smith 
6097d083f849SBarry Smith    Logically Collective on TS
6098f3b1f45cSBarry Smith 
6099f3b1f45cSBarry Smith     Input Parameters:
6100f3b1f45cSBarry Smith     TS - the time stepping routine
6101f3b1f45cSBarry Smith 
6102f3b1f45cSBarry Smith    Output Parameter:
6103f3b1f45cSBarry Smith .   flg - PETSC_TRUE if the multiply is likely correct
6104f3b1f45cSBarry Smith 
6105f3b1f45cSBarry Smith    Options Database:
6106f3b1f45cSBarry Smith .   -ts_rhs_jacobian_test_mult_transpose -mat_shell_test_mult_transpose_view - run the test at each timestep of the integrator
6107f3b1f45cSBarry Smith 
610895452b02SPatrick Sanan    Notes:
610995452b02SPatrick Sanan     This only works for problems defined only the RHS function and Jacobian NOT IFunction and IJacobian
6110f3b1f45cSBarry Smith 
6111f3b1f45cSBarry Smith    Level: advanced
6112f3b1f45cSBarry Smith 
6113db781477SPatrick Sanan .seealso: `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()`, `MatShellTestMultTranspose()`, `TSRHSJacobianTest()`
6114f3b1f45cSBarry Smith @*/
6115f3b1f45cSBarry Smith PetscErrorCode  TSRHSJacobianTestTranspose(TS ts,PetscBool *flg)
6116f3b1f45cSBarry Smith {
6117f3b1f45cSBarry Smith   Mat            J,B;
6118f3b1f45cSBarry Smith   void           *ctx;
6119f3b1f45cSBarry Smith   TSRHSJacobian  func;
6120f3b1f45cSBarry Smith 
6121f3b1f45cSBarry Smith   PetscFunctionBegin;
61229566063dSJacob Faibussowitsch   PetscCall(TSGetRHSJacobian(ts,&J,&B,&func,&ctx));
61239566063dSJacob Faibussowitsch   PetscCall((*func)(ts,0.0,ts->vec_sol,J,B,ctx));
61249566063dSJacob Faibussowitsch   PetscCall(MatShellTestMultTranspose(J,RHSWrapperFunction_TSRHSJacobianTest,ts->vec_sol,ts,flg));
6125f3b1f45cSBarry Smith   PetscFunctionReturn(0);
6126f3b1f45cSBarry Smith }
61270fe4d17eSHong Zhang 
61280fe4d17eSHong Zhang /*@
61290fe4d17eSHong Zhang   TSSetUseSplitRHSFunction - Use the split RHSFunction when a multirate method is used.
61300fe4d17eSHong Zhang 
61310fe4d17eSHong Zhang   Logically collective
61320fe4d17eSHong Zhang 
6133d8d19677SJose E. Roman   Input Parameters:
61340fe4d17eSHong Zhang +  ts - timestepping context
61350fe4d17eSHong Zhang -  use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used
61360fe4d17eSHong Zhang 
61370fe4d17eSHong Zhang   Options Database:
61380fe4d17eSHong Zhang .   -ts_use_splitrhsfunction - <true,false>
61390fe4d17eSHong Zhang 
61400fe4d17eSHong Zhang   Notes:
61410fe4d17eSHong Zhang     This is only useful for multirate methods
61420fe4d17eSHong Zhang 
61430fe4d17eSHong Zhang   Level: intermediate
61440fe4d17eSHong Zhang 
6145db781477SPatrick Sanan .seealso: `TSGetUseSplitRHSFunction()`
61460fe4d17eSHong Zhang @*/
61470fe4d17eSHong Zhang PetscErrorCode TSSetUseSplitRHSFunction(TS ts, PetscBool use_splitrhsfunction)
61480fe4d17eSHong Zhang {
61490fe4d17eSHong Zhang   PetscFunctionBegin;
61500fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
61510fe4d17eSHong Zhang   ts->use_splitrhsfunction = use_splitrhsfunction;
61520fe4d17eSHong Zhang   PetscFunctionReturn(0);
61530fe4d17eSHong Zhang }
61540fe4d17eSHong Zhang 
61550fe4d17eSHong Zhang /*@
61560fe4d17eSHong Zhang   TSGetUseSplitRHSFunction - Gets whether to use the split RHSFunction when a multirate method is used.
61570fe4d17eSHong Zhang 
61580fe4d17eSHong Zhang   Not collective
61590fe4d17eSHong Zhang 
61600fe4d17eSHong Zhang   Input Parameter:
61610fe4d17eSHong Zhang .  ts - timestepping context
61620fe4d17eSHong Zhang 
61630fe4d17eSHong Zhang   Output Parameter:
61640fe4d17eSHong Zhang .  use_splitrhsfunction - PETSC_TRUE indicates that the split RHSFunction will be used
61650fe4d17eSHong Zhang 
61660fe4d17eSHong Zhang   Level: intermediate
61670fe4d17eSHong Zhang 
6168db781477SPatrick Sanan .seealso: `TSSetUseSplitRHSFunction()`
61690fe4d17eSHong Zhang @*/
61700fe4d17eSHong Zhang PetscErrorCode TSGetUseSplitRHSFunction(TS ts, PetscBool *use_splitrhsfunction)
61710fe4d17eSHong Zhang {
61720fe4d17eSHong Zhang   PetscFunctionBegin;
61730fe4d17eSHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
61740fe4d17eSHong Zhang   *use_splitrhsfunction = ts->use_splitrhsfunction;
61750fe4d17eSHong Zhang   PetscFunctionReturn(0);
61760fe4d17eSHong Zhang }
6177d60b7d5cSBarry Smith 
6178d60b7d5cSBarry Smith /*@
6179d60b7d5cSBarry Smith     TSSetMatStructure - sets the relationship between the nonzero structure of the RHS Jacobian matrix to the IJacobian matrix.
6180d60b7d5cSBarry Smith 
6181d60b7d5cSBarry Smith    Logically  Collective on ts
6182d60b7d5cSBarry Smith 
6183d60b7d5cSBarry Smith    Input Parameters:
6184d60b7d5cSBarry Smith +  ts - the time-stepper
6185d60b7d5cSBarry Smith -  str - the structure (the default is UNKNOWN_NONZERO_PATTERN)
6186d60b7d5cSBarry Smith 
6187d60b7d5cSBarry Smith    Level: intermediate
6188d60b7d5cSBarry Smith 
6189d60b7d5cSBarry Smith    Notes:
6190d60b7d5cSBarry Smith      When the relationship between the nonzero structures is known and supplied the solution process can be much faster
6191d60b7d5cSBarry Smith 
6192db781477SPatrick Sanan .seealso: `MatAXPY()`, `MatStructure`
6193d60b7d5cSBarry Smith  @*/
6194d60b7d5cSBarry Smith PetscErrorCode TSSetMatStructure(TS ts,MatStructure str)
6195d60b7d5cSBarry Smith {
6196d60b7d5cSBarry Smith   PetscFunctionBegin;
6197d60b7d5cSBarry Smith   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
6198d60b7d5cSBarry Smith   ts->axpy_pattern = str;
6199d60b7d5cSBarry Smith   PetscFunctionReturn(0);
6200d60b7d5cSBarry Smith }
62014a658b32SHong Zhang 
62024a658b32SHong Zhang /*@
62034a658b32SHong Zhang   TSSetTimeSpan - sets the time span. The solution will be computed and stored for each time requested.
62044a658b32SHong Zhang 
62054a658b32SHong Zhang   Collective on ts
62064a658b32SHong Zhang 
62074a658b32SHong Zhang   Input Parameters:
62084a658b32SHong Zhang + ts - the time-stepper
62094a658b32SHong Zhang . n - number of the time points (>=2)
62104a658b32SHong Zhang - span_times - array of the time points. The first element and the last element are the initial time and the final time respectively.
62114a658b32SHong Zhang 
62124a658b32SHong Zhang   Options Database Keys:
62134a658b32SHong Zhang . -ts_time_span <t0,...tf> - Sets the time span
62144a658b32SHong Zhang 
62154a658b32SHong Zhang   Level: beginner
62164a658b32SHong Zhang 
62174a658b32SHong Zhang   Notes:
62184a658b32SHong Zhang   The elements in tspan must be all increasing. They correspond to the intermediate points for time integration.
62194a658b32SHong Zhang   TS_EXACTFINALTIME_MATCHSTEP must be used to make the last time step in each sub-interval match the intermediate points specified.
62204a658b32SHong Zhang   The intermediate solutions are saved in a vector array that can be accessed with TSGetSolutions(). Thus using time span may
62214a658b32SHong Zhang   pressure the memory system when using a large number of span points.
62224a658b32SHong Zhang 
6223c2e3fba1SPatrick Sanan .seealso: `TSGetTimeSpan()`, `TSGetSolutions()`
62244a658b32SHong Zhang  @*/
62254a658b32SHong Zhang PetscErrorCode TSSetTimeSpan(TS ts,PetscInt n,PetscReal *span_times)
62264a658b32SHong Zhang {
62274a658b32SHong Zhang   PetscFunctionBegin;
62284a658b32SHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
622963a3b9bcSJacob Faibussowitsch   PetscCheck(n >= 2,PetscObjectComm((PetscObject)ts),PETSC_ERR_ARG_WRONG,"Minimum time span size is 2 but %" PetscInt_FMT " is provided",n);
62304a658b32SHong Zhang   if (ts->tspan && n != ts->tspan->num_span_times) {
62314a658b32SHong Zhang     PetscCall(PetscFree(ts->tspan->span_times));
62324a658b32SHong Zhang     PetscCall(VecDestroyVecs(ts->tspan->num_span_times,&ts->tspan->vecs_sol));
62334a658b32SHong Zhang     PetscCall(PetscMalloc1(n,&ts->tspan->span_times));
62344a658b32SHong Zhang   }
62354a658b32SHong Zhang   if (!ts->tspan) {
62364a658b32SHong Zhang     TSTimeSpan tspan;
62374a658b32SHong Zhang     PetscCall(PetscNew(&tspan));
62384a658b32SHong Zhang     PetscCall(PetscMalloc1(n,&tspan->span_times));
6239e1db57b0SHong Zhang     tspan->reltol = 1e-6;
6240e1db57b0SHong Zhang     tspan->abstol = 10*PETSC_MACHINE_EPSILON;
62414a658b32SHong Zhang     ts->tspan = tspan;
62424a658b32SHong Zhang   }
62434a658b32SHong Zhang   ts->tspan->num_span_times = n;
62444a658b32SHong Zhang   PetscCall(PetscArraycpy(ts->tspan->span_times,span_times,n));
62454a658b32SHong Zhang   PetscCall(TSSetTime(ts,ts->tspan->span_times[0]));
62464a658b32SHong Zhang   PetscCall(TSSetMaxTime(ts,ts->tspan->span_times[n-1]));
62474a658b32SHong Zhang   PetscFunctionReturn(0);
62484a658b32SHong Zhang }
62494a658b32SHong Zhang 
62504a658b32SHong Zhang /*@C
62514a658b32SHong Zhang   TSGetTimeSpan - gets the time span.
62524a658b32SHong Zhang 
62534a658b32SHong Zhang   Not Collective
62544a658b32SHong Zhang 
62554a658b32SHong Zhang   Input Parameter:
62564a658b32SHong Zhang . ts - the time-stepper
62574a658b32SHong Zhang 
62584a658b32SHong Zhang   Output Parameters:
62594a658b32SHong Zhang + n - number of the time points (>=2)
62604a658b32SHong 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.
62614a658b32SHong Zhang 
62624a658b32SHong Zhang   Level: beginner
62634a658b32SHong Zhang   Notes: Both n and span_times can be NULL.
62644a658b32SHong Zhang 
6265c2e3fba1SPatrick Sanan .seealso: `TSSetTimeSpan()`, `TSGetSolutions()`
62664a658b32SHong Zhang  @*/
62674a658b32SHong Zhang PetscErrorCode TSGetTimeSpan(TS ts,PetscInt *n,const PetscReal **span_times)
62684a658b32SHong Zhang {
62694a658b32SHong Zhang   PetscFunctionBegin;
62704a658b32SHong Zhang   PetscValidHeaderSpecific(ts,TS_CLASSID,1);
62714a658b32SHong Zhang   if (n) PetscValidIntPointer(n,2);
62724a658b32SHong Zhang   if (span_times) PetscValidPointer(span_times,3);
62734a658b32SHong Zhang   if (!ts->tspan) {
62744a658b32SHong Zhang     if (n) *n = 0;
62754a658b32SHong Zhang     if (span_times) *span_times = NULL;
62764a658b32SHong Zhang   } else {
62774a658b32SHong Zhang     if (n) *n = ts->tspan->num_span_times;
62784a658b32SHong Zhang     if (span_times) *span_times = ts->tspan->span_times;
62794a658b32SHong Zhang   }
62804a658b32SHong Zhang   PetscFunctionReturn(0);
62814a658b32SHong Zhang }
62824a658b32SHong Zhang 
62834a658b32SHong Zhang /*@
62844a658b32SHong Zhang    TSGetTimeSpanSolutions - Get the number of solutions and the solutions at the time points specified by the time span.
62854a658b32SHong Zhang 
62864a658b32SHong Zhang    Input Parameter:
62874a658b32SHong Zhang .  ts - the TS context obtained from TSCreate()
62884a658b32SHong Zhang 
62894a658b32SHong Zhang    Output Parameters:
62904a658b32SHong Zhang +  nsol - the number of solutions
62914a658b32SHong Zhang -  Sols - the solution vectors
62924a658b32SHong Zhang 
62934a658b32SHong Zhang    Level: beginner
62944a658b32SHong Zhang 
629540bd4cedSHong Zhang    Notes:
629640bd4cedSHong Zhang     Both nsol and Sols can be NULL.
629740bd4cedSHong 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.
62984a658b32SHong Zhang 
6299db781477SPatrick Sanan .seealso: `TSSetTimeSpan()`
63004a658b32SHong Zhang @*/
63014a658b32SHong Zhang PetscErrorCode TSGetTimeSpanSolutions(TS ts,PetscInt *nsol,Vec **Sols)
63024a658b32SHong Zhang {
63034a658b32SHong Zhang   PetscFunctionBegin;
63044a658b32SHong Zhang   PetscValidHeaderSpecific(ts, TS_CLASSID,1);
63054a658b32SHong Zhang   if (nsol) PetscValidIntPointer(nsol,2);
63064a658b32SHong Zhang   if (Sols) PetscValidPointer(Sols,3);
63074a658b32SHong Zhang   if (!ts->tspan) {
63084a658b32SHong Zhang     if (nsol) *nsol = 0;
63094a658b32SHong Zhang     if (Sols) *Sols = NULL;
63104a658b32SHong Zhang   } else {
631140bd4cedSHong Zhang     if (nsol) *nsol = ts->tspan->spanctr;
63124a658b32SHong Zhang     if (Sols) *Sols = ts->tspan->vecs_sol;
63134a658b32SHong Zhang   }
63144a658b32SHong Zhang   PetscFunctionReturn(0);
63154a658b32SHong Zhang }
6316