@@ -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
212220Determines the set of equations/constraints and their unknowns that are associated with
213221the 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"""
237247function 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 (" \n Selected 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