Code
using Ribasim
@@ -590,49 +590,49 @@ println(p.allocation.allocation_models[1].problem)
Min F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #6] + F_abs_user_demand[UserDemand #13] + F_abs_level_demand[Basin #2] + F_abs_level_demand[Basin #12] + F_abs_level_demand[Basin #5]
+Min F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #6] + F_abs_level_demand[Basin #5] + F_abs_level_demand[Basin #12] + F_abs_level_demand[Basin #2]
Subject to
+ abs_positive_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0
abs_positive_user_demand[UserDemand #3] : -F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0
abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0
- abs_positive_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0
+ abs_negative_user_demand[UserDemand #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0
abs_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0
abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0
- abs_negative_user_demand[UserDemand #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0
- abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0
- abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0
abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0
- abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0
- abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0
+ abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0
+ abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0
abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0
- F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0
- F[(UserDemand #3, Basin #2)] ≥ 0
+ abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0
+ abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0
+ F[(UserDemand #13, Terminal #10)] ≥ 0
F[(Basin #5, UserDemand #6)] ≥ 0
+ F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0
+ F[(Basin #12, UserDemand #13)] ≥ 0
F[(FlowBoundary #1, Basin #2)] ≥ 0
+ F[(UserDemand #3, Basin #2)] ≥ 0
F[(Basin #2, Basin #5)] ≥ 0
- F[(Basin #5, Basin #2)] ≥ 0
F[(Basin #2, UserDemand #3)] ≥ 0
- F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0
F[(UserDemand #6, Basin #5)] ≥ 0
+ F[(Basin #5, Basin #2)] ≥ 0
F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0
- F[(UserDemand #13, Terminal #10)] ≥ 0
- F[(Basin #12, UserDemand #13)] ≥ 0
- F_basin_in[Basin #2] ≥ 0
- F_basin_in[Basin #12] ≥ 0
+ F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0
F_basin_in[Basin #5] ≥ 0
- F_basin_out[Basin #2] ≥ 0
- F_basin_out[Basin #12] ≥ 0
+ F_basin_in[Basin #12] ≥ 0
+ F_basin_in[Basin #2] ≥ 0
F_basin_out[Basin #5] ≥ 0
+ F_basin_out[Basin #12] ≥ 0
+ F_basin_out[Basin #2] ≥ 0
source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1
+ F[(UserDemand #13, Terminal #10)] ≤ 0
F[(UserDemand #3, Basin #2)] ≤ 0
F[(UserDemand #6, Basin #5)] ≤ 0
- F[(UserDemand #13, Terminal #10)] ≤ 0
- fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : F[(TabulatedRatingCurve #7, Basin #12)] - 0.4 F[(Basin #5, TabulatedRatingCurve #7)] ≤ 0
- basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0
- basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0
+ fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : -0.4 F[(Basin #5, TabulatedRatingCurve #7)] + F[(TabulatedRatingCurve #7, Basin #12)] ≤ 0
basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0
- flow_conservation_basin[Basin #2] : -F[(UserDemand #3, Basin #2)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] - F[(Basin #5, Basin #2)] + F[(Basin #2, UserDemand #3)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0
- flow_conservation_basin[Basin #12] : -F[(TabulatedRatingCurve #7, Basin #12)] + F[(Basin #12, UserDemand #13)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0
- flow_conservation_basin[Basin #5] : F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F[(Basin #5, TabulatedRatingCurve #7)] - F[(UserDemand #6, Basin #5)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0
+ basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0
+ basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0
+ flow_conservation_basin[Basin #5] : F[(Basin #5, UserDemand #6)] + F[(Basin #5, TabulatedRatingCurve #7)] - F[(Basin #2, Basin #5)] - F[(UserDemand #6, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0
+ flow_conservation_basin[Basin #12] : F[(Basin #12, UserDemand #13)] - F[(TabulatedRatingCurve #7, Basin #12)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0
+ flow_conservation_basin[Basin #2] : -F[(FlowBoundary #1, Basin #2)] - F[(UserDemand #3, Basin #2)] + F[(Basin #2, Basin #5)] + F[(Basin #2, UserDemand #3)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0
Here \(p > 0\) is the threshold value which determines the interval \([0,p]\) of the smooth transition between \(0\) and \(1\), see the plot below.
-
+
Code
import numpy as np
@@ -475,7 +475,7 @@
diff --git a/core/usage.html b/core/usage.html
index 65684b556..83cc801b0 100644
--- a/core/usage.html
+++ b/core/usage.html
@@ -2082,11 +2082,14 @@ 20 Results
20.1 Basin - basin.arrow
The Basin table contains:
-- Results of the storage and level of each basin, which are instantaneous values;
-- Results of the vertical fluxes on each basin, which are mean values over the
saveat
intervals. In the time column the start of the period is indicated.
-- The final state of the model is not part of this file, and will be placed in a separate output state file in the future.
+- Results of the storage and level of each Basin, which are instantaneous values;
+- Results of the fluxes on each Basin, which are mean values over the
saveat
intervals. In the time column the start of the period is indicated.
+- The initial condition is written to the file, but the final state is not. It will be placed in a separate output state file in the future.
+- The
inflow_rate
and outflow_rate
are the sum of the flows from other nodes into and out of the Basin respectively. The actual flows determine in which term they are counted, not the edge direction.
+- The
storage_rate
is flow that adds to the storage in the Basin, increasing the water level. In the equations below this number is split out into two non-negative numbers, storage_increase
and storage_decrease
.
+- The
balance_error
is the difference of all Basin inflows (total_inflow
) and outflows (total_outflow
), that is (inflow_rate
+ precipitation
+ drainage
- storage_increase
) - (outflow_rate
+ evaporation
+ infiltration
- storage_decrease
). It can be used to check if the numerical error when solving the water balance is sufficiently small.
+- The
relative_error
is the fraction of the balance_error
over the mean of the total_inflow
and total_outflow
.
-The initial condition is also written to the file.
@@ -2117,25 +2120,50 @@ \(m\)
-precipitation
+inflow_rate
Float64
\(m^3 s^{-1}\)
-evaporation
+outflow_rate
Float64
\(m^3 s^{-1}\)
-drainage
+storage_rate
+Float64
+\(m^3 s^{-1}\)
+
+
+precipitation
+Float64
+\(m^3 s^{-1}\)
+
+
+evaporation
Float64
\(m^3 s^{-1}\)
+drainage
+Float64
+\(m^3 s^{-1}\)
+
+
infiltration
Float64
\(m^3 s^{-1}\)
+
+balance_error
+Float64
+\(m^3 s^{-1}\)
+
+
+relative_error
+Float64
+-
+
The table is sorted by time, and per time it is sorted by node_id
.
diff --git a/core/validation.html b/core/validation.html
index ec480245a..3896a15da 100644
--- a/core/validation.html
+++ b/core/validation.html
@@ -262,7 +262,7 @@ Validation
1 Connectivity
In the table below, each column shows which node types are allowed to be downstream (or ‘down-control’) of the node type at the top of the column.
-
+
Code
using Ribasim
@@ -546,7 +546,7 @@ 1 Connectivity
2 Neighbor amounts
The table below shows for each node type between which bounds the amount of in- and outneighbors must be, for both flow and control edges.
-
+
Code
= Vector{String}()
diff --git a/python/examples_files/figure-html/cell-59-output-1.png b/python/examples_files/figure-html/cell-59-output-1.png
index ce06f995b..9f7e6fea8 100644
Binary files a/python/examples_files/figure-html/cell-59-output-1.png and b/python/examples_files/figure-html/cell-59-output-1.png differ
diff --git a/python/test-models.html b/python/test-models.html
index 733519cce..feefadd22 100644
--- a/python/test-models.html
+++ b/python/test-models.html
@@ -227,7 +227,7 @@ flow_in_min Test models
Ribasim developers use the following models in their testbench and in order to test new features.
-
+
Code
import ribasim_testmodels
diff --git a/search.json b/search.json
index e1acee0c1..a96c642ac 100644
--- a/search.json
+++ b/search.json
@@ -244,7 +244,7 @@
"href": "build/index.html#types",
"title": "1 API Reference",
"section": "1.2 Types",
- "text": "1.2 Types\n# Ribasim.Allocation — Type.\nObject for all information about allocation allocationnetworkids: The unique sorted allocation network IDs allocation models: The allocation models for the main network and subnetworks corresponding to allocationnetworkids mainnetworkconnections: (fromid, toid) from the main network to the subnetwork per subnetwork priorities: All used priority values. subnetworkdemands: The demand of an edge from the main network to a subnetwork recorddemand: A record of demands and allocated flows for nodes that have these. record_flow: A record of all flows computed by allocation optimization, eventually saved to output file\nsource\n# Ribasim.AllocationModel — Type.\nStore information for a subnetwork used for allocation.\nallocationnetworkid: The ID of this allocation network capacity: The capacity per edge of the allocation network, as constrained by nodes that have a maxflowrate problem: The JuMP.jl model for solving the allocation problem Δt_allocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nallocationnetworkid: the ID of this allocation network p: Ribasim problem parameters Δt_allocation: The timestep between successive allocation solves\nOutputs\nAn AllocationModel object.\nsource\n# Ribasim.Basin — Type.\nRequirements:\n\nMust be positive: precipitation, evaporation, infiltration, drainage\nIndex points to a Basin\nvolume, area, level must all be positive and monotonic increasing.\n\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of vectors or Arrow Tables, and is added to avoid type instabilities. The nodeid are Indices to support fast lookup of e.g. currentlevel using ID.\nif autodiff T = DiffCache{Vector{Float64}} else T = Vector{Float64} end\nsource\n# Ribasim.DiscreteControl — Type.\nnodeid: node ID of the DiscreteControl node; these are not unique but repeated by the amount of conditions of this DiscreteControl node listennodeid: the ID of the node being condition on variable: the name of the variable in the condition greaterthan: The threshold value in the condition conditionvalue: The current value of each condition controlstate: Dictionary: node ID => (control state, control state start) logic_mapping: Dictionary: (control node ID, truth state) => control state record: Namedtuple with discrete control information for results\nsource\n# Ribasim.EdgeMetadata — Type.\nType for storing metadata of edges in the graph: id: ID of the edge (only used for labeling flow output) type: type of the edge allocationnetworkidsource: ID of allocation network where this edge is a source (0 if not a source) fromid: the node ID of the source node toid: the node ID of the destination node allocationflow: whether this edge has a flow in an allocation network node_ids: if this edge has allocation flow, these are all the nodes from the physical layer this edge consists of\nsource\n# Ribasim.FlatVector — Type.\nstruct FlatVector{T} <: AbstractVector{T}\nA FlatVector is an AbstractVector that iterates the T of a Vector{Vector{T}}.\nEach inner vector is assumed to be of equal length.\nIt is similar to Iterators.flatten, though that doesn’t work with the Tables.Column interface, which needs length and getindex support.\nsource\n# Ribasim.FlowBoundary — Type.\nnodeid: node ID of the FlowBoundary node active: whether this node is active and thus contributes flow flowrate: target flow rate\nsource\n# Ribasim.FractionalFlow — Type.\nRequirements:\n\nfrom: must be (TabulatedRatingCurve,) node\nto: must be (Basin,) node\nfraction must be positive.\n\nnodeid: node ID of the TabulatedRatingCurve node fraction: The fraction in [0,1] of flow the node lets through controlmapping: dictionary from (nodeid, controlstate) to fraction\nsource\n# Ribasim.InNeighbors — Type.\nIterate over incoming neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.LevelBoundary — Type.\nnode_id: node ID of the LevelBoundary node active: whether this node is active level: the fixed level of this ‘infinitely big basin’\nsource\n# Ribasim.LevelDemand — Type.\nnodeid: node ID of the LevelDemand node minlevel: The minimum target level of the connected basin(s) max_level: The maximum target level of the connected basin(s) priority: If in a shortage state, the priority of the demand of the connected basin(s)\nsource\n# Ribasim.LinearResistance — Type.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\n\nnodeid: node ID of the LinearResistance node active: whether this node is active and thus contributes flows resistance: the resistance to flow; Q*unlimited = Δh/resistancemax_flow_rate: the maximum flow rate allowed through the node;Q = clamp(Q*unlimited, -max*flow*rate, max*flow*rate) controlmapping: dictionary from (nodeid, controlstate) to resistance and/or active state\nsource\n# Ribasim.ManningResistance — Type.\nThis is a simple Manning-Gauckler reach connection.\n\nLength describes the reach length.\nroughness describes Manning’s n in (SI units).\n\nThe profile is described by a trapezoid:\n \\ / ^\n \\ / |\n \\ / | dz\nbottom \\______/ |\n^ <--->\n| dy\n| <------>\n| width\n|\n|\n+ datum (e.g. MSL)\nWith profile_slope = dy / dz. A rectangular profile requires a slope of 0.0.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\nlength > 0\nroughess > 0\nprofile_width >= 0\nprofile_slope >= 0\n(profilewidth == 0) xor (profileslope == 0)\n\nsource\n# Ribasim.Model — Type.\nModel(config_path::AbstractString)\nModel(config::Config)\nInitialize a Model.\nThe Model struct is an initialized model, combined with the Config used to create it and saved results. The Basic Model Interface (BMI) is implemented on the Model. A Model can be created from the path to a TOML configuration file, or a Config object.\nsource\n# Ribasim.NodeMetadata — Type.\nType for storing metadata of nodes in the graph type: type of the node allocationnetworkid: Allocation network ID (0 if not in subnetwork)\nsource\n# Ribasim.OutNeighbors — Type.\nIterate over outgoing neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.Outlet — Type.\nnodeid: node ID of the Outlet node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the outlet maxflowrate: The maximum flow rate of the outlet controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this outlet is governed by PID control\nsource\n# Ribasim.PidControl — Type.\nPID control currently only supports regulating basin levels.\nnodeid: node ID of the PidControl node active: whether this node is active and thus sets flow rates listennodeid: the id of the basin being controlled pidparams: a vector interpolation for parameters changing over time. The parameters are respectively target, proportional, integral, derivative, where the last three are the coefficients for the PID equation. error: the current error; basintarget - currentlevel\nsource\n# Ribasim.Pump — Type.\nnodeid: node ID of the Pump node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the pump maxflowrate: The maximum flow rate of the pump controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this pump is governed by PID control\nsource\n# Ribasim.Subgrid — Type.\nSubgrid linearly interpolates basin levels.\nsource\n# Ribasim.TabulatedRatingCurve — Type.\nstruct TabulatedRatingCurve{C}\nRating curve from level to flow rate. The rating curve is a lookup table with linear interpolation in between. Relation can be updated in time, which is done by moving data from the time field into the tables, which is done in the update_tabulated_rating_curve callback.\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of Vectors or Arrow Primitives, and is added to avoid type instabilities.\nnodeid: node ID of the TabulatedRatingCurve node active: whether this node is active and thus contributes flows tables: The current Q(h) relationships time: The time table used for updating the tables controlmapping: dictionary from (nodeid, controlstate) to Q(h) and/or active state\nsource\n# Ribasim.Terminal — Type.\nnode_id: node ID of the Terminal node\nsource\n# Ribasim.UserDemand — Type.\nactive: whether this node is active and thus demands water realizedbmi: Cumulative inflow volume, for read or reset by BMI only demand: water flux demand of UserDemand per priority over time Each UserDemand has a demand for all priorities, which is 0.0 if it is not provided explicitly. demandreduced: the total demand reduced by allocated flows. This is used for goal programming, and requires separate memory from demand since demands can come from the BMI demanditp: Timeseries interpolation objects for demands demandfromtimeseries: If false the demand comes from the BMI or is fixed allocated: water flux currently allocated to UserDemand per priority returnfactor: 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\nsource\n# Ribasim.config.Config — Method.\nConfig(config_path::AbstractString; kwargs...)\nParse a TOML file to a Config. Keys can be overruled using keyword arguments. To overrule keys from a subsection, e.g. dt from the solver section, use underscores: solver_dt.\nsource",
+ "text": "1.2 Types\n# Ribasim.Allocation — Type.\nObject for all information about allocation allocationnetworkids: The unique sorted allocation network IDs allocation models: The allocation models for the main network and subnetworks corresponding to allocationnetworkids mainnetworkconnections: (fromid, toid) from the main network to the subnetwork per subnetwork priorities: All used priority values. subnetworkdemands: The demand of an edge from the main network to a subnetwork recorddemand: A record of demands and allocated flows for nodes that have these. record_flow: A record of all flows computed by allocation optimization, eventually saved to output file\nsource\n# Ribasim.AllocationModel — Type.\nStore information for a subnetwork used for allocation.\nallocationnetworkid: The ID of this allocation network capacity: The capacity per edge of the allocation network, as constrained by nodes that have a maxflowrate problem: The JuMP.jl model for solving the allocation problem Δt_allocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nallocationnetworkid: the ID of this allocation network p: Ribasim problem parameters Δt_allocation: The timestep between successive allocation solves\nOutputs\nAn AllocationModel object.\nsource\n# Ribasim.Basin — Type.\nRequirements:\n\nMust be positive: precipitation, evaporation, infiltration, drainage\nIndex points to a Basin\nvolume, area, level must all be positive and monotonic increasing.\n\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of vectors or Arrow Tables, and is added to avoid type instabilities. The nodeid are Indices to support fast lookup of e.g. currentlevel using ID.\nif autodiff T = DiffCache{Vector{Float64}} else T = Vector{Float64} end\nsource\n# Ribasim.DiscreteControl — Type.\nnodeid: node ID of the DiscreteControl node; these are not unique but repeated by the amount of conditions of this DiscreteControl node listennodeid: the ID of the node being condition on variable: the name of the variable in the condition greaterthan: The threshold value in the condition conditionvalue: The current value of each condition controlstate: Dictionary: node ID => (control state, control state start) logic_mapping: Dictionary: (control node ID, truth state) => control state record: Namedtuple with discrete control information for results\nsource\n# Ribasim.EdgeMetadata — Type.\nType for storing metadata of edges in the graph: id: ID of the edge (only used for labeling flow output) type: type of the edge allocationnetworkidsource: ID of allocation network where this edge is a source (0 if not a source) fromid: the node ID of the source node toid: the node ID of the destination node allocationflow: whether this edge has a flow in an allocation network node_ids: if this edge has allocation flow, these are all the nodes from the physical layer this edge consists of\nsource\n# Ribasim.FlatVector — Type.\nstruct FlatVector{T} <: AbstractVector{T}\nA FlatVector is an AbstractVector that iterates the T of a Vector{Vector{T}}.\nEach inner vector is assumed to be of equal length.\nIt is similar to Iterators.flatten, though that doesn’t work with the Tables.Column interface, which needs length and getindex support.\nsource\n# Ribasim.FlatVector — Method.\nConstruct a FlatVector from one of the fields of SavedFlow.\nsource\n# Ribasim.FlowBoundary — Type.\nnodeid: node ID of the FlowBoundary node active: whether this node is active and thus contributes flow flowrate: target flow rate\nsource\n# Ribasim.FractionalFlow — Type.\nRequirements:\n\nfrom: must be (TabulatedRatingCurve,) node\nto: must be (Basin,) node\nfraction must be positive.\n\nnodeid: node ID of the TabulatedRatingCurve node fraction: The fraction in [0,1] of flow the node lets through controlmapping: dictionary from (nodeid, controlstate) to fraction\nsource\n# Ribasim.InNeighbors — Type.\nIterate over incoming neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.LevelBoundary — Type.\nnode_id: node ID of the LevelBoundary node active: whether this node is active level: the fixed level of this ‘infinitely big basin’\nsource\n# Ribasim.LevelDemand — Type.\nnodeid: node ID of the LevelDemand node minlevel: The minimum target level of the connected basin(s) max_level: The maximum target level of the connected basin(s) priority: If in a shortage state, the priority of the demand of the connected basin(s)\nsource\n# Ribasim.LinearResistance — Type.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\n\nnodeid: node ID of the LinearResistance node active: whether this node is active and thus contributes flows resistance: the resistance to flow; Q*unlimited = Δh/resistancemax_flow_rate: the maximum flow rate allowed through the node;Q = clamp(Q*unlimited, -max*flow*rate, max*flow*rate) controlmapping: dictionary from (nodeid, controlstate) to resistance and/or active state\nsource\n# Ribasim.ManningResistance — Type.\nThis is a simple Manning-Gauckler reach connection.\n\nLength describes the reach length.\nroughness describes Manning’s n in (SI units).\n\nThe profile is described by a trapezoid:\n \\ / ^\n \\ / |\n \\ / | dz\nbottom \\______/ |\n^ <--->\n| dy\n| <------>\n| width\n|\n|\n+ datum (e.g. MSL)\nWith profile_slope = dy / dz. A rectangular profile requires a slope of 0.0.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\nlength > 0\nroughess > 0\nprofile_width >= 0\nprofile_slope >= 0\n(profilewidth == 0) xor (profileslope == 0)\n\nsource\n# Ribasim.Model — Type.\nModel(config_path::AbstractString)\nModel(config::Config)\nInitialize a Model.\nThe Model struct is an initialized model, combined with the Config used to create it and saved results. The Basic Model Interface (BMI) is implemented on the Model. A Model can be created from the path to a TOML configuration file, or a Config object.\nsource\n# Ribasim.NodeMetadata — Type.\nType for storing metadata of nodes in the graph type: type of the node allocationnetworkid: Allocation network ID (0 if not in subnetwork)\nsource\n# Ribasim.OutNeighbors — Type.\nIterate over outgoing neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.Outlet — Type.\nnodeid: node ID of the Outlet node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the outlet maxflowrate: The maximum flow rate of the outlet controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this outlet is governed by PID control\nsource\n# Ribasim.PidControl — Type.\nPID control currently only supports regulating basin levels.\nnodeid: node ID of the PidControl node active: whether this node is active and thus sets flow rates listennodeid: the id of the basin being controlled pidparams: a vector interpolation for parameters changing over time. The parameters are respectively target, proportional, integral, derivative, where the last three are the coefficients for the PID equation. error: the current error; basintarget - currentlevel\nsource\n# Ribasim.Pump — Type.\nnodeid: node ID of the Pump node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the pump maxflowrate: The maximum flow rate of the pump controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this pump is governed by PID control\nsource\n# Ribasim.SavedFlow — Type.\nIn-memory storage of saved mean flows for writing to results.\n\nflow: The mean flows on all edges\ninflow: The sum of the mean flows coming into each basin\noutflow: The sum of the mean flows going out of each basin\n\nsource\n# Ribasim.Subgrid — Type.\nSubgrid linearly interpolates basin levels.\nsource\n# Ribasim.TabulatedRatingCurve — Type.\nstruct TabulatedRatingCurve{C}\nRating curve from level to flow rate. The rating curve is a lookup table with linear interpolation in between. Relation can be updated in time, which is done by moving data from the time field into the tables, which is done in the update_tabulated_rating_curve callback.\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of Vectors or Arrow Primitives, and is added to avoid type instabilities.\nnodeid: node ID of the TabulatedRatingCurve node active: whether this node is active and thus contributes flows tables: The current Q(h) relationships time: The time table used for updating the tables controlmapping: dictionary from (nodeid, controlstate) to Q(h) and/or active state\nsource\n# Ribasim.Terminal — Type.\nnode_id: node ID of the Terminal node\nsource\n# Ribasim.UserDemand — Type.\nactive: whether this node is active and thus demands water realizedbmi: Cumulative inflow volume, for read or reset by BMI only demand: water flux demand of UserDemand per priority over time Each UserDemand has a demand for all priorities, which is 0.0 if it is not provided explicitly. demandreduced: the total demand reduced by allocated flows. This is used for goal programming, and requires separate memory from demand since demands can come from the BMI demanditp: Timeseries interpolation objects for demands demandfromtimeseries: If false the demand comes from the BMI or is fixed allocated: water flux currently allocated to UserDemand per priority returnfactor: 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\nsource\n# Ribasim.config.Config — Method.\nConfig(config_path::AbstractString; kwargs...)\nParse a TOML file to a Config. Keys can be overruled using keyword arguments. To overrule keys from a subsection, e.g. dt from the solver section, use underscores: solver_dt.\nsource",
"crumbs": [
"Julia core",
"API Reference"
@@ -255,7 +255,7 @@
"href": "build/index.html#functions",
"title": "1 API Reference",
"section": "1.3 Functions",
- "text": "1.3 Functions\n# BasicModelInterface.finalize — Method.\nBMI.finalize(model::Model)::Model\nWrite all results to the configured files.\nsource\n# BasicModelInterface.initialize — Method.\nBMI.initialize(T::Type{Model}, config_path::AbstractString)::Model\nInitialize a Model from the path to the TOML configuration file.\nsource\n# CommonSolve.solve! — Method.\nsolve!(model::Model)::ODESolution\nSolve a Model until the configured endtime.\nsource\n# Ribasim.add_basin_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a basin.\nsource\n# Ribasim.add_constraints_absolute_value! — Method.\nMinimizing |expr| can be achieved by introducing a new variable exprabs and posing the following constraints: exprabs >= expr expr_abs >= -expr\nsource\n# Ribasim.add_constraints_absolute_value_flow_demand! — Method.\nAdd constraints so that variables Fabsflow_demand act as the absolute value of the expression comparing flow to a flow buffer to the flow demand.\nsource\n# Ribasim.add_constraints_absolute_value_level_demand! — Method.\nAdd constraints so that variables Fabslevel_demand act as the absolute value of the expression comparing flow to a basin to its demand.\nsource\n# Ribasim.add_constraints_absolute_value_user_demand! — Method.\nAdd constraints so that variables Fabsuser_demand act as the absolute value of the expression comparing flow to a UserDemand to its demand.\nsource\n# Ribasim.add_constraints_basin_flow! — Method.\nAdd the Basin flow constraints to the allocation problem. The constraint indices are the Basin node IDs.\nConstraint: flow out of basin <= basin capacity\nsource\n# Ribasim.add_constraints_buffer! — Method.\nAdd the buffer outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of buffer <= flow buffer capacity\nsource\n# Ribasim.add_constraints_capacity! — Method.\nAdd the flow capacity constraints to the allocation problem. Only finite capacities get a constraint. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over edge <= edge capacity\nsource\n# Ribasim.add_constraints_conservation_basin! — Method.\nAdd the basin flow conservation constraints to the allocation problem. The constraint indices are Basin node IDs.\nConstraint: sum(flows out of basin) == sum(flows into basin) + flow from storage and vertical fluxes\nsource\n# Ribasim.add_constraints_conservation_flow_demand! — Method.\nAdd the conservation constraints for connector nodes with a flow demand to the allocation problem. The constraint indices are node IDs of the nodes with the flow demand (so not the IDs of the FlowDemand nodes).\nConstraint: flow into node + flow out of buffer = flow out of node + flow into buffer\nsource\n# Ribasim.add_constraints_conservation_subnetwork! — Method.\nAdd the subnetwork inlet flow conservation constraints to the allocation problem. The constraint indices are node IDs subnetwork inlet edge dst IDs.\nConstraint: sum(flows into node) == sum(flows out of node)\nsource\n# Ribasim.add_constraints_flow_demand_outflow! — Method.\nAdd the flow demand node outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of node with flow demand <= ∞ if not at flow demand priority, 0.0 otherwise\nsource\n# Ribasim.add_constraints_fractional_flow! — Method.\nAdd the fractional flow constraints to the allocation problem. The constraint indices are allocation edges over a fractional flow node.\nConstraint: flow after fractional_flow node <= fraction * inflow\nsource\n# Ribasim.add_constraints_source! — Method.\nAdd the source constraints to the allocation problem. The actual threshold values will be set before each allocation solve. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over source edge <= source flow in subnetwork\nsource\n# Ribasim.add_constraints_user_source! — Method.\nAdd capacity constraints to the outflow edge of UserDemand nodes. The constraint indices are the UserDemand node IDs.\nConstraint: flow over UserDemand edge outflow edge <= cumulative return flow from previous priorities\nsource\n# Ribasim.add_flow_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a node with a a flow demand.\nsource\n# Ribasim.add_objective_term! — Function.\nAdd a term to the objective function given by the objective type, depending in the provided flow variable and the associated demand.\nsource\n# Ribasim.add_subnetwork_connections! — Method.\nAdd the edges connecting the main network work to a subnetwork to both the main network and subnetwork allocation network.\nsource\n# Ribasim.add_user_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a UserDemand.\nsource\n# Ribasim.add_variables_absolute_value! — Method.\nCertain allocation distribution types use absolute values in the objective function. Since most optimization packages do not support the absolute value function directly, New variables are introduced that act as the absolute value of an expression by posing the appropriate constraints.\nsource\n# Ribasim.add_variables_basin! — Method.\nAdd the variables for supply/demand of a basin to the problem. The variable indices are the node_ids of the basins with a level demand in the subnetwork.\nsource\n# Ribasim.add_variables_flow! — Method.\nAdd the flow variables F to the allocation problem. The variable indices are (edgesourceid, edgedstid). Non-negativivity constraints are also immediately added to the flow variables.\nsource\n# Ribasim.add_variables_flow_buffer! — Method.\nAdd the variables for supply/demand of a node with a flow demand to the problem. The variable indices are the node_ids of the nodes with a flow demand in the subnetwork.\nsource\n# Ribasim.adjust_capacities_basin! — Method.\nSet the values of the basin outflows. 2 cases:\n\nBefore the first allocation solve, set the capacities to their full capacity if there is surplus storage;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the capacities.\n\nsource\n# Ribasim.adjust_capacities_buffer! — Method.\nIncrease the capacities of the flow buffers of nodes with a flow demand by the inflow to the respective buffers.\nsource\n# Ribasim.adjust_capacities_edge! — Method.\nSet the values of the edge capacities. 2 cases:\n\nBefore the first allocation solve, set the edge capacities to their full capacity;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the edge capacities.\n\nsource\n# Ribasim.adjust_capacities_returnflow! — Method.\nAdd the return flow fraction of the inflow to the UserDemand nodes to the capacity of the outflow source.\nsource\n# Ribasim.adjust_capacities_source! — Method.\nAdjust the source capacities by the flow used from the sources.\nsource\n# Ribasim.adjust_demands_flow! — Method.\nReduce the flow demand based on flow trough the node with the demand. Flow from any priority counts.\nsource\n# Ribasim.adjust_demands_level! — Method.\nSubtract the allocated flow to the basin from its demand, to obtain the reduced demand used for goal programming\nsource\n# Ribasim.adjust_demands_user! — Method.\nSet the demand of the flow demand nodes. 2 cases:\n\nBefore the first allocation solve, set the demands to their full value;\nBefore an allocation solve, subtract the flow trough the node with a flow demand from the total flow demand (which will be used at the priority of the flow demand only).\n\nsource\n# Ribasim.all_neighbor_labels_type — Method.\nGet the in- and outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.allocate! — Method.\nUpdate the allocation optimization problem for the given subnetwork with the problem state and flows, solve the allocation problem and assign the results to the UserDemand.\nsource\n# Ribasim.allocation_graph — Method.\nBuild the graph used for the allocation problem.\nsource\n# Ribasim.allocation_graph_used_nodes! — Method.\nFind all nodes in the subnetwork which will be used in the allocation network. Some nodes are skipped to optimize allocation optimization.\nsource\n# Ribasim.allocation_problem — Method.\nConstruct the allocation problem for the current subnetwork as a JuMP.jl model.\nsource\n# Ribasim.allocation_table — Method.\nCreate an allocation result table for the saved data\nsource\n# Ribasim.assign_allocations! — Method.\nAssign the allocations to the UserDemand as determined by the solution of the allocation problem.\nsource\n# Ribasim.basin_bottom — Method.\nReturn the bottom elevation of the basin with index i, or nothing if it doesn’t exist\nsource\n# Ribasim.basin_table — Method.\nCreate the basin result table from the saved data\nsource\n# Ribasim.create_callbacks — Method.\nCreate the different callbacks that are used to store results and feed the simulation with new data. The different callbacks are combined to a CallbackSet that goes to the integrator. Returns the CallbackSet and the SavedValues for flow.\nsource\n# Ribasim.create_graph — Method.\nReturn a directed metagraph with data of nodes (NodeMetadata): NodeMetadata\nand data of edges (EdgeMetadata): EdgeMetadata\nsource\n# Ribasim.create_storage_tables — Method.\nRead the Basin / profile table and return all area and level and computed storage values\nsource\n# Ribasim.datetime_since — Method.\ndatetime_since(t::Real, t0::DateTime)::DateTime\nConvert a Real that represents the seconds passed since the simulation start to the nearest DateTime. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.datetimes — Method.\nGet all saved times as a Vector{DateTime}\nsource\n# Ribasim.discrete_control_affect! — Method.\nChange parameters based on the control logic.\nsource\n# Ribasim.discrete_control_affect_downcrossing! — Method.\nAn downcrossing means that a condition (always greater than) becomes false.\nsource\n# Ribasim.discrete_control_affect_upcrossing! — Method.\nAn upcrossing means that a condition (always greater than) becomes true.\nsource\n# Ribasim.discrete_control_condition — Method.\nListens for changes in condition truths.\nsource\n# Ribasim.discrete_control_table — Method.\nCreate a discrete control result table from the saved data\nsource\n# Ribasim.expand_logic_mapping — Method.\nReplace the truth states in the logic mapping which contain wildcards with all possible explicit truth states.\nsource\n# Ribasim.find_allocation_graph_edges! — Method.\nThis loop finds allocation network edges in several ways:\n\nBetween allocation network nodes whose equivalent in the subnetwork are directly connected\nBetween allocation network nodes whose equivalent in the subnetwork are connected with one or more allocation network nodes in between\n\nsource\n# Ribasim.find_subnetwork_connections! — Method.\nFind the edges from the main network to a subnetwork.\nsource\n# Ribasim.findlastgroup — Method.\nFor an element id and a vector of elements ids, get the range of indices of the last consecutive block of id. Returns the empty range 1:0 if id is not in ids.\nsource\n# Ribasim.findsorted — Method.\nFind the index of element x in a sorted collection a. Returns the index of x if it exists, or nothing if it doesn’t. If x occurs more than once, throw an error.\nsource\n# Ribasim.flow_table — Method.\nCreate a flow result table from the saved data\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.formulate_flow! — Method.\nConservation of energy for two basins, a and b:\nh_a + v_a^2 / (2 * g) = h_b + v_b^2 / (2 * g) + S_f * L + C / 2 * g * (v_b^2 - v_a^2)\nWhere:\n\nha, hb are the heads at basin a and b.\nva, vb are the velocities at basin a and b.\ng is the gravitational constant.\nS_f is the friction slope.\nC is an expansion or extraction coefficient.\n\nWe assume velocity differences are negligible (va = vb):\nh_a = h_b + S_f * L\nThe friction losses are approximated by the Gauckler-Manning formula:\nQ = A * (1 / n) * R_h^(2/3) * S_f^(1/2)\nWhere:\n\nWhere A is the cross-sectional area.\nV is the cross-sectional average velocity.\nn is the Gauckler-Manning coefficient.\nR_h is the hydraulic radius.\nS_f is the friction slope.\n\nThe hydraulic radius is defined as:\nR_h = A / P\nWhere P is the wetted perimeter.\nThe average of the upstream and downstream water depth is used to compute cross-sectional area and hydraulic radius. This ensures that a basin can receive water after it has gone dry.\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.get_area_and_level — Method.\nCompute the area and level of a basin given its storage. Also returns darea/dlevel as it is needed for the Jacobian.\nsource\n# Ribasim.get_basin_capacity — Method.\nGet the capacity of the basin, i.e. the maximum flow that can be abstracted from the basin if it is in a state of surplus storage (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_basin_data — Method.\nGet several variables associated with a basin:\n\nIts current storage\nThe allocation update interval\nThe influx (sum of instantaneous vertical fluxes of the basin)\nThe index of the connected level_demand node (0 if such a node does not exist)\nThe index of the basin\n\nsource\n# Ribasim.get_basin_demand — Method.\nGet the demand of the basin, i.e. how large a flow the basin needs to get to its minimum target level (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_chunk_sizes — Method.\nGet the chunk sizes for DiffCache; differentiation w.r.t. u and t (the latter only if a Rosenbrock algorithm is used).\nsource\n# Ribasim.get_compressor — Method.\nGet the compressor based on the Results section\nsource\n# Ribasim.get_flow — Method.\nGet the flow over the given edge (val is needed for get_tmp from ForwardDiff.jl).\nsource\n# Ribasim.get_fractional_flow_connected_basins — Method.\nGet the node type specific indices of the fractional flows and basins, that are consecutively connected to a node of given id.\nsource\n# Ribasim.get_jac_prototype — Method.\nGet a sparse matrix whose sparsity matches (with some false positives) the sparsity of the Jacobian of the ODE problem. All nodes are taken into consideration, also the ones that are inactive.\nIn Ribasim the Jacobian is typically sparse because each state only depends on a small number of other states.\nNote: the name ‘prototype’ does not mean this code is a prototype, it comes from the naming convention of this sparsity structure in the differentialequations.jl docs.\nsource\n# Ribasim.get_level — Method.\nGet the current water level of a node ID. The ID can belong to either a Basin or a LevelBoundary. storage: tells ForwardDiff whether this call is for differentiation or not\nsource\n# Ribasim.get_scalar_interpolation — Method.\nLinear interpolation of a scalar with constant extrapolation.\nsource\n# Ribasim.get_storage_from_level — Method.\nGet the storage of a basin from its level.\nsource\n# Ribasim.get_storages_and_levels — Method.\nGet the storage and level of all basins as matrices of nbasin × ntime\nsource\n# Ribasim.get_storages_from_levels — Method.\nCompute the storages of the basins based on the water level of the basins.\nsource\n# Ribasim.get_tstops — Method.\nFrom an iterable of DateTimes, find the times the solver needs to stop\nsource\n# Ribasim.get_value — Method.\nGet a value for a condition. Currently supports getting levels from basins and flows from flow boundaries.\nsource\n# Ribasim.get_Δt — Method.\nGet the time interval between (flow) saves\nsource\n# Ribasim.id_index — Method.\nGet the index of an ID in a set of indices.\nsource\n# Ribasim.indicate_allocation_flow! — Method.\nAdd to the edge metadata that the given edge is used for allocation flow. If the edge does not exist, it is created.\nsource\n# Ribasim.inflow_id — Method.\nGet the unique inneighbor over a flow edge.\nsource\n# Ribasim.inflow_ids — Method.\nGet the inneighbors over flow edges.\nsource\n# Ribasim.inflow_ids_allocation — Method.\nGet the inneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.inneighbor_labels_type — Method.\nGet the inneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.inoutflow_ids — Method.\nGet the in- and outneighbors over flow edges.\nsource\n# Ribasim.integrate_flows! — Method.\nIntegrate flows over the last timestep\nsource\n# Ribasim.is_allocation_source — Method.\nFind out whether the given edge is a source for an allocation network.\nsource\n# Ribasim.is_current_module — Method.\nis_current_module(log::LogMessageType)::Bool\nReturns true if the log message is from the current module or a submodule.\n\nSee https://github.com/JuliaLogging/LoggingExtras.jl/blob/d35e7c8cfc197853ee336ace17182e6ed36dca24/src/CompositionalLoggers/earlyfiltered.jl#L39\nfor the information available in log.\nsource\n# Ribasim.is_flow_constraining — Method.\nWhether the given node node is flow constraining by having a maximum flow rate.\nsource\n# Ribasim.is_flow_direction_constraining — Method.\nWhether the given node is flow direction constraining (only in direction of edges).\nsource\n# Ribasim.load_data — Method.\nload_data(db::DB, config::Config, nodetype::Symbol, kind::Symbol)::Union{Table, Query, Nothing}\nLoad data from Arrow files if available, otherwise the database. Returns either an Arrow.Table, SQLite.Query or nothing if the data is not present.\nsource\n# Ribasim.load_structvector — Method.\nload_structvector(db::DB, config::Config, ::Type{T})::StructVector{T}\nLoad data from Arrow files if available, otherwise the database. Always returns a StructVector of the given struct type T, which is empty if the table is not found. This function validates the schema, and enforces the required sort order.\nsource\n# Ribasim.low_storage_factor — Method.\nIf id is a Basin with storage below the threshold, return a reduction factor != 1\nsource\n# Ribasim.main — Method.\nmain(toml_path::AbstractString)::Cint\nmain(ARGS::Vector{String})::Cint\nmain()::Cint\nThis is the main entry point of the application. Performs argument parsing and sets up logging for both terminal and file. Calls Ribasim.run() and handles exceptions to convert to exit codes.\nsource\n# Ribasim.metadata_from_edge — Method.\nGet the metadata of an edge in the graph from an edge of the underlying DiGraph.\nsource\n# Ribasim.nodefields — Method.\nGet all node fieldnames of the parameter object.\nsource\n# Ribasim.nodetype — Method.\nFrom a SchemaVersion(“ribasim.flowboundary.static”, 1) return (:FlowBoundary, :static)\nsource\n# Ribasim.outflow_id — Method.\nGet the unique outneighbor over a flow edge.\nsource\n# Ribasim.outflow_ids — Method.\nGet the outneighbors over flow edges.\nsource\n# Ribasim.outflow_ids_allocation — Method.\nGet the outneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.outneighbor_labels_type — Method.\nGet the outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.parse_static_and_time — Method.\nProcess the data in the static and time tables for a given node type. The ‘defaults’ named tuple dictates how missing data is filled in. ‘time_interpolatables’ is a vector of Symbols of parameter names for which a time interpolation (linear) object must be constructed. The control mapping for DiscreteControl is also constructed in this function. This function currently does not support node states that are defined by more than one row in a table, as is the case for TabulatedRatingCurve.\nsource\n# Ribasim.pkgversion — Method.\nGet the package version of a given module\nsource\n# Ribasim.process_allocation_graph_edges! — Method.\nFor the composite allocation network edges:\n\nFind out whether they are connected to allocation network nodes on both ends\nCompute their capacity\nFind out their allowed flow direction(s)\n\nsource\n# Ribasim.profile_storage — Method.\nCalculate a profile storage by integrating the areas over the levels\nsource\n# Ribasim.qh_interpolation — Method.\nFrom a table with columns nodeid, flowrate (Q) and level (h), create a LinearInterpolation from level to flow rate for a given node_id.\nsource\n# Ribasim.reduction_factor — Method.\nFunction that goes smoothly from 0 to 1 in the interval [0,threshold], and is constant outside this interval.\nsource\n# Ribasim.run — Method.\nrun(config_file::AbstractString)::Model\nrun(config::Config)::Model\nRun a Model, given a path to a TOML configuration file, or a Config object. Running a model includes initialization, solving to the end with [solve!](@ref) and writing results with write_results.\nsource\n# Ribasim.save_allocation_flows! — Method.\nSave the allocation flows per basin and physical edge.\nsource\n# Ribasim.save_demands_and_allocations! — Method.\nSave the demands and allocated flows for UserDemand and Basin. Note: Basin supply (negative demand) is only saved for the first priority.\nsource\n# Ribasim.save_flow — Method.\nCompute the average flows over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.save_subgrid_level — Method.\nInterpolate the levels and save them to SavedValues\nsource\n# Ribasim.save_vertical_flux — Method.\nCompute the average vertical fluxes over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.scalar_interpolation_derivative — Method.\nDerivative of scalar interpolation.\nsource\n# Ribasim.seconds_since — Method.\nseconds_since(t::DateTime, t0::DateTime)::Float64\nConvert a DateTime to a float that is the number of seconds since the start of the simulation. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.set_capacities_flow_demand_outflow! — Method.\nSet the capacity of the outflow edge from a node with a flow demand:\n\nTo Inf if the current priority is other than the priority of the flow demand\nTo 0.0 if the current priority is equal to the priority of the flow demand\n\nsource\n# Ribasim.set_current_value! — Method.\nFrom a timeseries table time, load the most recent applicable data into table. table must be a NamedTuple of vectors with all variables that must be loaded. The most recent applicable data is non-NaN data for a given ID that is on or before t.\nsource\n# Ribasim.set_flow! — Method.\nSet the given flow q over the edge between the given nodes.\nsource\n# Ribasim.set_fractional_flow_in_allocation! — Method.\nUpdate the fractional flow fractions in an allocation problem.\nsource\n# Ribasim.set_initial_capacities_basin! — Method.\nSet the initial capacity of each basin in the subnetwork as vertical fluxes + the disk of storage above the maximum level / Δt_allocation\nsource\n# Ribasim.set_initial_capacities_buffer! — Method.\nSet the flow buffer of nodes with a flow demand to 0.0\nsource\n# Ribasim.set_initial_capacities_edge! — Method.\nSet the capacities of the allocation flow edges as determined by the smallest maxflowrate of a node on this edge\nsource\n# Ribasim.set_initial_capacities_inlet! — Method.\nSet the capacities of the main network to subnetwork inlets. Per optimization type: internalsources: 0.0 collectdemands: Inf allocate: the total flow allocated to this inlet from the main network\nsource\n# Ribasim.set_initial_capacities_returnflow! — Method.\nSet the initial capacities of the UserDemand return flow sources to 0.\nsource\n# Ribasim.set_initial_capacities_source! — Method.\nSet the capacities of the sources in the subnetwork as the latest instantaneous flow out of the source in the physical layer\nsource\n# Ribasim.set_initial_demands_flow! — Method.\nSet the initial demands of the nodes with a flow demand to the interpolated value from the given timeseries.\nsource\n# Ribasim.set_initial_demands_level! — Method.\nSet the initial demand of each basin in the subnetwork as\n\nvertical fluxes + the disk of missing storage below the minimum level / Δt_allocation\n\nsource\n# Ribasim.set_initial_demands_user! — Method.\nSet the demands of the user demand nodes as given by either a coupled model or a timeseries\nsource\n# Ribasim.set_initial_discrete_controlled_parameters! — Method.\nSet parameters of nodes that are controlled by DiscreteControl to the values corresponding to the initial state of the model.\nsource\n# Ribasim.set_initial_values! — Method.\nSet the initial capacities and demands which are recudes by usage in the adjust*capacities**! and adjust*demands**! functions respectively.\nsource\n# Ribasim.set_is_pid_controlled! — Method.\nSet ispidcontrolled to true for those pumps and outlets that are PID controlled\nsource\n# Ribasim.set_objective_priority! — Method.\nSet the objective for the given priority. For an objective with absolute values this also involves adjusting constraints.\nsource\n# Ribasim.set_static_value! — Method.\nLoad data from a source table static into a destination table. Data is matched based on the node_id, which is sorted.\nsource\n# Ribasim.set_table_row! — Method.\nUpdate table at row index i, with the values of a given row. table must be a NamedTuple of vectors with all variables that must be loaded. The row must contain all the column names that are present in the table. If a value is missing, it is not set.\nsource\n# Ribasim.sorted_table! — Method.\nDepending on if a table can be sorted, either sort it or assert that it is sorted.\nTables loaded from the database into memory can be sorted. Tables loaded from Arrow files are memory mapped and can therefore not be sorted.\nsource\n# Ribasim.tsaves — Method.\nGet all saved times in seconds since start\nsource\n# Ribasim.update_allocation! — Method.\nSolve the allocation problem for all demands and assign allocated abstractions.\nsource\n# Ribasim.update_basin — Method.\nLoad updates from ‘Basin / time’ into the parameters\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for basins connected to eachother via 1 node and possibly a fractional flow node Basins are also assumed to depend on themselves (main diagonal terms)\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for the integral term and the basins on either side of the controlled node\nsource\n# Ribasim.update_tabulated_rating_curve! — Method.\nLoad updates from ‘TabulatedRatingCurve / time’ into the parameters\nsource\n# Ribasim.update_vertical_flux! — Method.\nSmoothly let the evaporation flux go to 0 when at small water depths Currently at less than 0.1 m.\nsource\n# Ribasim.valid_discrete_control — Method.\nCheck:\n\nwhether control states are defined for discrete controlled nodes;\nWhether the supplied truth states have the proper length;\nWhether look_ahead is only supplied for condition variables given by a time-series.\n\nsource\n# Ribasim.valid_edge_types — Method.\nCheck that only supported edge types are declared.\nsource\n# Ribasim.valid_edges — Method.\nTest for each node given its node type whether the nodes that\nare downstream (‘down-edge’) of this node are of an allowed type\nsource\n# Ribasim.valid_flow_rates — Method.\nTest whether static or discrete controlled flow rates are indeed non-negative.\nsource\n# Ribasim.valid_fractional_flow — Method.\nCheck that nodes that have fractional flow outneighbors do not have any other type of outneighbor, that the fractions leaving a node add up to ≈1 and that the fractions are non-negative.\nsource\n# Ribasim.valid_n_neighbors — Method.\nTest for each node given its node type whether it has an allowed number of flow/control inneighbors and outneighbors\nsource\n# Ribasim.valid_profiles — Method.\nCheck whether the profile data has no repeats in the levels and the areas start positive.\nsource\n# Ribasim.valid_sources — Method.\nThe source nodes must only have one allocation outneighbor and no allocation inneighbors.\nsource\n# Ribasim.valid_subgrid — Method.\nValidate the entries for a single subgrid element.\nsource\n# Ribasim.water_balance! — Method.\nThe right hand side function of the system of ODEs set up by Ribasim.\nsource\n# Ribasim.write_arrow — Method.\nWrite a result table to disk as an Arrow file\nsource\n# Ribasim.write_results — Method.\nwrite_results(model::Model)::Model\nWrite all results to the Arrow files as specified in the model configuration.\nsource\n# Ribasim.config.algorithm — Method.\nCreate an OrdinaryDiffEqAlgorithm from solver config\nsource\n# Ribasim.config.convert_dt — Method.\nConvert the dt from our Config to SciML stepsize control arguments\nsource\n# Ribasim.config.convert_saveat — Method.\nConvert the saveat Float64 from our Config to SciML’s saveat\nsource\n# Ribasim.config.input_path — Method.\nConstruct a path relative to both the TOML directory and the optional input_dir\nsource\n# Ribasim.config.results_path — Method.\nConstruct a path relative to both the TOML directory and the optional results_dir\nsource\n# Ribasim.config.snake_case — Method.\nConvert a string from CamelCase to snake_case.\nsource",
+ "text": "1.3 Functions\n# BasicModelInterface.finalize — Method.\nBMI.finalize(model::Model)::Model\nWrite all results to the configured files.\nsource\n# BasicModelInterface.initialize — Method.\nBMI.initialize(T::Type{Model}, config_path::AbstractString)::Model\nInitialize a Model from the path to the TOML configuration file.\nsource\n# CommonSolve.solve! — Method.\nsolve!(model::Model)::ODESolution\nSolve a Model until the configured endtime.\nsource\n# Ribasim.add_basin_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a basin.\nsource\n# Ribasim.add_constraints_absolute_value! — Method.\nMinimizing |expr| can be achieved by introducing a new variable exprabs and posing the following constraints: exprabs >= expr expr_abs >= -expr\nsource\n# Ribasim.add_constraints_absolute_value_flow_demand! — Method.\nAdd constraints so that variables Fabsflow_demand act as the absolute value of the expression comparing flow to a flow buffer to the flow demand.\nsource\n# Ribasim.add_constraints_absolute_value_level_demand! — Method.\nAdd constraints so that variables Fabslevel_demand act as the absolute value of the expression comparing flow to a basin to its demand.\nsource\n# Ribasim.add_constraints_absolute_value_user_demand! — Method.\nAdd constraints so that variables Fabsuser_demand act as the absolute value of the expression comparing flow to a UserDemand to its demand.\nsource\n# Ribasim.add_constraints_basin_flow! — Method.\nAdd the Basin flow constraints to the allocation problem. The constraint indices are the Basin node IDs.\nConstraint: flow out of basin <= basin capacity\nsource\n# Ribasim.add_constraints_buffer! — Method.\nAdd the buffer outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of buffer <= flow buffer capacity\nsource\n# Ribasim.add_constraints_capacity! — Method.\nAdd the flow capacity constraints to the allocation problem. Only finite capacities get a constraint. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over edge <= edge capacity\nsource\n# Ribasim.add_constraints_conservation_basin! — Method.\nAdd the basin flow conservation constraints to the allocation problem. The constraint indices are Basin node IDs.\nConstraint: sum(flows out of basin) == sum(flows into basin) + flow from storage and vertical fluxes\nsource\n# Ribasim.add_constraints_conservation_flow_demand! — Method.\nAdd the conservation constraints for connector nodes with a flow demand to the allocation problem. The constraint indices are node IDs of the nodes with the flow demand (so not the IDs of the FlowDemand nodes).\nConstraint: flow into node + flow out of buffer = flow out of node + flow into buffer\nsource\n# Ribasim.add_constraints_conservation_subnetwork! — Method.\nAdd the subnetwork inlet flow conservation constraints to the allocation problem. The constraint indices are node IDs subnetwork inlet edge dst IDs.\nConstraint: sum(flows into node) == sum(flows out of node)\nsource\n# Ribasim.add_constraints_flow_demand_outflow! — Method.\nAdd the flow demand node outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of node with flow demand <= ∞ if not at flow demand priority, 0.0 otherwise\nsource\n# Ribasim.add_constraints_fractional_flow! — Method.\nAdd the fractional flow constraints to the allocation problem. The constraint indices are allocation edges over a fractional flow node.\nConstraint: flow after fractional_flow node <= fraction * inflow\nsource\n# Ribasim.add_constraints_source! — Method.\nAdd the source constraints to the allocation problem. The actual threshold values will be set before each allocation solve. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over source edge <= source flow in subnetwork\nsource\n# Ribasim.add_constraints_user_source! — Method.\nAdd capacity constraints to the outflow edge of UserDemand nodes. The constraint indices are the UserDemand node IDs.\nConstraint: flow over UserDemand edge outflow edge <= cumulative return flow from previous priorities\nsource\n# Ribasim.add_flow_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a node with a a flow demand.\nsource\n# Ribasim.add_objective_term! — Function.\nAdd a term to the objective function given by the objective type, depending in the provided flow variable and the associated demand.\nsource\n# Ribasim.add_subnetwork_connections! — Method.\nAdd the edges connecting the main network work to a subnetwork to both the main network and subnetwork allocation network.\nsource\n# Ribasim.add_user_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a UserDemand.\nsource\n# Ribasim.add_variables_absolute_value! — Method.\nCertain allocation distribution types use absolute values in the objective function. Since most optimization packages do not support the absolute value function directly, New variables are introduced that act as the absolute value of an expression by posing the appropriate constraints.\nsource\n# Ribasim.add_variables_basin! — Method.\nAdd the variables for supply/demand of a basin to the problem. The variable indices are the node_ids of the basins with a level demand in the subnetwork.\nsource\n# Ribasim.add_variables_flow! — Method.\nAdd the flow variables F to the allocation problem. The variable indices are (edgesourceid, edgedstid). Non-negativivity constraints are also immediately added to the flow variables.\nsource\n# Ribasim.add_variables_flow_buffer! — Method.\nAdd the variables for supply/demand of a node with a flow demand to the problem. The variable indices are the node_ids of the nodes with a flow demand in the subnetwork.\nsource\n# Ribasim.adjust_capacities_basin! — Method.\nSet the values of the basin outflows. 2 cases:\n\nBefore the first allocation solve, set the capacities to their full capacity if there is surplus storage;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the capacities.\n\nsource\n# Ribasim.adjust_capacities_buffer! — Method.\nIncrease the capacities of the flow buffers of nodes with a flow demand by the inflow to the respective buffers.\nsource\n# Ribasim.adjust_capacities_edge! — Method.\nSet the values of the edge capacities. 2 cases:\n\nBefore the first allocation solve, set the edge capacities to their full capacity;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the edge capacities.\n\nsource\n# Ribasim.adjust_capacities_returnflow! — Method.\nAdd the return flow fraction of the inflow to the UserDemand nodes to the capacity of the outflow source.\nsource\n# Ribasim.adjust_capacities_source! — Method.\nAdjust the source capacities by the flow used from the sources.\nsource\n# Ribasim.adjust_demands_flow! — Method.\nReduce the flow demand based on flow trough the node with the demand. Flow from any priority counts.\nsource\n# Ribasim.adjust_demands_level! — Method.\nSubtract the allocated flow to the basin from its demand, to obtain the reduced demand used for goal programming\nsource\n# Ribasim.adjust_demands_user! — Method.\nSet the demand of the flow demand nodes. 2 cases:\n\nBefore the first allocation solve, set the demands to their full value;\nBefore an allocation solve, subtract the flow trough the node with a flow demand from the total flow demand (which will be used at the priority of the flow demand only).\n\nsource\n# Ribasim.all_neighbor_labels_type — Method.\nGet the in- and outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.allocate! — Method.\nUpdate the allocation optimization problem for the given subnetwork with the problem state and flows, solve the allocation problem and assign the results to the UserDemand.\nsource\n# Ribasim.allocation_graph — Method.\nBuild the graph used for the allocation problem.\nsource\n# Ribasim.allocation_graph_used_nodes! — Method.\nFind all nodes in the subnetwork which will be used in the allocation network. Some nodes are skipped to optimize allocation optimization.\nsource\n# Ribasim.allocation_problem — Method.\nConstruct the allocation problem for the current subnetwork as a JuMP.jl model.\nsource\n# Ribasim.allocation_table — Method.\nCreate an allocation result table for the saved data\nsource\n# Ribasim.assign_allocations! — Method.\nAssign the allocations to the UserDemand as determined by the solution of the allocation problem.\nsource\n# Ribasim.basin_bottom — Method.\nReturn the bottom elevation of the basin with index i, or nothing if it doesn’t exist\nsource\n# Ribasim.basin_table — Method.\nCreate the basin result table from the saved data\nsource\n# Ribasim.create_callbacks — Method.\nCreate the different callbacks that are used to store results and feed the simulation with new data. The different callbacks are combined to a CallbackSet that goes to the integrator. Returns the CallbackSet and the SavedValues for flow.\nsource\n# Ribasim.create_graph — Method.\nReturn a directed metagraph with data of nodes (NodeMetadata): NodeMetadata\nand data of edges (EdgeMetadata): EdgeMetadata\nsource\n# Ribasim.create_storage_tables — Method.\nRead the Basin / profile table and return all area and level and computed storage values\nsource\n# Ribasim.datetime_since — Method.\ndatetime_since(t::Real, t0::DateTime)::DateTime\nConvert a Real that represents the seconds passed since the simulation start to the nearest DateTime. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.datetimes — Method.\nGet all saved times as a Vector{DateTime}\nsource\n# Ribasim.discrete_control_affect! — Method.\nChange parameters based on the control logic.\nsource\n# Ribasim.discrete_control_affect_downcrossing! — Method.\nAn downcrossing means that a condition (always greater than) becomes false.\nsource\n# Ribasim.discrete_control_affect_upcrossing! — Method.\nAn upcrossing means that a condition (always greater than) becomes true.\nsource\n# Ribasim.discrete_control_condition — Method.\nListens for changes in condition truths.\nsource\n# Ribasim.discrete_control_table — Method.\nCreate a discrete control result table from the saved data\nsource\n# Ribasim.expand_logic_mapping — Method.\nReplace the truth states in the logic mapping which contain wildcards with all possible explicit truth states.\nsource\n# Ribasim.find_allocation_graph_edges! — Method.\nThis loop finds allocation network edges in several ways:\n\nBetween allocation network nodes whose equivalent in the subnetwork are directly connected\nBetween allocation network nodes whose equivalent in the subnetwork are connected with one or more allocation network nodes in between\n\nsource\n# Ribasim.find_subnetwork_connections! — Method.\nFind the edges from the main network to a subnetwork.\nsource\n# Ribasim.findlastgroup — Method.\nFor an element id and a vector of elements ids, get the range of indices of the last consecutive block of id. Returns the empty range 1:0 if id is not in ids.\nsource\n# Ribasim.findsorted — Method.\nFind the index of element x in a sorted collection a. Returns the index of x if it exists, or nothing if it doesn’t. If x occurs more than once, throw an error.\nsource\n# Ribasim.flow_table — Method.\nCreate a flow result table from the saved data\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.formulate_flow! — Method.\nConservation of energy for two basins, a and b:\nh_a + v_a^2 / (2 * g) = h_b + v_b^2 / (2 * g) + S_f * L + C / 2 * g * (v_b^2 - v_a^2)\nWhere:\n\nha, hb are the heads at basin a and b.\nva, vb are the velocities at basin a and b.\ng is the gravitational constant.\nS_f is the friction slope.\nC is an expansion or extraction coefficient.\n\nWe assume velocity differences are negligible (va = vb):\nh_a = h_b + S_f * L\nThe friction losses are approximated by the Gauckler-Manning formula:\nQ = A * (1 / n) * R_h^(2/3) * S_f^(1/2)\nWhere:\n\nWhere A is the cross-sectional area.\nV is the cross-sectional average velocity.\nn is the Gauckler-Manning coefficient.\nR_h is the hydraulic radius.\nS_f is the friction slope.\n\nThe hydraulic radius is defined as:\nR_h = A / P\nWhere P is the wetted perimeter.\nThe average of the upstream and downstream water depth is used to compute cross-sectional area and hydraulic radius. This ensures that a basin can receive water after it has gone dry.\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.get_area_and_level — Method.\nCompute the area and level of a basin given its storage. Also returns darea/dlevel as it is needed for the Jacobian.\nsource\n# Ribasim.get_basin_capacity — Method.\nGet the capacity of the basin, i.e. the maximum flow that can be abstracted from the basin if it is in a state of surplus storage (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_basin_data — Method.\nGet several variables associated with a basin:\n\nIts current storage\nThe allocation update interval\nThe influx (sum of instantaneous vertical fluxes of the basin)\nThe index of the connected level_demand node (0 if such a node does not exist)\nThe index of the basin\n\nsource\n# Ribasim.get_basin_demand — Method.\nGet the demand of the basin, i.e. how large a flow the basin needs to get to its minimum target level (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_chunk_sizes — Method.\nGet the chunk sizes for DiffCache; differentiation w.r.t. u and t (the latter only if a Rosenbrock algorithm is used).\nsource\n# Ribasim.get_compressor — Method.\nGet the compressor based on the Results section\nsource\n# Ribasim.get_flow — Method.\nGet the flow over the given edge (val is needed for get_tmp from ForwardDiff.jl).\nsource\n# Ribasim.get_fractional_flow_connected_basins — Method.\nGet the node type specific indices of the fractional flows and basins, that are consecutively connected to a node of given id.\nsource\n# Ribasim.get_jac_prototype — Method.\nGet a sparse matrix whose sparsity matches (with some false positives) the sparsity of the Jacobian of the ODE problem. All nodes are taken into consideration, also the ones that are inactive.\nIn Ribasim the Jacobian is typically sparse because each state only depends on a small number of other states.\nNote: the name ‘prototype’ does not mean this code is a prototype, it comes from the naming convention of this sparsity structure in the differentialequations.jl docs.\nsource\n# Ribasim.get_level — Method.\nGet the current water level of a node ID. The ID can belong to either a Basin or a LevelBoundary. storage: tells ForwardDiff whether this call is for differentiation or not\nsource\n# Ribasim.get_scalar_interpolation — Method.\nLinear interpolation of a scalar with constant extrapolation.\nsource\n# Ribasim.get_storage_from_level — Method.\nGet the storage of a basin from its level.\nsource\n# Ribasim.get_storages_and_levels — Method.\nGet the storage and level of all basins as matrices of nbasin × ntime\nsource\n# Ribasim.get_storages_from_levels — Method.\nCompute the storages of the basins based on the water level of the basins.\nsource\n# Ribasim.get_tstops — Method.\nFrom an iterable of DateTimes, find the times the solver needs to stop\nsource\n# Ribasim.get_value — Method.\nGet a value for a condition. Currently supports getting levels from basins and flows from flow boundaries.\nsource\n# Ribasim.get_Δt — Method.\nGet the time interval between (flow) saves\nsource\n# Ribasim.id_index — Method.\nGet the index of an ID in a set of indices.\nsource\n# Ribasim.indicate_allocation_flow! — Method.\nAdd to the edge metadata that the given edge is used for allocation flow. If the edge does not exist, it is created.\nsource\n# Ribasim.inflow_id — Method.\nGet the unique inneighbor over a flow edge.\nsource\n# Ribasim.inflow_ids — Method.\nGet the inneighbors over flow edges.\nsource\n# Ribasim.inflow_ids_allocation — Method.\nGet the inneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.inneighbor_labels_type — Method.\nGet the inneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.inoutflow_ids — Method.\nGet the in- and outneighbors over flow edges.\nsource\n# Ribasim.integrate_flows! — Method.\nIntegrate flows over the last timestep\nsource\n# Ribasim.is_allocation_source — Method.\nFind out whether the given edge is a source for an allocation network.\nsource\n# Ribasim.is_current_module — Method.\nis_current_module(log::LogMessageType)::Bool\nReturns true if the log message is from the current module or a submodule.\n\nSee https://github.com/JuliaLogging/LoggingExtras.jl/blob/d35e7c8cfc197853ee336ace17182e6ed36dca24/src/CompositionalLoggers/earlyfiltered.jl#L39\nfor the information available in log.\nsource\n# Ribasim.is_flow_constraining — Method.\nWhether the given node node is flow constraining by having a maximum flow rate.\nsource\n# Ribasim.is_flow_direction_constraining — Method.\nWhether the given node is flow direction constraining (only in direction of edges).\nsource\n# Ribasim.load_data — Method.\nload_data(db::DB, config::Config, nodetype::Symbol, kind::Symbol)::Union{Table, Query, Nothing}\nLoad data from Arrow files if available, otherwise the database. Returns either an Arrow.Table, SQLite.Query or nothing if the data is not present.\nsource\n# Ribasim.load_structvector — Method.\nload_structvector(db::DB, config::Config, ::Type{T})::StructVector{T}\nLoad data from Arrow files if available, otherwise the database. Always returns a StructVector of the given struct type T, which is empty if the table is not found. This function validates the schema, and enforces the required sort order.\nsource\n# Ribasim.low_storage_factor — Method.\nIf id is a Basin with storage below the threshold, return a reduction factor != 1\nsource\n# Ribasim.main — Method.\nmain(toml_path::AbstractString)::Cint\nmain(ARGS::Vector{String})::Cint\nmain()::Cint\nThis is the main entry point of the application. Performs argument parsing and sets up logging for both terminal and file. Calls Ribasim.run() and handles exceptions to convert to exit codes.\nsource\n# Ribasim.metadata_from_edge — Method.\nGet the metadata of an edge in the graph from an edge of the underlying DiGraph.\nsource\n# Ribasim.nodefields — Method.\nGet all node fieldnames of the parameter object.\nsource\n# Ribasim.nodetype — Method.\nFrom a SchemaVersion(“ribasim.flowboundary.static”, 1) return (:FlowBoundary, :static)\nsource\n# Ribasim.outflow_id — Method.\nGet the unique outneighbor over a flow edge.\nsource\n# Ribasim.outflow_ids — Method.\nGet the outneighbors over flow edges.\nsource\n# Ribasim.outflow_ids_allocation — Method.\nGet the outneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.outneighbor_labels_type — Method.\nGet the outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.parse_static_and_time — Method.\nProcess the data in the static and time tables for a given node type. The ‘defaults’ named tuple dictates how missing data is filled in. ‘time_interpolatables’ is a vector of Symbols of parameter names for which a time interpolation (linear) object must be constructed. The control mapping for DiscreteControl is also constructed in this function. This function currently does not support node states that are defined by more than one row in a table, as is the case for TabulatedRatingCurve.\nsource\n# Ribasim.pkgversion — Method.\nGet the package version of a given module\nsource\n# Ribasim.process_allocation_graph_edges! — Method.\nFor the composite allocation network edges:\n\nFind out whether they are connected to allocation network nodes on both ends\nCompute their capacity\nFind out their allowed flow direction(s)\n\nsource\n# Ribasim.profile_storage — Method.\nCalculate a profile storage by integrating the areas over the levels\nsource\n# Ribasim.qh_interpolation — Method.\nFrom a table with columns nodeid, flowrate (Q) and level (h), create a LinearInterpolation from level to flow rate for a given node_id.\nsource\n# Ribasim.reduction_factor — Method.\nFunction that goes smoothly from 0 to 1 in the interval [0,threshold], and is constant outside this interval.\nsource\n# Ribasim.run — Method.\nrun(config_file::AbstractString)::Model\nrun(config::Config)::Model\nRun a Model, given a path to a TOML configuration file, or a Config object. Running a model includes initialization, solving to the end with [solve!](@ref) and writing results with write_results.\nsource\n# Ribasim.save_allocation_flows! — Method.\nSave the allocation flows per basin and physical edge.\nsource\n# Ribasim.save_demands_and_allocations! — Method.\nSave the demands and allocated flows for UserDemand and Basin. Note: Basin supply (negative demand) is only saved for the first priority.\nsource\n# Ribasim.save_flow — Method.\nCompute the average flows over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.save_subgrid_level — Method.\nInterpolate the levels and save them to SavedValues\nsource\n# Ribasim.save_vertical_flux — Method.\nCompute the average vertical fluxes over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.scalar_interpolation_derivative — Method.\nDerivative of scalar interpolation.\nsource\n# Ribasim.seconds — Method.\nseconds(period::Millisecond)::Float64\nConvert a period of type Millisecond to a Float64 in seconds. You get Millisecond objects when subtracting two DateTime objects. Dates.value returns the number of milliseconds.\nsource\n# Ribasim.seconds_since — Method.\nseconds_since(t::DateTime, t0::DateTime)::Float64\nConvert a DateTime to a float that is the number of seconds since the start of the simulation. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.set_capacities_flow_demand_outflow! — Method.\nSet the capacity of the outflow edge from a node with a flow demand:\n\nTo Inf if the current priority is other than the priority of the flow demand\nTo 0.0 if the current priority is equal to the priority of the flow demand\n\nsource\n# Ribasim.set_current_value! — Method.\nFrom a timeseries table time, load the most recent applicable data into table. table must be a NamedTuple of vectors with all variables that must be loaded. The most recent applicable data is non-NaN data for a given ID that is on or before t.\nsource\n# Ribasim.set_flow! — Method.\nSet the given flow q over the edge between the given nodes.\nsource\n# Ribasim.set_fractional_flow_in_allocation! — Method.\nUpdate the fractional flow fractions in an allocation problem.\nsource\n# Ribasim.set_initial_capacities_basin! — Method.\nSet the initial capacity of each basin in the subnetwork as vertical fluxes + the disk of storage above the maximum level / Δt_allocation\nsource\n# Ribasim.set_initial_capacities_buffer! — Method.\nSet the flow buffer of nodes with a flow demand to 0.0\nsource\n# Ribasim.set_initial_capacities_edge! — Method.\nSet the capacities of the allocation flow edges as determined by the smallest maxflowrate of a node on this edge\nsource\n# Ribasim.set_initial_capacities_inlet! — Method.\nSet the capacities of the main network to subnetwork inlets. Per optimization type: internalsources: 0.0 collectdemands: Inf allocate: the total flow allocated to this inlet from the main network\nsource\n# Ribasim.set_initial_capacities_returnflow! — Method.\nSet the initial capacities of the UserDemand return flow sources to 0.\nsource\n# Ribasim.set_initial_capacities_source! — Method.\nSet the capacities of the sources in the subnetwork as the latest instantaneous flow out of the source in the physical layer\nsource\n# Ribasim.set_initial_demands_flow! — Method.\nSet the initial demands of the nodes with a flow demand to the interpolated value from the given timeseries.\nsource\n# Ribasim.set_initial_demands_level! — Method.\nSet the initial demand of each basin in the subnetwork as\n\nvertical fluxes + the disk of missing storage below the minimum level / Δt_allocation\n\nsource\n# Ribasim.set_initial_demands_user! — Method.\nSet the demands of the user demand nodes as given by either a coupled model or a timeseries\nsource\n# Ribasim.set_initial_discrete_controlled_parameters! — Method.\nSet parameters of nodes that are controlled by DiscreteControl to the values corresponding to the initial state of the model.\nsource\n# Ribasim.set_initial_values! — Method.\nSet the initial capacities and demands which are recudes by usage in the adjust*capacities**! and adjust*demands**! functions respectively.\nsource\n# Ribasim.set_is_pid_controlled! — Method.\nSet ispidcontrolled to true for those pumps and outlets that are PID controlled\nsource\n# Ribasim.set_objective_priority! — Method.\nSet the objective for the given priority. For an objective with absolute values this also involves adjusting constraints.\nsource\n# Ribasim.set_static_value! — Method.\nLoad data from a source table static into a destination table. Data is matched based on the node_id, which is sorted.\nsource\n# Ribasim.set_table_row! — Method.\nUpdate table at row index i, with the values of a given row. table must be a NamedTuple of vectors with all variables that must be loaded. The row must contain all the column names that are present in the table. If a value is missing, it is not set.\nsource\n# Ribasim.sorted_table! — Method.\nDepending on if a table can be sorted, either sort it or assert that it is sorted.\nTables loaded from the database into memory can be sorted. Tables loaded from Arrow files are memory mapped and can therefore not be sorted.\nsource\n# Ribasim.tsaves — Method.\nGet all saved times in seconds since start\nsource\n# Ribasim.update_allocation! — Method.\nSolve the allocation problem for all demands and assign allocated abstractions.\nsource\n# Ribasim.update_basin — Method.\nLoad updates from ‘Basin / time’ into the parameters\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for basins connected to eachother via 1 node and possibly a fractional flow node Basins are also assumed to depend on themselves (main diagonal terms)\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for the integral term and the basins on either side of the controlled node\nsource\n# Ribasim.update_tabulated_rating_curve! — Method.\nLoad updates from ‘TabulatedRatingCurve / time’ into the parameters\nsource\n# Ribasim.update_vertical_flux! — Method.\nSmoothly let the evaporation flux go to 0 when at small water depths Currently at less than 0.1 m.\nsource\n# Ribasim.valid_discrete_control — Method.\nCheck:\n\nwhether control states are defined for discrete controlled nodes;\nWhether the supplied truth states have the proper length;\nWhether look_ahead is only supplied for condition variables given by a time-series.\n\nsource\n# Ribasim.valid_edge_types — Method.\nCheck that only supported edge types are declared.\nsource\n# Ribasim.valid_edges — Method.\nTest for each node given its node type whether the nodes that\nare downstream (‘down-edge’) of this node are of an allowed type\nsource\n# Ribasim.valid_flow_rates — Method.\nTest whether static or discrete controlled flow rates are indeed non-negative.\nsource\n# Ribasim.valid_fractional_flow — Method.\nCheck that nodes that have fractional flow outneighbors do not have any other type of outneighbor, that the fractions leaving a node add up to ≈1 and that the fractions are non-negative.\nsource\n# Ribasim.valid_n_neighbors — Method.\nTest for each node given its node type whether it has an allowed number of flow/control inneighbors and outneighbors\nsource\n# Ribasim.valid_profiles — Method.\nCheck whether the profile data has no repeats in the levels and the areas start positive.\nsource\n# Ribasim.valid_sources — Method.\nThe source nodes must only have one allocation outneighbor and no allocation inneighbors.\nsource\n# Ribasim.valid_subgrid — Method.\nValidate the entries for a single subgrid element.\nsource\n# Ribasim.water_balance! — Method.\nThe right hand side function of the system of ODEs set up by Ribasim.\nsource\n# Ribasim.write_arrow — Method.\nWrite a result table to disk as an Arrow file\nsource\n# Ribasim.write_results — Method.\nwrite_results(model::Model)::Model\nWrite all results to the Arrow files as specified in the model configuration.\nsource\n# Ribasim.config.algorithm — Method.\nCreate an OrdinaryDiffEqAlgorithm from solver config\nsource\n# Ribasim.config.convert_dt — Method.\nConvert the dt from our Config to SciML stepsize control arguments\nsource\n# Ribasim.config.convert_saveat — Method.\nConvert the saveat Float64 from our Config to SciML’s saveat\nsource\n# Ribasim.config.input_path — Method.\nConstruct a path relative to both the TOML directory and the optional input_dir\nsource\n# Ribasim.config.results_path — Method.\nConstruct a path relative to both the TOML directory and the optional results_dir\nsource\n# Ribasim.config.snake_case — Method.\nConvert a string from CamelCase to snake_case.\nsource",
"crumbs": [
"Julia core",
"API Reference"
@@ -288,7 +288,7 @@
"href": "build/index.html#index",
"title": "1 API Reference",
"section": "1.6 Index",
- "text": "1.6 Index\n\nRibasim.Ribasim\nRibasim.config\nRibasim.config.algorithms\nRibasim.Allocation\nRibasim.AllocationModel\nRibasim.AllocationModel\nRibasim.Basin\nRibasim.DiscreteControl\nRibasim.EdgeMetadata\nRibasim.FlatVector\nRibasim.FlowBoundary\nRibasim.FractionalFlow\nRibasim.InNeighbors\nRibasim.LevelBoundary\nRibasim.LevelDemand\nRibasim.LinearResistance\nRibasim.ManningResistance\nRibasim.Model\nRibasim.NodeMetadata\nRibasim.OutNeighbors\nRibasim.Outlet\nRibasim.PidControl\nRibasim.Pump\nRibasim.Subgrid\nRibasim.TabulatedRatingCurve\nRibasim.Terminal\nRibasim.UserDemand\nRibasim.config.Config\nBasicModelInterface.finalize\nBasicModelInterface.initialize\nCommonSolve.solve!\nRibasim.add_basin_term!\nRibasim.add_constraints_absolute_value!\nRibasim.add_constraints_absolute_value_flow_demand!\nRibasim.add_constraints_absolute_value_level_demand!\nRibasim.add_constraints_absolute_value_user_demand!\nRibasim.add_constraints_basin_flow!\nRibasim.add_constraints_buffer!\nRibasim.add_constraints_capacity!\nRibasim.add_constraints_conservation_basin!\nRibasim.add_constraints_conservation_flow_demand!\nRibasim.add_constraints_conservation_subnetwork!\nRibasim.add_constraints_flow_demand_outflow!\nRibasim.add_constraints_fractional_flow!\nRibasim.add_constraints_source!\nRibasim.add_constraints_user_source!\nRibasim.add_flow_demand_term!\nRibasim.add_objective_term!\nRibasim.add_subnetwork_connections!\nRibasim.add_user_demand_term!\nRibasim.add_variables_absolute_value!\nRibasim.add_variables_basin!\nRibasim.add_variables_flow!\nRibasim.add_variables_flow_buffer!\nRibasim.adjust_capacities_basin!\nRibasim.adjust_capacities_buffer!\nRibasim.adjust_capacities_edge!\nRibasim.adjust_capacities_returnflow!\nRibasim.adjust_capacities_source!\nRibasim.adjust_demands_flow!\nRibasim.adjust_demands_level!\nRibasim.adjust_demands_user!\nRibasim.all_neighbor_labels_type\nRibasim.allocate!\nRibasim.allocation_graph\nRibasim.allocation_graph_used_nodes!\nRibasim.allocation_problem\nRibasim.allocation_table\nRibasim.assign_allocations!\nRibasim.basin_bottom\nRibasim.basin_table\nRibasim.config.algorithm\nRibasim.config.convert_dt\nRibasim.config.convert_saveat\nRibasim.config.input_path\nRibasim.config.results_path\nRibasim.config.snake_case\nRibasim.create_callbacks\nRibasim.create_graph\nRibasim.create_storage_tables\nRibasim.datetime_since\nRibasim.datetimes\nRibasim.discrete_control_affect!\nRibasim.discrete_control_affect_downcrossing!\nRibasim.discrete_control_affect_upcrossing!\nRibasim.discrete_control_condition\nRibasim.discrete_control_table\nRibasim.expand_logic_mapping\nRibasim.find_allocation_graph_edges!\nRibasim.find_subnetwork_connections!\nRibasim.findlastgroup\nRibasim.findsorted\nRibasim.flow_table\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.get_area_and_level\nRibasim.get_basin_capacity\nRibasim.get_basin_data\nRibasim.get_basin_demand\nRibasim.get_chunk_sizes\nRibasim.get_compressor\nRibasim.get_flow\nRibasim.get_fractional_flow_connected_basins\nRibasim.get_jac_prototype\nRibasim.get_level\nRibasim.get_scalar_interpolation\nRibasim.get_storage_from_level\nRibasim.get_storages_and_levels\nRibasim.get_storages_from_levels\nRibasim.get_tstops\nRibasim.get_value\nRibasim.get_Δt\nRibasim.id_index\nRibasim.indicate_allocation_flow!\nRibasim.inflow_id\nRibasim.inflow_ids\nRibasim.inflow_ids_allocation\nRibasim.inneighbor_labels_type\nRibasim.inoutflow_ids\nRibasim.integrate_flows!\nRibasim.is_allocation_source\nRibasim.is_current_module\nRibasim.is_flow_constraining\nRibasim.is_flow_direction_constraining\nRibasim.load_data\nRibasim.load_structvector\nRibasim.low_storage_factor\nRibasim.main\nRibasim.metadata_from_edge\nRibasim.nodefields\nRibasim.nodetype\nRibasim.outflow_id\nRibasim.outflow_ids\nRibasim.outflow_ids_allocation\nRibasim.outneighbor_labels_type\nRibasim.parse_static_and_time\nRibasim.pkgversion\nRibasim.process_allocation_graph_edges!\nRibasim.profile_storage\nRibasim.qh_interpolation\nRibasim.reduction_factor\nRibasim.run\nRibasim.save_allocation_flows!\nRibasim.save_demands_and_allocations!\nRibasim.save_flow\nRibasim.save_subgrid_level\nRibasim.save_vertical_flux\nRibasim.scalar_interpolation_derivative\nRibasim.seconds_since\nRibasim.set_capacities_flow_demand_outflow!\nRibasim.set_current_value!\nRibasim.set_flow!\nRibasim.set_fractional_flow_in_allocation!\nRibasim.set_initial_capacities_basin!\nRibasim.set_initial_capacities_buffer!\nRibasim.set_initial_capacities_edge!\nRibasim.set_initial_capacities_inlet!\nRibasim.set_initial_capacities_returnflow!\nRibasim.set_initial_capacities_source!\nRibasim.set_initial_demands_flow!\nRibasim.set_initial_demands_level!\nRibasim.set_initial_demands_user!\nRibasim.set_initial_discrete_controlled_parameters!\nRibasim.set_initial_values!\nRibasim.set_is_pid_controlled!\nRibasim.set_objective_priority!\nRibasim.set_static_value!\nRibasim.set_table_row!\nRibasim.sorted_table!\nRibasim.tsaves\nRibasim.update_allocation!\nRibasim.update_basin\nRibasim.update_jac_prototype!\nRibasim.update_jac_prototype!\nRibasim.update_tabulated_rating_curve!\nRibasim.update_vertical_flux!\nRibasim.valid_discrete_control\nRibasim.valid_edge_types\nRibasim.valid_edges\nRibasim.valid_flow_rates\nRibasim.valid_fractional_flow\nRibasim.valid_n_neighbors\nRibasim.valid_profiles\nRibasim.valid_sources\nRibasim.valid_subgrid\nRibasim.water_balance!\nRibasim.write_arrow\nRibasim.write_results\nRibasim.config.@addfields\nRibasim.config.@addnodetypes",
+ "text": "1.6 Index\n\nRibasim.Ribasim\nRibasim.config\nRibasim.config.algorithms\nRibasim.Allocation\nRibasim.AllocationModel\nRibasim.AllocationModel\nRibasim.Basin\nRibasim.DiscreteControl\nRibasim.EdgeMetadata\nRibasim.FlatVector\nRibasim.FlatVector\nRibasim.FlowBoundary\nRibasim.FractionalFlow\nRibasim.InNeighbors\nRibasim.LevelBoundary\nRibasim.LevelDemand\nRibasim.LinearResistance\nRibasim.ManningResistance\nRibasim.Model\nRibasim.NodeMetadata\nRibasim.OutNeighbors\nRibasim.Outlet\nRibasim.PidControl\nRibasim.Pump\nRibasim.SavedFlow\nRibasim.Subgrid\nRibasim.TabulatedRatingCurve\nRibasim.Terminal\nRibasim.UserDemand\nRibasim.config.Config\nBasicModelInterface.finalize\nBasicModelInterface.initialize\nCommonSolve.solve!\nRibasim.add_basin_term!\nRibasim.add_constraints_absolute_value!\nRibasim.add_constraints_absolute_value_flow_demand!\nRibasim.add_constraints_absolute_value_level_demand!\nRibasim.add_constraints_absolute_value_user_demand!\nRibasim.add_constraints_basin_flow!\nRibasim.add_constraints_buffer!\nRibasim.add_constraints_capacity!\nRibasim.add_constraints_conservation_basin!\nRibasim.add_constraints_conservation_flow_demand!\nRibasim.add_constraints_conservation_subnetwork!\nRibasim.add_constraints_flow_demand_outflow!\nRibasim.add_constraints_fractional_flow!\nRibasim.add_constraints_source!\nRibasim.add_constraints_user_source!\nRibasim.add_flow_demand_term!\nRibasim.add_objective_term!\nRibasim.add_subnetwork_connections!\nRibasim.add_user_demand_term!\nRibasim.add_variables_absolute_value!\nRibasim.add_variables_basin!\nRibasim.add_variables_flow!\nRibasim.add_variables_flow_buffer!\nRibasim.adjust_capacities_basin!\nRibasim.adjust_capacities_buffer!\nRibasim.adjust_capacities_edge!\nRibasim.adjust_capacities_returnflow!\nRibasim.adjust_capacities_source!\nRibasim.adjust_demands_flow!\nRibasim.adjust_demands_level!\nRibasim.adjust_demands_user!\nRibasim.all_neighbor_labels_type\nRibasim.allocate!\nRibasim.allocation_graph\nRibasim.allocation_graph_used_nodes!\nRibasim.allocation_problem\nRibasim.allocation_table\nRibasim.assign_allocations!\nRibasim.basin_bottom\nRibasim.basin_table\nRibasim.config.algorithm\nRibasim.config.convert_dt\nRibasim.config.convert_saveat\nRibasim.config.input_path\nRibasim.config.results_path\nRibasim.config.snake_case\nRibasim.create_callbacks\nRibasim.create_graph\nRibasim.create_storage_tables\nRibasim.datetime_since\nRibasim.datetimes\nRibasim.discrete_control_affect!\nRibasim.discrete_control_affect_downcrossing!\nRibasim.discrete_control_affect_upcrossing!\nRibasim.discrete_control_condition\nRibasim.discrete_control_table\nRibasim.expand_logic_mapping\nRibasim.find_allocation_graph_edges!\nRibasim.find_subnetwork_connections!\nRibasim.findlastgroup\nRibasim.findsorted\nRibasim.flow_table\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.get_area_and_level\nRibasim.get_basin_capacity\nRibasim.get_basin_data\nRibasim.get_basin_demand\nRibasim.get_chunk_sizes\nRibasim.get_compressor\nRibasim.get_flow\nRibasim.get_fractional_flow_connected_basins\nRibasim.get_jac_prototype\nRibasim.get_level\nRibasim.get_scalar_interpolation\nRibasim.get_storage_from_level\nRibasim.get_storages_and_levels\nRibasim.get_storages_from_levels\nRibasim.get_tstops\nRibasim.get_value\nRibasim.get_Δt\nRibasim.id_index\nRibasim.indicate_allocation_flow!\nRibasim.inflow_id\nRibasim.inflow_ids\nRibasim.inflow_ids_allocation\nRibasim.inneighbor_labels_type\nRibasim.inoutflow_ids\nRibasim.integrate_flows!\nRibasim.is_allocation_source\nRibasim.is_current_module\nRibasim.is_flow_constraining\nRibasim.is_flow_direction_constraining\nRibasim.load_data\nRibasim.load_structvector\nRibasim.low_storage_factor\nRibasim.main\nRibasim.metadata_from_edge\nRibasim.nodefields\nRibasim.nodetype\nRibasim.outflow_id\nRibasim.outflow_ids\nRibasim.outflow_ids_allocation\nRibasim.outneighbor_labels_type\nRibasim.parse_static_and_time\nRibasim.pkgversion\nRibasim.process_allocation_graph_edges!\nRibasim.profile_storage\nRibasim.qh_interpolation\nRibasim.reduction_factor\nRibasim.run\nRibasim.save_allocation_flows!\nRibasim.save_demands_and_allocations!\nRibasim.save_flow\nRibasim.save_subgrid_level\nRibasim.save_vertical_flux\nRibasim.scalar_interpolation_derivative\nRibasim.seconds\nRibasim.seconds_since\nRibasim.set_capacities_flow_demand_outflow!\nRibasim.set_current_value!\nRibasim.set_flow!\nRibasim.set_fractional_flow_in_allocation!\nRibasim.set_initial_capacities_basin!\nRibasim.set_initial_capacities_buffer!\nRibasim.set_initial_capacities_edge!\nRibasim.set_initial_capacities_inlet!\nRibasim.set_initial_capacities_returnflow!\nRibasim.set_initial_capacities_source!\nRibasim.set_initial_demands_flow!\nRibasim.set_initial_demands_level!\nRibasim.set_initial_demands_user!\nRibasim.set_initial_discrete_controlled_parameters!\nRibasim.set_initial_values!\nRibasim.set_is_pid_controlled!\nRibasim.set_objective_priority!\nRibasim.set_static_value!\nRibasim.set_table_row!\nRibasim.sorted_table!\nRibasim.tsaves\nRibasim.update_allocation!\nRibasim.update_basin\nRibasim.update_jac_prototype!\nRibasim.update_jac_prototype!\nRibasim.update_tabulated_rating_curve!\nRibasim.update_vertical_flux!\nRibasim.valid_discrete_control\nRibasim.valid_edge_types\nRibasim.valid_edges\nRibasim.valid_flow_rates\nRibasim.valid_fractional_flow\nRibasim.valid_n_neighbors\nRibasim.valid_profiles\nRibasim.valid_sources\nRibasim.valid_subgrid\nRibasim.water_balance!\nRibasim.write_arrow\nRibasim.write_results\nRibasim.config.@addfields\nRibasim.config.@addnodetypes",
"crumbs": [
"Julia core",
"API Reference"
@@ -732,7 +732,7 @@
"href": "core/usage.html#basin---basin.arrow",
"title": "Usage",
"section": "20.1 Basin - basin.arrow",
- "text": "20.1 Basin - basin.arrow\nThe Basin table contains:\n\nResults of the storage and level of each basin, which are instantaneous values;\nResults of the vertical fluxes on each basin, which are mean values over the saveat intervals. In the time column the start of the period is indicated.\nThe final state of the model is not part of this file, and will be placed in a separate output state file in the future.\n\nThe initial condition is also written to the file.\n\n\n\ncolumn\ntype\nunit\n\n\n\n\ntime\nDateTime\n-\n\n\nnode_id\nInt32\n-\n\n\nstorage\nFloat64\n\\(m^3\\)\n\n\nlevel\nFloat64\n\\(m\\)\n\n\nprecipitation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nevaporation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ndrainage\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ninfiltration\nFloat64\n\\(m^3 s^{-1}\\)\n\n\n\nThe table is sorted by time, and per time it is sorted by node_id.",
+ "text": "20.1 Basin - basin.arrow\nThe Basin table contains:\n\nResults of the storage and level of each Basin, which are instantaneous values;\nResults of the fluxes on each Basin, which are mean values over the saveat intervals. In the time column the start of the period is indicated.\nThe initial condition is written to the file, but the final state is not. It will be placed in a separate output state file in the future.\nThe inflow_rate and outflow_rate are the sum of the flows from other nodes into and out of the Basin respectively. The actual flows determine in which term they are counted, not the edge direction.\nThe storage_rate is flow that adds to the storage in the Basin, increasing the water level. In the equations below this number is split out into two non-negative numbers, storage_increase and storage_decrease.\nThe balance_error is the difference of all Basin inflows (total_inflow) and outflows (total_outflow), that is (inflow_rate + precipitation + drainage - storage_increase) - (outflow_rate + evaporation + infiltration - storage_decrease). It can be used to check if the numerical error when solving the water balance is sufficiently small.\nThe relative_error is the fraction of the balance_error over the mean of the total_inflow and total_outflow.\n\n\n\n\ncolumn\ntype\nunit\n\n\n\n\ntime\nDateTime\n-\n\n\nnode_id\nInt32\n-\n\n\nstorage\nFloat64\n\\(m^3\\)\n\n\nlevel\nFloat64\n\\(m\\)\n\n\ninflow_rate\nFloat64\n\\(m^3 s^{-1}\\)\n\n\noutflow_rate\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nstorage_rate\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nprecipitation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nevaporation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ndrainage\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ninfiltration\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nbalance_error\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nrelative_error\nFloat64\n-\n\n\n\nThe table is sorted by time, and per time it is sorted by node_id.",
"crumbs": [
"Julia core",
"Usage"
@@ -819,7 +819,7 @@
"href": "core/equations.html#sec-reduction_factor",
"title": "Equations",
"section": "2.1 The reduction factor",
- "text": "2.1 The reduction factor\nAt several points in the equations below a reduction factor is used. This is a term that makes certain transitions more smooth, for instance when a pump stops providing water when its source basin dries up. The reduction factor is given by\n\\[\\begin{align}\n \\phi(x; p) =\n \\begin{cases}\n 0 &\\text{if}\\quad x < 0 \\\\\n -2 \\left(\\frac{x}{p}\\right)^3 + 3\\left(\\frac{x}{p}\\right)^2 &\\text{if}\\quad 0 \\le x \\le p \\\\\n 1 &\\text{if}\\quad x > p\n \\end{cases}\n\\end{align}\\]\nHere \\(p > 0\\) is the threshold value which determines the interval \\([0,p]\\) of the smooth transition between \\(0\\) and \\(1\\), see the plot below.\n\n\nCode\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef f(x, p = 3):\n x_scaled = x / p\n phi = (-2 * x_scaled + 3) * x_scaled**2\n phi = np.where(x < 0, 0, phi)\n phi = np.where(x > p, 1, phi)\n\n return phi\n\nfontsize = 15\np = 3\nN = 100\nx_min = -1\nx_max = 4\nx = np.linspace(x_min,x_max,N)\nphi = f(x,p)\n\nfig,ax = plt.subplots(dpi=80)\nax.plot(x,phi)\n\ny_lim = ax.get_ylim()\n\nax.set_xticks([0,p], [0,\"$p$\"], fontsize=fontsize)\nax.set_yticks([0,1], [0,1], fontsize=fontsize)\nax.hlines([0,1],x_min,x_max, color = \"k\", ls = \":\", zorder=-1)\nax.vlines([0,p], *y_lim, color = \"k\", ls = \":\")\nax.set_xlim(x_min,x_max)\nax.set_xlabel(\"$x$\", fontsize=fontsize)\nax.set_ylabel(\"$\\phi(x;p)$\", fontsize=fontsize)\nax.set_ylim(y_lim)\n\nfig.tight_layout()\nplt.show()\n\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n/tmp/ipykernel_5182/665069857.py:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'",
+ "text": "2.1 The reduction factor\nAt several points in the equations below a reduction factor is used. This is a term that makes certain transitions more smooth, for instance when a pump stops providing water when its source basin dries up. The reduction factor is given by\n\\[\\begin{align}\n \\phi(x; p) =\n \\begin{cases}\n 0 &\\text{if}\\quad x < 0 \\\\\n -2 \\left(\\frac{x}{p}\\right)^3 + 3\\left(\\frac{x}{p}\\right)^2 &\\text{if}\\quad 0 \\le x \\le p \\\\\n 1 &\\text{if}\\quad x > p\n \\end{cases}\n\\end{align}\\]\nHere \\(p > 0\\) is the threshold value which determines the interval \\([0,p]\\) of the smooth transition between \\(0\\) and \\(1\\), see the plot below.\n\n\nCode\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef f(x, p = 3):\n x_scaled = x / p\n phi = (-2 * x_scaled + 3) * x_scaled**2\n phi = np.where(x < 0, 0, phi)\n phi = np.where(x > p, 1, phi)\n\n return phi\n\nfontsize = 15\np = 3\nN = 100\nx_min = -1\nx_max = 4\nx = np.linspace(x_min,x_max,N)\nphi = f(x,p)\n\nfig,ax = plt.subplots(dpi=80)\nax.plot(x,phi)\n\ny_lim = ax.get_ylim()\n\nax.set_xticks([0,p], [0,\"$p$\"], fontsize=fontsize)\nax.set_yticks([0,1], [0,1], fontsize=fontsize)\nax.hlines([0,1],x_min,x_max, color = \"k\", ls = \":\", zorder=-1)\nax.vlines([0,p], *y_lim, color = \"k\", ls = \":\")\nax.set_xlim(x_min,x_max)\nax.set_xlabel(\"$x$\", fontsize=fontsize)\nax.set_ylabel(\"$\\phi(x;p)$\", fontsize=fontsize)\nax.set_ylim(y_lim)\n\nfig.tight_layout()\nplt.show()\n\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n/tmp/ipykernel_5125/665069857.py:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'",
"crumbs": [
"Julia core",
"Equations"
@@ -973,7 +973,7 @@
"href": "core/allocation.html#example",
"title": "Allocation",
"section": "4.4 Example",
- "text": "4.4 Example\nThe following is an example of an optimization problem for the example shown here:\n\n\nCode\nusing Ribasim\nusing Ribasim: NodeID\nusing SQLite\nusing ComponentArrays: ComponentVector\n\ntoml_path = normpath(@__DIR__, \"../../generated_testmodels/allocation_example/ribasim.toml\")\np = Ribasim.Model(toml_path).integrator.p\nu = ComponentVector(; storage = zeros(length(p.basin.node_id)))\n\nallocation_model = p.allocation.allocation_models[1]\nt = 0.0\npriority_idx = 1\n\nRibasim.set_flow!(p.graph, NodeID(:FlowBoundary, 1), NodeID(:Basin, 2), 1.0)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\nRibasim.set_initial_values!(allocation_model, p, u, t)\n\nprintln(p.allocation.allocation_models[1].problem)\n\n\nMin F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #6] + F_abs_user_demand[UserDemand #13] + F_abs_level_demand[Basin #2] + F_abs_level_demand[Basin #12] + F_abs_level_demand[Basin #5]\nSubject to\n abs_positive_user_demand[UserDemand #3] : -F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_positive_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_negative_user_demand[UserDemand #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n F_basin_out[Basin #12] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n F[(UserDemand #3, Basin #2)] ≤ 0\n F[(UserDemand #6, Basin #5)] ≤ 0\n F[(UserDemand #13, Terminal #10)] ≤ 0\n fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : F[(TabulatedRatingCurve #7, Basin #12)] - 0.4 F[(Basin #5, TabulatedRatingCurve #7)] ≤ 0\n basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0\n flow_conservation_basin[Basin #2] : -F[(UserDemand #3, Basin #2)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] - F[(Basin #5, Basin #2)] + F[(Basin #2, UserDemand #3)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0\n flow_conservation_basin[Basin #12] : -F[(TabulatedRatingCurve #7, Basin #12)] + F[(Basin #12, UserDemand #13)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\n flow_conservation_basin[Basin #5] : F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F[(Basin #5, TabulatedRatingCurve #7)] - F[(UserDemand #6, Basin #5)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0",
+ "text": "4.4 Example\nThe following is an example of an optimization problem for the example shown here:\n\n\nCode\nusing Ribasim\nusing Ribasim: NodeID\nusing SQLite\nusing ComponentArrays: ComponentVector\n\ntoml_path = normpath(@__DIR__, \"../../generated_testmodels/allocation_example/ribasim.toml\")\np = Ribasim.Model(toml_path).integrator.p\nu = ComponentVector(; storage = zeros(length(p.basin.node_id)))\n\nallocation_model = p.allocation.allocation_models[1]\nt = 0.0\npriority_idx = 1\n\nRibasim.set_flow!(p.graph, NodeID(:FlowBoundary, 1), NodeID(:Basin, 2), 1.0)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\nRibasim.set_initial_values!(allocation_model, p, u, t)\n\nprintln(p.allocation.allocation_models[1].problem)\n\n\nMin F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #6] + F_abs_level_demand[Basin #5] + F_abs_level_demand[Basin #12] + F_abs_level_demand[Basin #2]\nSubject to\n abs_positive_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_positive_user_demand[UserDemand #3] : -F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_negative_user_demand[UserDemand #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n F_basin_out[Basin #12] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n F[(UserDemand #13, Terminal #10)] ≤ 0\n F[(UserDemand #3, Basin #2)] ≤ 0\n F[(UserDemand #6, Basin #5)] ≤ 0\n fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : -0.4 F[(Basin #5, TabulatedRatingCurve #7)] + F[(TabulatedRatingCurve #7, Basin #12)] ≤ 0\n basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0\n flow_conservation_basin[Basin #5] : F[(Basin #5, UserDemand #6)] + F[(Basin #5, TabulatedRatingCurve #7)] - F[(Basin #2, Basin #5)] - F[(UserDemand #6, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation_basin[Basin #12] : F[(Basin #12, UserDemand #13)] - F[(TabulatedRatingCurve #7, Basin #12)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\n flow_conservation_basin[Basin #2] : -F[(FlowBoundary #1, Basin #2)] - F[(UserDemand #3, Basin #2)] + F[(Basin #2, Basin #5)] + F[(Basin #2, UserDemand #3)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0",
"crumbs": [
"Julia core",
"Allocation"
Here \(p > 0\) is the threshold value which determines the interval \([0,p]\) of the smooth transition between \(0\) and \(1\), see the plot below.
-Code
import numpy as np
@@ -475,7 +475,7 @@
diff --git a/core/usage.html b/core/usage.html
index 65684b556..83cc801b0 100644
--- a/core/usage.html
+++ b/core/usage.html
@@ -2082,11 +2082,14 @@ 20 Results
20.1 Basin - basin.arrow
The Basin table contains:
-
-
- Results of the storage and level of each basin, which are instantaneous values; -
- Results of the vertical fluxes on each basin, which are mean values over the
saveat
intervals. In the time column the start of the period is indicated.
- - The final state of the model is not part of this file, and will be placed in a separate output state file in the future. +
- Results of the storage and level of each Basin, which are instantaneous values; +
- Results of the fluxes on each Basin, which are mean values over the
saveat
intervals. In the time column the start of the period is indicated.
+ - The initial condition is written to the file, but the final state is not. It will be placed in a separate output state file in the future. +
- The
inflow_rate
andoutflow_rate
are the sum of the flows from other nodes into and out of the Basin respectively. The actual flows determine in which term they are counted, not the edge direction.
+ - The
storage_rate
is flow that adds to the storage in the Basin, increasing the water level. In the equations below this number is split out into two non-negative numbers,storage_increase
andstorage_decrease
.
+ - The
balance_error
is the difference of all Basin inflows (total_inflow
) and outflows (total_outflow
), that is (inflow_rate
+precipitation
+drainage
-storage_increase
) - (outflow_rate
+evaporation
+infiltration
-storage_decrease
). It can be used to check if the numerical error when solving the water balance is sufficiently small.
+ - The
relative_error
is the fraction of thebalance_error
over the mean of thetotal_inflow
andtotal_outflow
.
The initial condition is also written to the file.
precipitation | +inflow_rate | Float64 | \(m^3 s^{-1}\) |
evaporation | +outflow_rate | Float64 | \(m^3 s^{-1}\) |
drainage | +storage_rate | +Float64 | +\(m^3 s^{-1}\) | +
precipitation | +Float64 | +\(m^3 s^{-1}\) | +|
evaporation | Float64 | \(m^3 s^{-1}\) | |
drainage | +Float64 | +\(m^3 s^{-1}\) | +|
infiltration | Float64 | \(m^3 s^{-1}\) | |
balance_error | +Float64 | +\(m^3 s^{-1}\) | +|
relative_error | +Float64 | +- | +
The table is sorted by time, and per time it is sorted by node_id
.
Validation
1 Connectivity
In the table below, each column shows which node types are allowed to be downstream (or ‘down-control’) of the node type at the top of the column.
-Code
using Ribasim
@@ -546,7 +546,7 @@ 1 Connectivity
2 Neighbor amounts
The table below shows for each node type between which bounds the amount of in- and outneighbors must be, for both flow and control edges.
-
+
Code
= Vector{String}()
diff --git a/python/examples_files/figure-html/cell-59-output-1.png b/python/examples_files/figure-html/cell-59-output-1.png
index ce06f995b..9f7e6fea8 100644
Binary files a/python/examples_files/figure-html/cell-59-output-1.png and b/python/examples_files/figure-html/cell-59-output-1.png differ
diff --git a/python/test-models.html b/python/test-models.html
index 733519cce..feefadd22 100644
--- a/python/test-models.html
+++ b/python/test-models.html
@@ -227,7 +227,7 @@ flow_in_min Test models
Ribasim developers use the following models in their testbench and in order to test new features.
-
+
Code
import ribasim_testmodels
diff --git a/search.json b/search.json
index e1acee0c1..a96c642ac 100644
--- a/search.json
+++ b/search.json
@@ -244,7 +244,7 @@
"href": "build/index.html#types",
"title": "1 API Reference",
"section": "1.2 Types",
- "text": "1.2 Types\n# Ribasim.Allocation — Type.\nObject for all information about allocation allocationnetworkids: The unique sorted allocation network IDs allocation models: The allocation models for the main network and subnetworks corresponding to allocationnetworkids mainnetworkconnections: (fromid, toid) from the main network to the subnetwork per subnetwork priorities: All used priority values. subnetworkdemands: The demand of an edge from the main network to a subnetwork recorddemand: A record of demands and allocated flows for nodes that have these. record_flow: A record of all flows computed by allocation optimization, eventually saved to output file\nsource\n# Ribasim.AllocationModel — Type.\nStore information for a subnetwork used for allocation.\nallocationnetworkid: The ID of this allocation network capacity: The capacity per edge of the allocation network, as constrained by nodes that have a maxflowrate problem: The JuMP.jl model for solving the allocation problem Δt_allocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nallocationnetworkid: the ID of this allocation network p: Ribasim problem parameters Δt_allocation: The timestep between successive allocation solves\nOutputs\nAn AllocationModel object.\nsource\n# Ribasim.Basin — Type.\nRequirements:\n\nMust be positive: precipitation, evaporation, infiltration, drainage\nIndex points to a Basin\nvolume, area, level must all be positive and monotonic increasing.\n\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of vectors or Arrow Tables, and is added to avoid type instabilities. The nodeid are Indices to support fast lookup of e.g. currentlevel using ID.\nif autodiff T = DiffCache{Vector{Float64}} else T = Vector{Float64} end\nsource\n# Ribasim.DiscreteControl — Type.\nnodeid: node ID of the DiscreteControl node; these are not unique but repeated by the amount of conditions of this DiscreteControl node listennodeid: the ID of the node being condition on variable: the name of the variable in the condition greaterthan: The threshold value in the condition conditionvalue: The current value of each condition controlstate: Dictionary: node ID => (control state, control state start) logic_mapping: Dictionary: (control node ID, truth state) => control state record: Namedtuple with discrete control information for results\nsource\n# Ribasim.EdgeMetadata — Type.\nType for storing metadata of edges in the graph: id: ID of the edge (only used for labeling flow output) type: type of the edge allocationnetworkidsource: ID of allocation network where this edge is a source (0 if not a source) fromid: the node ID of the source node toid: the node ID of the destination node allocationflow: whether this edge has a flow in an allocation network node_ids: if this edge has allocation flow, these are all the nodes from the physical layer this edge consists of\nsource\n# Ribasim.FlatVector — Type.\nstruct FlatVector{T} <: AbstractVector{T}\nA FlatVector is an AbstractVector that iterates the T of a Vector{Vector{T}}.\nEach inner vector is assumed to be of equal length.\nIt is similar to Iterators.flatten, though that doesn’t work with the Tables.Column interface, which needs length and getindex support.\nsource\n# Ribasim.FlowBoundary — Type.\nnodeid: node ID of the FlowBoundary node active: whether this node is active and thus contributes flow flowrate: target flow rate\nsource\n# Ribasim.FractionalFlow — Type.\nRequirements:\n\nfrom: must be (TabulatedRatingCurve,) node\nto: must be (Basin,) node\nfraction must be positive.\n\nnodeid: node ID of the TabulatedRatingCurve node fraction: The fraction in [0,1] of flow the node lets through controlmapping: dictionary from (nodeid, controlstate) to fraction\nsource\n# Ribasim.InNeighbors — Type.\nIterate over incoming neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.LevelBoundary — Type.\nnode_id: node ID of the LevelBoundary node active: whether this node is active level: the fixed level of this ‘infinitely big basin’\nsource\n# Ribasim.LevelDemand — Type.\nnodeid: node ID of the LevelDemand node minlevel: The minimum target level of the connected basin(s) max_level: The maximum target level of the connected basin(s) priority: If in a shortage state, the priority of the demand of the connected basin(s)\nsource\n# Ribasim.LinearResistance — Type.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\n\nnodeid: node ID of the LinearResistance node active: whether this node is active and thus contributes flows resistance: the resistance to flow; Q*unlimited = Δh/resistancemax_flow_rate: the maximum flow rate allowed through the node;Q = clamp(Q*unlimited, -max*flow*rate, max*flow*rate) controlmapping: dictionary from (nodeid, controlstate) to resistance and/or active state\nsource\n# Ribasim.ManningResistance — Type.\nThis is a simple Manning-Gauckler reach connection.\n\nLength describes the reach length.\nroughness describes Manning’s n in (SI units).\n\nThe profile is described by a trapezoid:\n \\ / ^\n \\ / |\n \\ / | dz\nbottom \\______/ |\n^ <--->\n| dy\n| <------>\n| width\n|\n|\n+ datum (e.g. MSL)\nWith profile_slope = dy / dz. A rectangular profile requires a slope of 0.0.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\nlength > 0\nroughess > 0\nprofile_width >= 0\nprofile_slope >= 0\n(profilewidth == 0) xor (profileslope == 0)\n\nsource\n# Ribasim.Model — Type.\nModel(config_path::AbstractString)\nModel(config::Config)\nInitialize a Model.\nThe Model struct is an initialized model, combined with the Config used to create it and saved results. The Basic Model Interface (BMI) is implemented on the Model. A Model can be created from the path to a TOML configuration file, or a Config object.\nsource\n# Ribasim.NodeMetadata — Type.\nType for storing metadata of nodes in the graph type: type of the node allocationnetworkid: Allocation network ID (0 if not in subnetwork)\nsource\n# Ribasim.OutNeighbors — Type.\nIterate over outgoing neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.Outlet — Type.\nnodeid: node ID of the Outlet node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the outlet maxflowrate: The maximum flow rate of the outlet controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this outlet is governed by PID control\nsource\n# Ribasim.PidControl — Type.\nPID control currently only supports regulating basin levels.\nnodeid: node ID of the PidControl node active: whether this node is active and thus sets flow rates listennodeid: the id of the basin being controlled pidparams: a vector interpolation for parameters changing over time. The parameters are respectively target, proportional, integral, derivative, where the last three are the coefficients for the PID equation. error: the current error; basintarget - currentlevel\nsource\n# Ribasim.Pump — Type.\nnodeid: node ID of the Pump node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the pump maxflowrate: The maximum flow rate of the pump controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this pump is governed by PID control\nsource\n# Ribasim.Subgrid — Type.\nSubgrid linearly interpolates basin levels.\nsource\n# Ribasim.TabulatedRatingCurve — Type.\nstruct TabulatedRatingCurve{C}\nRating curve from level to flow rate. The rating curve is a lookup table with linear interpolation in between. Relation can be updated in time, which is done by moving data from the time field into the tables, which is done in the update_tabulated_rating_curve callback.\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of Vectors or Arrow Primitives, and is added to avoid type instabilities.\nnodeid: node ID of the TabulatedRatingCurve node active: whether this node is active and thus contributes flows tables: The current Q(h) relationships time: The time table used for updating the tables controlmapping: dictionary from (nodeid, controlstate) to Q(h) and/or active state\nsource\n# Ribasim.Terminal — Type.\nnode_id: node ID of the Terminal node\nsource\n# Ribasim.UserDemand — Type.\nactive: whether this node is active and thus demands water realizedbmi: Cumulative inflow volume, for read or reset by BMI only demand: water flux demand of UserDemand per priority over time Each UserDemand has a demand for all priorities, which is 0.0 if it is not provided explicitly. demandreduced: the total demand reduced by allocated flows. This is used for goal programming, and requires separate memory from demand since demands can come from the BMI demanditp: Timeseries interpolation objects for demands demandfromtimeseries: If false the demand comes from the BMI or is fixed allocated: water flux currently allocated to UserDemand per priority returnfactor: 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\nsource\n# Ribasim.config.Config — Method.\nConfig(config_path::AbstractString; kwargs...)\nParse a TOML file to a Config. Keys can be overruled using keyword arguments. To overrule keys from a subsection, e.g. dt from the solver section, use underscores: solver_dt.\nsource",
+ "text": "1.2 Types\n# Ribasim.Allocation — Type.\nObject for all information about allocation allocationnetworkids: The unique sorted allocation network IDs allocation models: The allocation models for the main network and subnetworks corresponding to allocationnetworkids mainnetworkconnections: (fromid, toid) from the main network to the subnetwork per subnetwork priorities: All used priority values. subnetworkdemands: The demand of an edge from the main network to a subnetwork recorddemand: A record of demands and allocated flows for nodes that have these. record_flow: A record of all flows computed by allocation optimization, eventually saved to output file\nsource\n# Ribasim.AllocationModel — Type.\nStore information for a subnetwork used for allocation.\nallocationnetworkid: The ID of this allocation network capacity: The capacity per edge of the allocation network, as constrained by nodes that have a maxflowrate problem: The JuMP.jl model for solving the allocation problem Δt_allocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nallocationnetworkid: the ID of this allocation network p: Ribasim problem parameters Δt_allocation: The timestep between successive allocation solves\nOutputs\nAn AllocationModel object.\nsource\n# Ribasim.Basin — Type.\nRequirements:\n\nMust be positive: precipitation, evaporation, infiltration, drainage\nIndex points to a Basin\nvolume, area, level must all be positive and monotonic increasing.\n\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of vectors or Arrow Tables, and is added to avoid type instabilities. The nodeid are Indices to support fast lookup of e.g. currentlevel using ID.\nif autodiff T = DiffCache{Vector{Float64}} else T = Vector{Float64} end\nsource\n# Ribasim.DiscreteControl — Type.\nnodeid: node ID of the DiscreteControl node; these are not unique but repeated by the amount of conditions of this DiscreteControl node listennodeid: the ID of the node being condition on variable: the name of the variable in the condition greaterthan: The threshold value in the condition conditionvalue: The current value of each condition controlstate: Dictionary: node ID => (control state, control state start) logic_mapping: Dictionary: (control node ID, truth state) => control state record: Namedtuple with discrete control information for results\nsource\n# Ribasim.EdgeMetadata — Type.\nType for storing metadata of edges in the graph: id: ID of the edge (only used for labeling flow output) type: type of the edge allocationnetworkidsource: ID of allocation network where this edge is a source (0 if not a source) fromid: the node ID of the source node toid: the node ID of the destination node allocationflow: whether this edge has a flow in an allocation network node_ids: if this edge has allocation flow, these are all the nodes from the physical layer this edge consists of\nsource\n# Ribasim.FlatVector — Type.\nstruct FlatVector{T} <: AbstractVector{T}\nA FlatVector is an AbstractVector that iterates the T of a Vector{Vector{T}}.\nEach inner vector is assumed to be of equal length.\nIt is similar to Iterators.flatten, though that doesn’t work with the Tables.Column interface, which needs length and getindex support.\nsource\n# Ribasim.FlatVector — Method.\nConstruct a FlatVector from one of the fields of SavedFlow.\nsource\n# Ribasim.FlowBoundary — Type.\nnodeid: node ID of the FlowBoundary node active: whether this node is active and thus contributes flow flowrate: target flow rate\nsource\n# Ribasim.FractionalFlow — Type.\nRequirements:\n\nfrom: must be (TabulatedRatingCurve,) node\nto: must be (Basin,) node\nfraction must be positive.\n\nnodeid: node ID of the TabulatedRatingCurve node fraction: The fraction in [0,1] of flow the node lets through controlmapping: dictionary from (nodeid, controlstate) to fraction\nsource\n# Ribasim.InNeighbors — Type.\nIterate over incoming neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.LevelBoundary — Type.\nnode_id: node ID of the LevelBoundary node active: whether this node is active level: the fixed level of this ‘infinitely big basin’\nsource\n# Ribasim.LevelDemand — Type.\nnodeid: node ID of the LevelDemand node minlevel: The minimum target level of the connected basin(s) max_level: The maximum target level of the connected basin(s) priority: If in a shortage state, the priority of the demand of the connected basin(s)\nsource\n# Ribasim.LinearResistance — Type.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\n\nnodeid: node ID of the LinearResistance node active: whether this node is active and thus contributes flows resistance: the resistance to flow; Q*unlimited = Δh/resistancemax_flow_rate: the maximum flow rate allowed through the node;Q = clamp(Q*unlimited, -max*flow*rate, max*flow*rate) controlmapping: dictionary from (nodeid, controlstate) to resistance and/or active state\nsource\n# Ribasim.ManningResistance — Type.\nThis is a simple Manning-Gauckler reach connection.\n\nLength describes the reach length.\nroughness describes Manning’s n in (SI units).\n\nThe profile is described by a trapezoid:\n \\ / ^\n \\ / |\n \\ / | dz\nbottom \\______/ |\n^ <--->\n| dy\n| <------>\n| width\n|\n|\n+ datum (e.g. MSL)\nWith profile_slope = dy / dz. A rectangular profile requires a slope of 0.0.\nRequirements:\n\nfrom: must be (Basin,) node\nto: must be (Basin,) node\nlength > 0\nroughess > 0\nprofile_width >= 0\nprofile_slope >= 0\n(profilewidth == 0) xor (profileslope == 0)\n\nsource\n# Ribasim.Model — Type.\nModel(config_path::AbstractString)\nModel(config::Config)\nInitialize a Model.\nThe Model struct is an initialized model, combined with the Config used to create it and saved results. The Basic Model Interface (BMI) is implemented on the Model. A Model can be created from the path to a TOML configuration file, or a Config object.\nsource\n# Ribasim.NodeMetadata — Type.\nType for storing metadata of nodes in the graph type: type of the node allocationnetworkid: Allocation network ID (0 if not in subnetwork)\nsource\n# Ribasim.OutNeighbors — Type.\nIterate over outgoing neighbors of a given label in a MetaGraph, only for edges of edge_type\nsource\n# Ribasim.Outlet — Type.\nnodeid: node ID of the Outlet node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the outlet maxflowrate: The maximum flow rate of the outlet controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this outlet is governed by PID control\nsource\n# Ribasim.PidControl — Type.\nPID control currently only supports regulating basin levels.\nnodeid: node ID of the PidControl node active: whether this node is active and thus sets flow rates listennodeid: the id of the basin being controlled pidparams: a vector interpolation for parameters changing over time. The parameters are respectively target, proportional, integral, derivative, where the last three are the coefficients for the PID equation. error: the current error; basintarget - currentlevel\nsource\n# Ribasim.Pump — Type.\nnodeid: node ID of the Pump node active: whether this node is active and thus contributes flow flowrate: target flow rate minflowrate: The minimal flow rate of the pump maxflowrate: The maximum flow rate of the pump controlmapping: dictionary from (nodeid, controlstate) to target flow rate ispid_controlled: whether the flow rate of this pump is governed by PID control\nsource\n# Ribasim.SavedFlow — Type.\nIn-memory storage of saved mean flows for writing to results.\n\nflow: The mean flows on all edges\ninflow: The sum of the mean flows coming into each basin\noutflow: The sum of the mean flows going out of each basin\n\nsource\n# Ribasim.Subgrid — Type.\nSubgrid linearly interpolates basin levels.\nsource\n# Ribasim.TabulatedRatingCurve — Type.\nstruct TabulatedRatingCurve{C}\nRating curve from level to flow rate. The rating curve is a lookup table with linear interpolation in between. Relation can be updated in time, which is done by moving data from the time field into the tables, which is done in the update_tabulated_rating_curve callback.\nType parameter C indicates the content backing the StructVector, which can be a NamedTuple of Vectors or Arrow Primitives, and is added to avoid type instabilities.\nnodeid: node ID of the TabulatedRatingCurve node active: whether this node is active and thus contributes flows tables: The current Q(h) relationships time: The time table used for updating the tables controlmapping: dictionary from (nodeid, controlstate) to Q(h) and/or active state\nsource\n# Ribasim.Terminal — Type.\nnode_id: node ID of the Terminal node\nsource\n# Ribasim.UserDemand — Type.\nactive: whether this node is active and thus demands water realizedbmi: Cumulative inflow volume, for read or reset by BMI only demand: water flux demand of UserDemand per priority over time Each UserDemand has a demand for all priorities, which is 0.0 if it is not provided explicitly. demandreduced: the total demand reduced by allocated flows. This is used for goal programming, and requires separate memory from demand since demands can come from the BMI demanditp: Timeseries interpolation objects for demands demandfromtimeseries: If false the demand comes from the BMI or is fixed allocated: water flux currently allocated to UserDemand per priority returnfactor: 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\nsource\n# Ribasim.config.Config — Method.\nConfig(config_path::AbstractString; kwargs...)\nParse a TOML file to a Config. Keys can be overruled using keyword arguments. To overrule keys from a subsection, e.g. dt from the solver section, use underscores: solver_dt.\nsource",
"crumbs": [
"Julia core",
"API Reference"
@@ -255,7 +255,7 @@
"href": "build/index.html#functions",
"title": "1 API Reference",
"section": "1.3 Functions",
- "text": "1.3 Functions\n# BasicModelInterface.finalize — Method.\nBMI.finalize(model::Model)::Model\nWrite all results to the configured files.\nsource\n# BasicModelInterface.initialize — Method.\nBMI.initialize(T::Type{Model}, config_path::AbstractString)::Model\nInitialize a Model from the path to the TOML configuration file.\nsource\n# CommonSolve.solve! — Method.\nsolve!(model::Model)::ODESolution\nSolve a Model until the configured endtime.\nsource\n# Ribasim.add_basin_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a basin.\nsource\n# Ribasim.add_constraints_absolute_value! — Method.\nMinimizing |expr| can be achieved by introducing a new variable exprabs and posing the following constraints: exprabs >= expr expr_abs >= -expr\nsource\n# Ribasim.add_constraints_absolute_value_flow_demand! — Method.\nAdd constraints so that variables Fabsflow_demand act as the absolute value of the expression comparing flow to a flow buffer to the flow demand.\nsource\n# Ribasim.add_constraints_absolute_value_level_demand! — Method.\nAdd constraints so that variables Fabslevel_demand act as the absolute value of the expression comparing flow to a basin to its demand.\nsource\n# Ribasim.add_constraints_absolute_value_user_demand! — Method.\nAdd constraints so that variables Fabsuser_demand act as the absolute value of the expression comparing flow to a UserDemand to its demand.\nsource\n# Ribasim.add_constraints_basin_flow! — Method.\nAdd the Basin flow constraints to the allocation problem. The constraint indices are the Basin node IDs.\nConstraint: flow out of basin <= basin capacity\nsource\n# Ribasim.add_constraints_buffer! — Method.\nAdd the buffer outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of buffer <= flow buffer capacity\nsource\n# Ribasim.add_constraints_capacity! — Method.\nAdd the flow capacity constraints to the allocation problem. Only finite capacities get a constraint. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over edge <= edge capacity\nsource\n# Ribasim.add_constraints_conservation_basin! — Method.\nAdd the basin flow conservation constraints to the allocation problem. The constraint indices are Basin node IDs.\nConstraint: sum(flows out of basin) == sum(flows into basin) + flow from storage and vertical fluxes\nsource\n# Ribasim.add_constraints_conservation_flow_demand! — Method.\nAdd the conservation constraints for connector nodes with a flow demand to the allocation problem. The constraint indices are node IDs of the nodes with the flow demand (so not the IDs of the FlowDemand nodes).\nConstraint: flow into node + flow out of buffer = flow out of node + flow into buffer\nsource\n# Ribasim.add_constraints_conservation_subnetwork! — Method.\nAdd the subnetwork inlet flow conservation constraints to the allocation problem. The constraint indices are node IDs subnetwork inlet edge dst IDs.\nConstraint: sum(flows into node) == sum(flows out of node)\nsource\n# Ribasim.add_constraints_flow_demand_outflow! — Method.\nAdd the flow demand node outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of node with flow demand <= ∞ if not at flow demand priority, 0.0 otherwise\nsource\n# Ribasim.add_constraints_fractional_flow! — Method.\nAdd the fractional flow constraints to the allocation problem. The constraint indices are allocation edges over a fractional flow node.\nConstraint: flow after fractional_flow node <= fraction * inflow\nsource\n# Ribasim.add_constraints_source! — Method.\nAdd the source constraints to the allocation problem. The actual threshold values will be set before each allocation solve. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over source edge <= source flow in subnetwork\nsource\n# Ribasim.add_constraints_user_source! — Method.\nAdd capacity constraints to the outflow edge of UserDemand nodes. The constraint indices are the UserDemand node IDs.\nConstraint: flow over UserDemand edge outflow edge <= cumulative return flow from previous priorities\nsource\n# Ribasim.add_flow_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a node with a a flow demand.\nsource\n# Ribasim.add_objective_term! — Function.\nAdd a term to the objective function given by the objective type, depending in the provided flow variable and the associated demand.\nsource\n# Ribasim.add_subnetwork_connections! — Method.\nAdd the edges connecting the main network work to a subnetwork to both the main network and subnetwork allocation network.\nsource\n# Ribasim.add_user_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a UserDemand.\nsource\n# Ribasim.add_variables_absolute_value! — Method.\nCertain allocation distribution types use absolute values in the objective function. Since most optimization packages do not support the absolute value function directly, New variables are introduced that act as the absolute value of an expression by posing the appropriate constraints.\nsource\n# Ribasim.add_variables_basin! — Method.\nAdd the variables for supply/demand of a basin to the problem. The variable indices are the node_ids of the basins with a level demand in the subnetwork.\nsource\n# Ribasim.add_variables_flow! — Method.\nAdd the flow variables F to the allocation problem. The variable indices are (edgesourceid, edgedstid). Non-negativivity constraints are also immediately added to the flow variables.\nsource\n# Ribasim.add_variables_flow_buffer! — Method.\nAdd the variables for supply/demand of a node with a flow demand to the problem. The variable indices are the node_ids of the nodes with a flow demand in the subnetwork.\nsource\n# Ribasim.adjust_capacities_basin! — Method.\nSet the values of the basin outflows. 2 cases:\n\nBefore the first allocation solve, set the capacities to their full capacity if there is surplus storage;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the capacities.\n\nsource\n# Ribasim.adjust_capacities_buffer! — Method.\nIncrease the capacities of the flow buffers of nodes with a flow demand by the inflow to the respective buffers.\nsource\n# Ribasim.adjust_capacities_edge! — Method.\nSet the values of the edge capacities. 2 cases:\n\nBefore the first allocation solve, set the edge capacities to their full capacity;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the edge capacities.\n\nsource\n# Ribasim.adjust_capacities_returnflow! — Method.\nAdd the return flow fraction of the inflow to the UserDemand nodes to the capacity of the outflow source.\nsource\n# Ribasim.adjust_capacities_source! — Method.\nAdjust the source capacities by the flow used from the sources.\nsource\n# Ribasim.adjust_demands_flow! — Method.\nReduce the flow demand based on flow trough the node with the demand. Flow from any priority counts.\nsource\n# Ribasim.adjust_demands_level! — Method.\nSubtract the allocated flow to the basin from its demand, to obtain the reduced demand used for goal programming\nsource\n# Ribasim.adjust_demands_user! — Method.\nSet the demand of the flow demand nodes. 2 cases:\n\nBefore the first allocation solve, set the demands to their full value;\nBefore an allocation solve, subtract the flow trough the node with a flow demand from the total flow demand (which will be used at the priority of the flow demand only).\n\nsource\n# Ribasim.all_neighbor_labels_type — Method.\nGet the in- and outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.allocate! — Method.\nUpdate the allocation optimization problem for the given subnetwork with the problem state and flows, solve the allocation problem and assign the results to the UserDemand.\nsource\n# Ribasim.allocation_graph — Method.\nBuild the graph used for the allocation problem.\nsource\n# Ribasim.allocation_graph_used_nodes! — Method.\nFind all nodes in the subnetwork which will be used in the allocation network. Some nodes are skipped to optimize allocation optimization.\nsource\n# Ribasim.allocation_problem — Method.\nConstruct the allocation problem for the current subnetwork as a JuMP.jl model.\nsource\n# Ribasim.allocation_table — Method.\nCreate an allocation result table for the saved data\nsource\n# Ribasim.assign_allocations! — Method.\nAssign the allocations to the UserDemand as determined by the solution of the allocation problem.\nsource\n# Ribasim.basin_bottom — Method.\nReturn the bottom elevation of the basin with index i, or nothing if it doesn’t exist\nsource\n# Ribasim.basin_table — Method.\nCreate the basin result table from the saved data\nsource\n# Ribasim.create_callbacks — Method.\nCreate the different callbacks that are used to store results and feed the simulation with new data. The different callbacks are combined to a CallbackSet that goes to the integrator. Returns the CallbackSet and the SavedValues for flow.\nsource\n# Ribasim.create_graph — Method.\nReturn a directed metagraph with data of nodes (NodeMetadata): NodeMetadata\nand data of edges (EdgeMetadata): EdgeMetadata\nsource\n# Ribasim.create_storage_tables — Method.\nRead the Basin / profile table and return all area and level and computed storage values\nsource\n# Ribasim.datetime_since — Method.\ndatetime_since(t::Real, t0::DateTime)::DateTime\nConvert a Real that represents the seconds passed since the simulation start to the nearest DateTime. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.datetimes — Method.\nGet all saved times as a Vector{DateTime}\nsource\n# Ribasim.discrete_control_affect! — Method.\nChange parameters based on the control logic.\nsource\n# Ribasim.discrete_control_affect_downcrossing! — Method.\nAn downcrossing means that a condition (always greater than) becomes false.\nsource\n# Ribasim.discrete_control_affect_upcrossing! — Method.\nAn upcrossing means that a condition (always greater than) becomes true.\nsource\n# Ribasim.discrete_control_condition — Method.\nListens for changes in condition truths.\nsource\n# Ribasim.discrete_control_table — Method.\nCreate a discrete control result table from the saved data\nsource\n# Ribasim.expand_logic_mapping — Method.\nReplace the truth states in the logic mapping which contain wildcards with all possible explicit truth states.\nsource\n# Ribasim.find_allocation_graph_edges! — Method.\nThis loop finds allocation network edges in several ways:\n\nBetween allocation network nodes whose equivalent in the subnetwork are directly connected\nBetween allocation network nodes whose equivalent in the subnetwork are connected with one or more allocation network nodes in between\n\nsource\n# Ribasim.find_subnetwork_connections! — Method.\nFind the edges from the main network to a subnetwork.\nsource\n# Ribasim.findlastgroup — Method.\nFor an element id and a vector of elements ids, get the range of indices of the last consecutive block of id. Returns the empty range 1:0 if id is not in ids.\nsource\n# Ribasim.findsorted — Method.\nFind the index of element x in a sorted collection a. Returns the index of x if it exists, or nothing if it doesn’t. If x occurs more than once, throw an error.\nsource\n# Ribasim.flow_table — Method.\nCreate a flow result table from the saved data\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.formulate_flow! — Method.\nConservation of energy for two basins, a and b:\nh_a + v_a^2 / (2 * g) = h_b + v_b^2 / (2 * g) + S_f * L + C / 2 * g * (v_b^2 - v_a^2)\nWhere:\n\nha, hb are the heads at basin a and b.\nva, vb are the velocities at basin a and b.\ng is the gravitational constant.\nS_f is the friction slope.\nC is an expansion or extraction coefficient.\n\nWe assume velocity differences are negligible (va = vb):\nh_a = h_b + S_f * L\nThe friction losses are approximated by the Gauckler-Manning formula:\nQ = A * (1 / n) * R_h^(2/3) * S_f^(1/2)\nWhere:\n\nWhere A is the cross-sectional area.\nV is the cross-sectional average velocity.\nn is the Gauckler-Manning coefficient.\nR_h is the hydraulic radius.\nS_f is the friction slope.\n\nThe hydraulic radius is defined as:\nR_h = A / P\nWhere P is the wetted perimeter.\nThe average of the upstream and downstream water depth is used to compute cross-sectional area and hydraulic radius. This ensures that a basin can receive water after it has gone dry.\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.get_area_and_level — Method.\nCompute the area and level of a basin given its storage. Also returns darea/dlevel as it is needed for the Jacobian.\nsource\n# Ribasim.get_basin_capacity — Method.\nGet the capacity of the basin, i.e. the maximum flow that can be abstracted from the basin if it is in a state of surplus storage (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_basin_data — Method.\nGet several variables associated with a basin:\n\nIts current storage\nThe allocation update interval\nThe influx (sum of instantaneous vertical fluxes of the basin)\nThe index of the connected level_demand node (0 if such a node does not exist)\nThe index of the basin\n\nsource\n# Ribasim.get_basin_demand — Method.\nGet the demand of the basin, i.e. how large a flow the basin needs to get to its minimum target level (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_chunk_sizes — Method.\nGet the chunk sizes for DiffCache; differentiation w.r.t. u and t (the latter only if a Rosenbrock algorithm is used).\nsource\n# Ribasim.get_compressor — Method.\nGet the compressor based on the Results section\nsource\n# Ribasim.get_flow — Method.\nGet the flow over the given edge (val is needed for get_tmp from ForwardDiff.jl).\nsource\n# Ribasim.get_fractional_flow_connected_basins — Method.\nGet the node type specific indices of the fractional flows and basins, that are consecutively connected to a node of given id.\nsource\n# Ribasim.get_jac_prototype — Method.\nGet a sparse matrix whose sparsity matches (with some false positives) the sparsity of the Jacobian of the ODE problem. All nodes are taken into consideration, also the ones that are inactive.\nIn Ribasim the Jacobian is typically sparse because each state only depends on a small number of other states.\nNote: the name ‘prototype’ does not mean this code is a prototype, it comes from the naming convention of this sparsity structure in the differentialequations.jl docs.\nsource\n# Ribasim.get_level — Method.\nGet the current water level of a node ID. The ID can belong to either a Basin or a LevelBoundary. storage: tells ForwardDiff whether this call is for differentiation or not\nsource\n# Ribasim.get_scalar_interpolation — Method.\nLinear interpolation of a scalar with constant extrapolation.\nsource\n# Ribasim.get_storage_from_level — Method.\nGet the storage of a basin from its level.\nsource\n# Ribasim.get_storages_and_levels — Method.\nGet the storage and level of all basins as matrices of nbasin × ntime\nsource\n# Ribasim.get_storages_from_levels — Method.\nCompute the storages of the basins based on the water level of the basins.\nsource\n# Ribasim.get_tstops — Method.\nFrom an iterable of DateTimes, find the times the solver needs to stop\nsource\n# Ribasim.get_value — Method.\nGet a value for a condition. Currently supports getting levels from basins and flows from flow boundaries.\nsource\n# Ribasim.get_Δt — Method.\nGet the time interval between (flow) saves\nsource\n# Ribasim.id_index — Method.\nGet the index of an ID in a set of indices.\nsource\n# Ribasim.indicate_allocation_flow! — Method.\nAdd to the edge metadata that the given edge is used for allocation flow. If the edge does not exist, it is created.\nsource\n# Ribasim.inflow_id — Method.\nGet the unique inneighbor over a flow edge.\nsource\n# Ribasim.inflow_ids — Method.\nGet the inneighbors over flow edges.\nsource\n# Ribasim.inflow_ids_allocation — Method.\nGet the inneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.inneighbor_labels_type — Method.\nGet the inneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.inoutflow_ids — Method.\nGet the in- and outneighbors over flow edges.\nsource\n# Ribasim.integrate_flows! — Method.\nIntegrate flows over the last timestep\nsource\n# Ribasim.is_allocation_source — Method.\nFind out whether the given edge is a source for an allocation network.\nsource\n# Ribasim.is_current_module — Method.\nis_current_module(log::LogMessageType)::Bool\nReturns true if the log message is from the current module or a submodule.\n\nSee https://github.com/JuliaLogging/LoggingExtras.jl/blob/d35e7c8cfc197853ee336ace17182e6ed36dca24/src/CompositionalLoggers/earlyfiltered.jl#L39\nfor the information available in log.\nsource\n# Ribasim.is_flow_constraining — Method.\nWhether the given node node is flow constraining by having a maximum flow rate.\nsource\n# Ribasim.is_flow_direction_constraining — Method.\nWhether the given node is flow direction constraining (only in direction of edges).\nsource\n# Ribasim.load_data — Method.\nload_data(db::DB, config::Config, nodetype::Symbol, kind::Symbol)::Union{Table, Query, Nothing}\nLoad data from Arrow files if available, otherwise the database. Returns either an Arrow.Table, SQLite.Query or nothing if the data is not present.\nsource\n# Ribasim.load_structvector — Method.\nload_structvector(db::DB, config::Config, ::Type{T})::StructVector{T}\nLoad data from Arrow files if available, otherwise the database. Always returns a StructVector of the given struct type T, which is empty if the table is not found. This function validates the schema, and enforces the required sort order.\nsource\n# Ribasim.low_storage_factor — Method.\nIf id is a Basin with storage below the threshold, return a reduction factor != 1\nsource\n# Ribasim.main — Method.\nmain(toml_path::AbstractString)::Cint\nmain(ARGS::Vector{String})::Cint\nmain()::Cint\nThis is the main entry point of the application. Performs argument parsing and sets up logging for both terminal and file. Calls Ribasim.run() and handles exceptions to convert to exit codes.\nsource\n# Ribasim.metadata_from_edge — Method.\nGet the metadata of an edge in the graph from an edge of the underlying DiGraph.\nsource\n# Ribasim.nodefields — Method.\nGet all node fieldnames of the parameter object.\nsource\n# Ribasim.nodetype — Method.\nFrom a SchemaVersion(“ribasim.flowboundary.static”, 1) return (:FlowBoundary, :static)\nsource\n# Ribasim.outflow_id — Method.\nGet the unique outneighbor over a flow edge.\nsource\n# Ribasim.outflow_ids — Method.\nGet the outneighbors over flow edges.\nsource\n# Ribasim.outflow_ids_allocation — Method.\nGet the outneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.outneighbor_labels_type — Method.\nGet the outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.parse_static_and_time — Method.\nProcess the data in the static and time tables for a given node type. The ‘defaults’ named tuple dictates how missing data is filled in. ‘time_interpolatables’ is a vector of Symbols of parameter names for which a time interpolation (linear) object must be constructed. The control mapping for DiscreteControl is also constructed in this function. This function currently does not support node states that are defined by more than one row in a table, as is the case for TabulatedRatingCurve.\nsource\n# Ribasim.pkgversion — Method.\nGet the package version of a given module\nsource\n# Ribasim.process_allocation_graph_edges! — Method.\nFor the composite allocation network edges:\n\nFind out whether they are connected to allocation network nodes on both ends\nCompute their capacity\nFind out their allowed flow direction(s)\n\nsource\n# Ribasim.profile_storage — Method.\nCalculate a profile storage by integrating the areas over the levels\nsource\n# Ribasim.qh_interpolation — Method.\nFrom a table with columns nodeid, flowrate (Q) and level (h), create a LinearInterpolation from level to flow rate for a given node_id.\nsource\n# Ribasim.reduction_factor — Method.\nFunction that goes smoothly from 0 to 1 in the interval [0,threshold], and is constant outside this interval.\nsource\n# Ribasim.run — Method.\nrun(config_file::AbstractString)::Model\nrun(config::Config)::Model\nRun a Model, given a path to a TOML configuration file, or a Config object. Running a model includes initialization, solving to the end with [solve!](@ref) and writing results with write_results.\nsource\n# Ribasim.save_allocation_flows! — Method.\nSave the allocation flows per basin and physical edge.\nsource\n# Ribasim.save_demands_and_allocations! — Method.\nSave the demands and allocated flows for UserDemand and Basin. Note: Basin supply (negative demand) is only saved for the first priority.\nsource\n# Ribasim.save_flow — Method.\nCompute the average flows over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.save_subgrid_level — Method.\nInterpolate the levels and save them to SavedValues\nsource\n# Ribasim.save_vertical_flux — Method.\nCompute the average vertical fluxes over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.scalar_interpolation_derivative — Method.\nDerivative of scalar interpolation.\nsource\n# Ribasim.seconds_since — Method.\nseconds_since(t::DateTime, t0::DateTime)::Float64\nConvert a DateTime to a float that is the number of seconds since the start of the simulation. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.set_capacities_flow_demand_outflow! — Method.\nSet the capacity of the outflow edge from a node with a flow demand:\n\nTo Inf if the current priority is other than the priority of the flow demand\nTo 0.0 if the current priority is equal to the priority of the flow demand\n\nsource\n# Ribasim.set_current_value! — Method.\nFrom a timeseries table time, load the most recent applicable data into table. table must be a NamedTuple of vectors with all variables that must be loaded. The most recent applicable data is non-NaN data for a given ID that is on or before t.\nsource\n# Ribasim.set_flow! — Method.\nSet the given flow q over the edge between the given nodes.\nsource\n# Ribasim.set_fractional_flow_in_allocation! — Method.\nUpdate the fractional flow fractions in an allocation problem.\nsource\n# Ribasim.set_initial_capacities_basin! — Method.\nSet the initial capacity of each basin in the subnetwork as vertical fluxes + the disk of storage above the maximum level / Δt_allocation\nsource\n# Ribasim.set_initial_capacities_buffer! — Method.\nSet the flow buffer of nodes with a flow demand to 0.0\nsource\n# Ribasim.set_initial_capacities_edge! — Method.\nSet the capacities of the allocation flow edges as determined by the smallest maxflowrate of a node on this edge\nsource\n# Ribasim.set_initial_capacities_inlet! — Method.\nSet the capacities of the main network to subnetwork inlets. Per optimization type: internalsources: 0.0 collectdemands: Inf allocate: the total flow allocated to this inlet from the main network\nsource\n# Ribasim.set_initial_capacities_returnflow! — Method.\nSet the initial capacities of the UserDemand return flow sources to 0.\nsource\n# Ribasim.set_initial_capacities_source! — Method.\nSet the capacities of the sources in the subnetwork as the latest instantaneous flow out of the source in the physical layer\nsource\n# Ribasim.set_initial_demands_flow! — Method.\nSet the initial demands of the nodes with a flow demand to the interpolated value from the given timeseries.\nsource\n# Ribasim.set_initial_demands_level! — Method.\nSet the initial demand of each basin in the subnetwork as\n\nvertical fluxes + the disk of missing storage below the minimum level / Δt_allocation\n\nsource\n# Ribasim.set_initial_demands_user! — Method.\nSet the demands of the user demand nodes as given by either a coupled model or a timeseries\nsource\n# Ribasim.set_initial_discrete_controlled_parameters! — Method.\nSet parameters of nodes that are controlled by DiscreteControl to the values corresponding to the initial state of the model.\nsource\n# Ribasim.set_initial_values! — Method.\nSet the initial capacities and demands which are recudes by usage in the adjust*capacities**! and adjust*demands**! functions respectively.\nsource\n# Ribasim.set_is_pid_controlled! — Method.\nSet ispidcontrolled to true for those pumps and outlets that are PID controlled\nsource\n# Ribasim.set_objective_priority! — Method.\nSet the objective for the given priority. For an objective with absolute values this also involves adjusting constraints.\nsource\n# Ribasim.set_static_value! — Method.\nLoad data from a source table static into a destination table. Data is matched based on the node_id, which is sorted.\nsource\n# Ribasim.set_table_row! — Method.\nUpdate table at row index i, with the values of a given row. table must be a NamedTuple of vectors with all variables that must be loaded. The row must contain all the column names that are present in the table. If a value is missing, it is not set.\nsource\n# Ribasim.sorted_table! — Method.\nDepending on if a table can be sorted, either sort it or assert that it is sorted.\nTables loaded from the database into memory can be sorted. Tables loaded from Arrow files are memory mapped and can therefore not be sorted.\nsource\n# Ribasim.tsaves — Method.\nGet all saved times in seconds since start\nsource\n# Ribasim.update_allocation! — Method.\nSolve the allocation problem for all demands and assign allocated abstractions.\nsource\n# Ribasim.update_basin — Method.\nLoad updates from ‘Basin / time’ into the parameters\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for basins connected to eachother via 1 node and possibly a fractional flow node Basins are also assumed to depend on themselves (main diagonal terms)\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for the integral term and the basins on either side of the controlled node\nsource\n# Ribasim.update_tabulated_rating_curve! — Method.\nLoad updates from ‘TabulatedRatingCurve / time’ into the parameters\nsource\n# Ribasim.update_vertical_flux! — Method.\nSmoothly let the evaporation flux go to 0 when at small water depths Currently at less than 0.1 m.\nsource\n# Ribasim.valid_discrete_control — Method.\nCheck:\n\nwhether control states are defined for discrete controlled nodes;\nWhether the supplied truth states have the proper length;\nWhether look_ahead is only supplied for condition variables given by a time-series.\n\nsource\n# Ribasim.valid_edge_types — Method.\nCheck that only supported edge types are declared.\nsource\n# Ribasim.valid_edges — Method.\nTest for each node given its node type whether the nodes that\nare downstream (‘down-edge’) of this node are of an allowed type\nsource\n# Ribasim.valid_flow_rates — Method.\nTest whether static or discrete controlled flow rates are indeed non-negative.\nsource\n# Ribasim.valid_fractional_flow — Method.\nCheck that nodes that have fractional flow outneighbors do not have any other type of outneighbor, that the fractions leaving a node add up to ≈1 and that the fractions are non-negative.\nsource\n# Ribasim.valid_n_neighbors — Method.\nTest for each node given its node type whether it has an allowed number of flow/control inneighbors and outneighbors\nsource\n# Ribasim.valid_profiles — Method.\nCheck whether the profile data has no repeats in the levels and the areas start positive.\nsource\n# Ribasim.valid_sources — Method.\nThe source nodes must only have one allocation outneighbor and no allocation inneighbors.\nsource\n# Ribasim.valid_subgrid — Method.\nValidate the entries for a single subgrid element.\nsource\n# Ribasim.water_balance! — Method.\nThe right hand side function of the system of ODEs set up by Ribasim.\nsource\n# Ribasim.write_arrow — Method.\nWrite a result table to disk as an Arrow file\nsource\n# Ribasim.write_results — Method.\nwrite_results(model::Model)::Model\nWrite all results to the Arrow files as specified in the model configuration.\nsource\n# Ribasim.config.algorithm — Method.\nCreate an OrdinaryDiffEqAlgorithm from solver config\nsource\n# Ribasim.config.convert_dt — Method.\nConvert the dt from our Config to SciML stepsize control arguments\nsource\n# Ribasim.config.convert_saveat — Method.\nConvert the saveat Float64 from our Config to SciML’s saveat\nsource\n# Ribasim.config.input_path — Method.\nConstruct a path relative to both the TOML directory and the optional input_dir\nsource\n# Ribasim.config.results_path — Method.\nConstruct a path relative to both the TOML directory and the optional results_dir\nsource\n# Ribasim.config.snake_case — Method.\nConvert a string from CamelCase to snake_case.\nsource",
+ "text": "1.3 Functions\n# BasicModelInterface.finalize — Method.\nBMI.finalize(model::Model)::Model\nWrite all results to the configured files.\nsource\n# BasicModelInterface.initialize — Method.\nBMI.initialize(T::Type{Model}, config_path::AbstractString)::Model\nInitialize a Model from the path to the TOML configuration file.\nsource\n# CommonSolve.solve! — Method.\nsolve!(model::Model)::ODESolution\nSolve a Model until the configured endtime.\nsource\n# Ribasim.add_basin_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a basin.\nsource\n# Ribasim.add_constraints_absolute_value! — Method.\nMinimizing |expr| can be achieved by introducing a new variable exprabs and posing the following constraints: exprabs >= expr expr_abs >= -expr\nsource\n# Ribasim.add_constraints_absolute_value_flow_demand! — Method.\nAdd constraints so that variables Fabsflow_demand act as the absolute value of the expression comparing flow to a flow buffer to the flow demand.\nsource\n# Ribasim.add_constraints_absolute_value_level_demand! — Method.\nAdd constraints so that variables Fabslevel_demand act as the absolute value of the expression comparing flow to a basin to its demand.\nsource\n# Ribasim.add_constraints_absolute_value_user_demand! — Method.\nAdd constraints so that variables Fabsuser_demand act as the absolute value of the expression comparing flow to a UserDemand to its demand.\nsource\n# Ribasim.add_constraints_basin_flow! — Method.\nAdd the Basin flow constraints to the allocation problem. The constraint indices are the Basin node IDs.\nConstraint: flow out of basin <= basin capacity\nsource\n# Ribasim.add_constraints_buffer! — Method.\nAdd the buffer outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of buffer <= flow buffer capacity\nsource\n# Ribasim.add_constraints_capacity! — Method.\nAdd the flow capacity constraints to the allocation problem. Only finite capacities get a constraint. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over edge <= edge capacity\nsource\n# Ribasim.add_constraints_conservation_basin! — Method.\nAdd the basin flow conservation constraints to the allocation problem. The constraint indices are Basin node IDs.\nConstraint: sum(flows out of basin) == sum(flows into basin) + flow from storage and vertical fluxes\nsource\n# Ribasim.add_constraints_conservation_flow_demand! — Method.\nAdd the conservation constraints for connector nodes with a flow demand to the allocation problem. The constraint indices are node IDs of the nodes with the flow demand (so not the IDs of the FlowDemand nodes).\nConstraint: flow into node + flow out of buffer = flow out of node + flow into buffer\nsource\n# Ribasim.add_constraints_conservation_subnetwork! — Method.\nAdd the subnetwork inlet flow conservation constraints to the allocation problem. The constraint indices are node IDs subnetwork inlet edge dst IDs.\nConstraint: sum(flows into node) == sum(flows out of node)\nsource\n# Ribasim.add_constraints_flow_demand_outflow! — Method.\nAdd the flow demand node outflow constraints to the allocation problem. The constraint indices are the node IDs of the nodes that have a flow demand.\nConstraint: flow out of node with flow demand <= ∞ if not at flow demand priority, 0.0 otherwise\nsource\n# Ribasim.add_constraints_fractional_flow! — Method.\nAdd the fractional flow constraints to the allocation problem. The constraint indices are allocation edges over a fractional flow node.\nConstraint: flow after fractional_flow node <= fraction * inflow\nsource\n# Ribasim.add_constraints_source! — Method.\nAdd the source constraints to the allocation problem. The actual threshold values will be set before each allocation solve. The constraint indices are (edgesourceid, edgedstid).\nConstraint: flow over source edge <= source flow in subnetwork\nsource\n# Ribasim.add_constraints_user_source! — Method.\nAdd capacity constraints to the outflow edge of UserDemand nodes. The constraint indices are the UserDemand node IDs.\nConstraint: flow over UserDemand edge outflow edge <= cumulative return flow from previous priorities\nsource\n# Ribasim.add_flow_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a node with a a flow demand.\nsource\n# Ribasim.add_objective_term! — Function.\nAdd a term to the objective function given by the objective type, depending in the provided flow variable and the associated demand.\nsource\n# Ribasim.add_subnetwork_connections! — Method.\nAdd the edges connecting the main network work to a subnetwork to both the main network and subnetwork allocation network.\nsource\n# Ribasim.add_user_demand_term! — Method.\nAdd a term to the expression of the objective function corresponding to the demand of a UserDemand.\nsource\n# Ribasim.add_variables_absolute_value! — Method.\nCertain allocation distribution types use absolute values in the objective function. Since most optimization packages do not support the absolute value function directly, New variables are introduced that act as the absolute value of an expression by posing the appropriate constraints.\nsource\n# Ribasim.add_variables_basin! — Method.\nAdd the variables for supply/demand of a basin to the problem. The variable indices are the node_ids of the basins with a level demand in the subnetwork.\nsource\n# Ribasim.add_variables_flow! — Method.\nAdd the flow variables F to the allocation problem. The variable indices are (edgesourceid, edgedstid). Non-negativivity constraints are also immediately added to the flow variables.\nsource\n# Ribasim.add_variables_flow_buffer! — Method.\nAdd the variables for supply/demand of a node with a flow demand to the problem. The variable indices are the node_ids of the nodes with a flow demand in the subnetwork.\nsource\n# Ribasim.adjust_capacities_basin! — Method.\nSet the values of the basin outflows. 2 cases:\n\nBefore the first allocation solve, set the capacities to their full capacity if there is surplus storage;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the capacities.\n\nsource\n# Ribasim.adjust_capacities_buffer! — Method.\nIncrease the capacities of the flow buffers of nodes with a flow demand by the inflow to the respective buffers.\nsource\n# Ribasim.adjust_capacities_edge! — Method.\nSet the values of the edge capacities. 2 cases:\n\nBefore the first allocation solve, set the edge capacities to their full capacity;\nBefore an allocation solve, subtract the flow used by allocation for the previous priority from the edge capacities.\n\nsource\n# Ribasim.adjust_capacities_returnflow! — Method.\nAdd the return flow fraction of the inflow to the UserDemand nodes to the capacity of the outflow source.\nsource\n# Ribasim.adjust_capacities_source! — Method.\nAdjust the source capacities by the flow used from the sources.\nsource\n# Ribasim.adjust_demands_flow! — Method.\nReduce the flow demand based on flow trough the node with the demand. Flow from any priority counts.\nsource\n# Ribasim.adjust_demands_level! — Method.\nSubtract the allocated flow to the basin from its demand, to obtain the reduced demand used for goal programming\nsource\n# Ribasim.adjust_demands_user! — Method.\nSet the demand of the flow demand nodes. 2 cases:\n\nBefore the first allocation solve, set the demands to their full value;\nBefore an allocation solve, subtract the flow trough the node with a flow demand from the total flow demand (which will be used at the priority of the flow demand only).\n\nsource\n# Ribasim.all_neighbor_labels_type — Method.\nGet the in- and outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.allocate! — Method.\nUpdate the allocation optimization problem for the given subnetwork with the problem state and flows, solve the allocation problem and assign the results to the UserDemand.\nsource\n# Ribasim.allocation_graph — Method.\nBuild the graph used for the allocation problem.\nsource\n# Ribasim.allocation_graph_used_nodes! — Method.\nFind all nodes in the subnetwork which will be used in the allocation network. Some nodes are skipped to optimize allocation optimization.\nsource\n# Ribasim.allocation_problem — Method.\nConstruct the allocation problem for the current subnetwork as a JuMP.jl model.\nsource\n# Ribasim.allocation_table — Method.\nCreate an allocation result table for the saved data\nsource\n# Ribasim.assign_allocations! — Method.\nAssign the allocations to the UserDemand as determined by the solution of the allocation problem.\nsource\n# Ribasim.basin_bottom — Method.\nReturn the bottom elevation of the basin with index i, or nothing if it doesn’t exist\nsource\n# Ribasim.basin_table — Method.\nCreate the basin result table from the saved data\nsource\n# Ribasim.create_callbacks — Method.\nCreate the different callbacks that are used to store results and feed the simulation with new data. The different callbacks are combined to a CallbackSet that goes to the integrator. Returns the CallbackSet and the SavedValues for flow.\nsource\n# Ribasim.create_graph — Method.\nReturn a directed metagraph with data of nodes (NodeMetadata): NodeMetadata\nand data of edges (EdgeMetadata): EdgeMetadata\nsource\n# Ribasim.create_storage_tables — Method.\nRead the Basin / profile table and return all area and level and computed storage values\nsource\n# Ribasim.datetime_since — Method.\ndatetime_since(t::Real, t0::DateTime)::DateTime\nConvert a Real that represents the seconds passed since the simulation start to the nearest DateTime. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.datetimes — Method.\nGet all saved times as a Vector{DateTime}\nsource\n# Ribasim.discrete_control_affect! — Method.\nChange parameters based on the control logic.\nsource\n# Ribasim.discrete_control_affect_downcrossing! — Method.\nAn downcrossing means that a condition (always greater than) becomes false.\nsource\n# Ribasim.discrete_control_affect_upcrossing! — Method.\nAn upcrossing means that a condition (always greater than) becomes true.\nsource\n# Ribasim.discrete_control_condition — Method.\nListens for changes in condition truths.\nsource\n# Ribasim.discrete_control_table — Method.\nCreate a discrete control result table from the saved data\nsource\n# Ribasim.expand_logic_mapping — Method.\nReplace the truth states in the logic mapping which contain wildcards with all possible explicit truth states.\nsource\n# Ribasim.find_allocation_graph_edges! — Method.\nThis loop finds allocation network edges in several ways:\n\nBetween allocation network nodes whose equivalent in the subnetwork are directly connected\nBetween allocation network nodes whose equivalent in the subnetwork are connected with one or more allocation network nodes in between\n\nsource\n# Ribasim.find_subnetwork_connections! — Method.\nFind the edges from the main network to a subnetwork.\nsource\n# Ribasim.findlastgroup — Method.\nFor an element id and a vector of elements ids, get the range of indices of the last consecutive block of id. Returns the empty range 1:0 if id is not in ids.\nsource\n# Ribasim.findsorted — Method.\nFind the index of element x in a sorted collection a. Returns the index of x if it exists, or nothing if it doesn’t. If x occurs more than once, throw an error.\nsource\n# Ribasim.flow_table — Method.\nCreate a flow result table from the saved data\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.formulate_flow! — Method.\nConservation of energy for two basins, a and b:\nh_a + v_a^2 / (2 * g) = h_b + v_b^2 / (2 * g) + S_f * L + C / 2 * g * (v_b^2 - v_a^2)\nWhere:\n\nha, hb are the heads at basin a and b.\nva, vb are the velocities at basin a and b.\ng is the gravitational constant.\nS_f is the friction slope.\nC is an expansion or extraction coefficient.\n\nWe assume velocity differences are negligible (va = vb):\nh_a = h_b + S_f * L\nThe friction losses are approximated by the Gauckler-Manning formula:\nQ = A * (1 / n) * R_h^(2/3) * S_f^(1/2)\nWhere:\n\nWhere A is the cross-sectional area.\nV is the cross-sectional average velocity.\nn is the Gauckler-Manning coefficient.\nR_h is the hydraulic radius.\nS_f is the friction slope.\n\nThe hydraulic radius is defined as:\nR_h = A / P\nWhere P is the wetted perimeter.\nThe average of the upstream and downstream water depth is used to compute cross-sectional area and hydraulic radius. This ensures that a basin can receive water after it has gone dry.\nsource\n# Ribasim.formulate_flow! — Method.\nDirected graph: outflow is positive!\nsource\n# Ribasim.get_area_and_level — Method.\nCompute the area and level of a basin given its storage. Also returns darea/dlevel as it is needed for the Jacobian.\nsource\n# Ribasim.get_basin_capacity — Method.\nGet the capacity of the basin, i.e. the maximum flow that can be abstracted from the basin if it is in a state of surplus storage (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_basin_data — Method.\nGet several variables associated with a basin:\n\nIts current storage\nThe allocation update interval\nThe influx (sum of instantaneous vertical fluxes of the basin)\nThe index of the connected level_demand node (0 if such a node does not exist)\nThe index of the basin\n\nsource\n# Ribasim.get_basin_demand — Method.\nGet the demand of the basin, i.e. how large a flow the basin needs to get to its minimum target level (0 if no reference levels are provided by a level_demand node). Storages are converted to flows by dividing by the allocation timestep.\nsource\n# Ribasim.get_chunk_sizes — Method.\nGet the chunk sizes for DiffCache; differentiation w.r.t. u and t (the latter only if a Rosenbrock algorithm is used).\nsource\n# Ribasim.get_compressor — Method.\nGet the compressor based on the Results section\nsource\n# Ribasim.get_flow — Method.\nGet the flow over the given edge (val is needed for get_tmp from ForwardDiff.jl).\nsource\n# Ribasim.get_fractional_flow_connected_basins — Method.\nGet the node type specific indices of the fractional flows and basins, that are consecutively connected to a node of given id.\nsource\n# Ribasim.get_jac_prototype — Method.\nGet a sparse matrix whose sparsity matches (with some false positives) the sparsity of the Jacobian of the ODE problem. All nodes are taken into consideration, also the ones that are inactive.\nIn Ribasim the Jacobian is typically sparse because each state only depends on a small number of other states.\nNote: the name ‘prototype’ does not mean this code is a prototype, it comes from the naming convention of this sparsity structure in the differentialequations.jl docs.\nsource\n# Ribasim.get_level — Method.\nGet the current water level of a node ID. The ID can belong to either a Basin or a LevelBoundary. storage: tells ForwardDiff whether this call is for differentiation or not\nsource\n# Ribasim.get_scalar_interpolation — Method.\nLinear interpolation of a scalar with constant extrapolation.\nsource\n# Ribasim.get_storage_from_level — Method.\nGet the storage of a basin from its level.\nsource\n# Ribasim.get_storages_and_levels — Method.\nGet the storage and level of all basins as matrices of nbasin × ntime\nsource\n# Ribasim.get_storages_from_levels — Method.\nCompute the storages of the basins based on the water level of the basins.\nsource\n# Ribasim.get_tstops — Method.\nFrom an iterable of DateTimes, find the times the solver needs to stop\nsource\n# Ribasim.get_value — Method.\nGet a value for a condition. Currently supports getting levels from basins and flows from flow boundaries.\nsource\n# Ribasim.get_Δt — Method.\nGet the time interval between (flow) saves\nsource\n# Ribasim.id_index — Method.\nGet the index of an ID in a set of indices.\nsource\n# Ribasim.indicate_allocation_flow! — Method.\nAdd to the edge metadata that the given edge is used for allocation flow. If the edge does not exist, it is created.\nsource\n# Ribasim.inflow_id — Method.\nGet the unique inneighbor over a flow edge.\nsource\n# Ribasim.inflow_ids — Method.\nGet the inneighbors over flow edges.\nsource\n# Ribasim.inflow_ids_allocation — Method.\nGet the inneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.inneighbor_labels_type — Method.\nGet the inneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.inoutflow_ids — Method.\nGet the in- and outneighbors over flow edges.\nsource\n# Ribasim.integrate_flows! — Method.\nIntegrate flows over the last timestep\nsource\n# Ribasim.is_allocation_source — Method.\nFind out whether the given edge is a source for an allocation network.\nsource\n# Ribasim.is_current_module — Method.\nis_current_module(log::LogMessageType)::Bool\nReturns true if the log message is from the current module or a submodule.\n\nSee https://github.com/JuliaLogging/LoggingExtras.jl/blob/d35e7c8cfc197853ee336ace17182e6ed36dca24/src/CompositionalLoggers/earlyfiltered.jl#L39\nfor the information available in log.\nsource\n# Ribasim.is_flow_constraining — Method.\nWhether the given node node is flow constraining by having a maximum flow rate.\nsource\n# Ribasim.is_flow_direction_constraining — Method.\nWhether the given node is flow direction constraining (only in direction of edges).\nsource\n# Ribasim.load_data — Method.\nload_data(db::DB, config::Config, nodetype::Symbol, kind::Symbol)::Union{Table, Query, Nothing}\nLoad data from Arrow files if available, otherwise the database. Returns either an Arrow.Table, SQLite.Query or nothing if the data is not present.\nsource\n# Ribasim.load_structvector — Method.\nload_structvector(db::DB, config::Config, ::Type{T})::StructVector{T}\nLoad data from Arrow files if available, otherwise the database. Always returns a StructVector of the given struct type T, which is empty if the table is not found. This function validates the schema, and enforces the required sort order.\nsource\n# Ribasim.low_storage_factor — Method.\nIf id is a Basin with storage below the threshold, return a reduction factor != 1\nsource\n# Ribasim.main — Method.\nmain(toml_path::AbstractString)::Cint\nmain(ARGS::Vector{String})::Cint\nmain()::Cint\nThis is the main entry point of the application. Performs argument parsing and sets up logging for both terminal and file. Calls Ribasim.run() and handles exceptions to convert to exit codes.\nsource\n# Ribasim.metadata_from_edge — Method.\nGet the metadata of an edge in the graph from an edge of the underlying DiGraph.\nsource\n# Ribasim.nodefields — Method.\nGet all node fieldnames of the parameter object.\nsource\n# Ribasim.nodetype — Method.\nFrom a SchemaVersion(“ribasim.flowboundary.static”, 1) return (:FlowBoundary, :static)\nsource\n# Ribasim.outflow_id — Method.\nGet the unique outneighbor over a flow edge.\nsource\n# Ribasim.outflow_ids — Method.\nGet the outneighbors over flow edges.\nsource\n# Ribasim.outflow_ids_allocation — Method.\nGet the outneighbors of the given ID such that the connecting edge is an allocation flow edge.\nsource\n# Ribasim.outneighbor_labels_type — Method.\nGet the outneighbor node IDs of the given node ID (label) over the given edge type in the graph.\nsource\n# Ribasim.parse_static_and_time — Method.\nProcess the data in the static and time tables for a given node type. The ‘defaults’ named tuple dictates how missing data is filled in. ‘time_interpolatables’ is a vector of Symbols of parameter names for which a time interpolation (linear) object must be constructed. The control mapping for DiscreteControl is also constructed in this function. This function currently does not support node states that are defined by more than one row in a table, as is the case for TabulatedRatingCurve.\nsource\n# Ribasim.pkgversion — Method.\nGet the package version of a given module\nsource\n# Ribasim.process_allocation_graph_edges! — Method.\nFor the composite allocation network edges:\n\nFind out whether they are connected to allocation network nodes on both ends\nCompute their capacity\nFind out their allowed flow direction(s)\n\nsource\n# Ribasim.profile_storage — Method.\nCalculate a profile storage by integrating the areas over the levels\nsource\n# Ribasim.qh_interpolation — Method.\nFrom a table with columns nodeid, flowrate (Q) and level (h), create a LinearInterpolation from level to flow rate for a given node_id.\nsource\n# Ribasim.reduction_factor — Method.\nFunction that goes smoothly from 0 to 1 in the interval [0,threshold], and is constant outside this interval.\nsource\n# Ribasim.run — Method.\nrun(config_file::AbstractString)::Model\nrun(config::Config)::Model\nRun a Model, given a path to a TOML configuration file, or a Config object. Running a model includes initialization, solving to the end with [solve!](@ref) and writing results with write_results.\nsource\n# Ribasim.save_allocation_flows! — Method.\nSave the allocation flows per basin and physical edge.\nsource\n# Ribasim.save_demands_and_allocations! — Method.\nSave the demands and allocated flows for UserDemand and Basin. Note: Basin supply (negative demand) is only saved for the first priority.\nsource\n# Ribasim.save_flow — Method.\nCompute the average flows over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.save_subgrid_level — Method.\nInterpolate the levels and save them to SavedValues\nsource\n# Ribasim.save_vertical_flux — Method.\nCompute the average vertical fluxes over the last saveat interval and write them to SavedValues\nsource\n# Ribasim.scalar_interpolation_derivative — Method.\nDerivative of scalar interpolation.\nsource\n# Ribasim.seconds — Method.\nseconds(period::Millisecond)::Float64\nConvert a period of type Millisecond to a Float64 in seconds. You get Millisecond objects when subtracting two DateTime objects. Dates.value returns the number of milliseconds.\nsource\n# Ribasim.seconds_since — Method.\nseconds_since(t::DateTime, t0::DateTime)::Float64\nConvert a DateTime to a float that is the number of seconds since the start of the simulation. This is used to convert between the solver’s inner float time, and the calendar.\nsource\n# Ribasim.set_capacities_flow_demand_outflow! — Method.\nSet the capacity of the outflow edge from a node with a flow demand:\n\nTo Inf if the current priority is other than the priority of the flow demand\nTo 0.0 if the current priority is equal to the priority of the flow demand\n\nsource\n# Ribasim.set_current_value! — Method.\nFrom a timeseries table time, load the most recent applicable data into table. table must be a NamedTuple of vectors with all variables that must be loaded. The most recent applicable data is non-NaN data for a given ID that is on or before t.\nsource\n# Ribasim.set_flow! — Method.\nSet the given flow q over the edge between the given nodes.\nsource\n# Ribasim.set_fractional_flow_in_allocation! — Method.\nUpdate the fractional flow fractions in an allocation problem.\nsource\n# Ribasim.set_initial_capacities_basin! — Method.\nSet the initial capacity of each basin in the subnetwork as vertical fluxes + the disk of storage above the maximum level / Δt_allocation\nsource\n# Ribasim.set_initial_capacities_buffer! — Method.\nSet the flow buffer of nodes with a flow demand to 0.0\nsource\n# Ribasim.set_initial_capacities_edge! — Method.\nSet the capacities of the allocation flow edges as determined by the smallest maxflowrate of a node on this edge\nsource\n# Ribasim.set_initial_capacities_inlet! — Method.\nSet the capacities of the main network to subnetwork inlets. Per optimization type: internalsources: 0.0 collectdemands: Inf allocate: the total flow allocated to this inlet from the main network\nsource\n# Ribasim.set_initial_capacities_returnflow! — Method.\nSet the initial capacities of the UserDemand return flow sources to 0.\nsource\n# Ribasim.set_initial_capacities_source! — Method.\nSet the capacities of the sources in the subnetwork as the latest instantaneous flow out of the source in the physical layer\nsource\n# Ribasim.set_initial_demands_flow! — Method.\nSet the initial demands of the nodes with a flow demand to the interpolated value from the given timeseries.\nsource\n# Ribasim.set_initial_demands_level! — Method.\nSet the initial demand of each basin in the subnetwork as\n\nvertical fluxes + the disk of missing storage below the minimum level / Δt_allocation\n\nsource\n# Ribasim.set_initial_demands_user! — Method.\nSet the demands of the user demand nodes as given by either a coupled model or a timeseries\nsource\n# Ribasim.set_initial_discrete_controlled_parameters! — Method.\nSet parameters of nodes that are controlled by DiscreteControl to the values corresponding to the initial state of the model.\nsource\n# Ribasim.set_initial_values! — Method.\nSet the initial capacities and demands which are recudes by usage in the adjust*capacities**! and adjust*demands**! functions respectively.\nsource\n# Ribasim.set_is_pid_controlled! — Method.\nSet ispidcontrolled to true for those pumps and outlets that are PID controlled\nsource\n# Ribasim.set_objective_priority! — Method.\nSet the objective for the given priority. For an objective with absolute values this also involves adjusting constraints.\nsource\n# Ribasim.set_static_value! — Method.\nLoad data from a source table static into a destination table. Data is matched based on the node_id, which is sorted.\nsource\n# Ribasim.set_table_row! — Method.\nUpdate table at row index i, with the values of a given row. table must be a NamedTuple of vectors with all variables that must be loaded. The row must contain all the column names that are present in the table. If a value is missing, it is not set.\nsource\n# Ribasim.sorted_table! — Method.\nDepending on if a table can be sorted, either sort it or assert that it is sorted.\nTables loaded from the database into memory can be sorted. Tables loaded from Arrow files are memory mapped and can therefore not be sorted.\nsource\n# Ribasim.tsaves — Method.\nGet all saved times in seconds since start\nsource\n# Ribasim.update_allocation! — Method.\nSolve the allocation problem for all demands and assign allocated abstractions.\nsource\n# Ribasim.update_basin — Method.\nLoad updates from ‘Basin / time’ into the parameters\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for basins connected to eachother via 1 node and possibly a fractional flow node Basins are also assumed to depend on themselves (main diagonal terms)\nsource\n# Ribasim.update_jac_prototype! — Method.\nAdd nonzeros for the integral term and the basins on either side of the controlled node\nsource\n# Ribasim.update_tabulated_rating_curve! — Method.\nLoad updates from ‘TabulatedRatingCurve / time’ into the parameters\nsource\n# Ribasim.update_vertical_flux! — Method.\nSmoothly let the evaporation flux go to 0 when at small water depths Currently at less than 0.1 m.\nsource\n# Ribasim.valid_discrete_control — Method.\nCheck:\n\nwhether control states are defined for discrete controlled nodes;\nWhether the supplied truth states have the proper length;\nWhether look_ahead is only supplied for condition variables given by a time-series.\n\nsource\n# Ribasim.valid_edge_types — Method.\nCheck that only supported edge types are declared.\nsource\n# Ribasim.valid_edges — Method.\nTest for each node given its node type whether the nodes that\nare downstream (‘down-edge’) of this node are of an allowed type\nsource\n# Ribasim.valid_flow_rates — Method.\nTest whether static or discrete controlled flow rates are indeed non-negative.\nsource\n# Ribasim.valid_fractional_flow — Method.\nCheck that nodes that have fractional flow outneighbors do not have any other type of outneighbor, that the fractions leaving a node add up to ≈1 and that the fractions are non-negative.\nsource\n# Ribasim.valid_n_neighbors — Method.\nTest for each node given its node type whether it has an allowed number of flow/control inneighbors and outneighbors\nsource\n# Ribasim.valid_profiles — Method.\nCheck whether the profile data has no repeats in the levels and the areas start positive.\nsource\n# Ribasim.valid_sources — Method.\nThe source nodes must only have one allocation outneighbor and no allocation inneighbors.\nsource\n# Ribasim.valid_subgrid — Method.\nValidate the entries for a single subgrid element.\nsource\n# Ribasim.water_balance! — Method.\nThe right hand side function of the system of ODEs set up by Ribasim.\nsource\n# Ribasim.write_arrow — Method.\nWrite a result table to disk as an Arrow file\nsource\n# Ribasim.write_results — Method.\nwrite_results(model::Model)::Model\nWrite all results to the Arrow files as specified in the model configuration.\nsource\n# Ribasim.config.algorithm — Method.\nCreate an OrdinaryDiffEqAlgorithm from solver config\nsource\n# Ribasim.config.convert_dt — Method.\nConvert the dt from our Config to SciML stepsize control arguments\nsource\n# Ribasim.config.convert_saveat — Method.\nConvert the saveat Float64 from our Config to SciML’s saveat\nsource\n# Ribasim.config.input_path — Method.\nConstruct a path relative to both the TOML directory and the optional input_dir\nsource\n# Ribasim.config.results_path — Method.\nConstruct a path relative to both the TOML directory and the optional results_dir\nsource\n# Ribasim.config.snake_case — Method.\nConvert a string from CamelCase to snake_case.\nsource",
"crumbs": [
"Julia core",
"API Reference"
@@ -288,7 +288,7 @@
"href": "build/index.html#index",
"title": "1 API Reference",
"section": "1.6 Index",
- "text": "1.6 Index\n\nRibasim.Ribasim\nRibasim.config\nRibasim.config.algorithms\nRibasim.Allocation\nRibasim.AllocationModel\nRibasim.AllocationModel\nRibasim.Basin\nRibasim.DiscreteControl\nRibasim.EdgeMetadata\nRibasim.FlatVector\nRibasim.FlowBoundary\nRibasim.FractionalFlow\nRibasim.InNeighbors\nRibasim.LevelBoundary\nRibasim.LevelDemand\nRibasim.LinearResistance\nRibasim.ManningResistance\nRibasim.Model\nRibasim.NodeMetadata\nRibasim.OutNeighbors\nRibasim.Outlet\nRibasim.PidControl\nRibasim.Pump\nRibasim.Subgrid\nRibasim.TabulatedRatingCurve\nRibasim.Terminal\nRibasim.UserDemand\nRibasim.config.Config\nBasicModelInterface.finalize\nBasicModelInterface.initialize\nCommonSolve.solve!\nRibasim.add_basin_term!\nRibasim.add_constraints_absolute_value!\nRibasim.add_constraints_absolute_value_flow_demand!\nRibasim.add_constraints_absolute_value_level_demand!\nRibasim.add_constraints_absolute_value_user_demand!\nRibasim.add_constraints_basin_flow!\nRibasim.add_constraints_buffer!\nRibasim.add_constraints_capacity!\nRibasim.add_constraints_conservation_basin!\nRibasim.add_constraints_conservation_flow_demand!\nRibasim.add_constraints_conservation_subnetwork!\nRibasim.add_constraints_flow_demand_outflow!\nRibasim.add_constraints_fractional_flow!\nRibasim.add_constraints_source!\nRibasim.add_constraints_user_source!\nRibasim.add_flow_demand_term!\nRibasim.add_objective_term!\nRibasim.add_subnetwork_connections!\nRibasim.add_user_demand_term!\nRibasim.add_variables_absolute_value!\nRibasim.add_variables_basin!\nRibasim.add_variables_flow!\nRibasim.add_variables_flow_buffer!\nRibasim.adjust_capacities_basin!\nRibasim.adjust_capacities_buffer!\nRibasim.adjust_capacities_edge!\nRibasim.adjust_capacities_returnflow!\nRibasim.adjust_capacities_source!\nRibasim.adjust_demands_flow!\nRibasim.adjust_demands_level!\nRibasim.adjust_demands_user!\nRibasim.all_neighbor_labels_type\nRibasim.allocate!\nRibasim.allocation_graph\nRibasim.allocation_graph_used_nodes!\nRibasim.allocation_problem\nRibasim.allocation_table\nRibasim.assign_allocations!\nRibasim.basin_bottom\nRibasim.basin_table\nRibasim.config.algorithm\nRibasim.config.convert_dt\nRibasim.config.convert_saveat\nRibasim.config.input_path\nRibasim.config.results_path\nRibasim.config.snake_case\nRibasim.create_callbacks\nRibasim.create_graph\nRibasim.create_storage_tables\nRibasim.datetime_since\nRibasim.datetimes\nRibasim.discrete_control_affect!\nRibasim.discrete_control_affect_downcrossing!\nRibasim.discrete_control_affect_upcrossing!\nRibasim.discrete_control_condition\nRibasim.discrete_control_table\nRibasim.expand_logic_mapping\nRibasim.find_allocation_graph_edges!\nRibasim.find_subnetwork_connections!\nRibasim.findlastgroup\nRibasim.findsorted\nRibasim.flow_table\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.get_area_and_level\nRibasim.get_basin_capacity\nRibasim.get_basin_data\nRibasim.get_basin_demand\nRibasim.get_chunk_sizes\nRibasim.get_compressor\nRibasim.get_flow\nRibasim.get_fractional_flow_connected_basins\nRibasim.get_jac_prototype\nRibasim.get_level\nRibasim.get_scalar_interpolation\nRibasim.get_storage_from_level\nRibasim.get_storages_and_levels\nRibasim.get_storages_from_levels\nRibasim.get_tstops\nRibasim.get_value\nRibasim.get_Δt\nRibasim.id_index\nRibasim.indicate_allocation_flow!\nRibasim.inflow_id\nRibasim.inflow_ids\nRibasim.inflow_ids_allocation\nRibasim.inneighbor_labels_type\nRibasim.inoutflow_ids\nRibasim.integrate_flows!\nRibasim.is_allocation_source\nRibasim.is_current_module\nRibasim.is_flow_constraining\nRibasim.is_flow_direction_constraining\nRibasim.load_data\nRibasim.load_structvector\nRibasim.low_storage_factor\nRibasim.main\nRibasim.metadata_from_edge\nRibasim.nodefields\nRibasim.nodetype\nRibasim.outflow_id\nRibasim.outflow_ids\nRibasim.outflow_ids_allocation\nRibasim.outneighbor_labels_type\nRibasim.parse_static_and_time\nRibasim.pkgversion\nRibasim.process_allocation_graph_edges!\nRibasim.profile_storage\nRibasim.qh_interpolation\nRibasim.reduction_factor\nRibasim.run\nRibasim.save_allocation_flows!\nRibasim.save_demands_and_allocations!\nRibasim.save_flow\nRibasim.save_subgrid_level\nRibasim.save_vertical_flux\nRibasim.scalar_interpolation_derivative\nRibasim.seconds_since\nRibasim.set_capacities_flow_demand_outflow!\nRibasim.set_current_value!\nRibasim.set_flow!\nRibasim.set_fractional_flow_in_allocation!\nRibasim.set_initial_capacities_basin!\nRibasim.set_initial_capacities_buffer!\nRibasim.set_initial_capacities_edge!\nRibasim.set_initial_capacities_inlet!\nRibasim.set_initial_capacities_returnflow!\nRibasim.set_initial_capacities_source!\nRibasim.set_initial_demands_flow!\nRibasim.set_initial_demands_level!\nRibasim.set_initial_demands_user!\nRibasim.set_initial_discrete_controlled_parameters!\nRibasim.set_initial_values!\nRibasim.set_is_pid_controlled!\nRibasim.set_objective_priority!\nRibasim.set_static_value!\nRibasim.set_table_row!\nRibasim.sorted_table!\nRibasim.tsaves\nRibasim.update_allocation!\nRibasim.update_basin\nRibasim.update_jac_prototype!\nRibasim.update_jac_prototype!\nRibasim.update_tabulated_rating_curve!\nRibasim.update_vertical_flux!\nRibasim.valid_discrete_control\nRibasim.valid_edge_types\nRibasim.valid_edges\nRibasim.valid_flow_rates\nRibasim.valid_fractional_flow\nRibasim.valid_n_neighbors\nRibasim.valid_profiles\nRibasim.valid_sources\nRibasim.valid_subgrid\nRibasim.water_balance!\nRibasim.write_arrow\nRibasim.write_results\nRibasim.config.@addfields\nRibasim.config.@addnodetypes",
+ "text": "1.6 Index\n\nRibasim.Ribasim\nRibasim.config\nRibasim.config.algorithms\nRibasim.Allocation\nRibasim.AllocationModel\nRibasim.AllocationModel\nRibasim.Basin\nRibasim.DiscreteControl\nRibasim.EdgeMetadata\nRibasim.FlatVector\nRibasim.FlatVector\nRibasim.FlowBoundary\nRibasim.FractionalFlow\nRibasim.InNeighbors\nRibasim.LevelBoundary\nRibasim.LevelDemand\nRibasim.LinearResistance\nRibasim.ManningResistance\nRibasim.Model\nRibasim.NodeMetadata\nRibasim.OutNeighbors\nRibasim.Outlet\nRibasim.PidControl\nRibasim.Pump\nRibasim.SavedFlow\nRibasim.Subgrid\nRibasim.TabulatedRatingCurve\nRibasim.Terminal\nRibasim.UserDemand\nRibasim.config.Config\nBasicModelInterface.finalize\nBasicModelInterface.initialize\nCommonSolve.solve!\nRibasim.add_basin_term!\nRibasim.add_constraints_absolute_value!\nRibasim.add_constraints_absolute_value_flow_demand!\nRibasim.add_constraints_absolute_value_level_demand!\nRibasim.add_constraints_absolute_value_user_demand!\nRibasim.add_constraints_basin_flow!\nRibasim.add_constraints_buffer!\nRibasim.add_constraints_capacity!\nRibasim.add_constraints_conservation_basin!\nRibasim.add_constraints_conservation_flow_demand!\nRibasim.add_constraints_conservation_subnetwork!\nRibasim.add_constraints_flow_demand_outflow!\nRibasim.add_constraints_fractional_flow!\nRibasim.add_constraints_source!\nRibasim.add_constraints_user_source!\nRibasim.add_flow_demand_term!\nRibasim.add_objective_term!\nRibasim.add_subnetwork_connections!\nRibasim.add_user_demand_term!\nRibasim.add_variables_absolute_value!\nRibasim.add_variables_basin!\nRibasim.add_variables_flow!\nRibasim.add_variables_flow_buffer!\nRibasim.adjust_capacities_basin!\nRibasim.adjust_capacities_buffer!\nRibasim.adjust_capacities_edge!\nRibasim.adjust_capacities_returnflow!\nRibasim.adjust_capacities_source!\nRibasim.adjust_demands_flow!\nRibasim.adjust_demands_level!\nRibasim.adjust_demands_user!\nRibasim.all_neighbor_labels_type\nRibasim.allocate!\nRibasim.allocation_graph\nRibasim.allocation_graph_used_nodes!\nRibasim.allocation_problem\nRibasim.allocation_table\nRibasim.assign_allocations!\nRibasim.basin_bottom\nRibasim.basin_table\nRibasim.config.algorithm\nRibasim.config.convert_dt\nRibasim.config.convert_saveat\nRibasim.config.input_path\nRibasim.config.results_path\nRibasim.config.snake_case\nRibasim.create_callbacks\nRibasim.create_graph\nRibasim.create_storage_tables\nRibasim.datetime_since\nRibasim.datetimes\nRibasim.discrete_control_affect!\nRibasim.discrete_control_affect_downcrossing!\nRibasim.discrete_control_affect_upcrossing!\nRibasim.discrete_control_condition\nRibasim.discrete_control_table\nRibasim.expand_logic_mapping\nRibasim.find_allocation_graph_edges!\nRibasim.find_subnetwork_connections!\nRibasim.findlastgroup\nRibasim.findsorted\nRibasim.flow_table\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.formulate_flow!\nRibasim.get_area_and_level\nRibasim.get_basin_capacity\nRibasim.get_basin_data\nRibasim.get_basin_demand\nRibasim.get_chunk_sizes\nRibasim.get_compressor\nRibasim.get_flow\nRibasim.get_fractional_flow_connected_basins\nRibasim.get_jac_prototype\nRibasim.get_level\nRibasim.get_scalar_interpolation\nRibasim.get_storage_from_level\nRibasim.get_storages_and_levels\nRibasim.get_storages_from_levels\nRibasim.get_tstops\nRibasim.get_value\nRibasim.get_Δt\nRibasim.id_index\nRibasim.indicate_allocation_flow!\nRibasim.inflow_id\nRibasim.inflow_ids\nRibasim.inflow_ids_allocation\nRibasim.inneighbor_labels_type\nRibasim.inoutflow_ids\nRibasim.integrate_flows!\nRibasim.is_allocation_source\nRibasim.is_current_module\nRibasim.is_flow_constraining\nRibasim.is_flow_direction_constraining\nRibasim.load_data\nRibasim.load_structvector\nRibasim.low_storage_factor\nRibasim.main\nRibasim.metadata_from_edge\nRibasim.nodefields\nRibasim.nodetype\nRibasim.outflow_id\nRibasim.outflow_ids\nRibasim.outflow_ids_allocation\nRibasim.outneighbor_labels_type\nRibasim.parse_static_and_time\nRibasim.pkgversion\nRibasim.process_allocation_graph_edges!\nRibasim.profile_storage\nRibasim.qh_interpolation\nRibasim.reduction_factor\nRibasim.run\nRibasim.save_allocation_flows!\nRibasim.save_demands_and_allocations!\nRibasim.save_flow\nRibasim.save_subgrid_level\nRibasim.save_vertical_flux\nRibasim.scalar_interpolation_derivative\nRibasim.seconds\nRibasim.seconds_since\nRibasim.set_capacities_flow_demand_outflow!\nRibasim.set_current_value!\nRibasim.set_flow!\nRibasim.set_fractional_flow_in_allocation!\nRibasim.set_initial_capacities_basin!\nRibasim.set_initial_capacities_buffer!\nRibasim.set_initial_capacities_edge!\nRibasim.set_initial_capacities_inlet!\nRibasim.set_initial_capacities_returnflow!\nRibasim.set_initial_capacities_source!\nRibasim.set_initial_demands_flow!\nRibasim.set_initial_demands_level!\nRibasim.set_initial_demands_user!\nRibasim.set_initial_discrete_controlled_parameters!\nRibasim.set_initial_values!\nRibasim.set_is_pid_controlled!\nRibasim.set_objective_priority!\nRibasim.set_static_value!\nRibasim.set_table_row!\nRibasim.sorted_table!\nRibasim.tsaves\nRibasim.update_allocation!\nRibasim.update_basin\nRibasim.update_jac_prototype!\nRibasim.update_jac_prototype!\nRibasim.update_tabulated_rating_curve!\nRibasim.update_vertical_flux!\nRibasim.valid_discrete_control\nRibasim.valid_edge_types\nRibasim.valid_edges\nRibasim.valid_flow_rates\nRibasim.valid_fractional_flow\nRibasim.valid_n_neighbors\nRibasim.valid_profiles\nRibasim.valid_sources\nRibasim.valid_subgrid\nRibasim.water_balance!\nRibasim.write_arrow\nRibasim.write_results\nRibasim.config.@addfields\nRibasim.config.@addnodetypes",
"crumbs": [
"Julia core",
"API Reference"
@@ -732,7 +732,7 @@
"href": "core/usage.html#basin---basin.arrow",
"title": "Usage",
"section": "20.1 Basin - basin.arrow",
- "text": "20.1 Basin - basin.arrow\nThe Basin table contains:\n\nResults of the storage and level of each basin, which are instantaneous values;\nResults of the vertical fluxes on each basin, which are mean values over the saveat intervals. In the time column the start of the period is indicated.\nThe final state of the model is not part of this file, and will be placed in a separate output state file in the future.\n\nThe initial condition is also written to the file.\n\n\n\ncolumn\ntype\nunit\n\n\n\n\ntime\nDateTime\n-\n\n\nnode_id\nInt32\n-\n\n\nstorage\nFloat64\n\\(m^3\\)\n\n\nlevel\nFloat64\n\\(m\\)\n\n\nprecipitation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nevaporation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ndrainage\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ninfiltration\nFloat64\n\\(m^3 s^{-1}\\)\n\n\n\nThe table is sorted by time, and per time it is sorted by node_id.",
+ "text": "20.1 Basin - basin.arrow\nThe Basin table contains:\n\nResults of the storage and level of each Basin, which are instantaneous values;\nResults of the fluxes on each Basin, which are mean values over the saveat intervals. In the time column the start of the period is indicated.\nThe initial condition is written to the file, but the final state is not. It will be placed in a separate output state file in the future.\nThe inflow_rate and outflow_rate are the sum of the flows from other nodes into and out of the Basin respectively. The actual flows determine in which term they are counted, not the edge direction.\nThe storage_rate is flow that adds to the storage in the Basin, increasing the water level. In the equations below this number is split out into two non-negative numbers, storage_increase and storage_decrease.\nThe balance_error is the difference of all Basin inflows (total_inflow) and outflows (total_outflow), that is (inflow_rate + precipitation + drainage - storage_increase) - (outflow_rate + evaporation + infiltration - storage_decrease). It can be used to check if the numerical error when solving the water balance is sufficiently small.\nThe relative_error is the fraction of the balance_error over the mean of the total_inflow and total_outflow.\n\n\n\n\ncolumn\ntype\nunit\n\n\n\n\ntime\nDateTime\n-\n\n\nnode_id\nInt32\n-\n\n\nstorage\nFloat64\n\\(m^3\\)\n\n\nlevel\nFloat64\n\\(m\\)\n\n\ninflow_rate\nFloat64\n\\(m^3 s^{-1}\\)\n\n\noutflow_rate\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nstorage_rate\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nprecipitation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nevaporation\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ndrainage\nFloat64\n\\(m^3 s^{-1}\\)\n\n\ninfiltration\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nbalance_error\nFloat64\n\\(m^3 s^{-1}\\)\n\n\nrelative_error\nFloat64\n-\n\n\n\nThe table is sorted by time, and per time it is sorted by node_id.",
"crumbs": [
"Julia core",
"Usage"
@@ -819,7 +819,7 @@
"href": "core/equations.html#sec-reduction_factor",
"title": "Equations",
"section": "2.1 The reduction factor",
- "text": "2.1 The reduction factor\nAt several points in the equations below a reduction factor is used. This is a term that makes certain transitions more smooth, for instance when a pump stops providing water when its source basin dries up. The reduction factor is given by\n\\[\\begin{align}\n \\phi(x; p) =\n \\begin{cases}\n 0 &\\text{if}\\quad x < 0 \\\\\n -2 \\left(\\frac{x}{p}\\right)^3 + 3\\left(\\frac{x}{p}\\right)^2 &\\text{if}\\quad 0 \\le x \\le p \\\\\n 1 &\\text{if}\\quad x > p\n \\end{cases}\n\\end{align}\\]\nHere \\(p > 0\\) is the threshold value which determines the interval \\([0,p]\\) of the smooth transition between \\(0\\) and \\(1\\), see the plot below.\n\n\nCode\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef f(x, p = 3):\n x_scaled = x / p\n phi = (-2 * x_scaled + 3) * x_scaled**2\n phi = np.where(x < 0, 0, phi)\n phi = np.where(x > p, 1, phi)\n\n return phi\n\nfontsize = 15\np = 3\nN = 100\nx_min = -1\nx_max = 4\nx = np.linspace(x_min,x_max,N)\nphi = f(x,p)\n\nfig,ax = plt.subplots(dpi=80)\nax.plot(x,phi)\n\ny_lim = ax.get_ylim()\n\nax.set_xticks([0,p], [0,\"$p$\"], fontsize=fontsize)\nax.set_yticks([0,1], [0,1], fontsize=fontsize)\nax.hlines([0,1],x_min,x_max, color = \"k\", ls = \":\", zorder=-1)\nax.vlines([0,p], *y_lim, color = \"k\", ls = \":\")\nax.set_xlim(x_min,x_max)\nax.set_xlabel(\"$x$\", fontsize=fontsize)\nax.set_ylabel(\"$\\phi(x;p)$\", fontsize=fontsize)\nax.set_ylim(y_lim)\n\nfig.tight_layout()\nplt.show()\n\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n/tmp/ipykernel_5182/665069857.py:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'",
+ "text": "2.1 The reduction factor\nAt several points in the equations below a reduction factor is used. This is a term that makes certain transitions more smooth, for instance when a pump stops providing water when its source basin dries up. The reduction factor is given by\n\\[\\begin{align}\n \\phi(x; p) =\n \\begin{cases}\n 0 &\\text{if}\\quad x < 0 \\\\\n -2 \\left(\\frac{x}{p}\\right)^3 + 3\\left(\\frac{x}{p}\\right)^2 &\\text{if}\\quad 0 \\le x \\le p \\\\\n 1 &\\text{if}\\quad x > p\n \\end{cases}\n\\end{align}\\]\nHere \\(p > 0\\) is the threshold value which determines the interval \\([0,p]\\) of the smooth transition between \\(0\\) and \\(1\\), see the plot below.\n\n\nCode\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef f(x, p = 3):\n x_scaled = x / p\n phi = (-2 * x_scaled + 3) * x_scaled**2\n phi = np.where(x < 0, 0, phi)\n phi = np.where(x > p, 1, phi)\n\n return phi\n\nfontsize = 15\np = 3\nN = 100\nx_min = -1\nx_max = 4\nx = np.linspace(x_min,x_max,N)\nphi = f(x,p)\n\nfig,ax = plt.subplots(dpi=80)\nax.plot(x,phi)\n\ny_lim = ax.get_ylim()\n\nax.set_xticks([0,p], [0,\"$p$\"], fontsize=fontsize)\nax.set_yticks([0,1], [0,1], fontsize=fontsize)\nax.hlines([0,1],x_min,x_max, color = \"k\", ls = \":\", zorder=-1)\nax.vlines([0,p], *y_lim, color = \"k\", ls = \":\")\nax.set_xlim(x_min,x_max)\nax.set_xlabel(\"$x$\", fontsize=fontsize)\nax.set_ylabel(\"$\\phi(x;p)$\", fontsize=fontsize)\nax.set_ylim(y_lim)\n\nfig.tight_layout()\nplt.show()\n\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n<>:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'\n\n/tmp/ipykernel_5125/665069857.py:31: SyntaxWarning:\n\ninvalid escape sequence '\\p'",
"crumbs": [
"Julia core",
"Equations"
@@ -973,7 +973,7 @@
"href": "core/allocation.html#example",
"title": "Allocation",
"section": "4.4 Example",
- "text": "4.4 Example\nThe following is an example of an optimization problem for the example shown here:\n\n\nCode\nusing Ribasim\nusing Ribasim: NodeID\nusing SQLite\nusing ComponentArrays: ComponentVector\n\ntoml_path = normpath(@__DIR__, \"../../generated_testmodels/allocation_example/ribasim.toml\")\np = Ribasim.Model(toml_path).integrator.p\nu = ComponentVector(; storage = zeros(length(p.basin.node_id)))\n\nallocation_model = p.allocation.allocation_models[1]\nt = 0.0\npriority_idx = 1\n\nRibasim.set_flow!(p.graph, NodeID(:FlowBoundary, 1), NodeID(:Basin, 2), 1.0)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\nRibasim.set_initial_values!(allocation_model, p, u, t)\n\nprintln(p.allocation.allocation_models[1].problem)\n\n\nMin F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #6] + F_abs_user_demand[UserDemand #13] + F_abs_level_demand[Basin #2] + F_abs_level_demand[Basin #12] + F_abs_level_demand[Basin #5]\nSubject to\n abs_positive_user_demand[UserDemand #3] : -F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_positive_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_negative_user_demand[UserDemand #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n F_basin_out[Basin #12] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n F[(UserDemand #3, Basin #2)] ≤ 0\n F[(UserDemand #6, Basin #5)] ≤ 0\n F[(UserDemand #13, Terminal #10)] ≤ 0\n fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : F[(TabulatedRatingCurve #7, Basin #12)] - 0.4 F[(Basin #5, TabulatedRatingCurve #7)] ≤ 0\n basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0\n flow_conservation_basin[Basin #2] : -F[(UserDemand #3, Basin #2)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] - F[(Basin #5, Basin #2)] + F[(Basin #2, UserDemand #3)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0\n flow_conservation_basin[Basin #12] : -F[(TabulatedRatingCurve #7, Basin #12)] + F[(Basin #12, UserDemand #13)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\n flow_conservation_basin[Basin #5] : F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F[(Basin #5, TabulatedRatingCurve #7)] - F[(UserDemand #6, Basin #5)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0",
+ "text": "4.4 Example\nThe following is an example of an optimization problem for the example shown here:\n\n\nCode\nusing Ribasim\nusing Ribasim: NodeID\nusing SQLite\nusing ComponentArrays: ComponentVector\n\ntoml_path = normpath(@__DIR__, \"../../generated_testmodels/allocation_example/ribasim.toml\")\np = Ribasim.Model(toml_path).integrator.p\nu = ComponentVector(; storage = zeros(length(p.basin.node_id)))\n\nallocation_model = p.allocation.allocation_models[1]\nt = 0.0\npriority_idx = 1\n\nRibasim.set_flow!(p.graph, NodeID(:FlowBoundary, 1), NodeID(:Basin, 2), 1.0)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\nRibasim.set_initial_values!(allocation_model, p, u, t)\n\nprintln(p.allocation.allocation_models[1].problem)\n\n\nMin F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #6] + F_abs_level_demand[Basin #5] + F_abs_level_demand[Basin #12] + F_abs_level_demand[Basin #2]\nSubject to\n abs_positive_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_positive_user_demand[UserDemand #3] : -F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_negative_user_demand[UserDemand #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_level_demand[Basin #12] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_level_demand[Basin #2] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n F_basin_out[Basin #12] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n F[(UserDemand #13, Terminal #10)] ≤ 0\n F[(UserDemand #3, Basin #2)] ≤ 0\n F[(UserDemand #6, Basin #5)] ≤ 0\n fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : -0.4 F[(Basin #5, TabulatedRatingCurve #7)] + F[(TabulatedRatingCurve #7, Basin #12)] ≤ 0\n basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0\n flow_conservation_basin[Basin #5] : F[(Basin #5, UserDemand #6)] + F[(Basin #5, TabulatedRatingCurve #7)] - F[(Basin #2, Basin #5)] - F[(UserDemand #6, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation_basin[Basin #12] : F[(Basin #12, UserDemand #13)] - F[(TabulatedRatingCurve #7, Basin #12)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\n flow_conservation_basin[Basin #2] : -F[(FlowBoundary #1, Basin #2)] - F[(UserDemand #3, Basin #2)] + F[(Basin #2, Basin #5)] + F[(Basin #2, UserDemand #3)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0",
"crumbs": [
"Julia core",
"Allocation"