@@ -9,34 +9,62 @@ function try_assign_eq!(ict::IncrementalCycleTracker, vj::Integer, eq::Integer)
9
9
end
10
10
end
11
11
12
- function tearEquations ! (ict:: IncrementalCycleTracker , Gsolvable, es :: Vector{Int} ,
13
- vs :: Vector{Int} )
12
+ function try_assign_eq ! (ict:: IncrementalCycleTracker , vars, v_active, eq :: Integer ,
13
+ condition :: F = _ -> true ) where {F}
14
14
G = ict. graph
15
- vActive = BitSet (vs)
15
+ for vj in vars
16
+ (vj in v_active && G. matching[vj] === unassigned && condition (vj)) || continue
17
+ try_assign_eq! (ict, vj, eq) && return true
18
+ end
19
+ return false
20
+ end
16
21
22
+ function tearEquations! (ict:: IncrementalCycleTracker , Gsolvable, es:: Vector{Int} ,
23
+ v_active:: BitSet , isder′:: F ) where {F}
24
+ check_der = isder′ != = nothing
25
+ if check_der
26
+ has_der = Ref (false )
27
+ isder = let has_der = has_der, isder′ = isder′
28
+ v -> begin
29
+ r = isder′ (v)
30
+ has_der[] |= r
31
+ r
32
+ end
33
+ end
34
+ end
17
35
for eq in es # iterate only over equations that are not in eSolvedFixed
18
- for vj in Gsolvable[eq]
19
- if G. matching[vj] === unassigned && (vj in vActive)
20
- r = try_assign_eq! (ict, vj, eq)
21
- r && break
36
+ vs = Gsolvable[eq]
37
+ #=
38
+ if check_der
39
+ # if there're differentiated variables, then only consider them
40
+ try_assign_eq!(ict, vs, v_active, eq, isder)
41
+ @show has_der[]
42
+ if has_der[]
43
+ has_der[] = false
44
+ continue
22
45
end
23
46
end
47
+ =#
48
+ try_assign_eq! (ict, vs, v_active, eq)
24
49
end
25
50
26
51
return ict
27
52
end
28
53
29
- function tear_graph_block_modia! (var_eq_matching, graph, solvable_graph, eqs, vars)
54
+ function tear_graph_block_modia! (var_eq_matching, graph, solvable_graph, eqs, vars,
55
+ isder:: F ) where {F}
30
56
ict = IncrementalCycleTracker (DiCMOBiGraph {true} (graph); dir = :in )
31
- tearEquations! (ict, solvable_graph. fadjlist, eqs, vars)
57
+ tearEquations! (ict, solvable_graph. fadjlist, eqs, vars, isder )
32
58
for var in vars
33
59
var_eq_matching[var] = ict. graph. matching[var]
34
60
end
35
61
return nothing
36
62
end
37
63
38
- function tear_graph_modia (structure:: SystemStructure , :: Type{U} = Unassigned;
39
- varfilter = v -> true , eqfilter = eq -> true ) where {U}
64
+ function tear_graph_modia (structure:: SystemStructure , isder:: F = nothing ,
65
+ :: Type{U} = Unassigned;
66
+ varfilter:: F2 = v -> true ,
67
+ eqfilter:: F3 = eq -> true ) where {F, U, F2, F3}
40
68
# It would be possible here to simply iterate over all variables and attempt to
41
69
# use tearEquations! to produce a matching that greedily selects the minimal
42
70
# number of torn variables. However, we can do this process faster if we first
@@ -52,14 +80,22 @@ function tear_graph_modia(structure::SystemStructure, ::Type{U} = Unassigned;
52
80
var_eq_matching = complete (maximal_matching (graph, eqfilter, varfilter, U))
53
81
var_sccs:: Vector{Union{Vector{Int}, Int}} = find_var_sccs (graph, var_eq_matching)
54
82
83
+ ieqs = Int[]
84
+ filtered_vars = BitSet ()
55
85
for vars in var_sccs
56
- filtered_vars = filter (varfilter, vars)
57
- ieqs = Int[var_eq_matching[v]
58
- for v in filtered_vars if var_eq_matching[v] != = unassigned]
59
86
for var in vars
87
+ if varfilter (var)
88
+ push! (filtered_vars, var)
89
+ if var_eq_matching[var] != = unassigned
90
+ push! (ieqs, var_eq_matching[var])
91
+ end
92
+ end
60
93
var_eq_matching[var] = unassigned
61
94
end
62
- tear_graph_block_modia! (var_eq_matching, graph, solvable_graph, ieqs, filtered_vars)
95
+ tear_graph_block_modia! (var_eq_matching, graph, solvable_graph, ieqs, filtered_vars,
96
+ isder)
97
+ empty! (ieqs)
98
+ empty! (filtered_vars)
63
99
end
64
100
65
101
return var_eq_matching
0 commit comments