I also implemented that in the following Julia package: https://github.com/ufechner7/KiteModels.jl/blob/main/src/KPS4.jl , but in this package I was doing these calculations numerically and not symbolically. It uses a lookup table:
const SPRINGS_INPUT = [0. 1. 150.
1. 2. -1. # s1, p7, p8
4. 2. -1. # s2, p10, p8
4. 5. -1. # s3, p10, p11
3. 4. -1. # s4, p9, p10
5. 1. -1. # s5, p11, p7
4. 1. -1. # s6, p10, p7
3. 5. -1. # s7, p9, p11
5. 2. -1. # s8, p11, p8
2. 3. -1.] # s9, p8, p9
to define which springs are connecting which point masses…
I don’t see any issue to do something similar symbolically… But it would take a lot of time, it is very easy to make mistakes and they are hard to debug…
In other words, perhaps the better approach with ModelingToolkit is to create components and connect them, but I don’t have any experience with this approach…
Yes I think it is the way to go too. I wonder, if this necessitates connectors, or if a more straightforward approach like in my previous post is enough.
Another thing. I get some errors related to symbolic vectors when calling structural_simplify
without specifying only scalar parameters in ODESystem
. Such as the following.
julia> sys = structural_simplify(model)
ERROR: MethodError: no method matching hasmetadata(::Vector{SymbolicUtils.BasicSymbolic{Real}}, ::Type{Symbolics.VariableDefaultValue})
Did you get such errors ?
@ChrisRackauckas, is this still a missing functionality, should I file an issue ?
EDIT : So I found a way to circumvent this problem by (without much surprise) iterating through the symbolic vectors. So for instance, if you have an ODESystem
such as
@named _model = ODESystem(eqs, t)
where some symbolic parameters are arrays, one way to make it work is to do
@named _model = ODESystem(eqs, t, [<list of all symbolic variables of interest, even arrays>], [mysymbolicparameterarray...])
With the same logic, getting the default value of a given parameter array dos not work so something like [ModelingToolkit.getdefault(d) for d in sys.mysymbolicparameterarray]
seems to be the only solution.
For the record it seems such an implementation is presented in Exposing More Parallelism By Tearing Algebraic Equations in ODESystems · ModelingToolkit.jl
<...>
eqs = [
D(E) ~ sum(((i, sys),) -> getproperty(sys, Symbol(:resistor, i)).h.Q_flow,
enumerate(rc_systems)),
]
<...>