Skip to content

Commit

Permalink
Merge pull request #166 from ModiaSim/Release0.11.0
Browse files Browse the repository at this point in the history
Prepare release 0.11.0
  • Loading branch information
MartinOtter authored Jun 4, 2023
2 parents 78048a7 + e2ef5f5 commit 572ab57
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 21 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.10.0"
version = "0.11.0"

[deps]
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
Expand Down
14 changes: 14 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ functionalities of these packages.

## Release Notes

### Version 0.11.0

- Require ModiaBase 0.11.1
- Manifest.toml file removed.
- test.yml for github actions changed to use Julia 1.9.0

**Non-backwards** compatible changes

These changes only influence models that use the new feature of built-in components.

- `_buildFunction` argument list changed (options of @instantiateModel added)



### Version 0.10.0

- Initial support of segmented simulations where the number of states can change during simulation.
Expand Down
3 changes: 2 additions & 1 deletion models/HeatTransfer/InsulatedRod2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ end


# Called from @instantiateModel(..) before getDerivatives!(..) is generated
function build_InsulatedRod2!(model::AbstractDict, FloatType, TimeType, unitless::Bool, ID, pathAST)
function build_InsulatedRod2!(model::AbstractDict, modelModule, FloatType, TimeType, instantiateModelOptions, ID, pathAST)
unitless = instantiateModelOptions[:unitless]
model = model | Model(
insRod = Var(hideResult=true), # InsulatedRodStruct instance (an equation to return this variable is generated by _buildFunction)
success = Var(hideResult=true), # Dummy return argument
Expand Down
4 changes: 2 additions & 2 deletions src/Modia.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Main module of Modia.
module Modia

const path = dirname(dirname(@__FILE__)) # Absolute path of package directory
const Version = "0.10.0"
const Date = "2023-05-29"
const Version = "0.11.0"
const Date = "2023-06-04"
const modelsPath = joinpath(Modia.path, "models")

print(" \n\nWelcome to ")
Expand Down
46 changes: 34 additions & 12 deletions src/ModiaLang.jl
Original file line number Diff line number Diff line change
Expand Up @@ -583,13 +583,15 @@ function stateSelectionAndCodeGeneration(modStructure, Gexplicit, name, modelMod
if int_v > 0
value = value / u"s"
end
# if length(value) == 1

if ! (typeof(value) <: AbstractArray)
un = unit(value)
else
elseif length(value) > 0
un = unit.(value)
@assert all([un[i] == un[1] for i in 2:length(un)]) "The unit of all elements of state vector must be equal: $var::$(value)"
un = un[1]
else
un = ""
end
return SignalTables.unitAsParseableString(un)
end
Expand Down Expand Up @@ -836,56 +838,59 @@ end
appendSymbol(path::Nothing, name::Symbol) = name
appendSymbol(path , name::Symbol) = :( $path.$name )


"""
modifiedModel = buildSubmodels!(model, modelModule, FloatType, TimeType, unitless, buildDict::OrderedDict)
modifiedModel = buildSubmodels!(model, modelModule, FloatType, TimeType,
instantiateModelOptions, buildDict::AbstractDict)
Traverse `model` and for every `<submodel>` that is a `Model(..)` and has a key-value pair
`:_buildFunction = Par(functionName = <buildFunction>)` and optionally `:_buildOption=<buildOption>`, call
```
updatedSubmodel = <buildFunction>(submodel, FloatType::Type, TimeType::Type, unitless::Bool,
updatedSubmodel = <buildFunction>(submodel, modelModule, FloatType::Type, TimeType::Type, instantiateModelOptions,
ID, pathAST::Union{Expr,Symbol,Nothing}, buildOption = <buildOption>)
```
A new `updatedSubmodel` is generated from `submodel` merged with additional code and then returned.
The arguments of `<buildFunction>`are:
- `updatedSubmodel`: A potentially new reference to the updated `submodel`
- `modelModule`: Module in which the model is defined
- `FloatType`, `TimeType`: Types used when instantiating `SimulationModel{FloatType,TimeType}`
- `unitless`: Argument `unitless` of `@instantiateModel`.
- `instantiateModelOptions`: Optional arguments of `@instantiateModel` provided as `OrderedDict{Symbol,Any}`.
- `ID`: Unique ID to identify the generated submodel (to be used in the code merged into the submodel)
- `pathAST`: Path upto `<submodel>` as Abstract Syntax Tree, such as: `:( a.b.c )`
(this path might be used as part of a variable name in the code merged into the submodel).
- `buildOption`: Option used for the generation of `buildCode`.
Note, keys `_buildFunction` and `_buildOption` have been deleted in the returned `updatedSubmodel`.
"""
function buildSubmodels!(model::AbstractDict, modelModule, FloatType::Type, TimeType::Type, unitless::Bool,
function buildSubmodels!(model::AbstractDict, modelModule, FloatType::Type, TimeType::Type, instantiateModelOptions::OrderedDict{Symbol,Any},
buildDict::OrderedDict{String,Any}; pathAST::Union{Expr,Symbol,Nothing}=nothing)
if haskey(model, :_buildFunction)
_buildFunction = model[:_buildFunction]
if haskey(_buildFunction, :functionName)
buildFunction = _buildFunction[:functionName]
else
@error "Model $pathAST has key :_buildFunction but its value has no key :functionName"
end
end
delete!(model, :_buildFunction)
ID = modelPathAsString(pathAST)
ID = modelPathAsString(pathAST)
quotedPathAST = Meta.quot(pathAST)
if haskey(model, :_buildOption)
buildOption = model[:_buildOption]
delete!(model, :_buildOption)
(model, instantiatedSubmodelStruct) = Core.eval(modelModule, :($buildFunction($model, $FloatType, $TimeType, $unitless, $ID, $quotedPathAST, buildOption=$buildOption)) )
(model, instantiatedSubmodelStruct) = Core.eval(modelModule, :($buildFunction($model, $modelModule, $FloatType, $TimeType, $instantiateModelOptions, $ID, $quotedPathAST, buildOption=$buildOption)))
else
(model, instantiatedSubmodelStruct) = Core.eval(modelModule, :($buildFunction($model, $FloatType, $TimeType, $unitless, $ID, $quotedPathAST)))
(model, instantiatedSubmodelStruct) = Core.eval(modelModule, :($buildFunction($model, $modelModule, $FloatType, $TimeType, $instantiateModelOptions, $ID, $quotedPathAST)))
end
buildDict[ID] = instantiatedSubmodelStruct
return model
end

for (key,value) in model
if typeof(value) <: OrderedDict && haskey(value, :_class) && value[:_class] == :Model
model[key] = buildSubmodels!(value, modelModule, FloatType, TimeType, unitless, buildDict; pathAST=appendSymbol(pathAST,key))
model[key] = buildSubmodels!(value, modelModule, FloatType, TimeType, instantiateModelOptions, buildDict; pathAST=appendSymbol(pathAST,key))
end
end
return model
Expand Down Expand Up @@ -954,11 +959,28 @@ function instantiateModel(model; modelName="", modelModule=nothing, source=nothi
if typeof(model) <: NamedTuple || typeof(model) <: Dict || typeof(model) <: OrderedDict
# Traverse model and execute functions _buildFunction(..), to include code into sub-models
buildDict = OrderedDict{String,Any}()
instantiateModelOptions = OrderedDict{Symbol, Any}(
:modelName => modelName,
:source => source,
:aliasReduction => aliasReduction,
:unitless => unitless,
:log => log,
:logModel => logModel,
:logDetails => logDetails,
:logStateSelection => logStateSelection,
:logCode => logCode,
:logExecution => logExecution,
:logCalculations => logCalculations,
:logTiming => logTiming,
:logFile => logFile,
:evaluateParameters => evaluateParameters,
:saveCodeOnFile => saveCodeOnFile)

TimeType = if FloatType <: Measurements.Measurement ||
FloatType <: MonteCarloMeasurements.AbstractParticles;
baseType(FloatType) else FloatType end # baseType(..) is defined in CodeGeneration.jl
model = deepcopy(model)
model = buildSubmodels!(model, modelModule, FloatType, TimeType, unitless, buildDict)
model = buildSubmodels!(model, modelModule, FloatType, TimeType, instantiateModelOptions, buildDict)

if logModel
@showModel(model)
Expand Down
6 changes: 3 additions & 3 deletions test/TestLinearSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ mutable struct LinearStateSpaceBuild{FloatType}
end


function build_LinearStateSpace!(model::AbstractDict, FloatType::Type, TimeType::Type, unitless::Bool,
ID, pathAST::Union{Expr,Symbol,Nothing})
# Called from @instantiatedModel, during instantiation of the model.
function build_LinearStateSpace!(model::AbstractDict, modelModule, FloatType::Type, TimeType::Type,
instantiateModelOptions, ID, pathAST::Union{Expr,Symbol,Nothing})
# Called from @instantiateModel, during instantiation of the model.
pathAsString = Modia.modelPathAsString(pathAST)
#println("... 1: build_LinearStateSpace! called for path = ", pathAsString)

Expand Down
4 changes: 2 additions & 2 deletions test/TestMultiReturningFunction10.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ end
struct Dummy
end;

function myBuildFunction(model::AbstractDict, FloatType::Type, TimeType::Type, unitless::Bool,
ID, modelPathAST; buildOption = "Default")
function myBuildFunction(model::AbstractDict, modelModule, FloatType::Type, TimeType::Type,
instantiateModelOptions, ID, modelPathAST; buildOption = "Default")
modelPathAsString = if isnothing(modelPathAST); "" else string(modelPathAST) end
println(" TestMultiReturningFunction10: Test output from function myBuildFunction at modelPath = \"$modelPathAsString\":\n Code could be constructed here and merged to the model with buildOption=$buildOption")
return (model, Dummy())
Expand Down

0 comments on commit 572ab57

Please sign in to comment.