I’ve constructed a simple resistive circuit with a quadratically increasing voltage using ModelingToolkit. The following diagram gives a graphical depiction of the code below:
using ModelingToolkit
using ModelingToolkitStandardLibrary.Electrical
using ModelingToolkitStandardLibrary.Blocks
@mtkmodel SimpleCircuit begin
@components begin
resistor = Resistor(R=1)
ground = Ground()
voltage = Voltage()
ramp = Ramp(height=10)
product = Product()
end
@equations begin
connect(resistor.p, voltage.p)
connect(resistor.n, voltage.n, ground.g)
connect(ramp.output, product.input1)
connect(ramp.output, product.input2)
connect(voltage.V, product.output)
end
end
@mtkcompile sys = SimpleCircuit()
prob = ODEProblem(sys, Pair[], (0.0,1.0))
sol = solve(prob)
As can be seen above, after compiling the system, I cast it to an ODEProblem and then solve. Looking at the solution (below), we see that it solved the system at the start/end times of the provided time interval and the resistor current behaves as expected at these times (e.g. at 1 second, voltage = 100 and thus current should be 100 given R=1).
julia> sol
retcode: Success
Interpolation: 1st order linear
t: 2-element Vector{Float64}:
0.0
1.0
u: 2-element Vector{Vector{Float64}}:
[]
[]
julia> sol[sys.resistor.i]
2-element Vector{Float64}:
0.0
100.0
My question then is: How does ModelingToolkit handle time varying, but purely algebraic systems? As a point of reference, if I were to set up this exact same problem in Simscape and then plot the resistor current time series data, I would see a nice smooth curve of resistor currents evaluated at time-points dictated by the max step size setting of the solver.
As far as I’m aware, since there aren’t any differential quantities to integrate, an ODE solver would not work for a problem like this – rather it has to be done as a sequence of repeated algebraic solves (numerically or analytically) at each time step. I could see the argument that maybe this should be set up then as a NonlinearProblem rather than an ODEProblem, but I’m not sure how that would work since the variables defined in each component have an explicit time dependence. If posed as a NonlinearProblem, is the time dependence of the variables just dropped? Perhaps more important though, I feel that setting it up as a NonlinearProblem goes against the intent of the problem formulation above – which is to solve the time evolution of a system (that just happens to be purely algebraic in nature). The above implementation makes the intent very clear – apply a time varying excitation and compute how the system reacts to it.
What happens under the hood when ModelingToolkit is provided a system like the above? And how would I go about forcing it to evaluate more time points?
As a follow-up but related question: when looking at the System object, I see that all equations are observed – I’m assuming that it’s because the equations are simple enough that ModelingToolkit has deduced that it can solve for each variable explicitly?
