Skip to content

Commit 3c4ea7d

Browse files
committed
Add some convenient interfaces
1 parent 2b1bf2f commit 3c4ea7d

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

src/systems/systemstructure.jl

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
module SystemStructures
2+
3+
using ..ModelingToolkit
4+
using ..ModelingToolkit: isdiffeq, var_from_nested_derivative, vars!
5+
using SymbolicUtils: arguments
6+
using ..BipartiteGraphs
7+
using UnPack
8+
using Setfield
19
using SparseArrays
210

311
#=
@@ -27,10 +35,18 @@ for v in 𝑣vertices(graph); active_𝑣vertices[v] || continue
2735
end
2836
=#
2937

38+
export SystemStructure, initialize_system_structure
39+
export diffvars_range, dervars_range, algvars_range
40+
export isdiffvars, isdervars, isalgvars
41+
export DIFFERENTIAL_VARIABLE, ALGEBRAIC_VARIABLE, DERIVATIVE_VARIABLE
42+
export DIFFERENTIAL_EQUATION, ALGEBRAIC_EQUATION
43+
export vartype, eqtype
44+
3045
struct SystemStructure
3146
dxvar_offset::Int
3247
fullvars::Vector # [xvar; dxvars; algvars]
3348
varassoc::Vector{Int}
49+
algeqs::BitVector
3450
graph::BipartiteGraph{Int}
3551
solvable_graph::BipartiteGraph{Int}
3652
assign::Vector{Int}
@@ -39,12 +55,33 @@ struct SystemStructure
3955
partitions::Vector{NTuple{4, Vector{Int}}}
4056
end
4157

58+
diffvars_range(s::SystemStructure) = 1:s.dxvar_offset
59+
dervars_range(s::SystemStructure) = s.dxvar_offset+1:2s.dxvar_offset
60+
algvars_range(s::SystemStructure) = 2s.dxvar_offset+1:length(s.fullvars)
61+
62+
isdiffvar(s::SystemStructure, var::Integer) = var in diffvars_range(s)
63+
isdervar(s::SystemStructure, var::Integer) = var in dervars_range(s)
64+
isalgvar(s::SystemStructure, var::Integer) = var in algvars_range(s)
65+
66+
@enum VariableType DIFFERENTIAL_VARIABLE ALGEBRAIC_VARIABLE DERIVATIVE_VARIABLE
67+
68+
function vartype(s::SystemStructure, var::Integer)::VariableType
69+
isdiffvar(s, var) ? DIFFERENTIAL_VARIABLE :
70+
isdervar(s, var) ? DERIVATIVE_VARIABLE :
71+
isalgvar(s, var) ? ALGEBRAIC_VARIABLE : error("Variable $var out of bounds")
72+
end
73+
74+
@enum EquationType DIFFERENTIAL_EQUATION ALGEBRAIC_EQUATION
75+
76+
eqtype(s::SystemStructure, eq::Integer)::EquationType = s.algeqs[eq] ? ALGEBRAIC_EQUATION : DIFFERENTIAL_EQUATION
77+
4278
function initialize_system_structure(sys)
43-
sys, dxvar_offset, fullvars, varassoc, graph, solvable_graph = init_graph(flatten(sys))
79+
sys, dxvar_offset, fullvars, varassoc, algeqs, graph, solvable_graph = init_graph(sys)
4480
@set sys.structure = SystemStructure(
4581
dxvar_offset,
4682
fullvars,
4783
varassoc,
84+
algeqs,
4885
graph,
4986
solvable_graph,
5087
Int[],
@@ -74,8 +111,10 @@ end
74111
function collect_variables(sys)
75112
dxvars = []
76113
eqs = equations(sys)
114+
algeqs = falses(length(eqs))
77115
for (i, eq) in enumerate(eqs)
78116
if isdiffeq(eq)
117+
algeqs[i] = true
79118
lhs = eq.lhs
80119
# Make sure that the LHS is a first order derivative of a var.
81120
@assert !(arguments(lhs)[1] isa Differential) "The equation $eq is not first order"
@@ -86,11 +125,11 @@ function collect_variables(sys)
86125

87126
xvars = (first var_from_nested_derivative).(dxvars)
88127
algvars = setdiff(states(sys), xvars)
89-
return xvars, dxvars, algvars
128+
return xvars, dxvars, algvars, algeqs
90129
end
91130

92131
function init_graph(sys)
93-
xvars, dxvars, algvars = collect_variables(sys)
132+
xvars, dxvars, algvars, algeqs = collect_variables(sys)
94133
dxvar_offset = length(xvars)
95134
algvar_offset = 2dxvar_offset
96135

@@ -119,5 +158,7 @@ function init_graph(sys)
119158
end
120159

121160
varassoc = Int[(1:dxvar_offset) .+ dxvar_offset; zeros(Int, length(fullvars) - dxvar_offset)] # variable association list
122-
sys, dxvar_offset, fullvars, varassoc, graph, solvable_graph
161+
sys, dxvar_offset, fullvars, varassoc, algeqs, graph, solvable_graph
123162
end
163+
164+
end # module

0 commit comments

Comments
 (0)