Skip to content

Commit f0fec8a

Browse files
authored
Merge pull request #153 from ModiaSim/improve_SignalTables
Improve signal tables
2 parents 009b497 + fe13924 commit f0fec8a

11 files changed

+290
-191
lines changed

Manifest.toml

+104-90
Large diffs are not rendered by default.

Project.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
authors = ["Hilding Elmqvist <[email protected]>", "Martin Otter <[email protected]>"]
22
name = "Modia"
33
uuid = "cb905087-75eb-5f27-8515-1ce0ec8e839e"
4-
version = "0.9.2"
4+
version = "0.9.3"
55

66
[deps]
77
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
@@ -27,7 +27,7 @@ TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
2727
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
2828

2929
[compat]
30-
DiffEqBase = "6.82.0"
30+
DiffEqBase = "6"
3131
DataFrames = "1"
3232
DifferentialEquations = "7"
3333
FiniteDiff = "2"
@@ -39,7 +39,7 @@ MonteCarloMeasurements = "1"
3939
OrderedCollections = "1"
4040
RecursiveFactorization = "0.2"
4141
Reexport = "1"
42-
SignalTables = "0.3.5"
42+
SignalTables = "0.4.0"
4343
StaticArrays = "1"
4444
Sundials = "4"
4545
TimerOutputs = "0.5"

docs/src/index.md

+13-5
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,29 @@ functionalities of these packages.
4242

4343
## Release Notes
4444

45+
### Version 0.9.3
46+
47+
- Requires SignalTables 0.4.0 (introduces Map-signal)
48+
- getSignalNames(...; getVar=true, getPar=true, getMap=true): New keyword arguments to filter names.
49+
- writeSignalTable(instantiatedModel,..): Include attributes = Map(model=..., experiment=...).
50+
- Some internal bug-fixes.
51+
52+
4553
### Version 0.9.2
4654

4755
- Bug fix: integrator IDA() can be used (especially to avoid solving large linear equation systems in the model).\
4856
Extend some test models to use IDA().
49-
57+
5058

5159
### Version 0.9.1
5260

5361
- Requires SignalTables 0.3.5.
5462

5563
- [`@usingModiaPlot`](@ref): corrected and fixed in docu. Alternatively, @usingPlotPackage can be used,
5664
provided package SignalTables is present in your current environment.
57-
65+
5866
- Internal: A function call in the generated code prefixed with `Modia.`.
59-
67+
6068

6169
### Version 0.9.0
6270

