Skip to content

Jacobian order #1303

@baggepinnen

Description

@baggepinnen

There is currently a potential mismatch between the order in which states and equations are stored, in the following case, the dynamics for the spring deflection and damper velocity are equations 3 and 4, but the corresponding states are numbered 3 and 6. There is no error here, but when the jacobian is calculated, it will not be on the form

x' = Ax

but rather

xp = states(model)[permutation]
xp' = A*xp

where permutation is determined by the equation order.

julia> equations(model)
6-element Vector{Equation}:
 Differential(t)(mass1₊vel(t)) ~ (u(t) - sd₊damper₊c*sd₊damper₊vel(t) - sd₊spring₊k*sd₊spring₊x(t)) / mass1₊m
 Differential(t)(mass2₊vel(t)) ~ (sd₊damper₊c*sd₊damper₊vel(t) + sd₊spring₊k*sd₊spring₊x(t)) / mass2₊m
 sd₊spring₊x(t) ~ mass1₊pos(t) - mass2₊pos(t)
 sd₊damper₊vel(t) ~ mass1₊vel(t) - mass2₊vel(t)
 Differential(t)(mass1₊pos(t)) ~ mass1₊vel(t)
 Differential(t)(mass2₊pos(t)) ~ mass2₊vel(t)

julia> states(model)
6-element Vector{Term{Real, Base.ImmutableDict{DataType, Any}}}:
 mass1₊vel(t)
 mass2₊vel(t)
 sd₊spring₊x(t)
 mass1₊pos(t)
 mass2₊pos(t)
 sd₊damper₊vel(t)

julia> calculate_jacobian(model)
6×6 Matrix{Num}:
 0   0  (-sd₊spring₊k) / mass1₊m  0   0  (-sd₊damper₊c) / mass1₊m
 0   0     sd₊spring₊k / mass2₊m  0   0    sd₊damper₊c / mass2₊m
 0   0                         0  1  -1          0
 1  -1                         0  0   0          0
 1   0                         0  0   0          0
 0   1                         0  0   0          0

The model above is not minimal, in the sense that some states can be computed from others. The problem goes away after strucutral_simplify

julia> equations(model)
4-element Vector{Equation}:
 Differential(t)(mass1₊vel(t)) ~ (u(t) - sd₊spring₊k*(mass1₊pos(t) - mass2₊pos(t)) - sd₊damper₊c*(mass1₊vel(t) - mass2₊vel(t))) / mass1₊m
 Differential(t)(mass2₊vel(t)) ~ (sd₊spring₊k*(mass1₊pos(t) - mass2₊pos(t)) + sd₊damper₊c*(mass1₊vel(t) - mass2₊vel(t))) / mass2₊m
 Differential(t)(mass1₊pos(t)) ~ mass1₊vel(t)
 Differential(t)(mass2₊pos(t)) ~ mass2₊vel(t)

julia> calculate_jacobian(model)
4×4 Matrix{Num}:
 (-sd₊damper₊c) / mass1₊m    sd₊damper₊c / mass1₊m   (-sd₊spring₊k) / mass1₊m     sd₊spring₊k / mass1₊m
   sd₊damper₊c / mass2₊m   (-sd₊damper₊c) / mass2₊m     sd₊spring₊k / mass2₊m  (-sd₊spring₊k) / mass2₊m
         1                         0                                        0                         0
         0                         1                                        0                         0

Is the ordering after simplification a lucky coincidence, or can the ordering of states and equations always be made the same?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions