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
1
9
using SparseArrays
2
10
3
11
#=
@@ -27,10 +35,18 @@ for v in 𝑣vertices(graph); active_𝑣vertices[v] || continue
27
35
end
28
36
=#
29
37
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
+
30
45
struct SystemStructure
31
46
dxvar_offset:: Int
32
47
fullvars:: Vector # [xvar; dxvars; algvars]
33
48
varassoc:: Vector{Int}
49
+ algeqs:: BitVector
34
50
graph:: BipartiteGraph{Int}
35
51
solvable_graph:: BipartiteGraph{Int}
36
52
assign:: Vector{Int}
@@ -39,12 +55,35 @@ struct SystemStructure
39
55
partitions:: Vector{NTuple{4, Vector{Int}}}
40
56
end
41
57
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
+
42
80
function 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))
44
82
@set sys. structure = SystemStructure (
45
83
dxvar_offset,
46
84
fullvars,
47
85
varassoc,
86
+ algeqs,
48
87
graph,
49
88
solvable_graph,
50
89
Int[],
74
113
function collect_variables (sys)
75
114
dxvars = []
76
115
eqs = equations (sys)
116
+ algeqs = trues (length (eqs))
77
117
for (i, eq) in enumerate (eqs)
78
118
if isdiffeq (eq)
119
+ algeqs[i] = false
79
120
lhs = eq. lhs
80
121
# Make sure that the LHS is a first order derivative of a var.
81
122
@assert ! (arguments (lhs)[1 ] isa Differential) " The equation $eq is not first order"
@@ -86,11 +127,11 @@ function collect_variables(sys)
86
127
87
128
xvars = (first ∘ var_from_nested_derivative). (dxvars)
88
129
algvars = setdiff (states (sys), xvars)
89
- return xvars, dxvars, algvars
130
+ return xvars, dxvars, algvars, algeqs
90
131
end
91
132
92
133
function init_graph (sys)
93
- xvars, dxvars, algvars = collect_variables (sys)
134
+ xvars, dxvars, algvars, algeqs = collect_variables (sys)
94
135
dxvar_offset = length (xvars)
95
136
algvar_offset = 2 dxvar_offset
96
137
@@ -119,5 +160,7 @@ function init_graph(sys)
119
160
end
120
161
121
162
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
123
164
end
165
+
166
+ end # module
0 commit comments