@@ -77,13 +85,13 @@ functionalities of these packages.
7785
with `writeSignalTable(filename, instantiatedModel)` (or in HDF5 format via [JDL](https://github.com/JuliaIO/JLD.jl)).
7886
You get an overview of a simulation result via `showInfo(instantiatedModel)`.
7987

80-
- New functions [`hasParameter`](@ref), [`getParameter`](@ref), [`getEvaluatedParameter`](@ref),
88+
- New functions [`hasParameter`](@ref), [`getParameter`](@ref), [`getEvaluatedParameter`](@ref),
8189
[`showParameters`](@ref), [`showEvaluatedParameters`](@ref) to
8290
get parameter/init/start values by name (e.g. `getEvaluatedParameter(instantiatedModel, "a.b.c")`) or
8391
show all parameters.
8492

8593
- New functions to add states and algebraic variables from within functions that are not visible in the generated code
86-
(see [Variable definitions in functions](@ref) and example `Modia/test/TestLinearSystems.jl`).
94+
(see [Variable definitions in functions](@ref) and example `Modia/test/TestLinearSystems.jl`).
8795
This feature is used in the next version of
8896
Modia3D to allow (Modia3D) model changes after code generation and to get more light weight code.
8997

src/CodeGeneration.jl

+17-11
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ mutable struct SimulationModel{FloatType,TimeType}
329329

330330
parameters::OrderedDict{Symbol,Any} # Parameters as provided to SimulationModel constructor
331331
equationInfo::Modia.EquationInfo # Invariant part of equations are available
332+
x_terminate::Vector{FloatType} # States x used at the last terminate!(..) call or [], if terminate!(..) not yet called.
332333

333334
# Available after propagateEvaluateAndInstantiate!(..) called
334335
instantiateFunctions::Vector{Tuple{Union{Expr,Symbol},OrderedDict{Symbol,Any},String}}
@@ -353,6 +354,7 @@ mutable struct SimulationModel{FloatType,TimeType}
353354
der_x_segmented::Vector{FloatType} # Derivatives of states x or x_init that correspond to segmented states (defined in functions and not visible in getDerivatives!(..))
354355
der_x::Vector{FloatType} # Derivatives of states x
355356

357+
356358
function SimulationModel{FloatType,TimeType}(modelModule, modelName, buildDict, getDerivatives!, equationInfo,
357359
previousVars, preVars, holdVars,
358360
parameterDefinition, timeName, w_invariant_names, hideResult_names;
@@ -408,6 +410,7 @@ mutable struct SimulationModel{FloatType,TimeType}
408410
instantiateResult = true
409411
newResultSegment = false
410412
parameters = deepcopy(parameterDefinition)
413+
x_terminate = FloatType[]
411414

412415
new(modelModule, modelName, buildDict, TimerOutputs.TimerOutput(), UInt64(0), UInt64(0), SimulationOptions{FloatType,TimeType}(), getDerivatives!,
413416
equationInfo, linearEquations, eventHandler,
@@ -418,7 +421,7 @@ mutable struct SimulationModel{FloatType,TimeType}
418421
isInitial, solve_leq, true, storeResult, convert(TimeType, 0), nGetDerivatives, nf,
419422
odeIntegrator, daeCopyInfo, algorithmName, sundials, addEventPointsDueToDEBug, success, unitless,
420423
string(timeName), w_invariant_names, hideResult_names, vEliminated, vProperty, var_name, result,
421-
parameters, equationInfo)
424+
parameters, equationInfo, x_terminate)
422425
end
423426

424427
#=
@@ -876,11 +879,11 @@ Return the names of the elements of the x-vector in a Vector{String}.
876879
get_xNames(m::SimulationModel) = Modia.get_xNames(m.equationInfo)
877880

878881

879-
880882
"""
881883
isInitial(instantiatedModel)
882884
883-
Return true, if **initialization phase** of simulation.
885+
Return true, if **initialization phase** of simulation
886+
(of the current segment of a segmented simulation).
884887
"""
885888
isInitial(m::SimulationModel) = m.eventHandler.initial
886889
initial( m::SimulationModel) = m.eventHandler.initial
@@ -898,19 +901,20 @@ isFirstInitialOfAllSegments(m::SimulationModel) = m.eventHandler.firstInitialOfA
898901
"""
899902
isTerminal(instantiatedModel)
900903
901-
Return true, if **terminal phase** of simulation.
904+
Return true, if **terminal phase** of simulation
905+
(of the current segment of a segmented simulation).
902906
"""
903907
isTerminal(m::SimulationModel) = m.eventHandler.terminal
904908
terminal( m::SimulationModel) = m.eventHandler.terminal
905909

906910

907911
"""
908-
isTerminalOfAllSegmenteds(instantiatedModel)
912+
isTerminalOfAllSegments(instantiatedModel)
909913
910914
Return true, if **terminal phase** of simulation of the **last segment**
911915
of a segmented simulation.
912916
"""
913-
isTerminalOfAllSegmenteds(m::SimulationModel) = m.eventHandler.terminalOfAllSegments
917+
isTerminalOfAllSegments(m::SimulationModel) = m.eventHandler.terminalOfAllSegments
914918

915919

916920
"""
@@ -1073,7 +1077,6 @@ function init!(m::SimulationModel{FloatType,TimeType})::Bool where {FloatType,Ti
10731077
if isnothing(evaluatedParameters)
10741078
return false
10751079
end
1076-
10771080
m.evaluatedParameters = evaluatedParameters
10781081
m.nextPrevious = deepcopy(m.previous)
10791082
m.nextPre = deepcopy(m.pre)
@@ -1122,7 +1125,7 @@ function init!(m::SimulationModel{FloatType,TimeType})::Bool where {FloatType,Ti
11221125
# xe_nominal = isnan(xe_info.nominal) ? "" : xe_info.nominal
11231126
push!(x_table, (xe_info.x_name, xe_init, xe_info.unit)) #, xe_nominal))
11241127
end
1125-
show(stdout, x_table; allrows=true, allcols=true, rowlabel = Symbol("#"), summary=false, eltypes=false)
1128+
show(stdout, x_table; allrows=true, allcols=true, rowlabel = Symbol("#"), summary=false, eltypes=false, truncate=60)
11261129
println("\n")
11271130
end
11281131

@@ -1171,9 +1174,10 @@ function initFullRestart!(m::SimulationModel{FloatType,TimeType})::Nothing where
11711174
logInstantiatedFunctionCalls = false
11721175
Core.eval(m.modelModule, :($(fc[1])($m, $(fc[2]), $(fc[3]), log=$logInstantiatedFunctionCalls)))
11731176
end
1177+
resizeLinearEquations!(m, m.evaluatedParameters, m.options.log)
11741178

11751179
# Get initial state vector
1176-
m.x_start = initialStateVector!(m.equationInfo, FloatType)
1180+
m.x_start = initialStateVector!(m)
11771181

11781182
# update equationInfo
11791183
x_info = m.equationInfo.x_info
@@ -1222,7 +1226,6 @@ function initFullRestart!(m::SimulationModel{FloatType,TimeType})::Nothing where
12221226
m.x_init[i] = deepcopy(m.x_start[i])
12231227
end
12241228
eventIteration!(m, m.x_init, m.options.startTime)
1225-
m.success = false # is set to true at the first outputs! call.
12261229
eh.fullRestart = false
12271230
eh.initial = false
12281231
m.isInitial = false
@@ -1287,8 +1290,11 @@ function terminate!(m::SimulationModel, x, t)::Nothing
12871290
#println("... terminate! called at time = $t")
12881291
eh = m.eventHandler
12891292
eh.terminal = true
1293+
eh.terminalOfAllSegments = m.eventHandler.restart != Modia.FullRestart
12901294
invokelatest_getDerivatives_without_der_x!(x, m, t)
12911295
eh.terminal = false
1296+
eh.terminalOfAllSegments = false
1297+
m.x_terminate = deepcopy(x)
12921298
return nothing
12931299
end
12941300

@@ -1886,7 +1892,7 @@ function initialStateVector!(m::SimulationModel{FloatType,TimeType})::Vector{Flo
18861892
# differential equation der_x[1] = -x[1], with state name _dummy_x
18871893
new_x_segmented_variable!(m, "_dummy_x", "der(_dummy_x)", FloatType(0))
18881894
end
1889-
return initialStateVector!(m.equationInfo, FloatType)
1895+
return initialStateVector!(m.equationInfo, FloatType, !isFullRestart(m), m.x_terminate)
18901896
end
18911897

18921898

src/EquationAndStateInfo.jl

+36-16
Original file line numberDiff line numberDiff line change
@@ -744,13 +744,13 @@ end
744744

745745

746746
"""
747-
x_start = initialStateVector!(eqInfo::EquationInfo, FloatType)::Vector{FloatType}
747+
x_start = initialStateVector!(eqInfo::EquationInfo, FloatType, isFirstSegment, x_terminate)::Vector{FloatType}
748748
749749
The function updates `eqInfo` (e.g. sets eqInfo.nx, eqInfo.nxInvariant) and returns the initial state vector x_start.
750750
751751
This function must be called, after all states are known (after calling propagateEvaluateAndInstantiate!(..)).
752752
"""
753-
function initialStateVector!(eqInfo::EquationInfo, FloatType::Type)::Vector{FloatType}
753+
function initialStateVector!(eqInfo::EquationInfo, FloatType::Type, isFirstSegment::Bool, x_terminate)::Vector{FloatType}
754754
@assert(eqInfo.status == EquationInfo_Initialized_Before_All_States_Are_Known)
755755
nx_info_fixedLength = eqInfo.nx_info_fixedLength
756756
x_info = eqInfo.x_info
@@ -770,7 +770,7 @@ function initialStateVector!(eqInfo::EquationInfo, FloatType::Type)::Vector{Floa
770770
xi_info.scalar = true
771771
end
772772
end
773-
773+
774774
# Set startIndex for invariant states where the size was not fixed before code generation
775775
for i = nx_info_fixedLength+1:eqInfo.nx_info_invariant
776776
xi_info = x_info[i]
@@ -792,31 +792,51 @@ function initialStateVector!(eqInfo::EquationInfo, FloatType::Type)::Vector{Floa
792792

793793
# Construct x_start
794794
x_start = zeros(FloatType, eqInfo.nx)
795-
startIndex = 1
796-
for xe_info in eqInfo.x_info
797-
if xe_info.scalar
798-
@assert(length(xe_info.startOrInit) == 1)
799-
x_start[startIndex] = FloatType(ustrip(xe_info.startOrInit))
800-
startIndex += 1
801-
else
802-
xe_start = Vector{FloatType}(ustrip(xe_info.startOrInit))
803-
@assert(length(xe_start) == xe_info.length)
804-
copyto!(x_start, startIndex, xe_start, 1, length(xe_start))
805-
startIndex += length(xe_start)
795+
if isFirstSegment
796+
startIndex = 1
797+
for xe_info in x_info
798+
if xe_info.scalar
799+
@assert(length(xe_info.startOrInit) == 1)
800+
x_start[startIndex] = FloatType(ustrip(xe_info.startOrInit))
801+
startIndex += 1
802+
else
803+
xe_start = Vector{FloatType}(ustrip(xe_info.startOrInit))
804+
@assert(length(xe_start) == xe_info.length)
805+
copyto!(x_start, startIndex, xe_start, 1, length(xe_start))
806+
startIndex += length(xe_start)
807+
end
808+
end
809+
else
810+
for i in 1:eqInfo.nxInvariant
811+
x_start[i] = x_terminate[i]
812+
end
813+
startIndex = eqInfo.nxInvariant+1
814+
for i = eqInfo.nx_info_invariant+1:length(x_info)
815+
xe_info = x_info[i]
816+
if xe_info.scalar
817+
@assert(length(xe_info.startOrInit) == 1)
818+
x_start[startIndex] = FloatType(ustrip(xe_info.startOrInit))
819+
startIndex += 1
820+
else
821+
xe_start = Vector{FloatType}(ustrip(xe_info.startOrInit))
822+
@assert(length(xe_start) == xe_info.length)
823+
copyto!(x_start, startIndex, xe_start, 1, length(xe_start))
824+
startIndex += length(xe_start)
825+
end
806826
end
807827
end
808828

809829
@assert(eqInfo.nx == startIndex - 1)
810830
eqInfo.status = EquationInfo_After_All_States_Are_Known
811-
831+
812832
# Final check
813833
for (i, xi_info) = enumerate(eqInfo.x_info)
814834
@assert(xi_info.startIndex > 0)
815835
if i <= eqInfo.nx_info_invariant
816836
@assert(xi_info.x_segmented_startIndex == -1)
817837
else
818838
@assert(xi_info.x_segmented_startIndex > 0)
819-
end
839+
end
820840
end
821841
return x_start
822842
end

src/EvaluateParameters.jl

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ function getConstructorAsString(path, constructor, parameters):String
1818
end
1919
if typeof(value) == Symbol
2020
svalue = ":" * string(value)
21+
elseif typeof(value) == String
22+
svalue = value
2123
elseif typeof(value) <: AbstractDict
2224
svalue = "..." # Do not show dictionaries, since too much output, especially due to pointers to Object3Ds
2325
else

src/Modia.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Main module of Modia.
99
module Modia
1010

1111
const path = dirname(dirname(@__FILE__)) # Absolute path of package directory
12-
const Version = "0.9.2"
13-
const Date = "2022-07-12"
12+
const Version = "0.9.3"
13+
const Date = "2022-08-05"
1414
const modelsPath = joinpath(Modia.path, "models")
1515

1616
print(" \n\nWelcome to ")
@@ -43,11 +43,11 @@ import SignalTables: AvailablePlotPackages
4343

4444
"""
4545
@usingModiaPlot()
46-
46+
4747
Execute `using XXX`, where `XXX` is the Plot package that was activated with `usePlotPackage(plotPackage)`.
4848
So this is similar to @usingPlotPackage (from SignalTables, that is reexported from Modia).
4949
50-
There is, however, a difference when XXX = "SilentNoPlot":
50+
There is, however, a difference when XXX = "SilentNoPlot":
5151
5252
- @usingPlotPackage() executes `using SignalTables.SilentNoPlot` and therefore requires that package `SignalTables` is available in your environment.
5353
- @usingModiaPlot() executes `using Modia.SignalTables.SilentNoPlot` and therefore requires that package `Modia` is available in your environment.

0 commit comments

Comments
 (0)