Skip to content

Commit dbec056

Browse files
authored
Merge pull request #711 from mimiframework/explorer
Explorer for Composite Components
2 parents c904608 + 9d68ba2 commit dbec056

File tree

4 files changed

+161
-1
lines changed

4 files changed

+161
-1
lines changed

examples/compositecomp-model.jl

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using Mimi
2+
3+
# components
4+
@defcomp Comp1 begin
5+
par_1_1 = Parameter(index=[time]) # external input
6+
var_1_1 = Variable(index=[time]) # computed
7+
foo = Parameter()
8+
9+
function run_timestep(p, v, d, t)
10+
v.var_1_1[t] = p.par_1_1[t]
11+
end
12+
end
13+
14+
@defcomp Comp2 begin
15+
par_2_1 = Parameter(index=[time]) # connected to Comp1.var_1_1
16+
par_2_2 = Parameter(index=[time]) # external input
17+
var_2_1 = Variable(index=[time]) # computed
18+
foo = Parameter()
19+
20+
function run_timestep(p, v, d, t)
21+
v.var_2_1[t] = p.par_2_1[t] + p.foo * p.par_2_2[t]
22+
end
23+
end
24+
25+
@defcomp Comp3 begin
26+
par_3_1 = Parameter(index=[time]) # connected to Comp2.var_2_1
27+
var_3_1 = Variable(index=[time]) # external output
28+
foo = Parameter(default=30)
29+
30+
function run_timestep(p, v, d, t)
31+
# @info "Comp3 run_timestep"
32+
v.var_3_1[t] = p.par_3_1[t] * 2
33+
end
34+
end
35+
36+
@defcomp Comp4 begin
37+
par_4_1 = Parameter(index=[time]) # connected to Comp2.var_2_1
38+
var_4_1 = Variable(index=[time]) # external output
39+
foo = Parameter(default=300)
40+
41+
function run_timestep(p, v, d, t)
42+
# @info "Comp4 run_timestep"
43+
v.var_4_1[t] = p.par_4_1[t] * 2
44+
end
45+
end
46+
47+
@defcomposite A begin
48+
Component(Comp1)
49+
Component(Comp2)
50+
51+
foo1 = Parameter(Comp1.foo)
52+
foo2 = Parameter(Comp2.foo)
53+
54+
var_2_1 = Variable(Comp2.var_2_1)
55+
56+
connect(Comp2.par_2_1, Comp1.var_1_1)
57+
connect(Comp2.par_2_2, Comp1.var_1_1)
58+
end
59+
60+
@defcomposite B begin
61+
Component(Comp3)
62+
Component(Comp4)
63+
64+
foo3 = Parameter(Comp3.foo)
65+
foo4 = Parameter(Comp4.foo)
66+
67+
var_3_1 = Variable(Comp3.var_3_1)
68+
end
69+
70+
@defcomposite top begin
71+
Component(A)
72+
73+
fooA1 = Parameter(A.foo1)
74+
fooA2 = Parameter(A.foo2)
75+
76+
# TBD: component B isn't getting added to mi
77+
Component(B)
78+
foo3 = Parameter(B.foo3)
79+
foo4 = Parameter(B.foo4)
80+
81+
var_3_1 = Variable(B.var_3_1)
82+
83+
connect(B.par_3_1, A.var_2_1)
84+
connect(B.par_4_1, B.var_3_1)
85+
end
86+
87+
# model
88+
m = Model()
89+
md = m.md
90+
set_dimension!(m, :time, 2005:2020)
91+
add_comp!(m, top, nameof(top))
92+
93+
set_param!(m, :fooA1, 1)
94+
set_param!(m, :fooA2, 2)
95+
set_param!(m, :foo3, 10)
96+
set_param!(m, :foo4, 20)
97+
set_param!(m, :par_1_1, collect(1:length(time_labels(md))))
98+
run(m)

src/core/model.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ Return an iterator on the components in a model's model instance.
205205
206206
Return a DatumDef for `item` in the given component `comp_def`.
207207
"""
208-
function datumdef(comp_def::ComponentDef, item::Symbol)
208+
function datumdef(comp_def::AbstractComponentDef, item::Symbol)
209209
if has_variable(comp_def, item)
210210
return variable(comp_def, item)
211211

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ Electron.prep_test_env()
110110
@info("test_explorer_sim.jl")
111111
@time include("test_explorer_sim.jl")
112112

113+
@info("test_explorer_compositecomp.jl")
114+
@time include("test_explorer_compositecomp.jl")
115+
113116
@info("test_plotting.jl")
114117
@time include("test_plotting.jl")
115118

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using Mimi
2+
using Test
3+
using DataFrames
4+
using VegaLite
5+
using Electron
6+
7+
import Mimi:
8+
dataframe_or_scalar, _spec_for_item, menu_item_list, getdataframe, dim_names, time_labels
9+
10+
# Helper function returns true if VegaLite is verison 3 or above, and false otherwise
11+
function _is_VegaLite_v3()
12+
return isdefined(VegaLite, :vlplot) ? true : false
13+
end
14+
15+
include("../examples/compositecomp-model.jl") # constructs and runs model
16+
# m's structure is as follows:
17+
#
18+
# top
19+
# / \
20+
# A B
21+
# / \ / \
22+
# 1 2 3 4
23+
24+
25+
# 1. dataframe helper functions
26+
@test typeof(dataframe_or_scalar(m, :top, :fooA1)) == Float64 # same for fooA2, foo3, foo4
27+
@test typeof(dataframe_or_scalar(m, :top, :var_3_1)) == DataFrame
28+
@test typeof(dataframe_or_scalar(m, :top, :par_1_1)) == DataFrame
29+
30+
#2. Specs and menu
31+
items = [:fooA1, :fooA2, :foo3, :foo4, :var_3_1, :par_1_1]
32+
for item in items
33+
static_spec = _spec_for_item(m, :top, item; interactive = false)
34+
interactive_spec = _spec_for_item(m, :top, item)
35+
if length(dim_names(m, :top, item)) == 0
36+
name = string(:top, " : ", item, " = ", m[:top, item])
37+
else
38+
name = string(:top, " : ", item)
39+
end
40+
@test static_spec["name"] == interactive_spec["name"] == name
41+
end
42+
43+
s = menu_item_list(m)
44+
@test typeof(s) == Array{Any, 1}
45+
@test length(s) == 6
46+
47+
#3. explore(m::Model, title = "Electron")
48+
w = explore(m, title = "Testing Window")
49+
@test typeof(w) == Electron.Window
50+
close(w)
51+
52+
#4. Mim.plot(m::Model, comp_name::Symbol, datum_name::Symbol;
53+
# dim_name::Union{Nothing, Symbol} = nothing)
54+
items = [:fooA1, :fooA2, :foo3, :foo4, :var_3_1, :par_1_1]
55+
for item in items
56+
p = Mimi.plot(m, :top, item)
57+
p_type = _is_VegaLite_v3() ? VegaLite.VLSpec : VegaLite.VLSpec{:plot}
58+
@test typeof(p) == p_type
59+
end

0 commit comments

Comments
 (0)