Skip to content

Commit

Permalink
Prepare release 0.12.0
Browse files Browse the repository at this point in the history
- Rename functions of built-in components
- Improve docu of built-in components
  • Loading branch information
MartinOtter committed Jun 4, 2023
1 parent 572ab57 commit e81114f
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 89 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
authors = ["Hilding Elmqvist <[email protected]>", "Martin Otter <[email protected]>"]
name = "Modia"
uuid = "cb905087-75eb-5f27-8515-1ce0ec8e839e"
version = "0.11.0"
version = "0.12.0"

[deps]
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
Expand Down
8 changes: 4 additions & 4 deletions docs/src/Functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ showEvaluatedParameters
CurrentModule = Modia
```

The simulation result of a model `instantiatedModel` are provided as a *signal table*,
The simulation result of a model `instantiatedModel` are provided as a *signal table*,
see [SignalTables.jl](https://github.com/ModiaSim/SignalTables.jl).

Therefore, all [signal table functions](https://modiasim.github.io/SignalTables.jl/stable/Functions/OverviewOfFunctions.html)
can be used on a simulated model

To activate the defined plot package, use

- [`@usingModiaPlot`](@ref)
- [`@usingModiaPlot`](@ref)

Alternatively, `usingPlotPackage` (from Modia reexported macro of SignalTables) can be used,
but then package `SignalTables` must be in your current environment.
Expand All @@ -87,11 +87,11 @@ FirstOrder = Model(
)
simulate!(firstOrder, stopTime=10)
showInfo(firstOrder) # list info about the result
t = getValues(firstOrder, "time")
t = getValues(firstOrder, "time")
y = getValues(firstOrder, "y") # use any plot program: plot(t,y)
# Write result on file
writeSignalTable("firstOrder.json", firstOrder, indent=2, log=true)
writeSignalTable("firstOrder.json", firstOrder, indent=2, log=true)
```

See the generated [json-file](../resources/fileio/firstOrder.json).
Expand Down
94 changes: 58 additions & 36 deletions docs/src/Internal.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,91 @@
# Internal

This chapter documents internal functions that are typically only
for use of the developers of package Modia.
for use of the developers of a model library or of Modia.

## Code Generation

This section provides functions to **generate Julia code** of the
transformed equations.
## Variables of built-in Components

```@meta
CurrentModule = Modia
```

The following functions are provided to define and access new variables
in built-in components (seee for example model `InsulatedRod2` in `Modia/models/HeatTransfer.jl`).

| Functions | Description |
|:--------------------------------------------------------|:----------------------------------------------------------------------------------|
| [`new_x_segmented_variable!`](@ref) | Generate new state variable (`x_segmented` and `der_x_segmented` variables) |
| [`new_w_segmented_variable!`](@ref) | Generate new local variable (`w_segmented` variable) |
| [`new_alias_segmented_variable!`](@ref) | Generate new alias variable |
| [`new_z_segmented_variable!`](@ref) | Generate new zero crossing variables (`z_segmented` variables) |
| [`get_x_startIndex_from_x_segmented_startIndex`](@ref) | Return start index of `x_segmented` variable with respect to state vector `x` |
| [`copy_scalar_x_segmented_value_from_state`](@ref) | Return value of scalar `x_segmented` variable from state vector `x` |
| [`copy_SVector3_x_segmented_value_from_state`](@ref) | Return value of `SVector{3,FloatType}` x_segmented variable from state vector `x` |
| [`copy_Vector_x_segmented_value_from_state`](@ref) | Return value of `Vector{FloatType}` x_segmented variable from state vector `x` |
| [`copy_der_x_segmented_value_to_state`](@ref) | Copy value of `der_x_segmented` variable to state derivative vector `der(x)` |
| [`copy_w_segmented_value_to_result`](@ref) | Copy value of local variable (`w-segmented`) to result |


```@docs
SimulationModel
generate_getDerivatives!
init!
outputs!
terminate!
derivatives!
DAEresidualsForODE!
affectEvent!
zeroCrossings!
affectStateEvent!
timeEventCondition!
affectTimeEvent!
addToResult!
getFloatType
measurementToString
new_x_segmented_variable!
new_w_segmented_variable!
new_alias_segmented_variable!
new_z_segmented_variable!
get_x_startIndex_from_x_segmented_startIndex
copy_scalar_x_segmented_value_from_state
copy_SVector3_x_segmented_value_from_state
copy_Vector_x_segmented_value_from_state
copy_der_x_segmented_value_to_state
copy_w_segmented_value_to_result
```

## Inquiries in Model
## Inquiries in built-in Components

The functions in this section can be called in the model code or in
functions that are called from the model code.
The following functions are provided to inquire properties
in built-in components at the current state of the simulation
(see for example model `InsulatedRod2` in `Modia/models/HeatTransfer.jl`).

```@docs
isInitial
isFirstInitialOfAllSegments
isTerminal
isTerminalOfAllSegments
isEvent
isFirstEventIteration
isFirstEventIterationDirectlyAfterInitial
isFullRestart
isAfterSimulationStart
isZeroCrossing
storeResults
getTime
```

## Variable definitions in functions
## Code Generation

The following functions can be used to define states and algebraic variables inside functions:
This section lists internal functions to **generate Julia code** of the
transformed equations.

