Skip to content

Commit 0a44f6b

Browse files
committed
Add dummy_derivative (WIP)
1 parent 6b92d37 commit 0a44f6b

File tree

4 files changed

+94
-4
lines changed

4 files changed

+94
-4
lines changed

src/bipartite_graph.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,13 @@ Base.in(edge::BipartiteEdge, g::BipartiteGraph) = Graphs.has_edge(g, edge)
234234

235235
### Maximal matching
236236
"""
237-
construct_augmenting_path!(m::Matching, g::BipartiteGraph, vsrc, dstfilter, vcolor=falses(ndsts(g)), ecolor=falses(nsrcs(g))) -> path_found::Bool
237+
construct_augmenting_path!(m::Matching, g::BipartiteGraph, vsrc, dstfilter, vcolor=falses(ndsts(g)), ecolor=nothing) -> path_found::Bool
238238
239239
Try to construct an augmenting path in matching and if such a path is found,
240240
update the matching accordingly.
241241
"""
242-
function construct_augmenting_path!(matching::Matching, g::BipartiteGraph, vsrc, dstfilter, dcolor=falses(ndsts(g)), scolor=falses(nsrcs(g)))
243-
scolor[vsrc] = true
242+
function construct_augmenting_path!(matching::Matching, g::BipartiteGraph, vsrc, dstfilter, dcolor=falses(ndsts(g)), scolor=nothing)
243+
scolor === nothing || (scolor[vsrc] = true)
244244

245245
# if a `vdst` is unassigned and the edge `vsrc <=> vdst` exists
246246
for vdst in 𝑠neighbors(g, vsrc)

src/structural_transformation/StructuralTransformations.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ using ModelingToolkit.BipartiteGraphs
2727
import .BipartiteGraphs: invview
2828
using Graphs
2929
using ModelingToolkit.SystemStructures
30-
using ModelingToolkit.SystemStructures: algeqs
30+
using ModelingToolkit.SystemStructures: algeqs, EquationsView
3131

3232
using ModelingToolkit.DiffEqBase
3333
using ModelingToolkit.StaticArrays
@@ -40,6 +40,7 @@ using SparseArrays
4040
using NonlinearSolve
4141

4242
export tearing, partial_state_selection, dae_index_lowering, check_consistency
43+
export dummy_derivative
4344
export build_torn_function, build_observed_function, ODAEProblem
4445
export sorted_incidence_matrix, pantelides!, tearing_reassemble, find_solvables!
4546
export tearing_assignments, tearing_substitution

src/structural_transformation/partial_state_selection.jl

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,80 @@ function partial_state_selection_graph!(structure::SystemStructure, var_eq_match
139139

140140
var_eq_matching
141141
end
142+
143+
function dummy_derivative_graph!(state::TransformationState)
144+
var_eq_matching = complete(pantelides!(state))
145+
complete!(state.structure)
146+
dummy_derivative_graph!(state.structure, var_eq_matching)
147+
end
148+
149+
function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching)
150+
@unpack eq_to_diff, var_to_diff, graph = structure
151+
diff_to_eq = invview(eq_to_diff)
152+
diff_to_var = invview(var_to_diff)
153+
invgraph = invview(graph)
154+
155+
neqs = nsrcs(graph)
156+
eqlevel = zeros(Int, neqs)
157+
maxlevel = 0
158+
for i in 1:neqs
159+
level = 0
160+
eq = i
161+
while diff_to_eq[eq] !== nothing
162+
eq = diff_to_eq[eq]
163+
level += 1
164+
end
165+
maxlevel = max(maxlevel, level)
166+
eqlevel[i] = level
167+
end
168+
169+
nvars = ndsts(graph)
170+
varlevel = zeros(Int, nvars)
171+
for i in 1:nvars
172+
level = 0
173+
var = i
174+
while diff_to_var[var] !== nothing
175+
var = diff_to_var[var]
176+
level += 1
177+
end
178+
maxlevel = max(maxlevel, level)
179+
varlevel[i] = level
180+
end
181+
182+
var_sccs = find_var_sccs(graph, var_eq_matching)
183+
eqcolor = falses(neqs)
184+
dummy_derivatives = Int[]
185+
for vars in var_sccs
186+
eqs = [var_eq_matching[var] for var in vars if var_eq_matching[var] !== unassigned]
187+
isempty(eqs) && continue
188+
maxlevel = maximum(map(x->eqlevel[x], eqs))
189+
iszero(maxlevel) && continue
190+
191+
rank_matching = Matching(nvars)
192+
for level in maxlevel:-1:1
193+
eqs = filter(eq->diff_to_eq[eq] !== nothing, eqs)
194+
nrows = length(eqs)
195+
iszero(nrows) && break
196+
eqs_set = BitSet(eqs)
197+
198+
structural_rank = 0
199+
for var in vars
200+
pathfound = construct_augmenting_path!(rank_matching, invgraph, var, eq->eq in eqs_set, eqcolor)
201+
pathfound || continue
202+
push!(dummy_derivatives, var)
203+
structural_rank += 1
204+
structural_rank == nrows && break
205+
end
206+
if structural_rank != nrows
207+
@warn "The DAE system is structurally singular!"
208+
end
209+
fill!(rank_matching, unassigned)
210+
211+
# prepare the next iteration
212+
eqs = map(eq->diff_to_eq[eq], eqs)
213+
vars = [diff_to_var[var] for var in vars if diff_to_var[var] !== nothing]
214+
end
215+
end
216+
217+
dummy_derivatives
218+
end

src/structural_transformation/symbolics_tearing.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,3 +282,15 @@ function partial_state_selection(sys; simplify=false)
282282

283283
tearing_reassemble(state, var_eq_matching; simplify=simplify)
284284
end
285+
286+
"""
287+
dummy_derivative(sys)
288+
289+
Perform index reduction and use the dummy derivative techinque to ensure that
290+
the system is balanced.
291+
"""
292+
function dummy_derivative(sys)
293+
state = TearingState(sys)
294+
dds = dummy_derivative_graph!(state)
295+
EquationsView(state), state.fullvars[dds]
296+
end

0 commit comments

Comments
 (0)