@@ -140,13 +140,14 @@ function partial_state_selection_graph!(structure::SystemStructure, var_eq_match
140
140
var_eq_matching
141
141
end
142
142
143
- function dummy_derivative_graph! (state:: TransformationState )
143
+ function dummy_derivative_graph! (state:: TransformationState , jac = nothing )
144
144
var_eq_matching = complete (pantelides! (state))
145
145
complete! (state. structure)
146
- dummy_derivative_graph! (state. structure, var_eq_matching)
146
+ # TODO : remove state when done
147
+ dummy_derivative_graph! (state. structure, var_eq_matching, jac, state)
147
148
end
148
149
149
- function dummy_derivative_graph! (structure:: SystemStructure , var_eq_matching)
150
+ function dummy_derivative_graph! (structure:: SystemStructure , var_eq_matching, jac, state )
150
151
@unpack eq_to_diff, var_to_diff, graph = structure
151
152
diff_to_eq = invview (eq_to_diff)
152
153
diff_to_var = invview (var_to_diff)
@@ -182,6 +183,7 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching)
182
183
var_sccs = find_var_sccs (graph, var_eq_matching)
183
184
eqcolor = falses (neqs)
184
185
dummy_derivatives = Int[]
186
+ col_order = Int[]
185
187
for vars in var_sccs
186
188
eqs = [var_eq_matching[var] for var in vars if var_eq_matching[var] != = unassigned]
187
189
isempty (eqs) && continue
@@ -195,18 +197,35 @@ function dummy_derivative_graph!(structure::SystemStructure, var_eq_matching)
195
197
iszero (nrows) && break
196
198
eqs_set = BitSet (eqs)
197
199
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
200
+ # TODO : making the algorithm more robust
201
+ # 1. If the Jacobian is a integer matrix, use Bareiss to check
202
+ # linear independence. (done)
203
+ #
204
+ # 2. If the Jacobian is a single row, generate pivots. (Dynamic
205
+ # state selection.)
206
+ #
207
+ # 3. If the Jacobian is a polynomial matrix, use Gröbner basis (?)
208
+ if jac != = nothing && (_J = jac (eqs, vars); all (x-> unwrap (x) isa Integer, _J))
209
+ J = Int .(unwrap .(_J))
210
+ N = ModelingToolkit. nullspace (J; col_order) # modifies col_order
211
+ rank = length (col_order)- size (N, 2 )
212
+ for i in 1 : rank
213
+ push! (dummy_derivatives, vars[col_order[i]])
214
+ end
215
+ else
216
+ rank = 0
217
+ for var in vars
218
+ pathfound = construct_augmenting_path! (rank_matching, invgraph, var, eq-> eq in eqs_set, eqcolor)
219
+ pathfound || continue
220
+ push! (dummy_derivatives, var)
221
+ rank += 1
222
+ rank == nrows && break
223
+ end
224
+ fill! (rank_matching, unassigned)
205
225
end
206
- if structural_rank != nrows
226
+ if rank != nrows
207
227
@warn " The DAE system is structurally singular!"
208
228
end
209
- fill! (rank_matching, unassigned)
210
229
211
230
# prepare the next iteration
212
231
eqs = map (eq-> diff_to_eq[eq], eqs)
0 commit comments