Code
using Ribasim
@@ -648,44 +648,44 @@ println(p.allocation.allocation_models[1].problem)
Min F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #6] + F_abs_basin[Basin #2] + F_abs_basin[Basin #5] + F_abs_basin[Basin #12]
+Min F_abs_user_demand[UserDemand #6] + F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #13] + F_abs_basin[Basin #5] + F_abs_basin[Basin #2] + F_abs_basin[Basin #12]
Subject to
- flow_conservation[Basin #2] : F[(Basin #2, UserDemand #3)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0
flow_conservation[Basin #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0
- flow_conservation[Basin #12] : F[(Basin #12, UserDemand #13)] - F[(TabulatedRatingCurve #7, Basin #12)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0
- 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
+ flow_conservation[Basin #2] : F[(Basin #2, UserDemand #3)] + F[(Basin #2, Basin #5)] - F[(FlowBoundary #1, Basin #2)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0
+ flow_conservation[Basin #12] : -F[(TabulatedRatingCurve #7, Basin #12)] + F[(Basin #12, UserDemand #13)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0
abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ -1.5
- 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_positive_user_demand[UserDemand #3] : -F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0
+ abs_positive_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0
abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 1.5
- abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0
+ abs_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0
+ abs_negative_user_demand[UserDemand #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0
abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0
+ abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0
abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0
- abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0
abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0
+ abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0
abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0
source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1
return_flow[UserDemand #13] : F[(UserDemand #13, Terminal #10)] ≤ 0
fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : -0.4 F[(Basin #5, TabulatedRatingCurve #7)] + F[(TabulatedRatingCurve #7, Basin #12)] ≤ 0
- basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0
basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0
+ basin_outflow[Basin #2] : F_basin_out[Basin #2] ≤ 0
basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0
F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0
- F[(Basin #12, UserDemand #13)] ≥ 0
+ F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0
+ F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0
F[(Basin #2, UserDemand #3)] ≥ 0
F[(Basin #5, UserDemand #6)] ≥ 0
- F[(FlowBoundary #1, Basin #2)] ≥ 0
+ F[(Basin #12, UserDemand #13)] ≥ 0
F[(Basin #2, Basin #5)] ≥ 0
- F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0
+ F[(FlowBoundary #1, Basin #2)] ≥ 0
F[(Basin #5, Basin #2)] ≥ 0
- F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0
F[(UserDemand #13, Terminal #10)] ≥ 0
- F_basin_in[Basin #2] ≥ 0
F_basin_in[Basin #5] ≥ 0
+ F_basin_in[Basin #2] ≥ 0
F_basin_in[Basin #12] ≥ 0
- F_basin_out[Basin #2] ≥ 0
F_basin_out[Basin #5] ≥ 0
+ F_basin_out[Basin #2] ≥ 0
F_basin_out[Basin #12] ≥ 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
diff --git a/core/validation.html b/core/validation.html
index 0b8663bfc..c6da4e0c1 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-71-output-1.png b/python/examples_files/figure-html/cell-71-output-1.png
index 3ef67556a..acca048b7 100644
Binary files a/python/examples_files/figure-html/cell-71-output-1.png and b/python/examples_files/figure-html/cell-71-output-1.png differ
diff --git a/python/test-models.html b/python/test-models.html
index d4d61a38c..27a82b752 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 a649a02a9..2d56cc9a5 100644
--- a/search.json
+++ b/search.json
@@ -15,7 +15,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.\nobjectivetype: The name of the type of objective used allocationnetworkid: 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 Δtallocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nconfig: The model configuration with allocation configuration in config.allocation 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.\ndemand: 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. active: whether this node is active and thus demands water 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 minlevel: 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.\nobjectivetype: The name of the type of objective used allocationnetworkid: 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 Δtallocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nconfig: The model configuration with allocation configuration in config.allocation 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.\ndemand: 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. realizedbmi: Cumulative inflow volume, for read or reset by BMI only. active: whether this node is active and thus demands water 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"
@@ -850,7 +850,7 @@
"href": "core/allocation.html#example",
"title": "Allocation",
"section": "5.1 Example",
- "text": "5.1 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)\n\nRibasim.adjust_source_capacities!(allocation_model, p, priority_idx)\nRibasim.adjust_edge_capacities!(allocation_model, p, priority_idx)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\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_basin[Basin #2] + F_abs_basin[Basin #5] + F_abs_basin[Basin #12]\nSubject to\n flow_conservation[Basin #2] : F[(Basin #2, UserDemand #3)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0\n flow_conservation[Basin #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation[Basin #12] : F[(Basin #12, UserDemand #13)] - F[(TabulatedRatingCurve #7, Basin #12)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\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] ≥ -1.5\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] ≥ 1.5\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n return_flow[UserDemand #13] : F[(UserDemand #13, Terminal #10)] ≤ 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 #2] : F_basin_out[Basin #2] ≤ 0\n basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n F_basin_out[Basin #12] ≥ 0",
+ "text": "5.1 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)\n\nRibasim.adjust_source_capacities!(allocation_model, p, priority_idx)\nRibasim.adjust_edge_capacities!(allocation_model, p, priority_idx)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\n\nprintln(p.allocation.allocation_models[1].problem)\n\n\nMin F_abs_user_demand[UserDemand #6] + F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #13] + F_abs_basin[Basin #5] + F_abs_basin[Basin #2] + F_abs_basin[Basin #12]\nSubject to\n flow_conservation[Basin #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation[Basin #2] : F[(Basin #2, UserDemand #3)] + F[(Basin #2, Basin #5)] - F[(FlowBoundary #1, Basin #2)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0\n flow_conservation[Basin #12] : -F[(TabulatedRatingCurve #7, Basin #12)] + F[(Basin #12, UserDemand #13)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\n abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ -1.5\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 #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 1.5\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 #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n return_flow[UserDemand #13] : F[(UserDemand #13, Terminal #10)] ≤ 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 #2] : F_basin_out[Basin #2] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n F_basin_out[Basin #12] ≥ 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
diff --git a/core/validation.html b/core/validation.html
index 0b8663bfc..c6da4e0c1 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-71-output-1.png b/python/examples_files/figure-html/cell-71-output-1.png
index 3ef67556a..acca048b7 100644
Binary files a/python/examples_files/figure-html/cell-71-output-1.png and b/python/examples_files/figure-html/cell-71-output-1.png differ
diff --git a/python/test-models.html b/python/test-models.html
index d4d61a38c..27a82b752 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 a649a02a9..2d56cc9a5 100644
--- a/search.json
+++ b/search.json
@@ -15,7 +15,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.\nobjectivetype: The name of the type of objective used allocationnetworkid: 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 Δtallocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nconfig: The model configuration with allocation configuration in config.allocation 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.\ndemand: 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. active: whether this node is active and thus demands water 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 minlevel: 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.\nobjectivetype: The name of the type of objective used allocationnetworkid: 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 Δtallocation: The time interval between consecutive allocation solves\nsource\n# Ribasim.AllocationModel — Method.\nConstruct the JuMP.jl problem for allocation.\nInputs\nconfig: The model configuration with allocation configuration in config.allocation 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.\ndemand: 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. realizedbmi: Cumulative inflow volume, for read or reset by BMI only. active: whether this node is active and thus demands water 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"
@@ -850,7 +850,7 @@
"href": "core/allocation.html#example",
"title": "Allocation",
"section": "5.1 Example",
- "text": "5.1 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)\n\nRibasim.adjust_source_capacities!(allocation_model, p, priority_idx)\nRibasim.adjust_edge_capacities!(allocation_model, p, priority_idx)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\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_basin[Basin #2] + F_abs_basin[Basin #5] + F_abs_basin[Basin #12]\nSubject to\n flow_conservation[Basin #2] : F[(Basin #2, UserDemand #3)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0\n flow_conservation[Basin #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation[Basin #12] : F[(Basin #12, UserDemand #13)] - F[(TabulatedRatingCurve #7, Basin #12)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\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] ≥ -1.5\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] ≥ 1.5\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n return_flow[UserDemand #13] : F[(UserDemand #13, Terminal #10)] ≤ 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 #2] : F_basin_out[Basin #2] ≤ 0\n basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n F_basin_out[Basin #12] ≥ 0",
+ "text": "5.1 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)\n\nRibasim.adjust_source_capacities!(allocation_model, p, priority_idx)\nRibasim.adjust_edge_capacities!(allocation_model, p, priority_idx)\nRibasim.set_objective_priority!(allocation_model, p, u, t, priority_idx)\n\nprintln(p.allocation.allocation_models[1].problem)\n\n\nMin F_abs_user_demand[UserDemand #6] + F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #13] + F_abs_basin[Basin #5] + F_abs_basin[Basin #2] + F_abs_basin[Basin #12]\nSubject to\n flow_conservation[Basin #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, UserDemand #6)] - F[(Basin #2, Basin #5)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation[Basin #2] : F[(Basin #2, UserDemand #3)] + F[(Basin #2, Basin #5)] - F[(FlowBoundary #1, Basin #2)] - F[(Basin #5, Basin #2)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 0\n flow_conservation[Basin #12] : -F[(TabulatedRatingCurve #7, Basin #12)] + F[(Basin #12, UserDemand #13)] + F_basin_in[Basin #12] - F_basin_out[Basin #12] = 0\n abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ -1.5\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 #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 1.5\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 #13] : F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_positive_basin[Basin #2] : -F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_positive_basin[Basin #12] : -F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_basin[Basin #5] ≥ 0\n abs_negative_basin[Basin #2] : F_basin_in[Basin #2] + F_abs_basin[Basin #2] ≥ 0\n abs_negative_basin[Basin #12] : F_basin_in[Basin #12] + F_abs_basin[Basin #12] ≥ 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n return_flow[UserDemand #13] : F[(UserDemand #13, Terminal #10)] ≤ 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 #2] : F_basin_out[Basin #2] ≤ 0\n basin_outflow[Basin #12] : F_basin_out[Basin #12] ≤ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F_basin_in[Basin #5] ≥ 0\n F_basin_in[Basin #2] ≥ 0\n F_basin_in[Basin #12] ≥ 0\n F_basin_out[Basin #5] ≥ 0\n F_basin_out[Basin #2] ≥ 0\n F_basin_out[Basin #12] ≥ 0",
"crumbs": [
"Julia core",
"Allocation"