Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/internals/structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@ In the new version, all component definitions are represented by one type, `Comp

## 3. Pre-compilation and built-in components

To get `__precompile__()` to work required moving the creation of "helper" components to an `__init__()` method in Mimi.jl, which is run automatically after Mimi loads. It defines the two "built-in" components, from `adder.jl` and `connector.jl` in the `components` subdirectory.
To get `__precompile__()` to work required moving the creation of "helper" components to an `__init__()` method in Mimi.jl, which is run automatically after Mimi loads. It defines the three "built-in" components, from `adder.jl`, `multiplier.jl`, and `connector.jl` in the `components` subdirectory.
4 changes: 3 additions & 1 deletion docs/src/tutorials/tutorial_3.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,12 @@ run(m)

Most model modifications will include not only parametric updates, but also structural changes and component modification, addition, replacement, and deletion along with the required re-wiring of parameters etc. The most useful functions of the common API, in these cases are likely **[`replace!`](@ref), [`add_comp!`](@ref)** along with **`delete!`** and the requisite functions for parameter setting and connecting. For detail on the public API functions look at the API reference.

If you wish to modify the component structure we recommend you also look into the **built-in helper components `adder`, `ConnectorCompVector`, and `ConnectorCompMatrix`** in the `src/components` folder, as these can prove quite useful.
If you wish to modify the component structure we recommend you also look into the **built-in helper components `adder`, `multiplier`,`ConnectorCompVector`, and `ConnectorCompMatrix`** in the `src/components` folder, as these can prove quite useful.

* `adder.jl` -- Defines `Mimi.adder`, which simply adds two parameters, `input` and `add` and stores the result in `output`.

* `multiplier.jl` -- Defines `Mimi.multiplier`, which simply multiplies two parameters, `input` and `multiply` and stores the result in `output`.

* `connector.jl` -- Defines a pair of components, `Mimi.ConnectorCompVector` and `Mimi.ConnectorCompMatrix`. These copy the value of parameter `input1`, if available, to the variable `output`, otherwise the value of parameter `input2` is used. It is an error if neither has a value.

## Component and Structural Modifications: DICE Example
Expand Down
1 change: 1 addition & 0 deletions src/Mimi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ include("utils/misc.jl")

# Load built-in components
include("components/adder.jl")
include("components/multiplier.jl")
include("components/connector.jl")

end # module
2 changes: 2 additions & 0 deletions src/components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ module. So to place components defined here in `Mimi`, prefix the component name

* `adder.jl` -- Defines `Mimi.adder`, which simply adds two parameters, `input` and `add` and stores the result in `output`.

* `multiplier.jl` -- Defines `Mimi.multiplier`, which simply multiplies two parameters, `input` and `multiply` and stores the result in `output`.

* `connector.jl` -- Defines a pair of components, `Mimi.ConnectorCompVector` and `Mimi.ConnectorCompMatrix`. These copy the
value of parameter `input1`, if available, to the variable `output`, otherwise the value of parameter `input2` is used. It is an error if neither has a value.
6 changes: 5 additions & 1 deletion src/components/adder.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using Mimi

# the @allow_missing macro allows a parameter or variable to access a missing value
# without throwing an error, which is less safe for users but avoids some corner
# case problems in the context of this type of connectin or unit-conversion component

@defcomp adder begin
add = Parameter(index=[time])
input = Parameter(index=[time])
output = Variable(index=[time])

function run_timestep(p, v, d, t)
v.output[t] = p.input[t] + p.add[t]
v.output[t] = @allow_missing(p.input[t]) + p.add[t]
end
end

16 changes: 16 additions & 0 deletions src/components/multiplier.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Mimi

# the @allow_missing macro allows a parameter or variable to access a missing value
# without throwing an error, which is less safe for users but avoids some corner
# case problems in the context of this type of connectin or unit-conversion component

@defcomp multiplier begin

multiply = Parameter(index=[time])
input = Parameter(index=[time])
output = Variable(index=[time])

function run_timestep(p, v, d, t)
v.output[t] = @allow_missing(p.input[t]) * p.multiply[t]
end
end
2 changes: 1 addition & 1 deletion src/core/defcomp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using MacroTools

# Store a list of built-in components so we can suppress messages about creating them.
# TBD: suppress returning these in the list of components at the user level.
const global built_in_comps = (:adder, :ConnectorCompVector, :ConnectorCompMatrix)
const global built_in_comps = (:adder, :multiplier, :ConnectorCompVector, :ConnectorCompMatrix)

is_builtin(comp_name) = comp_name in built_in_comps

Expand Down
3 changes: 3 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ Electron.prep_test_env()
@info("test_adder.jl")
@time include("test_adder.jl")

@info("test_multiplier.jl")
@time include("test_multiplier.jl")

@info("test_getindex.jl")
@time include("test_getindex.jl")

Expand Down
4 changes: 2 additions & 2 deletions test/test_explorer_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ set_param!(m2, :MyComp2, :a, ones(101, 3, 4))
run(m2)

# spec creation for MyComp.a should warn because over 2 indexed dimensions
@test_logs (:warn, "MyComp2.a has > 2 indexed dimensions, not yet implemented in explorer") explore(m2)
@test_logs (:warn, "MyComp2.a has > 2 indexed dimensions, not yet implemented in explorer") _spec_for_item(m2, :MyComp2, :a)
# @test_logs (:warn, "MyComp2.a has > 2 indexed dimensions, not yet implemented in explorer") explore(m2) #URI Parser warning from within Electron (?)
# @test_logs (:warn, "MyComp2.a has > 2 indexed dimensions, not yet implemented in explorer") _spec_for_item(m2, :MyComp2, :a) #URI Parser warning from within Electron (?)

#7. Test TimestepArrays with time not as the first dimension

Expand Down
37 changes: 37 additions & 0 deletions test/test_multiplier.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module TestMultiplier

using Mimi
using Test

############################################
# adder component without a different name #
############################################

model1 = Model()
set_dimension!(model1, :time, 1:10)
add_comp!(model1, Mimi.multiplier)

x = collect(1:10)
y = collect(2:2:20)

set_param!(model1, :multiplier, :input, x)
set_param!(model1, :multiplier, :multiply, y)

run(model1)

@test model1[:multiplier, :output] == x.*y

##############################################
# test adder component with a different name #
##############################################

model2 = Model()
set_dimension!(model2, :time, 1:10)
add_comp!(model2, Mimi.multiplier, :compA)
set_param!(model2, :compA, :input, x)
set_param!(model2, :compA, :multiply, y)
run(model2)

@test model2[:compA, :output] == x.*y

end #module