@@ -119,12 +119,25 @@ function structural_transformation!(state::TransformationState)
119119 first = false
120120 continue
121121 end
122-
122+
123123 return StateSelection. complete (var_eq_matching, nsrcs (state. structure. graph))
124124 end
125125end
126126
127127using StateSelection: Unassigned, SelectedState, unassigned
128+
129+ struct StateInvariant; end
130+ StateSelection. BipartiteGraphs. overview_label (:: Type{StateInvariant} ) = (' P' , " State Invariant / Parameter" , :red )
131+
132+ struct InOut
133+ ordinal:: Int
134+ end
135+ StateSelection. BipartiteGraphs. overview_label (:: Type{InOut} ) = (' #' , " IPO in var / out eq" , :green )
136+ StateSelection. BipartiteGraphs. overview_label (io:: InOut ) = (string (io. ordinal), " IPO in var / out eq" , :green )
137+
138+ const IPOMatches = Union{Unassigned, SelectedState, StateInvariant, InOut}
139+ const IPOMatching = StateSelection. Matching{IPOMatches}
140+
128141function top_level_state_selection! (tstate)
129142 (; result, structure) = tstate
130143 # For the top-level problem, all external vars are state-invariant, and we do no other fissioning
@@ -135,16 +148,20 @@ function top_level_state_selection!(tstate)
135148 StateSelection. complete! (structure)
136149
137150 # # Part 1: Perform the selection of differential states and subsequent tearing of the
138- # non-linear problem at every time step.
151+ # non-linear problem at every time step.
139152
140- var_eq_matching = StateSelection. partial_state_selection_graph! (structure, highest_diff_max_match)
153+ var_eq_matching = convert (IPOMatching, StateSelection. partial_state_selection_graph! (structure, highest_diff_max_match) )
141154
142155 diff_vars = BitSet ()
143156 alg_vars = BitSet ()
144157 explicit_eqs = BitSet ()
145158
146159 for (v, match) in enumerate (var_eq_matching)
147- v in param_vars && continue
160+ if v in param_vars
161+ @assert match === unassigned
162+ var_eq_matching[v] = StateInvariant ()
163+ continue
164+ end
148165 if match === SelectedState ()
149166 push! (diff_vars, v)
150167 elseif match === unassigned
@@ -164,14 +181,19 @@ function top_level_state_selection!(tstate)
164181 varfilter (var) = varkind (result, structure, var) == Intrinsics. Continuous && ! (var <= result. nexternalvars)
165182
166183 # # Part 2: Perform the selection of differential states and subsequent tearing of the
167- # non-linear problem at every time step.
168- init_var_eq_matching = StateSelection. complete (StateSelection. maximal_matching (structure. graph;
184+ # non-linear problem at every time step.
185+ init_var_eq_matching = StateSelection. complete (StateSelection. maximal_matching (structure. graph, IPOMatches ;
169186 dstfilter = varfilter, srcfilter = eq-> eqkind (result, structure, eq) in (Intrinsics. Always, Intrinsics. Initial)), nsrcs (structure. graph))
170- init_var_eq_matching = StateSelection. pss_graph_modia! (structure, init_var_eq_matching)
187+ init_var_eq_matching = convert (IPOMatching, StateSelection. pss_graph_modia! (structure, init_var_eq_matching) )
171188
172189 init_state_vars = BitSet ()
173190 init_explicit_eqs = BitSet ()
174191 for (v, match) in enumerate (init_var_eq_matching)
192+ if v in param_vars
193+ @assert match === unassigned
194+ init_var_eq_matching[v] = StateInvariant ()
195+ continue
196+ end
175197 varfilter (v) || continue
176198 if match === unassigned
177199 push! (init_state_vars, v)
0 commit comments