@@ -146,53 +146,48 @@ function partial_state_selection_graph!(structure::SystemStructure, var_eq_match
146
146
var_eq_matching
147
147
end
148
148
149
- function dummy_derivative_graph! (state:: TransformationState , jac = nothing )
149
+ function dummy_derivative_graph! (state:: TransformationState , jac = nothing ; kwargs... )
150
+ state. structure. solvable_graph === nothing && find_solvables! (state; kwargs... )
150
151
var_eq_matching = complete (pantelides! (state))
151
152
complete! (state. structure)
152
153
dummy_derivative_graph! (state. structure, var_eq_matching, jac)
153
154
end
154
155
155
- function dummy_derivative_graph! (structure:: SystemStructure , var_eq_matching, jac)
156
- @unpack eq_to_diff, var_to_diff, graph = structure
157
- diff_to_eq = invview (eq_to_diff)
158
- diff_to_var = invview (var_to_diff)
159
- invgraph = invview (graph)
160
-
161
- neqs = nsrcs (graph)
162
- eqlevel = zeros (Int, neqs)
156
+ function compute_diff_level (diff_to_x)
157
+ nxs = length (diff_to_x)
158
+ xlevel = zeros (Int, nxs)
163
159
maxlevel = 0
164
- for i in 1 : neqs
160
+ for i in 1 : nxs
165
161
level = 0
166
- eq = i
167
- while diff_to_eq[eq ] != = nothing
168
- eq = diff_to_eq[eq ]
162
+ x = i
163
+ while diff_to_x[x ] != = nothing
164
+ x = diff_to_x[x ]
169
165
level += 1
170
166
end
171
167
maxlevel = max (maxlevel, level)
172
- eqlevel [i] = level
168
+ xlevel [i] = level
173
169
end
170
+ return xlevel, maxlevel
171
+ end
174
172
175
- nvars = ndsts (graph)
176
- varlevel = zeros (Int, nvars)
177
- for i in 1 : nvars
178
- level = 0
179
- var = i
180
- while diff_to_var[var] != = nothing
181
- var = diff_to_var[var]
182
- level += 1
183
- end
184
- maxlevel = max (maxlevel, level)
185
- varlevel[i] = level
186
- end
173
+ function dummy_derivative_graph! (structure:: SystemStructure , var_eq_matching, jac)
174
+ @unpack eq_to_diff, var_to_diff, graph = structure
175
+ diff_to_eq = invview (eq_to_diff)
176
+ diff_to_var = invview (var_to_diff)
177
+ invgraph = invview (graph)
178
+
179
+ eqlevel, _ = compute_diff_level (diff_to_eq)
180
+ varlevel, _ = compute_diff_level (diff_to_var)
187
181
188
182
var_sccs = find_var_sccs (graph, var_eq_matching)
189
- eqcolor = falses (neqs )
183
+ eqcolor = falses (nsrcs (graph) )
190
184
dummy_derivatives = Int[]
191
185
col_order = Int[]
186
+ nvars = ndsts (graph)
192
187
for vars in var_sccs
193
188
eqs = [var_eq_matching[var] for var in vars if var_eq_matching[var] != = unassigned]
194
189
isempty (eqs) && continue
195
- maxlevel = maximum (map (x -> eqlevel[x] , eqs) )
190
+ maxlevel = maximum (Base . Fix1 (getindex, eqlevel) , eqs)
196
191
iszero (maxlevel) && continue
197
192
198
193
rank_matching = Matching (nvars)
@@ -220,8 +215,10 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
220
215
else
221
216
rank = 0
222
217
for var in vars
218
+ # We need `invgraph` here because we are matching from
219
+ # variables to equations.
223
220
pathfound = construct_augmenting_path! (rank_matching, invgraph, var,
224
- eq -> eq in eqs_set, eqcolor)
221
+ Base . Fix2 (in, eqs_set) , eqcolor)
225
222
pathfound || continue
226
223
push! (dummy_derivatives, var)
227
224
rank += 1
@@ -239,5 +236,35 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
239
236
end
240
237
end
241
238
242
- dummy_derivatives
239
+ dummy_derivatives_set = BitSet (dummy_derivatives)
240
+ # We can eliminate variables that are not a selected state (differential
241
+ # variables). Selected states are differentiated variables that are not
242
+ # dummy derivatives.
243
+ can_eliminate = let var_to_diff = var_to_diff,
244
+ dummy_derivatives_set = dummy_derivatives_set
245
+
246
+ v -> begin
247
+ dv = var_to_diff[v]
248
+ dv === nothing || dv in dummy_derivatives_set
249
+ end
250
+ end
251
+
252
+ # We don't want tearing to give us `y_t ~ D(y)`, so we skip equations with
253
+ # actually differentiated variables.
254
+ isdiffed = let diff_to_var = diff_to_var, dummy_derivatives_set = dummy_derivatives_set
255
+ v -> diff_to_var[v] != = nothing && ! (v in dummy_derivatives_set)
256
+ end
257
+ should_consider = let graph = graph, isdiffed = isdiffed
258
+ eq -> ! any (isdiffed, 𝑠neighbors (graph, eq))
259
+ end
260
+
261
+ var_eq_matching = tear_graph_modia (structure, Union{Unassigned, SelectedState};
262
+ varfilter = can_eliminate,
263
+ eqfilter = should_consider)
264
+ for v in eachindex (var_eq_matching)
265
+ can_eliminate (v) && continue
266
+ var_eq_matching[v] = SelectedState ()
267
+ end
268
+
269
+ return var_eq_matching
243
270
end
0 commit comments