Skip to content

Commit 621a5ac

Browse files
committed
WIP: robust dummy_derivatives and pantelides
1 parent 8dc7f45 commit 621a5ac

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

src/structural_transformation/pantelides.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,30 +83,39 @@ function pantelides!(state::TransformationState, ag::Union{AliasGraph, Nothing}
8383
ecolor = falses(neqs)
8484
var_eq_matching = Matching(nvars)
8585
neqs′ = neqs
86-
nnonemptyeqs = count(eq -> !isempty(𝑠neighbors(graph, eq)), 1:neqs′)
86+
nnonemptyeqs = count(eq -> !isempty(𝑠neighbors(graph, eq)) && eq_to_diff[eq] === nothing,
87+
1:neqs′)
8788

8889
# Allow matching for the highest differentiated variable that
8990
# currently appears in an equation (or implicit equation in a side ag)
9091
varwhitelist = falses(nvars)
9192
for var in 1:nvars
92-
if var_to_diff[var] === nothing
93+
if var_to_diff[var] === nothing && !varwhitelist[var]
9394
while isempty(𝑑neighbors(graph, var)) && (ag === nothing || !haskey(ag, var))
9495
var′ = invview(var_to_diff)[var]
9596
var′ === nothing && break
9697
var = var′
9798
end
9899
if !isempty(𝑑neighbors(graph, var)) || (ag !== nothing && haskey(ag, var))
99-
varwhitelist[var] = true
100+
if haskey(ag, var)
101+
# TODO: remove lower diff vars from whitelist
102+
c, a = ag[var]
103+
iszero(c) || (varwhitelist[a] = true)
104+
else
105+
varwhitelist[var] = true
106+
end
100107
end
101108
end
102109
end
110+
@show varwhitelist
103111

104112
if nnonemptyeqs > count(varwhitelist)
105113
throw(InvalidSystemException("System is structurally singular"))
106114
end
107115

108116
for k in 1:neqs′
109117
eq′ = k
118+
eq_to_diff[eq′] === nothing || continue
110119
isempty(𝑠neighbors(graph, eq′)) && continue
111120
pathfound = false
112121
# In practice, `maxiters=8000` should never be reached, otherwise, the

src/structural_transformation/partial_state_selection.jl

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,12 @@ function partial_state_selection_graph!(structure::SystemStructure, var_eq_match
157157
var_eq_matching
158158
end
159159

160-
function dummy_derivative_graph!(state::TransformationState, jac = nothing; kwargs...)
160+
function dummy_derivative_graph!(state::TransformationState, jac = nothing, ag = nothing;
161+
kwargs...)
161162
state.structure.solvable_graph === nothing && find_solvables!(state; kwargs...)
162-
var_eq_matching = complete(pantelides!(state))
163+
var_eq_matching = complete(pantelides!(state, ag === nothing ? nothing : first(ag)))
163164
complete!(state.structure)
164-
dummy_derivative_graph!(state.structure, var_eq_matching, jac)
165+
dummy_derivative_graph!(state.structure, var_eq_matching, jac, ag)
165166
end
166167

167168
function compute_diff_level(diff_to_x)
@@ -181,8 +182,10 @@ function compute_diff_level(diff_to_x)
181182
return xlevel, maxlevel
182183
end
183184

184-
function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, jac)
185+
function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, jac,
186+
(ag, diff_va))
185187
@unpack eq_to_diff, var_to_diff, graph = structure
188+
display(structure)
186189
diff_to_eq = invview(eq_to_diff)
187190
diff_to_var = invview(var_to_diff)
188191
invgraph = invview(graph)
@@ -194,6 +197,7 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
194197
dummy_derivatives = Int[]
195198
col_order = Int[]
196199
nvars = ndsts(graph)
200+
@info "" var_eq_matching
197201
for vars in var_sccs
198202
eqs = [var_eq_matching[var] for var in vars if var_eq_matching[var] !== unassigned]
199203
isempty(eqs) && continue
@@ -245,6 +249,16 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
245249
vars = [diff_to_var[var] for var in vars if diff_to_var[var] !== nothing]
246250
end
247251
end
252+
n_dummys = length(dummy_derivatives)
253+
needed = count(x -> x isa Int, diff_to_eq) - n_dummys
254+
n = 0
255+
for v in diff_va
256+
c, a = ag[v]
257+
n += 1
258+
push!(dummy_derivatives, iszero(c) ? v : a)
259+
needed == n && break
260+
continue
261+
end
248262

249263
dummy_derivatives_set = BitSet(dummy_derivatives)
250264
# We can eliminate variables that are not a selected state (differential
@@ -254,6 +268,9 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
254268
dummy_derivatives_set = dummy_derivatives_set
255269

256270
v -> begin
271+
if ag !== nothing
272+
haskey(ag, v) && return false
273+
end
257274
dv = var_to_diff[v]
258275
dv === nothing || dv in dummy_derivatives_set
259276
end
@@ -269,7 +286,8 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
269286
Union{Unassigned, SelectedState};
270287
varfilter = can_eliminate)
271288
for v in eachindex(var_eq_matching)
272-
can_eliminate(v) && continue
289+
dv = var_to_diff[v]
290+
(dv === nothing || dv in dummy_derivatives_set) && continue
273291
var_eq_matching[v] = SelectedState()
274292
end
275293

0 commit comments

Comments
 (0)