Argument "tgrad" in ODEFunction appears to have no influence. Correct?

[Question replicated from DifferentialEquations Lobby at JuliaDiffEq/Lobby - Gitter ]

Hi All. I have got a question to the “DifferentialEquations” and “ModelingToolbox” Pkg developers, probably the right addressees are: @ChrisRackauckas and @YingboMa .

It concerns argument “tgrad” which according to documentation is “The gradient of the differential equation with respect to t at state u with parameters p”. The argument “tgrad” is used in function ODEFunction in package “DifferentialEquations” and also it is used in System/Problem Constructors DiffEqBase.ODEFunction and DiffEqBase.ODEProblem in “ModelingToolkit”. In the latter the “tgrad” is defined only after “calculate_tgrad” is called on the system.

Question #1: Does “tgrad” argument in both use cases have any impact on the ODE solver? Probably not, since these directional row-vectors are already in Jacobian. Last time “tgrad” argument is used in “DifferentialEquation” Pkg is in call of function DiffEqBase.__init (line 4 of solve.jl) as part of kwargs structure but it has no influence on the output structure “integrator” which then passed to the solver. Code extract is below.

function DiffEqBase.__solve(prob::Union{DiffEqBase.AbstractODEProblem,DiffEqBase.AbstractDAEProblem},
                            alg::Union{OrdinaryDiffEqAlgorithm,DAEAlgorithm}, args...;
  integrator = DiffEqBase.__init(prob, alg, args...; kwargs...)

Question #2: Do you have any examples of using “tgrad” for “ModelingToolkit” scenario? The comments in lines 5-7 of abstractodesystem.jl (“…we need to remove explicit time dependence on the state because when we have u(t) * t we want to …”) indicates a particular purpose, however the context is not really clear. Do you have any links to lectures/info pages which clarify that?
Link and code extract of abstractodesystem.jl are below:

function calculate_tgrad(sys::AbstractODESystem;
  isempty(get_tgrad(sys)[]) || return get_tgrad(sys)[]  # use cached tgrad, if possible

  # We need to remove explicit time dependence on the state because when we
  # have `u(t) * t` we want to have the tgrad to be `u(t)` instead of `u'(t) *
  # t + u(t)`.
  rhs = [detime_dvs(eq.rhs) for eq ∈ equations(sys)]
  iv = get_iv(sys)


Rosenbrock methods explicitly use this value, so it can effect the performance there. That then describes its purpose: make Rodas4 etc. a little bit faster in some cases.

Chris, thanks for the answer.

Do you have a pseudocode for Rodas4? Would like to see what changes in solver when tgrad is true or is false.

If i am not mistaken, in case there is an influence of tgrad argument then i assume there should be some property transfer from kwargs structure to integrator structure in function DiffEqBase.__init (line 4 of solve.jl - this is in DifferentialEquation Pkg source files), which i could not really find. Maybe i am looking at the wrong function.