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
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 isdiffvars, isdervars, isalgvars
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,33 @@ 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
+ eqtype (s:: SystemStructure , eq:: Integer ):: EquationType = s. algeqs[eq] ? ALGEBRAIC_EQUATION : DIFFERENTIAL_EQUATION
77
+
42
78
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)
44
80
@set sys. structure = SystemStructure (
45
81
dxvar_offset,
46
82
fullvars,
47
83
varassoc,
84
+ algeqs,
48
85
graph,
49
86
solvable_graph,
50
87
Int[],
74
111
function collect_variables (sys)
75
112
dxvars = []
76
113
eqs = equations (sys)
114
+ algeqs = falses (length (eqs))
77
115
for (i, eq) in enumerate (eqs)
78
116
if isdiffeq (eq)
117
+ algeqs[i] = true
79
118
lhs = eq. lhs
80
119
# Make sure that the LHS is a first order derivative of a var.
81
120
@assert ! (arguments (lhs)[1 ] isa Differential) " The equation $eq is not first order"
@@ -86,11 +125,11 @@ function collect_variables(sys)
86
125
87
126
xvars = (first ∘ var_from_nested_derivative). (dxvars)
88
127
algvars = setdiff (states (sys), xvars)
89
- return xvars, dxvars, algvars
128
+ return xvars, dxvars, algvars, algeqs
90
129
end
91
130
92
131
function init_graph (sys)
93
- xvars, dxvars, algvars = collect_variables (sys)
132
+ xvars, dxvars, algvars, algeqs = collect_variables (sys)
94
133
dxvar_offset = length (xvars)
95
134
algvar_offset = 2 dxvar_offset
96
135
@@ -119,5 +158,7 @@ function init_graph(sys)
119
158
end
120
159
121
160
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
123
162
end
163
+
164
+ end # module
0 commit comments