Skip to content

Commit b27a1eb

Browse files
committed
Add state_priority to prefer some states in dummy derivative
1 parent 3b16c9c commit b27a1eb

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

src/structural_transformation/partial_state_selection.jl

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ function partial_state_selection_graph!(structure::SystemStructure, var_eq_match
147147
var_eq_matching
148148
end
149149

150-
function dummy_derivative_graph!(state::TransformationState, jac = nothing; kwargs...)
150+
function dummy_derivative_graph!(state::TransformationState, jac = nothing, state_priority = nothing; kwargs...)
151151
state.structure.solvable_graph === nothing && find_solvables!(state; kwargs...)
152152
var_eq_matching = complete(pantelides!(state))
153153
complete!(state.structure)
154-
dummy_derivative_graph!(state.structure, var_eq_matching, jac)
154+
dummy_derivative_graph!(state.structure, var_eq_matching, jac, state_priority)
155155
end
156156

157157
function compute_diff_level(diff_to_x)
@@ -171,7 +171,7 @@ function compute_diff_level(diff_to_x)
171171
return xlevel, maxlevel
172172
end
173173

174-
function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, jac)
174+
function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, jac, state_priority)
175175
@unpack eq_to_diff, var_to_diff, graph = structure
176176
diff_to_eq = invview(eq_to_diff)
177177
diff_to_var = invview(var_to_diff)
@@ -191,12 +191,17 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching, ja
191191
iszero(maxlevel) && continue
192192

193193
rank_matching = Matching(nvars)
194+
isfirst = true
194195
for _ in maxlevel:-1:1
195196
eqs = filter(eq -> diff_to_eq[eq] !== nothing, eqs)
196197
nrows = length(eqs)
197198
iszero(nrows) && break
198199
eqs_set = BitSet(eqs)
199200

201+
if state_priority !== nothing && isfirst
202+
sort!(vars, by = state_priority)
203+
end
204+
isfirst = false
200205
# TODO: making the algorithm more robust
201206
# 1. If the Jacobian is a integer matrix, use Bareiss to check
202207
# linear independence. (done)

src/structural_transformation/symbolics_tearing.jl

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -648,10 +648,27 @@ Perform index reduction and use the dummy derivative technique to ensure that
648648
the system is balanced.
649649
"""
650650
function dummy_derivative(sys, state = TearingState(sys); simplify = false, kwargs...)
651-
function jac(eqs, vars)
652-
symeqs = EquationsView(state)[eqs]
653-
Symbolics.jacobian((x -> x.rhs).(symeqs), state.fullvars[vars])
651+
jac = let state = state
652+
(eqs, vars) -> begin
653+
symeqs = EquationsView(state)[eqs]
654+
Symbolics.jacobian((x -> x.rhs).(symeqs), state.fullvars[vars])
655+
end
656+
end
657+
state_priority = let state = state
658+
var -> begin
659+
p = 0.0
660+
var_to_diff = state.structure.var_to_diff
661+
diff_to_var = invview(var_to_diff)
662+
while var_to_diff[var] !== nothing
663+
var = var_to_diff[var]
664+
end
665+
while true
666+
p = max(p, ModelingToolkit.state_priority(state.fullvars[var]))
667+
(var = diff_to_var[var]) === nothing && break
668+
end
669+
p
670+
end
654671
end
655-
var_eq_matching = dummy_derivative_graph!(state, jac; kwargs...)
672+
var_eq_matching = dummy_derivative_graph!(state, jac, state_priority; kwargs...)
656673
tearing_reassemble(state, var_eq_matching; simplify = simplify)
657674
end

src/variables.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ struct VariableNoiseType end
44
struct VariableInput end
55
struct VariableOutput end
66
struct VariableIrreducible end
7+
struct VariableStatePriority end
78
Symbolics.option_to_metadata_type(::Val{:unit}) = VariableUnit
89
Symbolics.option_to_metadata_type(::Val{:connect}) = VariableConnectType
910
Symbolics.option_to_metadata_type(::Val{:noise}) = VariableNoiseType
1011
Symbolics.option_to_metadata_type(::Val{:input}) = VariableInput
1112
Symbolics.option_to_metadata_type(::Val{:output}) = VariableOutput
1213
Symbolics.option_to_metadata_type(::Val{:irreducible}) = VariableIrreducible
14+
Symbolics.option_to_metadata_type(::Val{:state_priority}) = VariableStatePriority
1315

1416
abstract type AbstractConnectType end
1517
struct Equality <: AbstractConnectType end # Equality connection
@@ -26,6 +28,7 @@ end
2628
isinput(x) = isvarkind(VariableInput, x)
2729
isoutput(x) = isvarkind(VariableOutput, x)
2830
isirreducible(x) = isvarkind(VariableIrreducible, x) || isinput(x)
31+
state_priority(x) = convert(Float64, getmetadata(x, VariableStatePriority, 0.0))::Float64
2932

3033
"""
3134
$(SIGNATURES)

0 commit comments

Comments
 (0)