Skip to content

Commit

Permalink
Don't use RefValue{Float64} as dictionary values
Browse files Browse the repository at this point in the history
  • Loading branch information
SouthEndMusic committed Jun 5, 2024
1 parent 7bf24c2 commit 8e337aa
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 31 deletions.
6 changes: 3 additions & 3 deletions core/src/allocation_optim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ function save_demands_and_allocations!(
user_demand_idx = findsorted(user_demand.node_id, node_id)
demand = user_demand.demand[user_demand_idx, priority_idx]
allocated = user_demand.allocated[user_demand_idx, priority_idx]
realized = mean_realized_flows[(inflow_id(graph, node_id), node_id)][]
realized = mean_realized_flows[(inflow_id(graph, node_id), node_id)]

elseif has_external_demand(graph, node_id, :level_demand)[1]
basin_priority_idx = get_external_priority_idx(p, node_id)
Expand All @@ -744,7 +744,7 @@ function save_demands_and_allocations!(
end
allocated =
JuMP.value(F_basin_in[node_id]) - JuMP.value(F_basin_out[node_id])
realized = mean_realized_flows[(node_id, node_id)][]
realized = mean_realized_flows[(node_id, node_id)]
end

else
Expand All @@ -760,7 +760,7 @@ function save_demands_and_allocations!(
flow_demand_node_id,
)] : 0.0
allocated = JuMP.value(F[(inflow_id(graph, node_id), node_id)])
realized = mean_realized_flows[(inflow_id(graph, node_id), node_id)][]
realized = mean_realized_flows[(inflow_id(graph, node_id), node_id)]
end
end

Expand Down
23 changes: 13 additions & 10 deletions core/src/callback.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,22 +118,25 @@ function integrate_flows!(u, t, integrator)::Nothing
if edge[1] == edge[2]
# Vertical fluxes
_, basin_idx = id_index(basin.node_id, edge[1])
value[] +=
allocation.mean_input_flows[edge] =
value +
0.5 *
(get_influx(basin, basin_idx) + get_influx(basin, basin_idx; prev = true)) *
dt
else
# Horizontal flows
value[] +=
allocation.mean_input_flows[edge] =
value +
0.5 * (get_flow(graph, edge..., 0) + get_flow_prev(graph, edge..., 0)) * dt
end
end

# Realized demand flows
for (edge, value) in allocation.mean_realized_flows
if edge[1] !== edge[2]
value[] +=
value +=
0.5 * (get_flow(graph, edge..., 0) + get_flow_prev(graph, edge..., 0)) * dt
allocation.mean_realized_flows[edge] = value
end
end

Expand Down Expand Up @@ -481,8 +484,8 @@ function update_allocation!(integrator)::Nothing

# Divide by the allocation Δt to obtain the mean input flows
# from the integrated flows
for value in values(mean_input_flows)
value[] /= Δt_allocation
for key in keys(mean_input_flows)
mean_input_flows[key] = mean_input_flows[key] / Δt_allocation
end

# Divide by the allocation Δt to obtain the mean realized flows
Expand All @@ -491,9 +494,9 @@ function update_allocation!(integrator)::Nothing
if edge[1] == edge[2]
# Compute the mean realized demand for basins as Δstorage/Δt_allocation
_, basin_idx = id_index(basin.node_id, edge[1])
value[] += u[basin_idx]
mean_realized_flows[edge] = value + u[basin_idx]
end
value[] /= Δt_allocation
mean_realized_flows[edge] = mean_realized_flows[edge] / Δt_allocation
end

# If a main network is present, collect demands of subnetworks
Expand All @@ -512,16 +515,16 @@ function update_allocation!(integrator)::Nothing

# Reset the mean flows
for mean_flows in (mean_input_flows, mean_realized_flows)
for value in values(mean_flows)
value[] = 0.0
for edge in keys(mean_flows)
mean_flows[edge] = 0.0
end
end

# Set basin storages for mean storage change computation
for (edge, value) in mean_realized_flows
if edge[1] == edge[2]
_, basin_idx = id_index(basin.node_id, edge[1])
value[] = -u[basin_idx]
mean_realized_flows[edge] = value - u[basin_idx]
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions core/src/parameter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ struct Allocation
priorities::Vector{Int32}
subnetwork_demands::Dict{Tuple{NodeID, NodeID}, Vector{Float64}}
subnetwork_allocateds::Dict{Tuple{NodeID, NodeID}, Vector{Float64}}
mean_input_flows::Dict{Tuple{NodeID, NodeID}, Base.RefValue{Float64}}
mean_realized_flows::Dict{Tuple{NodeID, NodeID}, Base.RefValue{Float64}}
mean_input_flows::Dict{Tuple{NodeID, NodeID}, Float64}
mean_realized_flows::Dict{Tuple{NodeID, NodeID}, Float64}
record_demand::@NamedTuple{
time::Vector{Float64},
subnetwork_id::Vector{Int32},
Expand Down
12 changes: 6 additions & 6 deletions core/src/read.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1036,24 +1036,24 @@ function Allocation(db::DB, config::Config, graph::MetaGraph)::Allocation
optimization_type = String[],
)

mean_input_flows = Dict{Tuple{NodeID, NodeID}, Base.RefValue{Float64}}()
mean_input_flows = Dict{Tuple{NodeID, NodeID}, Float64}()

# Find edges which serve as sources in allocation
for edge_metadata in values(graph.edge_data)
(; subnetwork_id_source, edge) = edge_metadata
if subnetwork_id_source != 0
mean_input_flows[edge] = Ref(0.0)
mean_input_flows[edge] = 0.0
end
end

# Find basins with a level demand
for node_id in values(graph.vertex_labels)
if has_external_demand(graph, node_id, :level_demand)[1]
mean_input_flows[(node_id, node_id)] = Ref(0.0)
mean_input_flows[(node_id, node_id)] = 0.0
end
end

mean_realized_flows = Dict{Tuple{NodeID, NodeID}, Base.RefValue{Float64}}()
mean_realized_flows = Dict{Tuple{NodeID, NodeID}, Float64}()

# Find edges that realize a demand
for edge_metadata in values(graph.edge_data)
Expand All @@ -1067,9 +1067,9 @@ function Allocation(db::DB, config::Config, graph::MetaGraph)::Allocation
(type == EdgeType.flow) && has_external_demand(graph, dst_id, :flow_demand)[1]

if user_demand_inflow || flow_demand_inflow
mean_realized_flows[edge] = Ref(0.0)
mean_realized_flows[edge] = 0.0
elseif level_demand_inflow
mean_realized_flows[(dst_id, dst_id)] = Ref(0.0)
mean_realized_flows[(dst_id, dst_id)] = 0.0
end
end

Expand Down
10 changes: 5 additions & 5 deletions core/src/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -768,26 +768,26 @@ function set_initial_allocation_mean_flows!(integrator)::Nothing
# one is just to make sure.
water_balance!(get_du(integrator), u, p, t)

for (edge, value) in mean_input_flows
for edge in keys(mean_input_flows)
if edge[1] == edge[2]
q = get_influx(basin, edge[1])
else
q = get_flow(graph, edge..., 0)
end
# Multiply by Δt_allocation as averaging divides by this factor
# in update_allocation!
value[] = q * Δt_allocation
mean_input_flows[edge] = q * Δt_allocation
end

# Mean realized demands for basins are calculated as Δstorage/Δt
# This sets the realized demands as -storage_old
for (edge, value) in mean_realized_flows
for edge in keys(mean_realized_flows)
if edge[1] == edge[2]
_, basin_idx = id_index(basin.node_id, edge[1])
value[] = -u[basin_idx]
mean_realized_flows[edge] = -u[basin_idx]
else
q = get_flow(graph, edge..., 0)
value[] = q * Δt_allocation
mean_realized_flows[edge] = q * Δt_allocation
end
end

Expand Down
10 changes: 5 additions & 5 deletions core/test/allocation_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
(; graph, allocation) = p
close(db)

allocation.mean_input_flows[(NodeID(:FlowBoundary, 1), NodeID(:Basin, 2))][] = 4.5
allocation.mean_input_flows[(NodeID(:FlowBoundary, 1), NodeID(:Basin, 2))] = 4.5
allocation_model = p.allocation.allocation_models[1]
u = ComponentVector(; storage = zeros(length(p.basin.node_id)))
Ribasim.allocate_demands!(p, allocation_model, 0.0, u)
Expand Down Expand Up @@ -252,7 +252,7 @@ end

# Running full allocation algorithm
(; Δt_allocation) = allocation_models[1]
mean_input_flows[(NodeID(:FlowBoundary, 1), NodeID(:Basin, 2))][] = 4.5 * Δt_allocation
mean_input_flows[(NodeID(:FlowBoundary, 1), NodeID(:Basin, 2))] = 4.5 * Δt_allocation
u = ComponentVector(; storage = zeros(length(p.basin.node_id)))
Ribasim.update_allocation!((; p, t, u))

Expand Down Expand Up @@ -300,8 +300,8 @@ end
t = 0.0

# Set flows of sources in
mean_input_flows[(NodeID(:FlowBoundary, 58), NodeID(:Basin, 16))][] = 1.0
mean_input_flows[(NodeID(:FlowBoundary, 59), NodeID(:Basin, 44))][] = 1e-3
mean_input_flows[(NodeID(:FlowBoundary, 58), NodeID(:Basin, 16))] = 1.0
mean_input_flows[(NodeID(:FlowBoundary, 59), NodeID(:Basin, 44))] = 1e-3

# Collecting demands
u = ComponentVector(; storage = zeros(length(basin.node_id)))
Expand Down Expand Up @@ -333,7 +333,7 @@ end
(; user_demand, graph, allocation, basin, level_demand) = p

# Initial "integrated" vertical flux
@test allocation.mean_input_flows[(NodeID(:Basin, 2), NodeID(:Basin, 2))][] 1e2
@test allocation.mean_input_flows[(NodeID(:Basin, 2), NodeID(:Basin, 2))] 1e2

Ribasim.solve!(model)

Expand Down

0 comments on commit 8e337aa

Please sign in to comment.