@@ -71,7 +71,7 @@ function pantelides_reassemble(state::TearingState, var_eq_matching)
7171end
7272
7373"""
74- computed_highest_diff_variables(structure)
74+ computed_highest_diff_variables(structure; whitelisted_vars = () )
7575
7676Computes which variables are the "highest-differentiated" for purposes of
7777pantelides. Ordinarily this is relatively straightforward. However, in our
@@ -83,12 +83,18 @@ case, there is one complicating condition:
8383
8484This function takes care of these complications are returns a boolean array
8585for every variable, indicating whether it is considered "highest-differentiated".
86+
87+ For each index `i` in `whitelisted_vars`, the `i`th variable is included if it
88+ is the highest differentiated variable even if it doesn't appear in the system.
8689"""
87- function computed_highest_diff_variables (structure)
90+ function computed_highest_diff_variables (structure; whitelisted_vars = () )
8891 @unpack graph, var_to_diff = structure
8992
9093 nvars = length (var_to_diff)
9194 varwhitelist = falses (nvars)
95+ for i in whitelisted_vars
96+ varwhitelist[i] = true
97+ end
9298 for var in 1 : nvars
9399 if var_to_diff[var] === nothing && ! varwhitelist[var]
94100 # This variable is structurally highest-differentiated, but may not actually appear in the
125131Perform Pantelides algorithm.
126132"""
127133function pantelides! (
128- state:: TransformationState ; finalize = true , maxiters = 8000 , kwargs... )
134+ state:: TransformationState ; finalize = true , maxiters = 8000 , whitelisted_vars = (), kwargs... )
129135 @unpack graph, solvable_graph, var_to_diff, eq_to_diff = state. structure
130136 neqs = nsrcs (graph)
131137 nvars = nv (var_to_diff)
@@ -137,8 +143,7 @@ function pantelides!(
137143 eq -> ! isempty (𝑠neighbors (graph, eq)) && eq_to_diff[eq] === nothing ,
138144 1 : neqs′)
139145
140- varwhitelist = computed_highest_diff_variables (state. structure)
141-
146+ varwhitelist = computed_highest_diff_variables (state. structure; whitelisted_vars)
142147 if nnonemptyeqs > count (varwhitelist)
143148 throw (InvalidSystemException (" System is structurally singular" ))
144149 end
@@ -206,14 +211,19 @@ function pantelides!(
206211end
207212
208213"""
209- dae_index_lowering(sys::ODESystem; kwargs...) -> ODESystem
214+ dae_index_lowering(sys::ODESystem; to_index_zero = false, kwargs...) -> ODESystem
210215
211216Perform the Pantelides algorithm to transform a higher index DAE to an index 1
212217DAE. `kwargs` are forwarded to [`pantelides!`](@ref). End users are encouraged to call [`structural_simplify`](@ref)
213- instead, which calls this function internally.
218+ instead, which calls this function internally. If `to_index_zero` is true, the DAE will be reduced to an index 1 DAE.
214219"""
215- function dae_index_lowering (sys:: ODESystem ; kwargs... )
220+ function dae_index_lowering (sys:: ODESystem ; to_index_zero = false , kwargs... )
216221 state = TearingState (sys)
217- var_eq_matching = pantelides! (state; finalize = false , kwargs... )
222+ if to_index_zero
223+ newvars = ModelingToolkit. add_missing_differentials! (state)
224+ else
225+ newvars = ()
226+ end
227+ var_eq_matching = pantelides! (state; finalize = false , whitelisted_vars = newvars, kwargs... )
218228 return invalidate_cache! (pantelides_reassemble (state, var_eq_matching))
219229end
0 commit comments