I have a model that couples components with varying timestep lengths. If I create a connection between two of the shorter components, the array holding this parameter takes on the length of the longer component (with the timesteps the shorter component doesn’t cover = missing). If I also do a set_param!()
within this shorter component for a time-varying parameter, the array holding it takes on the size of the shorter component.
Am I understanding this correctly, and if so is this the desired behavior? It was causing all kinds of errors in my model because I was inadvertently indexing into these components the wrong way and having a bunch of missing values pop up. I attached a working example of what I’m talking about below (In this case the error arises from using [1]
to index the first value. I know there are ways around this, but the error could still occur in more complicated indexing cases).
Here’s a toy model where the period 15 temperature value is either calculated or missing depending on how I index.
using Mimi
# An economy component (the longer component).
@defcomp economy begin
gdp = Variable(index=[time])
function run_timestep(p, v, d, t)
if is_first(t)
v.gdp[t] = 10.0
else
v.gdp[t] = v.gdp[t-1] * 1.02
end
end
end
# A shorter emissions component that switches on in period 15.
@defcomp co2_emissions begin
gdp = Parameter(index=[time])
co2 = Variable(index=[time])
function run_timestep(p, v, d, t)
v.co2[t] = (0.1 * p.gdp[t])
end
end
# A shorter climate component that switches on in period 15.
@defcomp climate begin
co2 = Parameter(index=[time])
other_ghg = Parameter(index=[time])
temperature = Variable(index=[time])
function run_timestep(p, v, d, t)
if is_first(t)
v.temperature[t] = (p.co2[1] + p.other_ghg[1]) ^ 2
else
v.temperature[t] = (p.co2[t] + p.other_ghg[t]) ^ 1.5
end
end
end
# Create the model for 20 time steps.
m = Model()
set_dimension!(m, :time, 20)
# Add components (emissions and climate turn on in period 15).
add_comp!(m, economy)
add_comp!(m, co2_emissions; first=15)
add_comp!(m, climate; first=15)
# Set exogenous gas scenario for periods 15-20.
set_param!(m, :climate, :other_ghg, ones(6))
# Create component connections.
connect_param!(m, :co2_emissions => :gdp, :economy => :gdp)
connect_param!(m, :climate, :co2, :co2_emissions, :co2)
run(m)
In this example, m[:climate, :temperature][15]
is a missing value. But the temperature will be calculated If I change the initial temperature calculation to :
v.temperature[t] = (p.co2[15] + p.other_ghg[1]) ^ 2
because the connected co2
parameter ends up in a 20x1 array while the external other_ghg
parameter is in a 6x1 array. This can get really confusing with more complicated set ups.