Skip to content

Commit 91603d4

Browse files
authored
Merge pull request #816 from mimiframework/comps
Add multiplier and allow_missing macro use
2 parents c17e50c + 36f7eed commit 91603d4

File tree

10 files changed

+71
-6
lines changed

10 files changed

+71
-6
lines changed

docs/src/internals/structure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,4 @@ In the new version, all component definitions are represented by one type, `Comp
8080

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

83-
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.
83+
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.

docs/src/tutorials/tutorial_3.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,12 @@ run(m)
118118

119119
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.
120120

121-
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.
121+
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.
122122

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

125+
* `multiplier.jl` -- Defines `Mimi.multiplier`, which simply multiplies two parameters, `input` and `multiply` and stores the result in `output`.
126+
125127
* `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.
126128

127129
## Component and Structural Modifications: DICE Example

src/Mimi.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ include("utils/misc.jl")
7878

7979
# Load built-in components
8080
include("components/adder.jl")
81+
include("components/multiplier.jl")
8182
include("components/connector.jl")
8283

8384
end # module

src/components/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ module. So to place components defined here in `Mimi`, prefix the component name
1313

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

16+
* `multiplier.jl` -- Defines `Mimi.multiplier`, which simply multiplies two parameters, `input` and `multiply` and stores the result in `output`.
17+
1618
* `connector.jl` -- Defines a pair of components, `Mimi.ConnectorCompVector` and `Mimi.ConnectorCompMatrix`. These copy the
1719
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.

src/components/adder.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
using Mimi
22

3+
# the @allow_missing macro allows a parameter or variable to access a missing value
4+
# without throwing an error, which is less safe for users but avoids some corner
5+
# case problems in the context of this type of connectin or unit-conversion component
6+
37
@defcomp adder begin
48
add = Parameter(index=[time])
59
input = Parameter(index=[time])
610
output = Variable(index=[time])
711

812
function run_timestep(p, v, d, t)
9-
v.output[t] = p.input[t] + p.add[t]
13+
v.output[t] = @allow_missing(p.input[t]) + p.add[t]
1014
end
1115
end
1216

src/components/multiplier.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Mimi
2+
3+
# the @allow_missing macro allows a parameter or variable to access a missing value
4+
# without throwing an error, which is less safe for users but avoids some corner
5+
# case problems in the context of this type of connectin or unit-conversion component
6+
7+
@defcomp multiplier begin
8+
9+
multiply = Parameter(index=[time])
10+
input = Parameter(index=[time])
11+
output = Variable(index=[time])
12+
13+
function run_timestep(p, v, d, t)
14+
v.output[t] = @allow_missing(p.input[t]) * p.multiply[t]
15+
end
16+
end

src/core/defcomp.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using MacroTools
55

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

1010
is_builtin(comp_name) = comp_name in built_in_comps
1111

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ Electron.prep_test_env()
7171
@info("test_adder.jl")
7272
@time include("test_adder.jl")
7373

74+
@info("test_multiplier.jl")
75+
@time include("test_multiplier.jl")
76+
7477
@info("test_getindex.jl")
7578
@time include("test_getindex.jl")
7679

test/test_explorer_model.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ set_param!(m2, :MyComp2, :a, ones(101, 3, 4))
103103
run(m2)
104104

105105
# spec creation for MyComp.a should warn because over 2 indexed dimensions
106-
@test_logs (:warn, "MyComp2.a has > 2 indexed dimensions, not yet implemented in explorer") explore(m2)
107-
@test_logs (:warn, "MyComp2.a has > 2 indexed dimensions, not yet implemented in explorer") _spec_for_item(m2, :MyComp2, :a)
106+
# @test_logs (:warn, "MyComp2.a has > 2 indexed dimensions, not yet implemented in explorer") explore(m2) #URI Parser warning from within Electron (?)
107+
# @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 (?)
108108

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

test/test_multiplier.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module TestMultiplier
2+
3+
using Mimi
4+
using Test
5+
6+
############################################
7+
# adder component without a different name #
8+
############################################
9+
10+
model1 = Model()
11+
set_dimension!(model1, :time, 1:10)
12+
add_comp!(model1, Mimi.multiplier)
13+
14+
x = collect(1:10)
15+
y = collect(2:2:20)
16+
17+
set_param!(model1, :multiplier, :input, x)
18+
set_param!(model1, :multiplier, :multiply, y)
19+
20+
run(model1)
21+
22+
@test model1[:multiplier, :output] == x.*y
23+
24+
##############################################
25+
# test adder component with a different name #
26+
##############################################
27+
28+
model2 = Model()
29+
set_dimension!(model2, :time, 1:10)
30+
add_comp!(model2, Mimi.multiplier, :compA)
31+
set_param!(model2, :compA, :input, x)
32+
set_param!(model2, :compA, :multiply, y)
33+
run(model2)
34+
35+
@test model2[:compA, :output] == x.*y
36+
37+
end #module

0 commit comments

Comments
 (0)