1+ module SystemStructures
2+
3+ using .. ModelingToolkit
4+ import .. ModelingToolkit: isdiffeq, var_from_nested_derivative, vars!, flatten
5+ using SymbolicUtils: arguments
6+ using .. BipartiteGraphs
7+ using UnPack
8+ using Setfield
19using SparseArrays
210
311#=
@@ -27,10 +35,18 @@ for v in 𝑣vertices(graph); active_𝑣vertices[v] || continue
2735end
2836=#
2937
38+ export SystemStructure, initialize_system_structure
39+ export diffvars_range, dervars_range, algvars_range
40+ export isdiffvar, isdervar, isalgvar, isdiffeq, isalgeq
41+ export DIFFERENTIAL_VARIABLE, ALGEBRAIC_VARIABLE, DERIVATIVE_VARIABLE
42+ export DIFFERENTIAL_EQUATION, ALGEBRAIC_EQUATION
43+ export vartype, eqtype
44+
3045struct 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,35 @@ struct SystemStructure
3955 partitions:: Vector{NTuple{4, Vector{Int}}}
4056end
4157
58+ diffvars_range (s:: SystemStructure ) = 1 : s. dxvar_offset
59+ dervars_range (s:: SystemStructure ) = s. dxvar_offset+ 1 : 2 s. dxvar_offset
60+ algvars_range (s:: SystemStructure ) = 2 s. 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+ isalgeq (s:: SystemStructure , eq:: Integer ) = s. algeqs[eq]
77+ isdiffeq (s:: SystemStructure , eq:: Integer ) = ! isalgeq (s, eq)
78+ eqtype (s:: SystemStructure , eq:: Integer ):: EquationType = isalgeq (s, eq) ? ALGEBRAIC_EQUATION : DIFFERENTIAL_EQUATION
79+
4280function initialize_system_structure (sys)
43- sys, dxvar_offset, fullvars, varassoc, graph, solvable_graph = init_graph (flatten (sys))
81+ sys, dxvar_offset, fullvars, varassoc, algeqs, graph, solvable_graph = init_graph (flatten (sys))
4482 @set sys. structure = SystemStructure (
4583 dxvar_offset,
4684 fullvars,
4785 varassoc,
86+ algeqs,
4887 graph,
4988 solvable_graph,
5089 Int[],
74113function collect_variables (sys)
75114 dxvars = []
76115 eqs = equations (sys)
116+ algeqs = trues (length (eqs))
77117 for (i, eq) in enumerate (eqs)
78118 if isdiffeq (eq)
119+ algeqs[i] = false
79120 lhs = eq. lhs
80121 # Make sure that the LHS is a first order derivative of a var.
81122 @assert ! (arguments (lhs)[1 ] isa Differential) " The equation $eq is not first order"
@@ -86,11 +127,11 @@ function collect_variables(sys)
86127
87128 xvars = (first ∘ var_from_nested_derivative). (dxvars)
88129 algvars = setdiff (states (sys), xvars)
89- return xvars, dxvars, algvars
130+ return xvars, dxvars, algvars, algeqs
90131end
91132
92133function init_graph (sys)
93- xvars, dxvars, algvars = collect_variables (sys)
134+ xvars, dxvars, algvars, algeqs = collect_variables (sys)
94135 dxvar_offset = length (xvars)
95136 algvar_offset = 2 dxvar_offset
96137
@@ -119,5 +160,7 @@ function init_graph(sys)
119160 end
120161
121162 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
163+ sys, dxvar_offset, fullvars, varassoc, algeqs, graph, solvable_graph
123164end
165+
166+ end # module
0 commit comments