Skip to content

Commit

Permalink
Allows for stocks with null upstreams and downstreams (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
jClugstor authored Apr 12, 2024
1 parent 7e7fbe7 commit c9c6995
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions src/model_parsers/StockFlow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function parse_askem_model(input::AbstractDict, ::Type{ASKEMStockFlow})
for param in input[:semantics][:ode][:parameters]
# want to exclude
id = Symbol(param[:id])
name = Symbol(param[:name])
name = haskey(param,:name) ? Symbol(param[:name]) : :nothing
value = param[:value]
expr = only((@parameters $id))
if haskey(param,:distribution)
Expand Down Expand Up @@ -128,6 +128,7 @@ function parse_askem_model(input::AbstractDict, ::Type{ASKEMStockFlow})
add_part!(d,:Stock, s_name = Symbol(name), s_id = Symbol(id),s_initial = new_initial,s_expr = s_expr)
end

add_part!(d,:Stock, s_name = :nothing, s_id = :nothing, s_initial = 0, s_expr = only(@variables null)) #stands in for a source or a sink for now
# remove the "initial condition" parameters after they've been used
for initial in input[:semantics][:ode][:initials]
for i in 1:nparts(d,:Parameter)
Expand All @@ -141,7 +142,7 @@ function parse_askem_model(input::AbstractDict, ::Type{ASKEMStockFlow})
name = Symbol(flow[:name])
id = Symbol(flow[:id])
upstream_stock_str = Symbol(flow[:upstream_stock])
upstream_stock = only(filter(i -> subpart(d,i,:s_id) == upstream_stock_str, 1:nparts(d,:Stock)))
upstream_stock = only(filter(i -> subpart(d,i,:s_id) == upstream_stock_str, 1:nparts(d,:Stock)))

downstream_stock_str = Symbol(flow[:downstream_stock])
downstream_stock = only(filter(i -> subpart(d,i,:s_id) == downstream_stock_str, 1:nparts(d,:Stock)))
Expand Down Expand Up @@ -169,10 +170,10 @@ function ASKEM_ACSet_to_MTK(sf::ASKEMStockFlow)
vars_symbolics = [only(@parameters $var) for var in vars_symbols] #ugh the aux_dict line is giving me trouble so I'll do this
aux_dict = Dict([vars_symbolics[i] => subpart(sf,i,:aux_expr) for i in 1:nparts(sf,:Auxiliary)])

stock_names = [subpart(sf,n,:s_id) for n in 1:nparts(sf,:Stock)]
stock_names = [subpart(sf,n,:s_id) for n in 1:nparts(sf,:Stock) if subpart(sf,n,:s_id) != :nothing]
stock_funcs = [only(@variables $s(t)) for s in stock_names]

stock_dict = Dict([subpart(sf,i,:s_expr) => stock_funcs[i] for i in 1:nparts(sf,:Stock)])
stock_dict = Dict([subpart(sf,i,:s_expr) => stock_funcs[i] for i in 1:nparts(sf,:Stock) if subpart(sf,i,:s_id) != :nothing])

flow_exprs = [ModelingToolkit.substitute(flow_expr, aux_dict) for flow_expr in aux_flows]
flow_exprs = [ModelingToolkit.substitute(flow_expr, param_dict) for flow_expr in flow_exprs]
Expand All @@ -191,13 +192,13 @@ function ASKEM_ACSet_to_MTK(sf::ASKEMStockFlow)
inflow_list = [reduce(+, [flow_exprs[i] for i in inflows(sf,n) if !isempty(inflows(sf,n))], init = 0.0) for n in 1:nparts(sf,:Stock)]
outflow_list = [reduce(+, [flow_exprs[i] for i in outflows(sf,n) if !isempty(outflows(sf,n))], init = 0.0) for n in 1:nparts(sf,:Stock)]

eqs = [D(stock_funcs[n]) ~ inflow_list[n] - outflow_list[n] for n in 1:nparts(sf,:Stock)]
eqs = [D(stock_funcs[n]) ~ inflow_list[n] - outflow_list[n] for n in 1:nparts(sf,:Stock) if subpart(sf,n,:s_id) != :nothing]

if nparts(sf,:Observable) > 0
eqs = [eqs ; obs_eqs]
end

inits = Dict(stock_funcs .=> [subpart(sf,n,:s_initial) for n in 1:nparts(sf,:Stock)])
inits = Dict(stock_funcs .=> [subpart(sf,n,:s_initial) for n in 1:nparts(sf,:Stock) if subpart(sf,n,:s_id) != :nothing])
paramvals = Dict(paramvars .=> [subpart(sf,n,:p_value) for n in 1:nparts(sf,:Parameter)])
defaults = merge(inits,paramvals)
name = subpart(sf,1,:head_name)
Expand Down

0 comments on commit c9c6995

Please sign in to comment.