Skip to content

Commit 09a1c47

Browse files
committed
Bug fixed, if algebraic equations appear differentiated + new optional arguments var_is_state + logStates
1 parent 7db826f commit 09a1c47

File tree

1 file changed

+63
-20
lines changed

1 file changed

+63
-20
lines changed

src/StateSelection.jl

+63-20
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const ERROR = 2
4646
var_has_start = v_original -> false,
4747
var_fixed = v_original -> nothing,
4848
var_length = v_original -> 1,
49+
var_is_state = v_original -> false,
4950
equation = e -> ""
5051
isSolvableEquation = (e_original,v_original) -> false,
5152
isLinearEquation = (e_original,v_original) -> (false, false),
@@ -78,6 +79,9 @@ The functions need to have the following arguments:
7879
7980
- `var_length(v_original::Int)::Int`:\\
8081
Return length of variable `v_original` from the original, undifferentiated equations.
82+
83+
- `var_is_state(v_original::Int)::Bool`:\\
84+
Return true, if variable `v_original` is defined to be a state.
8185
8286
- `equation(e::Int)`:\\
8387
Return equation as string or "", if equation is not provided.
@@ -113,6 +117,7 @@ struct StateSelectionFunctions
113117
var_nominal::Function
114118
var_unbounded::Function
115119
var_length::Function
120+
var_is_state::Function
116121
equation::Function
117122
isSolvableEquation::Function
118123
isLinearEquation::Function
@@ -129,6 +134,7 @@ struct StateSelectionFunctions
129134
var_nominal = v_original -> NaN,
130135
var_unbounded = v_original -> false,
131136
var_length = v_original -> 1,
137+
var_is_state = v_original -> false,
132138
equation = e -> "",
133139
isSolvableEquation = (e_original,v_original) -> false,
134140
isLinearEquation = (e_original,v_original) -> (false, false),
@@ -144,6 +150,7 @@ struct StateSelectionFunctions
144150
var_nominal,
145151
var_unbounded,
146152
var_length,
153+
var_is_state,
147154
equation,
148155
isSolvableEquation,
149156
isLinearEquation,
@@ -207,7 +214,8 @@ showCodeWithoutComments(code) = println("code = ", replace(sprint(show,code), r"
207214

208215

209216
"""
210-
(eConstraints,vConstraints) = getConstraintSets(BLT_i, assignRev, Arev, Brev, showMessage)
217+
(eConstraints,vConstraints) = getConstraintSets(BLT_i, assignRev, Arev, Brev,
218+
var_is_state, showMessage)
211219
212220
Determines the set of equations/constraints and their unknowns that are associated with
213221
the highest derivative level BLT block i (BLT_i), according to the dummy derivative
@@ -231,13 +239,16 @@ vConstraints[j] are the unknowns of eConstraints[j].
231239
232240
- `Brev::Vector{Int}`: Reverted equation association: `Erev[i] = der(E[k]) == E[i] ? k : 0`.
233241
242+
- `var_is_state::Function`: var_is_state(`vi`) returns true, if `vi` is defined to be a definite state.
243+
234244
- showMessage: showMessage2 below to print error/warning message
235245
236246
"""
237247
function getConstraintSets(BLT_i::Vector{Int},
238248
assignRev::Vector{Int},
239249
Arev::Vector{Int},
240250
Brev::Vector{Int},
251+
var_is_state::Function,
241252
showMessage::Function)
242253
# Determine unknowns of BLT block i
243254
BLT_i_unknowns = fill(0, length(BLT_i))
@@ -271,13 +282,25 @@ function getConstraintSets(BLT_i::Vector{Int},
271282
pushfirst!(eConstraints, ceq) # move ceq to the beginning of the constraints vector
272283

273284
# Determine unknowns of ceq
274-
veq = fill(0, 0)
285+
veq = fill(0,0)
286+
veq_states = fill(0,0)
275287
for vc in vConstraints[1]
276288
if Arev[vc] > 0
277-
push!(veq, Arev[vc])
289+
if var_is_state( Arev[vc] )
290+
push!(veq_states, Arev[vc])
291+
else
292+
push!(veq, Arev[vc])
293+
end
278294
end
279295
end
280-
@assert( length(veq) > 0 )
296+
if length(veq) < length(ceq)
297+
nRemoveStates = length(veq_states) - (length(ceq) - length(veq))
298+
showMessage("$nRemoveStates of the followig defined states cannot be states!";
299+
severity = ERROR,
300+
variables = veq_states,
301+
equations = ceq)
302+
return (eConstraints, vConstraints, false)
303+
end
281304
pushfirst!(vConstraints, veq) # move veq to the beginning of the constraints vector
282305
end
283306

@@ -479,7 +502,12 @@ mutable struct EquationGraph
479502

480503
# Initialize the active variables
481504
vActive = fill(true, length(A))
482-
505+
for v = 1:length(vActive)
506+
if Arev[v] > 0
507+
vActive[ Arev[v] ] = false # Arev[v] is a potential state
508+
end
509+
end
510+
483511
# Define empty constraint sets
484512
eConstraintsVec = Vector{Vector{Int}}[]
485513
vConstraintsVec = Vector{Vector{Int}}[]
@@ -521,20 +549,21 @@ mutable struct EquationGraph
521549
if highest
522550
# Get all equation sets eConstraints and their corresponding unknowns vConstraints
523551
# from lowest to highest differentiation order (eConstraints[end] is c)
524-
(eConstraints, vConstraints, success2) = getConstraintSets(BLT_i, assignRev, Arev, Brev, showMessage)
552+
(eConstraints, vConstraints, success2) = getConstraintSets(BLT_i, assignRev, Arev, Brev,
553+
stateSelectionFunctions.var_is_state, showMessage)
525554
if !success2
526555
success=false
527556
break
528557
end
529558

530559
# Initialize vActive
531-
for vc in vConstraints
532-
for v in vc
533-
if Arev[v] > 0
534-
vActive[ Arev[v] ] = false # Arev[v] is a potential state
535-
end
536-
end
537-
end
560+
#for vc in vConstraints
561+
# for v in vc
562+
# if Arev[v] > 0
563+
# vActive[ Arev[v] ] = false # Arev[v] is a potential state
564+
# end
565+
# end
566+
#end
538567

539568
push!(eConstraintsVec, eConstraints)
540569
push!(vConstraintsVec, vConstraints)
@@ -963,7 +992,7 @@ function sortEquations!(eq::EquationGraph)::Nothing
963992
# Matching of all equations
964993
assign = matching(eq.G, length(eq.A), eq.vActive)
965994
assignRev = revertAssociation(assign)
966-
995+
967996
# Sort equations and find strong components
968997
blt = BLT(eq.G,assign)
969998

@@ -1160,6 +1189,7 @@ function getSortedAndSolvedAST(G, # Typically ::Vector{Vector{Int}}
11601189
stateSelectionFunctions::StateSelectionFunctions;
11611190
log::Bool = false,
11621191
logDetails::Bool = false,
1192+
logStates::Bool = false,
11631193
modelName = "???",
11641194
unitless::Bool = false,
11651195
defaultParameterAndStartValues = nothing)
@@ -1270,16 +1300,29 @@ function getSortedAndSolvedAST(G, # Typically ::Vector{Vector{Int}}
12701300

12711301
# Select dummy states
12721302
if i < length(eConstraints)
1273-
# Not on highest derivative level. Solved variables are dummy states.
1303+
# Not on highest derivative level. Solved variables are dummy states
12741304
for v in eq.vSolved
12751305
@assert(!eq.vActive[v])
12761306
eq.vActive[v] = true
1277-
end
1278-
if log
1279-
println(" All other unknowns are solved and are dummy states.")
1307+
end
1308+
1309+
if length(eConstraints[i]) == length(vConstraints[i])
1310+
# N equations in N unknowns - tearing variables are dummy states
1311+
for v in eq.vTear
1312+
@assert(!eq.vActive[v])
1313+
eq.vActive[v] = true
1314+
end
1315+
if log
1316+
println(" All unknowns are dummy states.")
1317+
end
1318+
1319+
else
1320+
if log
1321+
println(" All solved unknowns are dummy states.")
1322+
end
12801323
end
12811324
elseif log
1282-
println(" All other unknowns are solved.")
1325+
println(" All unknowns are solved.")
12831326
end
12841327

12851328
# Further actions depending on type of equations
@@ -1379,7 +1422,7 @@ function getSortedAndSolvedAST(G, # Typically ::Vector{Vector{Int}}
13791422
v_stateCategory, v_length, v_unit, v_fixed2,
13801423
v_nominal, v_unbounded))
13811424
end
1382-
if log
1425+
if log || logStates
13831426
println("\nSelected ODE states: ")
13841427
x_table = ModiaBase.get_x_table(x_info)
13851428
show(stdout, x_table; allrows=true, allcols=true, summary=false, eltypes=false)

0 commit comments

Comments
 (0)