```@docs
new_x_segmented_variable!
new_w_segmented_variable!
new_alias_segmented_variable!
new_z_segmented_variable!
get_x_startIndex_from_x_segmented_startIndex
get_scalar_x_segmented_value
get_SVector3_x_segmented_value
get_Vector_x_segmented_value!
add_der_x_segmented_value!
add_w_segmented_value!
```@meta
CurrentModule = Modia
```

```@docs
SimulationModel
generate_getDerivatives!
init!
outputs!
terminate!
derivatives!
DAEresidualsForODE!
affectEvent!
zeroCrossings!
affectStateEvent!
timeEventCondition!
affectTimeEvent!
addToResult!
getFloatType
measurementToString
```



Expand Down
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
activ# Modia Documentation
# Modia Documentation

[Modia](https://github.com/ModiaSim/Modia.jl) is an environment in form of a Julia package to model and simulate physical systems (electrical, mechanical, thermo-dynamical, etc.) described by differential and algebraic equations. A user defines a model on a high level with model components (like a mechanical body, an electrical resistance, or a pipe) that are physically connected together. A model component is constructed by **`expression = expression` equations** or by Julia structs/functions, such as the pre-defined [Modia3D] (https://github.com/ModiaSim/Modia3D.jl) multibody components. The defined model is symbolically processed (for example, equations might be analytically differentiated) with algorithms from package [ModiaBase.jl](https://github.com/ModiaSim/ModiaBase.jl). From the transformed model a Julia function is generated that is used to simulate the model with integrators from [DifferentialEquations.jl](https://github.com/SciML/DifferentialEquations.jl).
The basic type of the floating point variables is usually `Float64`, but can be set to any
Expand Down Expand Up @@ -140,7 +140,7 @@ These changes should usually not influence user models.
show all parameters.

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

Expand Down
4 changes: 2 additions & 2 deletions models/HeatTransfer/InsulatedRod2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ end
# Open an initialized InsulatedRod2 model and return a reference to it
function openInsulatedRod!(instantiatedModel::SimulationModel{FloatType,TimeType}, ID)::InsulatedRodStruct{FloatType} where {FloatType,TimeType}
obj::InsulatedRodStruct{FloatType} = Modia.get_instantiatedSubmodel(instantiatedModel, ID)
Modia.get_Vector_x_segmented_value!(instantiatedModel, obj.T_startIndex, obj.T)
Modia.copy_Vector_x_segmented_value_from_state(instantiatedModel, obj.T_startIndex, obj.T)
return obj
end

Expand All @@ -127,6 +127,6 @@ function computeInsulatedRodDerivatives!(instantiatedModel, obj::InsulatedRodStr
for i in 1:length(T)
obj.der_T[i] = k*(T_grad1(T,Ta,i) - T_grad2(T,Tb,i))
end
Modia.add_der_x_segmented_value!(instantiatedModel, obj.T_startIndex, obj.der_T)
Modia.copy_der_x_segmented_value_to_state(instantiatedModel, obj.T_startIndex, obj.der_T)
return true
end
90 changes: 49 additions & 41 deletions src/CodeGeneration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1680,20 +1680,22 @@ get_instantiatedSubmodel(instantiatedModel, ID) = instantiatedModel.buildDict[ID


"""
index = new_x_segmented_variable!(
instantiatedModel::SimulationModel,
x_name::String, der_x_name::String, startOrInit, x_unit::String="";
nominal::Float64 = NaN, unbounded::Bool = false)::Int
startIndex = new_x_segmented_variable!(
partiallyInstantiatedModel::SimulationModel,
x_name::String, der_x_name::String, startOrInit, x_unit::String="";
nominal::Float64 = NaN, unbounded::Bool = false)::Int
Reserves storage location for a new x_segmented and der_x_segmented variable and returns
the index (= x_segmented_startIndex) to access this storage location, in particular
Generate new states (`x_segmented` and `der_x_segmented` variables) and return the
`startIndex` of the variables in order that actual values can be inquired or copied from the
state `x` and state derivative `der(x)`vectors via [`get_x_startIndex_from_x_segmented_startIndex`](@ref).
`startOrInit` contain the `start` or `init` values of the newly generated `x_segmented` variable.
- to copy state values from instantiatedModel.x_segmented[index:index+prod(dims(startOrInit))-1]
into this storage location
- to copy state derivative values of this storage location to
instantiatedModel.der_x_segmented[index:index+prod(dims(startOrInit))-1]
Actual values of these new variables are stored in:
Value startOrInit is the start/init value used during re-initialization of the new segment with initFullRestart!(..).
- `instantiatedModel.x_segmented[startIndex:startIndex+prod(dims(startOrInit))-1]`
- `instantiatedModel.der_x_segmented[startIndex:startIndex+prod(dims(startOrInit))-1]`
Value `startOrInit` is the start/init value used during re-initialization of the new segment with `initFullRestart!(..)`.
"""
function new_x_segmented_variable!(m::SimulationModel{FloatType,TimeType}, x_name::String, der_x_name::String, startOrInit, x_unit::String="";
nominal::Float64 = NaN, unbounded::Bool = false)::Int where {FloatType,TimeType}
Expand Down Expand Up @@ -1760,23 +1762,26 @@ end


"""
x_startIndex = get_x_startIndex_from_x_segmented_startIndex(instantiatedModel::SimulationModel, x_segmented_startIndex)
x_startIndex = get_x_startIndex_from_x_segmented_startIndex(
instantiatedModel::SimulationModel, x_segmented_startIndex)
Return the startindex of an x_segmented state with respect to the x-vector,
given the startIndex with respect to the x_segmented vector
(x_segmented_startIndex is the return value of new_x_segmented_variable!(..)).
Return the startindex of an `x_segmented` state with respect to the `x`-vector,
given the startIndex with respect to the `x_segmented` vector
(`x_segmented_startIndex` is the return value of `new_x_segmented_variable!(..)`).
"""
get_x_startIndex_from_x_segmented_startIndex(m::SimulationModel, x_segmented_startIndex::Int) = m.equationInfo.nxInvariant + x_segmented_startIndex


"""
index = new_w_segmented_variable!(partiallyInstantiatedModel::SimulationModel, name::String,
w_segmented_default, unit::String="")::Int
index = new_w_segmented_variable!(
partiallyInstantiatedModel::SimulationModel, name::String,
w_segmented_default, unit::String="")::Int
Reserve storage location for a new w_segmented variable. The returned `index` is
used to store the w_segmented value at communication points in the result data structure.
Generate new local variable (`w_segmented` variable) and return the `index` of the variable
in order that actual values can be inquired or copied from the result data structure.
New values of `w_segmented` variables need only to be computed at communication points.
Value w_segmented_default is stored as default value and defines type and (fixed) size of the variable
in this segment.
in this simulation segment.
"""
function new_w_segmented_variable!(m::SimulationModel, name::String, w_segmented_default, unit::String="")::Int
result = m.result
Expand Down Expand Up @@ -1810,9 +1815,10 @@ end


"""
new_alias_segmented_variable!(partiallyInstantiatedModel, name, aliasName, aliasNegate=false)
new_alias_segmented_variable!(partiallyInstantiatedModel::SimulationModel,
name, aliasName, aliasNegate=false)
Define new alias segmented variable.
Define new alias variable.
"""
function new_alias_segmented_variable!(m::SimulationModel, name::String, aliasName::String, aliasNegate::Bool=false)::Int
result = m.result
Expand All @@ -1832,8 +1838,8 @@ end
"""
startIndex = new_z_segmented_variable!(instantiatedModel, nz)
Reserve storage location for nz new segmented zero crossing function and return the startIndex to
copy it in the vectors of zero crossings
Generate `nz` new zero crossing variables and return the startIndex to of the variables
in order that actual values can be copied into the vector of zero crossings.
"""
function new_z_segmented_variable!(m::SimulationModel{F,TimeType}, nz::Int)::Int where {F,TimeType}
eh = m.eventHandler
Expand All @@ -1850,58 +1856,60 @@ end


"""
value = Modia.get_scalar_x_segmented_value(instantiatedModel, startIndex)
value = Modia.copy_scalar_x_segmented_value_from_state(instantiatedModel, startIndex)
Return scalar segmented state value from instantiatedModel given `startIndex`
Return value of scalar x_segmented variable from state vector `x` by providing its `startIndex`
(returned from `new_x_segmented_variable!(..)`).
"""
get_scalar_x_segmented_value(m::SimulationModel, startIndex::Int) = m.x_segmented[startIndex]
copy_scalar_x_segmented_value_from_state(m::SimulationModel, startIndex::Int) = m.x_segmented[startIndex]


"""
value = Modia.get_SVector3_x_segmented_value(instantiatedModel, startIndex)
value = Modia.copy_SVector3_x_segmented_value_from_state(instantiatedModel, startIndex)
Return SVector{3,FloatType}(..) segmented state value from instantiatedModel given `startIndex`
Return value of `SVector{3,FloatType}` x_segmented variable from state vector `x` by providing its `startIndex`
(returned from `new_x_segmented_variable!(..)`).
"""
@inline get_SVector3_x_segmented_value(m::SimulationModel{FloatType,TimeType}, startIndex::Int) where {FloatType,TimeType} = begin
@inline copy_SVector3_x_segmented_value_from_state(m::SimulationModel{FloatType,TimeType}, startIndex::Int) where {FloatType,TimeType} = begin
x_segmented = m.x_segmented
return SVector{3,FloatType}(x_segmented[startIndex], x_segmented[startIndex+1], x_segmented[startIndex+2])
end

"""
Modia.get_Vector_x_segmented_value!(instantiatedModel::SimulationModel, startIndex, xi::Vector{FloatType})::Nothing
Modia.copy_Vector_x_segmented_value_from_state(instantiatedModel::SimulationModel, startIndex, xi::Vector{FloatType})::Nothing
Copy state from `instantiatedModel` at index `startIndex` into pre-allocated vector `xi`.
Return value of `Vector{FloatType}` x_segmented variable from state vector `x` by providing its `startIndex`
(returned from `new_x_segmented_variable!(..)`) and copying it into the pre-allocated vector `xi`.
"""
@inline function get_Vector_x_segmented_value!(m::SimulationModel{FloatType,TimeType}, startIndex::Int, xi::Vector{FloatType})::Nothing where {FloatType,TimeType}
@inline function copy_Vector_x_segmented_value_from_state(m::SimulationModel{FloatType,TimeType}, startIndex::Int, xi::Vector{FloatType})::Nothing where {FloatType,TimeType}
copyto!(xi, 1, m.x_segmented, startIndex, length(xi))
return nothing
end


"""
Modia.add_der_x_segmented_value!(instantiatedModel, startIndex, der_x_segmented_value::[FloatType|Vector{FloatType}])
Modia.copy_der_x_segmented_value_to_state(instantiatedModel, startIndex, der_x_segmented_value::[FloatType|Vector{FloatType}])
Copy scalar or array segmented state derivative value `der_x_segmented_value` into `instantiatedModel` starting at index `startIndex`
(returned from `new_x_segmented_variable!(..)`).
Copy `der_x_segmented_value` to state derivative vector `der(x)` by providing its `startIndex`
(returned from `new_x_segmented_variable!(..)`) and copying it into the pre-allocated vector `der_x_segmented_value`.
"""
@inline function add_der_x_segmented_value!(m::SimulationModel{FloatType,TimeType}, startIndex::Int, der_x_segmented_value::FloatType)::Nothing where {FloatType,TimeType}
@inline function copy_der_x_segmented_value_to_state(m::SimulationModel{FloatType,TimeType}, startIndex::Int, der_x_segmented_value::FloatType)::Nothing where {FloatType,TimeType}
m.der_x_segmented[startIndex] = der_x_segmented_value
return nothing
end
@inline function add_der_x_segmented_value!(m::SimulationModel{FloatType,TimeType}, startIndex::Int, der_x_segmented_value::Vector{FloatType})::Nothing where {FloatType,TimeType}
@inline function copy_der_x_segmented_value_to_state(m::SimulationModel{FloatType,TimeType}, startIndex::Int, der_x_segmented_value::Vector{FloatType})::Nothing where {FloatType,TimeType}
copyto!(m.der_x_segmented, startIndex, der_x_segmented_value, 1, length(der_x_segmented_value))
return nothing
end


"""
Modia.add_w_segmented_value!(instantiatedModel::SimulationModel, index::Int, w_segmented_value)::Nothing
Modia.copy_w_segmented_value_to_result(instantiatedModel::SimulationModel, index::Int, w_segmented_value)::Nothing
Store deepcopy(w_segmented_value) at index in instantiatedModel.
Copy value of local variable (`w-segmented`) to result by providing its `index`
(returned from `new_w_segmented_variable!`),
"""
@inline function add_w_segmented_value!(m::SimulationModel, index::Int, w_segmented_value)::Nothing
@inline function copy_w_segmented_value_to_result(m::SimulationModel, index::Int, w_segmented_value)::Nothing
w_segmented_temp = m.result.w_segmented_temp
@assert(typeof(w_segmented_value) == typeof(w_segmented_temp[index]))
@assert(size( w_segmented_value) == size( w_segmented_temp[index]))
Expand Down
6 changes: 3 additions & 3 deletions test/TestLinearSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,11 @@ end

function openLinearStateSpace!(instantiatedModel::SimulationModel{FloatType,TimeType}, ID)::LinearStateSpaceStruct{FloatType} where {FloatType,TimeType}
ls = Modia.get_instantiatedSubmodel(instantiatedModel,ID).ls
Modia.get_Vector_x_segmented_value!(instantiatedModel, ls.x_startIndex, ls.x)
Modia.copy_Vector_x_segmented_value_from_state(instantiatedModel, ls.x_startIndex, ls.x)
if Modia.storeResults(instantiatedModel) && length(ls.W) > 0
# w = W*x
mul!(ls.w, ls.W, ls.x)
Modia.add_w_segmented_value!(instantiatedModel, ls.w_index, ls.w)
Modia.copy_w_segmented_value_to_result(instantiatedModel, ls.w_index, ls.w)
end
return ls
end
Expand All @@ -188,7 +188,7 @@ function computeStateDerivatives!(instantiatedModel, ls, u)::Bool
# der_x = A*x + B*u
mul!(ls.der_x, ls.A, ls.x)
mul!(ls.der_x, ls.B, u, 1.0, 1.0)
Modia.add_der_x_segmented_value!(instantiatedModel, ls.x_startIndex, ls.der_x)
Modia.copy_der_x_segmented_value_to_state(instantiatedModel, ls.x_startIndex, ls.der_x)
return true
end

Expand Down

0 comments on commit e81114f

Please sign in to comment.