Transient Analysis
The TransientAnalysis
is used to simulate a component over a given time interval. For this analysis, the user defines an initial value problem (IVP) with a time interval to simulate and the transient analysis returns artifacts which describe the solution trajectory of the system.
Method Overview
The Dyad compiler uses the physical description of the system to generate a system of differential-algebraic equations:
where
where initial
). This initial value problem is then solved over a time interval from
Example Definition
For this example we will run a transient analysis on the component DeSauty
from the ElectricalComponents standard library. A basic usage of the transient analysis sets a run-specific parameters and time interval is given as follows:
analysis MyTransientAnalysis
extends TransientAnalysis(start = 0, stop = 1e-3)
parameter C::Conductance = 30e-6
model = ElectricalComponents.DeSauty(C₁ = C)
end
The Dyad compiler will generate the MyTransientAnalysis
function that will run the analysis.
result = MyTransientAnalysis()
Transient Analysis Solution for TransientAnalysis
retcode: Success
Interpolation: 3rd order Hermite
t: 16-element Vector{Float64}:
0.0
1.0e-6
1.586795936450487e-6
7.454755300955357e-6
2.28115432997575e-5
4.5664104448907174e-5
7.651106128366515e-5
0.00011836165460786049
0.0001727101289840257
0.00024226131134568842
0.0003294888857079311
0.0004383985383000816
0.0005747975715449812
0.0007483524114999508
0.00097303843348701
0.001
u: 16-element Vector{Vector{Float64}}:
[0.0, 0.0]
[-2.923820899891337e-6, -0.00017511050717338244]
[-7.347382279861189e-6, -0.00027710640828700934]
[-0.00015923569257947438, -0.0012669182617594144]
[-0.0014230120785277591, -0.003614635515402228]
[-0.005330345933874919, -0.0065400498003263885]
[-0.013712472833941782, -0.009615852490729606]
[-0.02933712753910297, -0.012589684835191446]
[-0.05456302521738237, -0.015047506091293622]
[-0.09169025462020348, -0.016783167056749024]
[-0.14213061212383468, -0.017756962170787358]
[-0.20738685163523904, -0.018087139454824725]
[-0.2893823819109583, -0.01791257448531749]
[-0.3913426476626362, -0.01728306433626297]
[-0.5165378314750091, -0.01608841469422157]
[-0.5309222101075886, -0.015921651811767683]
We can plot this result, using either Plots.jl or Makie.jl. We'll use Plots here:
using Plots
Plots.plot(result)
Analysis Arguments
The following arguments define a TransientAnalysis
:
Required Arguments
model
: the Dyad model that the analysis is being applied to.stop::Time
: chooses the end time for the interval.
Optional Arguments
alg::String
: chooses the solver algorithm for the solution process. The default is "auto". The choices are:"auto"
- Automatic algorithm choice with stiffness detection, size detection, and linear solve swapping from OrdinaryDiffEq.jl."Rodas5P"
- Adaptive time Rosenbrock method from OrdinaryDiffEqRosenbrock.jl. The Rosenbrock methods are specifically fast for small systems of stiff equations and DAEs which avoid Jacobian singularity issues (i.e. no variable-index DAE behavior)."FBDF"
- Adaptive order, adaptive time fixed leading coefficient backwards differentiation formulae (BDF) method from OrdinaryDiffEqBDF.jl, modeled after the FLC formulation of VODE. This is a good method for large stiff systems and DAEs."Tsit5"
- 5th order explicit Runge-Kutta method from OrdinaryDiffEqTsit5.jl. This method is not applicable to DAEs and is only applicable to systems which have no algebraic constraints (post simplification).
start::Time
: chooses the start time for the interval. Defaults to 0.abstol::Real
: chooses the absolute tolerance for the solver. Defaults to1e-6
.reltol::Real
: chooses the relative tolerance for the solver. Defaults to1e-3
.saveat::Real
: chooses the saving interval for the solving process. The default is 0, which corresponds to saving a dense output with a continuous time interpolation for high-fidelity solution at all points. If a non-zero value is chosen, for example,0.1
, then it will save at only the interval points (0.1, 0.2, ...) and use a linear interpolation between those points. This should only be used as a performance and memory optimization.dtmax::Time
: sets thedtmax
of the ODE solver. Defaults to 0 which uses the default of the solver. Setting this lower can be used to force smaller steps and thus a more accurate solution.
Experimental Arguments
IfLifting::Boolean
: sets the iflifting compiler pass in the ModelingToolkit code generation. Currently defaults to false, but will default to true after the feature is made non-experimental.
Artifacts
A TransientAnalysis
returns the following artifacts:
Customizable Plot
The customizable plot of a TransientAnalysis
is the timeseries plot of the ODE/DAE solve which satisfies the rules and definitiosn of the DifferentialEquations.jl plotting interface.
Standard Plots
:SimulationSolutionPlot
: Returns the standard time series plot of the solution trajectory for all values in the state vector.
Tables
:SimulationSolutionTable
: Returns a DataFrame of the solution. Ifsaveat=0
, then thet
are the adaptively chosen points, otherwise thet
matches the interval chosen bysaveat
.
Julia-Side Artifacts
:RawSolution
: Returns the DifferentialEquations.jl solution type from the run.:SimplifiedSystem
: Returns the ModelingToolkit.jl model after structural simplification was performed.:InitialSystem
: Returns the initial ModelingToolkit.jl model that was passed to the analysis.
Special Julia-Side Interactivity
The TransientAnalysis
includes special Julia-side behaviors for better analyzing the time series of solutions. In particular, if you do:
result = MyTransientAnalysis(; #= kwargs... =#)
Transient Analysis Solution for TransientAnalysis
retcode: Success
Interpolation: 3rd order Hermite
t: 16-element Vector{Float64}:
0.0
1.0e-6
1.586795936450487e-6
7.454755300955357e-6
2.28115432997575e-5
4.5664104448907174e-5
7.651106128366515e-5
0.00011836165460786049
0.0001727101289840257
0.00024226131134568842
0.0003294888857079311
0.0004383985383000816
0.0005747975715449812
0.0007483524114999508
0.00097303843348701
0.001
u: 16-element Vector{Vector{Float64}}:
[0.0, 0.0]
[-2.923820899891337e-6, -0.00017511050717338244]
[-7.347382279861189e-6, -0.00027710640828700934]
[-0.00015923569257947438, -0.0012669182617594144]
[-0.0014230120785277591, -0.003614635515402228]
[-0.005330345933874919, -0.0065400498003263885]
[-0.013712472833941782, -0.009615852490729606]
[-0.02933712753910297, -0.012589684835191446]
[-0.05456302521738237, -0.015047506091293622]
[-0.09169025462020348, -0.016783167056749024]
[-0.14213061212383468, -0.017756962170787358]
[-0.20738685163523904, -0.018087139454824725]
[-0.2893823819109583, -0.01791257448531749]
[-0.3913426476626362, -0.01728306433626297]
[-0.5165378314750091, -0.01608841469422157]
[-0.5309222101075886, -0.015921651811767683]
then artifacts(result, :RawSolution)
gives you the DifferentialEquations.jl solution type from the run. Thus for example:
using DyadInterface: artifacts
sol = artifacts(result, :RawSolution)
retcode: Success
Interpolation: 3rd order Hermite
t: 16-element Vector{Float64}:
0.0
1.0e-6
1.586795936450487e-6
7.454755300955357e-6
2.28115432997575e-5
4.5664104448907174e-5
7.651106128366515e-5
0.00011836165460786049
0.0001727101289840257
0.00024226131134568842
0.0003294888857079311
0.0004383985383000816
0.0005747975715449812
0.0007483524114999508
0.00097303843348701
0.001
u: 16-element Vector{Vector{Float64}}:
[0.0, 0.0]
[-2.923820899891337e-6, -0.00017511050717338244]
[-7.347382279861189e-6, -0.00027710640828700934]
[-0.00015923569257947438, -0.0012669182617594144]
[-0.0014230120785277591, -0.003614635515402228]
[-0.005330345933874919, -0.0065400498003263885]
[-0.013712472833941782, -0.009615852490729606]
[-0.02933712753910297, -0.012589684835191446]
[-0.05456302521738237, -0.015047506091293622]
[-0.09169025462020348, -0.016783167056749024]
[-0.14213061212383468, -0.017756962170787358]
[-0.20738685163523904, -0.018087139454824725]
[-0.2893823819109583, -0.01791257448531749]
[-0.3913426476626362, -0.01728306433626297]
[-0.5165378314750091, -0.01608841469422157]
[-0.5309222101075886, -0.015921651811767683]
sol(1.0)
2-element Vector{Float64}:
-5.370930557667406e9
1.0124597660934585e9
For more information on using the solution object, see the DifferentialEquations.jl solution interface for more information. This solution allows for using the DifferentialEquations.jl plotting interface, for example:
using Plots
plot(sol)
See the DifferentialEquations.jl plotting documentation for more details. Note that for convenience, the original result
object can be plotted directly without rebuilding the solution:
plot(result)