Code
using Ribasim
@@ -590,49 +590,49 @@ println(p.allocation.allocation_models[1].problem)
Min F_abs_user_demand[UserDemand #6] + F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #3] + F_abs_level_demand[Basin #5] + F_abs_level_demand[Basin #2] + F_abs_level_demand[Basin #12]
+Min F_abs_user_demand[UserDemand #3] + F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #6] + F_abs_level_demand[Basin #2] + F_abs_level_demand[Basin #12] + F_abs_level_demand[Basin #5]
Subject to
- 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_positive_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_user_demand[UserDemand #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 0
+ abs_positive_user_demand[UserDemand #6] : -F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 0
abs_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0
- abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0
+ abs_negative_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] ≥ 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_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 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
- F[(Basin #2, Basin #5)] ≥ 0
- F[(UserDemand #13, Terminal #10)] ≥ 0
- F[(UserDemand #6, Basin #5)] ≥ 0
- F[(FlowBoundary #1, Basin #2)] ≥ 0
- F[(Basin #2, UserDemand #3)] ≥ 0
- F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0
- F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0
+ abs_negative_basin[Basin #5] : F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 0
F[(UserDemand #3, Basin #2)] ≥ 0
- F[(Basin #5, UserDemand #6)] ≥ 0
- F[(Basin #12, UserDemand #13)] ≥ 0
+ F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0
F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0
F[(Basin #5, Basin #2)] ≥ 0
- F_basin_in[Basin #5] ≥ 0
+ F[(FlowBoundary #1, Basin #2)] ≥ 0
+ F[(Basin #5, UserDemand #6)] ≥ 0
+ F[(UserDemand #6, Basin #5)] ≥ 0
+ F[(Basin #12, UserDemand #13)] ≥ 0
+ F[(Basin #2, Basin #5)] ≥ 0
+ F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0
+ F[(Basin #2, UserDemand #3)] ≥ 0
+ F[(UserDemand #13, Terminal #10)] ≥ 0
F_basin_in[Basin #2] ≥ 0
F_basin_in[Basin #12] ≥ 0
- F_basin_out[Basin #5] ≥ 0
+ F_basin_in[Basin #5] ≥ 0
F_basin_out[Basin #2] ≥ 0
F_basin_out[Basin #12] ≥ 0
+ F_basin_out[Basin #5] ≥ 0
source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1
- F[(UserDemand #6, Basin #5)] ≤ 0
- F[(UserDemand #13, Terminal #10)] ≤ 0
F[(UserDemand #3, Basin #2)] ≤ 0
- fractional_flow[(TabulatedRatingCurve #7, Basin #12)] : F[(TabulatedRatingCurve #7, Basin #12)] - 0.4 F[(Basin #5, TabulatedRatingCurve #7)] ≤ 0
- basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0
+ F[(UserDemand #13, Terminal #10)] ≤ 0
+ F[(UserDemand #6, Basin #5)] ≤ 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 #12] : F_basin_out[Basin #12] ≤ 0
- flow_conservation_basin[Basin #5] : -F[(Basin #2, Basin #5)] - F[(UserDemand #6, Basin #5)] + F[(Basin #5, UserDemand #6)] + F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0
- flow_conservation_basin[Basin #2] : F[(Basin #2, Basin #5)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, UserDemand #3)] - F[(UserDemand #3, Basin #2)] - F[(Basin #5, Basin #2)] + 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
+ basin_outflow[Basin #5] : F_basin_out[Basin #5] ≤ 0
+ flow_conservation_basin[Basin #2] : -F[(UserDemand #3, Basin #2)] - F[(Basin #5, Basin #2)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] + F[(Basin #2, UserDemand #3)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 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 #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, Basin #2)] + F[(Basin #5, UserDemand #6)] - F[(UserDemand #6, Basin #5)] - F[(Basin #2, Basin #5)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 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/validation.html b/core/validation.html
index b0d68fd73..bff939113 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 a8716877a..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 bf85e3825..0ca7ac3e7 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 16c3c39aa..d4b58c367 100644
--- a/search.json
+++ b/search.json
@@ -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_5285/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_5033/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 #6] + F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #3] + F_abs_level_demand[Basin #5] + F_abs_level_demand[Basin #2] + F_abs_level_demand[Basin #12]\nSubject to\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_positive_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_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 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_negative_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 F[(Basin #2, Basin #5)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 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\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n F[(UserDemand #6, Basin #5)] ≤ 0\n F[(UserDemand #13, Terminal #10)] ≤ 0\n F[(UserDemand #3, Basin #2)] ≤ 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 #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 flow_conservation_basin[Basin #5] : -F[(Basin #2, Basin #5)] - F[(UserDemand #6, Basin #5)] + F[(Basin #5, UserDemand #6)] + F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation_basin[Basin #2] : F[(Basin #2, Basin #5)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, UserDemand #3)] - F[(UserDemand #3, Basin #2)] - F[(Basin #5, Basin #2)] + 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",
+ "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 #13] + F_abs_user_demand[UserDemand #6] + 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 #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 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 #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_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 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[(UserDemand #3, Basin #2)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 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 #13, Terminal #10)] ≤ 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 #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[(Basin #5, Basin #2)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] + F[(Basin #2, UserDemand #3)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 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 #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, Basin #2)] + F[(Basin #5, UserDemand #6)] - F[(UserDemand #6, Basin #5)] - F[(Basin #2, Basin #5)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 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/validation.html b/core/validation.html
index b0d68fd73..bff939113 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 a8716877a..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 bf85e3825..0ca7ac3e7 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 16c3c39aa..d4b58c367 100644
--- a/search.json
+++ b/search.json
@@ -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_5285/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_5033/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 #6] + F_abs_user_demand[UserDemand #13] + F_abs_user_demand[UserDemand #3] + F_abs_level_demand[Basin #5] + F_abs_level_demand[Basin #2] + F_abs_level_demand[Basin #12]\nSubject to\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_positive_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_negative_user_demand[UserDemand #3] : F[(Basin #2, UserDemand #3)] + F_abs_user_demand[UserDemand #3] ≥ 0\n abs_positive_basin[Basin #5] : -F_basin_in[Basin #5] + F_abs_level_demand[Basin #5] ≥ 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_negative_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 F[(Basin #2, Basin #5)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 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\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 1\n F[(UserDemand #6, Basin #5)] ≤ 0\n F[(UserDemand #13, Terminal #10)] ≤ 0\n F[(UserDemand #3, Basin #2)] ≤ 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 #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 flow_conservation_basin[Basin #5] : -F[(Basin #2, Basin #5)] - F[(UserDemand #6, Basin #5)] + F[(Basin #5, UserDemand #6)] + F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, Basin #2)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0\n flow_conservation_basin[Basin #2] : F[(Basin #2, Basin #5)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, UserDemand #3)] - F[(UserDemand #3, Basin #2)] - F[(Basin #5, Basin #2)] + 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",
+ "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 #13] + F_abs_user_demand[UserDemand #6] + 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 #13] : -F[(Basin #12, UserDemand #13)] + F_abs_user_demand[UserDemand #13] ≥ 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 #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_negative_user_demand[UserDemand #6] : F[(Basin #5, UserDemand #6)] + F_abs_user_demand[UserDemand #6] ≥ 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[(UserDemand #3, Basin #2)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #10)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #5, Basin #2)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(Basin #12, UserDemand #13)] ≥ 0\n F[(Basin #2, Basin #5)] ≥ 0\n F[(TabulatedRatingCurve #7, Basin #12)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(UserDemand #13, Terminal #10)] ≥ 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 #13, Terminal #10)] ≤ 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 #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[(Basin #5, Basin #2)] - F[(FlowBoundary #1, Basin #2)] + F[(Basin #2, Basin #5)] + F[(Basin #2, UserDemand #3)] + F_basin_in[Basin #2] - F_basin_out[Basin #2] = 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 #5] : F[(Basin #5, TabulatedRatingCurve #7)] + F[(Basin #5, Basin #2)] + F[(Basin #5, UserDemand #6)] - F[(UserDemand #6, Basin #5)] - F[(Basin #2, Basin #5)] + F_basin_in[Basin #5] - F_basin_out[Basin #5] = 0",
"crumbs": [
"Julia core",
"Allocation"