diff --git a/core/src/callback.jl b/core/src/callback.jl index 8c03d1cc5..3ec332faf 100644 --- a/core/src/callback.jl +++ b/core/src/callback.jl @@ -109,8 +109,8 @@ Update with the latest timestep: During these cumulative flow updates, we can also update the mass balance of the system, as each flow carries mass, based on the concentrations of the flow source. -Specifically, we first use all the inflows to update the mass of the basins, recalculate -the basin concentration(s) and then remove the mass that is being lost to the outflows. +Specifically, we first use all the inflows to update the mass of the Basins, recalculate +the Basin concentration(s) and then remove the mass that is being lost to the outflows. """ function update_cumulative_flows!(u, t, integrator)::Nothing (; p, uprev, tprev, dt) = integrator @@ -130,7 +130,7 @@ function update_cumulative_flows!(u, t, integrator)::Nothing # Reset cumulative flows, used to calculate the concentration # of the basins after processing inflows only - fill!(basin.cumulative_in, 0.0) + basin.cumulative_in .= 0.0 # Update cumulative forcings which are integrated exactly @. basin.cumulative_drainage += vertical_flux.drainage * dt @@ -264,10 +264,10 @@ function update_cumulative_flows!(u, t, integrator)::Nothing end end - # Update the basin concentrations based on the added mass and flows + # Update the Basin concentrations based on the added mass and flows basin.concentration_state .= basin.mass ./ (basin.storage_prev .+ basin.cumulative_in) - # Process all mass outflows from basins + # Process all mass outflows from Basins for (inflow_edge, outflow_edge) in zip(state_inflow_edge, state_outflow_edge) from_node = inflow_edge.edge[1] to_node = outflow_edge.edge[2] @@ -311,7 +311,7 @@ function update_cumulative_flows!(u, t, integrator)::Nothing error("Negative mass(es) detected") end - # Update the basin concentrations again based on the removed mass + # Update the Basin concentrations again based on the removed mass basin.concentration_state .= basin.mass ./ basin.current_storage[parent(u)] basin.storage_prev .= basin.current_storage[parent(u)] @@ -320,8 +320,8 @@ end """ Given an edge (from_id, to_id), compute the cumulative flow over that -edge over the latest timestep. If from_id and to_id are both the same basin, -the function returns the sum of the basin forcings. +edge over the latest timestep. If from_id and to_id are both the same Basin, +the function returns the sum of the Basin forcings. """ function flow_update_on_edge( integrator::DEIntegrator, @@ -366,7 +366,7 @@ end """ Save all cumulative forcings and flows over edges over the latest timestep, Both computed by the solver and integrated exactly. Also computes the total horizontal -inflow and outflow per basin. +inflow and outflow per Basin. """ function save_flow(u, t, integrator) (; p) = integrator diff --git a/core/src/parameter.jl b/core/src/parameter.jl index 075764e6d..8dcf03705 100644 --- a/core/src/parameter.jl +++ b/core/src/parameter.jl @@ -106,7 +106,7 @@ const ScalarInterpolation = LinearInterpolation{ Float64, } -set_zero!(v) = fill!(v, zero(eltype(v))) +set_zero!(v) = v .= zero(eltype(v)) const Cache = LazyBufferCache{Returns{Int}, typeof(set_zero!)} """ @@ -266,12 +266,12 @@ abstract type AbstractDemandNode <: AbstractParameterNode end In-memory storage of saved mean flows for writing to results. - `flow`: The mean flows on all edges and state-dependent forcings -- `inflow`: The sum of the mean flows coming into each basin -- `outflow`: The sum of the mean flows going out of each basin +- `inflow`: The sum of the mean flows coming into each Basin +- `outflow`: The sum of the mean flows going out of each Basin - `flow_boundary`: The exact integrated mean flows of flow boundaries - `precipitation`: The exact integrated mean precipitation - `drainage`: The exact integrated mean drainage -- `concentration`: Concentrations for each basin and substance +- `concentration`: Concentrations for each Basin and substance - `balance_error`: The (absolute) water balance error - `relative_error`: The relative water balance error - `t`: Endtime of the interval over which is averaged @@ -356,15 +356,15 @@ end # Concentrations # Config setting to enable/disable evaporation of mass evaporate_mass::Bool = true - # Cumulative inflow for each basin at a given time + # Cumulative inflow for each Basin at a given time cumulative_in::Vector{Float64} = zeros(length(node_id)) - # Storage for each basin at the previous time step + # Storage for each Basin at the previous time step storage_prev::Vector{Float64} = zeros(length(node_id)) - # matrix with concentrations for each basin and substance - concentration_state::Matrix{Float64} # basin, substance - # matrix with boundary concentrations for each boundary, basin and substance + # matrix with concentrations for each Basin and substance + concentration_state::Matrix{Float64} # Basin, substance + # matrix with boundary concentrations for each boundary, Basin and substance concentration::Array{Float64, 3} - # matrix with mass for each basin and substance + # matrix with mass for each Basin and substance mass::Matrix{Float64} # substances in use by the model (ordered like their axis in the concentration matrices) substances::OrderedSet{Symbol} @@ -482,8 +482,8 @@ end """ node_id: node ID of the LevelBoundary node active: whether this node is active -level: the fixed level of this 'infinitely big basin' -concentration: matrix with boundary concentrations for each basin and substance +level: the fixed level of this 'infinitely big Basin' +concentration: matrix with boundary concentrations for each Basin and substance concentration_time: Data source for concentration updates """ @kwdef struct LevelBoundary{C} <: AbstractParameterNode @@ -501,7 +501,7 @@ active: whether this node is active and thus contributes flow cumulative_flow: The exactly integrated cumulative boundary flow since the start of the simulation cumulative_flow_saveat: The exactly integrated cumulative boundary flow since the last saveat flow_rate: flow rate (exact) -concentration: matrix with boundary concentrations for each basin and substance +concentration: matrix with boundary concentrations for each Basin and substance concentration_time: Data source for concentration updates """ @kwdef struct FlowBoundary{C} <: AbstractParameterNode @@ -776,8 +776,8 @@ demand_itp: Timeseries interpolation objects for demands demand_from_timeseries: If false the demand comes from the BMI or is fixed allocated: water flux currently allocated to UserDemand per priority (node_idx, priority_idx) return_factor: the factor in [0,1] of how much of the abstracted water is given back to the system -min_level: The level of the source basin below which the UserDemand does not abstract -concentration: matrix with boundary concentrations for each basin and substance +min_level: The level of the source Basin below which the UserDemand does not abstract +concentration: matrix with boundary concentrations for each Basin and substance concentration_time: Data source for concentration updates """ @kwdef struct UserDemand{C} <: AbstractDemandNode diff --git a/core/test/allocation_test.jl b/core/test/allocation_test.jl index f7549f1d1..47050c682 100644 --- a/core/test/allocation_test.jl +++ b/core/test/allocation_test.jl @@ -582,8 +582,8 @@ end (; allocation_models) = p.allocation (; basin, level_demand, graph) = p - fill!(level_demand.max_level[1].u, Inf) - fill!(level_demand.max_level[2].u, Inf) + level_demand.max_level[1].u .= Inf + level_demand.max_level[2].u .= Inf # Given a max_level of Inf, the basin capacity is 0.0 because it is not possible for the basin level to be > Inf @test Ribasim.get_basin_capacity(allocation_models[1], u, p, t, basin.node_id[1]) == 0.0 diff --git a/docs/concept/core.qmd b/docs/concept/core.qmd index 59970797d..ebfc9d201 100644 --- a/docs/concept/core.qmd +++ b/docs/concept/core.qmd @@ -124,14 +124,14 @@ user_demand->>basin: abstracted Ribasim can calculate concentrations of conservative tracers (i.e. substances that are non-reactive). It does so by calculating the mass transports by flows for each timestep, in the `update_cumulative_flows!` callback. -Specifically, for each basin at each timestep we calculate: +Specifically, for each Basin at each timestep we calculate: - all mass inflows (flow * source_concentration) given the edge inflows -- update the concentrations in the basin based on the added storage (previous storage + inflows) +- update the concentrations in the Basin based on the added storage (previous storage + inflows) - all mass outflows (flow * basin_concentration_state) give the edge outflows -- update the concentrations in the basin based on the current storage +- update the concentrations in the Basin based on the current storage -We thus keep track of both mass and concentration of substances for each basin. +We thus keep track of both mass and concentration of substances for each Basin. Note that we have not added the substance mass to the states, and we assume that concentrations of flows are piecewise constant over a timestep. By default we calculate concentrations for the following source tracers. diff --git a/docs/reference/node/basin.qmd b/docs/reference/node/basin.qmd index 1105684a0..ee87fb99a 100644 --- a/docs/reference/node/basin.qmd +++ b/docs/reference/node/basin.qmd @@ -392,7 +392,7 @@ Note that the interpolation to subgrid water level is not constrained by any wat Generally, to create physically meaningful subgrid water levels, the subgrid table must be parametrized properly such that the spatially integrated water volume of the subgrid elements agrees with the total storage volume of the basin. ## Concentration {#sec-basin-conc} -This table defines the concentration(s) of (a) substance(s) for the inflow boundaries of a Basin node. +This table defines the concentration of substances for the inflow boundaries of a Basin node. column | type | unit | restriction ------------- | -------- | ------------------------ | ----------- @@ -403,7 +403,7 @@ drainage | Float64 | $\text{g}/\text{m}^3$ | (optional) precipitation | Float64 | $\text{g}/\text{m}^3$ | (optional) ## ConcentrationState {#sec-basin-conc-state} -This table defines the concentration(s) of (a) substance(s) in the Basin at the start of the simulation. +This table defines the concentration of substances in the Basin at the start of the simulation. column | type | unit | restriction -------------- | -------- | ------------------------ | ----------- diff --git a/docs/reference/node/flow-boundary.qmd b/docs/reference/node/flow-boundary.qmd index 3600ead68..e2b465d89 100644 --- a/docs/reference/node/flow-boundary.qmd +++ b/docs/reference/node/flow-boundary.qmd @@ -38,7 +38,7 @@ time | DateTime | - | sorted per node_id flow_rate | Float64 | $\text{m}^3/\text{s}$ | non-negative ## Concentration {#sec-flow-boundary-conc} -This table defines the concentration(s) of (a) substance(s) for the flow from the FlowBoundary. +This table defines the concentration of substances for the flow from the FlowBoundary. column | type | unit | restriction -------------- | -------- | --------------------- | ----------- diff --git a/docs/reference/node/level-boundary.qmd b/docs/reference/node/level-boundary.qmd index 3cb322f56..ca77ef0a3 100644 --- a/docs/reference/node/level-boundary.qmd +++ b/docs/reference/node/level-boundary.qmd @@ -34,7 +34,7 @@ time | DateTime | - | sorted per node_id level | Float64 | $\text{m}$ | - ## Concentration {#sec-level-boundary-conc} -This table defines the concentration(s) of (a) substance(s) for the flow from the LevelBoundary. +This table defines the concentration of substances for the flow from the LevelBoundary. column | type | unit | restriction -------------- | -------- | --------------------- | ----------- diff --git a/docs/reference/node/user-demand.qmd b/docs/reference/node/user-demand.qmd index bd0cb879e..9239cd853 100644 --- a/docs/reference/node/user-demand.qmd +++ b/docs/reference/node/user-demand.qmd @@ -52,7 +52,7 @@ return_factor | Float64 | - | between [0 - 1] min_level | Float64 | $\text{m}$ | - ## Concentration -This table defines the concentration(s) of (a) substance(s) for the flow from the UserDemand. +This table defines the concentration of substances for the flow from the UserDemand. column | type | unit | restriction -------------- | -------- | --------------------- | ----------- diff --git a/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py b/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py index e3523eb3d..745efc563 100644 --- a/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py +++ b/python/ribasim_testmodels/ribasim_testmodels/discrete_control.py @@ -613,7 +613,7 @@ def continuous_concentration_condition_model() -> Model: basin.State(level=[10.0]), basin.ConcentrationState( substance=["Cl"], - concentration=[35.0], # start of slightly salty + concentration=[35.0], # slightly salty start ), basin.Concentration( time=pd.date_range(