diff --git a/CNAME b/CNAME deleted file mode 100644 index 088592015..000000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -www.ribasim.org \ No newline at end of file diff --git a/concept/allocation.html b/concept/allocation.html index 213ce6c7d..5408cc26a 100644 --- a/concept/allocation.html +++ b/concept/allocation.html @@ -584,7 +584,7 @@

4.4 Example

The following is an example of an optimization problem for the example shown here:

-
+
Code
using Ribasim
@@ -607,27 +607,27 @@ 

println(p.allocation.allocation_models[1].problem)

-
Min F[(Basin #2, UserDemand #3)]² + F[(Basin #5, UserDemand #6)]²
+
Min F[(Basin #5, UserDemand #6)]² + F[(Basin #2, UserDemand #3)]²
 Subject to
  F[(LinearResistance #4, Basin #5)] ≥ 0
  F[(Basin #5, LinearResistance #4)] ≥ 0
- F[(UserDemand #3, Basin #2)] ≥ 0
+ F[(Basin #5, UserDemand #6)] ≥ 0
  F[(UserDemand #6, Basin #5)] ≥ 0
- F[(Basin #2, UserDemand #3)] ≥ 0
- F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0
  F[(Basin #2, LinearResistance #4)] ≥ 0
  F[(LinearResistance #4, Basin #2)] ≥ 0
- F[(Basin #5, UserDemand #6)] ≥ 0
- F[(TabulatedRatingCurve #7, Terminal #8)] ≥ 0
+ F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0
+ F[(Basin #2, UserDemand #3)] ≥ 0
  F[(FlowBoundary #1, Basin #2)] ≥ 0
- flow_conservation[Basin #5] : F[(LinearResistance #4, Basin #5)] - F[(Basin #5, LinearResistance #4)] + F[(UserDemand #6, Basin #5)] - F[(Basin #5, TabulatedRatingCurve #7)] - F[(Basin #5, UserDemand #6)] = 0
- flow_conservation[LinearResistance #4] : -F[(LinearResistance #4, Basin #5)] + F[(Basin #5, LinearResistance #4)] + F[(Basin #2, LinearResistance #4)] - F[(LinearResistance #4, Basin #2)] = 0
- flow_conservation[Terminal #8] : F[(TabulatedRatingCurve #7, Terminal #8)] = 0
- flow_conservation[Basin #2] : F[(UserDemand #3, Basin #2)] - F[(Basin #2, UserDemand #3)] - F[(Basin #2, LinearResistance #4)] + F[(LinearResistance #4, Basin #2)] + F[(FlowBoundary #1, Basin #2)] = 0
+ F[(UserDemand #3, Basin #2)] ≥ 0
+ F[(TabulatedRatingCurve #7, Terminal #8)] ≥ 0
  flow_conservation[TabulatedRatingCurve #7] : F[(Basin #5, TabulatedRatingCurve #7)] - F[(TabulatedRatingCurve #7, Terminal #8)] = 0
+ flow_conservation[Basin #5] : F[(LinearResistance #4, Basin #5)] - F[(Basin #5, LinearResistance #4)] - F[(Basin #5, UserDemand #6)] + F[(UserDemand #6, Basin #5)] - F[(Basin #5, TabulatedRatingCurve #7)] = 0
+ flow_conservation[Basin #2] : -F[(Basin #2, LinearResistance #4)] + F[(LinearResistance #4, Basin #2)] - F[(Basin #2, UserDemand #3)] + F[(FlowBoundary #1, Basin #2)] + F[(UserDemand #3, Basin #2)] = 0
+ flow_conservation[Terminal #8] : F[(TabulatedRatingCurve #7, Terminal #8)] = 0
+ flow_conservation[LinearResistance #4] : -F[(LinearResistance #4, Basin #5)] + F[(Basin #5, LinearResistance #4)] + F[(Basin #2, LinearResistance #4)] - F[(LinearResistance #4, Basin #2)] = 0
  source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 172800
- source_user[UserDemand #6] : F[(UserDemand #6, Basin #5)] ≤ 0
  source_user[UserDemand #3] : F[(UserDemand #3, Basin #2)] ≤ 0
+ source_user[UserDemand #6] : F[(UserDemand #6, Basin #5)] ≤ 0
 
diff --git a/guide/examples.html b/guide/examples.html index 4637b31d8..58e623e64 100644 --- a/guide/examples.html +++ b/guide/examples.html @@ -383,7 +383,7 @@

1 Basic model wit
q = 10 / 86400  # 10 m³/day
 tabulated_rating_curve4 = model.tabulated_rating_curve.add(
-    Node(8, Point(4.0, 0.0)),
+    Node(8, Point(3.0, -1.0)),
     [
         tabulated_rating_curve.Static(
             level=[0.0, 1.0],
@@ -401,7 +401,7 @@ 

1 Basic model wit ], ) tabulated_rating_curve8 = model.tabulated_rating_curve.add( - Node(4, Point(3.0, -1.0)), + Node(4, Point(4.0, 0.0)), [ tabulated_rating_curve.Static( level=[0.0, 1.0], diff --git a/guide/examples_files/figure-html/cell-15-output-1.png b/guide/examples_files/figure-html/cell-15-output-1.png index 0bff89610..27f0b48ee 100644 Binary files a/guide/examples_files/figure-html/cell-15-output-1.png and b/guide/examples_files/figure-html/cell-15-output-1.png differ diff --git a/guide/examples_files/figure-html/cell-18-output-1.png b/guide/examples_files/figure-html/cell-18-output-1.png index 1398c8375..76e96a45c 100644 Binary files a/guide/examples_files/figure-html/cell-18-output-1.png and b/guide/examples_files/figure-html/cell-18-output-1.png differ diff --git a/guide/examples_files/figure-html/cell-19-output-1.png b/guide/examples_files/figure-html/cell-19-output-1.png index f27278240..696a52df0 100644 Binary files a/guide/examples_files/figure-html/cell-19-output-1.png and b/guide/examples_files/figure-html/cell-19-output-1.png differ diff --git a/guide/examples_files/figure-html/cell-56-output-1.png b/guide/examples_files/figure-html/cell-56-output-1.png index 4dd26aa63..5a08ff5da 100644 Binary files a/guide/examples_files/figure-html/cell-56-output-1.png and b/guide/examples_files/figure-html/cell-56-output-1.png differ diff --git a/guide/examples_files/figure-html/cell-57-output-2.png b/guide/examples_files/figure-html/cell-57-output-2.png index cb96e6502..21fb09e0d 100644 Binary files a/guide/examples_files/figure-html/cell-57-output-2.png and b/guide/examples_files/figure-html/cell-57-output-2.png differ diff --git a/guide/examples_files/figure-html/cell-68-output-1.png b/guide/examples_files/figure-html/cell-68-output-1.png index 5c3059fa4..7a588082d 100644 Binary files a/guide/examples_files/figure-html/cell-68-output-1.png and b/guide/examples_files/figure-html/cell-68-output-1.png differ diff --git a/reference/node/basin.html b/reference/node/basin.html index 54f4474aa..3b783c351 100644 --- a/reference/node/basin.html +++ b/reference/node/basin.html @@ -832,7 +832,7 @@

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/reference/node/discrete-control.html b/reference/node/discrete-control.html
index ce9d172fb..c9fbb7f81 100644
--- a/reference/node/discrete-control.html
+++ b/reference/node/discrete-control.html
@@ -386,7 +386,7 @@ 

DiscreteControl

Set parameters of other nodes based on model state conditions (e.g. Basin level). The table below shows which parameters are controllable for a given node type.

-
+
Code
using Ribasim
diff --git a/reference/test-models.html b/reference/test-models.html
index 01642ccba..da1abd2b6 100644
--- a/reference/test-models.html
+++ b/reference/test-models.html
@@ -346,7 +346,7 @@ 

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/reference/test-models_files/figure-html/cell-2-output-39.png b/reference/test-models_files/figure-html/cell-2-output-39.png
index cd690187d..8824681e6 100644
Binary files a/reference/test-models_files/figure-html/cell-2-output-39.png and b/reference/test-models_files/figure-html/cell-2-output-39.png differ
diff --git a/reference/validation.html b/reference/validation.html
index e8cebc624..af8623f8f 100644
--- a/reference/validation.html
+++ b/reference/validation.html
@@ -356,7 +356,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
@@ -706,7 +706,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
flow_in_min = Vector{String}()
diff --git a/search.json b/search.json
index 5f233e2d1..01168a51c 100644
--- a/search.json
+++ b/search.json
@@ -99,7 +99,7 @@
     "href": "concept/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, p), NodeID(:Basin, 2, p), 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[(Basin #2, UserDemand #3)]² + F[(Basin #5, UserDemand #6)]²\nSubject to\n F[(LinearResistance #4, Basin #5)] ≥ 0\n F[(Basin #5, LinearResistance #4)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #2, LinearResistance #4)] ≥ 0\n F[(LinearResistance #4, Basin #2)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #8)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n flow_conservation[Basin #5] : F[(LinearResistance #4, Basin #5)] - F[(Basin #5, LinearResistance #4)] + F[(UserDemand #6, Basin #5)] - F[(Basin #5, TabulatedRatingCurve #7)] - F[(Basin #5, UserDemand #6)] = 0\n flow_conservation[LinearResistance #4] : -F[(LinearResistance #4, Basin #5)] + F[(Basin #5, LinearResistance #4)] + F[(Basin #2, LinearResistance #4)] - F[(LinearResistance #4, Basin #2)] = 0\n flow_conservation[Terminal #8] : F[(TabulatedRatingCurve #7, Terminal #8)] = 0\n flow_conservation[Basin #2] : F[(UserDemand #3, Basin #2)] - F[(Basin #2, UserDemand #3)] - F[(Basin #2, LinearResistance #4)] + F[(LinearResistance #4, Basin #2)] + F[(FlowBoundary #1, Basin #2)] = 0\n flow_conservation[TabulatedRatingCurve #7] : F[(Basin #5, TabulatedRatingCurve #7)] - F[(TabulatedRatingCurve #7, Terminal #8)] = 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 172800\n source_user[UserDemand #6] : F[(UserDemand #6, Basin #5)] ≤ 0\n source_user[UserDemand #3] : F[(UserDemand #3, Basin #2)] ≤ 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, p), NodeID(:Basin, 2, p), 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[(Basin #5, UserDemand #6)]² + F[(Basin #2, UserDemand #3)]²\nSubject to\n F[(LinearResistance #4, Basin #5)] ≥ 0\n F[(Basin #5, LinearResistance #4)] ≥ 0\n F[(Basin #5, UserDemand #6)] ≥ 0\n F[(UserDemand #6, Basin #5)] ≥ 0\n F[(Basin #2, LinearResistance #4)] ≥ 0\n F[(LinearResistance #4, Basin #2)] ≥ 0\n F[(Basin #5, TabulatedRatingCurve #7)] ≥ 0\n F[(Basin #2, UserDemand #3)] ≥ 0\n F[(FlowBoundary #1, Basin #2)] ≥ 0\n F[(UserDemand #3, Basin #2)] ≥ 0\n F[(TabulatedRatingCurve #7, Terminal #8)] ≥ 0\n flow_conservation[TabulatedRatingCurve #7] : F[(Basin #5, TabulatedRatingCurve #7)] - F[(TabulatedRatingCurve #7, Terminal #8)] = 0\n flow_conservation[Basin #5] : F[(LinearResistance #4, Basin #5)] - F[(Basin #5, LinearResistance #4)] - F[(Basin #5, UserDemand #6)] + F[(UserDemand #6, Basin #5)] - F[(Basin #5, TabulatedRatingCurve #7)] = 0\n flow_conservation[Basin #2] : -F[(Basin #2, LinearResistance #4)] + F[(LinearResistance #4, Basin #2)] - F[(Basin #2, UserDemand #3)] + F[(FlowBoundary #1, Basin #2)] + F[(UserDemand #3, Basin #2)] = 0\n flow_conservation[Terminal #8] : F[(TabulatedRatingCurve #7, Terminal #8)] = 0\n flow_conservation[LinearResistance #4] : -F[(LinearResistance #4, Basin #5)] + F[(Basin #5, LinearResistance #4)] + F[(Basin #2, LinearResistance #4)] - F[(LinearResistance #4, Basin #2)] = 0\n source[(FlowBoundary #1, Basin #2)] : F[(FlowBoundary #1, Basin #2)] ≤ 172800\n source_user[UserDemand #3] : F[(UserDemand #3, Basin #2)] ≤ 0\n source_user[UserDemand #6] : F[(UserDemand #6, Basin #5)] ≤ 0",
     "crumbs": [
       "Concepts",
       "Implementation",
@@ -167,7 +167,7 @@
     "href": "guide/examples.html",
     "title": "Examples",
     "section": "",
-    "text": "import shutil\nfrom pathlib import Path\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom ribasim import Allocation, Model, Node\nfrom ribasim.nodes import (\n    basin,\n    continuous_control,\n    discrete_control,\n    flow_boundary,\n    level_boundary,\n    level_demand,\n    linear_resistance,\n    manning_resistance,\n    outlet,\n    pid_control,\n    pump,\n    tabulated_rating_curve,\n    user_demand,\n)\nfrom shapely.geometry import Point\n\n\ndatadir = Path(\"data\")\nshutil.rmtree(datadir, ignore_errors=True)\n\n\nmodel = Model(starttime=\"2020-01-01\", endtime=\"2021-01-01\", crs=\"EPSG:4326\")\n\nSetup the basins:\n\ntime = pd.date_range(model.starttime, model.endtime)\nday_of_year = time.day_of_year.to_numpy()\nseconds_per_day = 24 * 60 * 60\nevaporation = (\n    (-1.0 * np.cos(day_of_year / 365.0 * 2 * np.pi) + 1.0) * 0.0025 / seconds_per_day\n)\nrng = np.random.default_rng(seed=0)\nprecipitation = (\n    rng.lognormal(mean=-1.0, sigma=1.7, size=time.size) * 0.001 / seconds_per_day\n)\n\n# Convert steady forcing to m/s\n# 2 mm/d precipitation, 1 mm/d evaporation\n\nbasin_data = [\n    basin.Profile(area=[0.01, 1000.0], level=[0.0, 1.0]),\n    basin.Time(\n        time=pd.date_range(model.starttime, model.endtime),\n        drainage=0.0,\n        potential_evaporation=evaporation,\n        infiltration=0.0,\n        precipitation=precipitation,\n    ),\n    basin.State(level=[1.4]),\n]\n\nbasin1 = model.basin.add(Node(1, Point(0.0, 0.0)), basin_data)\nbasin3 = model.basin.add(Node(3, Point(2.0, 0.0)), basin_data)\nbasin6 = model.basin.add(Node(6, Point(3.0, 2.0)), basin_data)\nbasin9 = model.basin.add(Node(9, Point(5.0, 0.0)), basin_data)\n\nSetup linear resistance:\n\nlinear_resistance10 = model.linear_resistance.add(\n    Node(10, Point(6.0, 0.0)),\n    [linear_resistance.Static(resistance=[5e3])],\n)\nlinear_resistance12 = model.linear_resistance.add(\n    Node(12, Point(2.0, 1.0)),\n    [linear_resistance.Static(resistance=[3600.0 * 24.0 / 100.0])],\n)\n\nSetup Manning resistance:\n\nmanning_resistance2 = model.manning_resistance.add(\n    Node(2, Point(1.0, 0.0)),\n    [\n        manning_resistance.Static(\n            length=[900], manning_n=[0.04], profile_width=[6.0], profile_slope=[3.0]\n        )\n    ],\n)\n\nSet up rating curve nodes:\n\nq = 10 / 86400  # 10 m³/day\ntabulated_rating_curve4 = model.tabulated_rating_curve.add(\n    Node(8, Point(4.0, 0.0)),\n    [\n        tabulated_rating_curve.Static(\n            level=[0.0, 1.0],\n            flow_rate=[0.0, 0.6 * q],\n        )\n    ],\n)\ntabulated_rating_curve5 = model.tabulated_rating_curve.add(\n    Node(5, Point(3.0, 1.0)),\n    [\n        tabulated_rating_curve.Static(\n            level=[0.0, 1.0],\n            flow_rate=[0.0, 0.3 * q],\n        )\n    ],\n)\ntabulated_rating_curve8 = model.tabulated_rating_curve.add(\n    Node(4, Point(3.0, -1.0)),\n    [\n        tabulated_rating_curve.Static(\n            level=[0.0, 1.0],\n            flow_rate=[0.0, 0.1 * q],\n        )\n    ],\n)\n\nSetup pump:\n\npump7 = model.pump.add(Node(7, Point(4.0, 1.0)), [pump.Static(flow_rate=[0.5 / 3600])])\n\nSetup level boundary:\n\nlevel_boundary11 = model.level_boundary.add(\n    Node(11, Point(2.0, 2.0)), [level_boundary.Static(level=[0.5])]\n)\nlevel_boundary17 = model.level_boundary.add(\n    Node(17, Point(6.0, 1.0)), [level_boundary.Static(level=[1.5])]\n)\n\nSetup flow boundary:\n\nflow_boundary15 = model.flow_boundary.add(\n    Node(15, Point(3.0, 3.0)), [flow_boundary.Static(flow_rate=[1e-4])]\n)\nflow_boundary16 = model.flow_boundary.add(\n    Node(16, Point(0.0, 1.0)), [flow_boundary.Static(flow_rate=[1e-4])]\n)\n\nSetup terminal:\n\nterminal14 = model.terminal.add(Node(14, Point(3.0, -2.0)))\n\nSetup the edges:\n\nmodel.edge.add(basin1, manning_resistance2)\nmodel.edge.add(manning_resistance2, basin3)\nmodel.edge.add(\n    basin3,\n    tabulated_rating_curve8,\n)\nmodel.edge.add(\n    basin3,\n    tabulated_rating_curve5,\n)\nmodel.edge.add(\n    basin3,\n    tabulated_rating_curve4,\n)\nmodel.edge.add(tabulated_rating_curve5, basin6)\nmodel.edge.add(tabulated_rating_curve8, basin9)\nmodel.edge.add(\n    tabulated_rating_curve4,\n    terminal14,\n)\nmodel.edge.add(basin6, pump7)\nmodel.edge.add(pump7, basin9)\nmodel.edge.add(basin9, linear_resistance10)\nmodel.edge.add(level_boundary11, linear_resistance12)\nmodel.edge.add(linear_resistance12, basin3)\nmodel.edge.add(flow_boundary15, basin6)\nmodel.edge.add(flow_boundary16, basin1)\nmodel.edge.add(linear_resistance10, level_boundary17)\n\nLet’s take a look at the model:\n\nmodel.plot()\n\n\n\n\n\n\n\n\nWrite the model to a TOML and GeoPackage:\n\ntoml_path = datadir / \"basic/ribasim.toml\"\nmodel.write(toml_path)\n\nPosixPath('data/basic/ribasim.toml')\n\n\n\n\nNow run the model. You can open a terminal and run it from there. For example, to run the basic model, input:\nribasim basic/ribasim.toml\nFrom Python you can run it with:\nimport subprocess\nresult = subprocess.run([cli_path, toml_path], capture_output=True, encoding=\"utf-8\")\nprint(result.stderr)\nresult.check_returncode()\nWhere cli_path is a string with either the full path to the Ribasim executable, like r\"c:\\ribasim_windows\\ribasim\", or just \"ribasim\" in case you added the ribasim_windows folder to your PATH.\nThe print(result.stderr) ensures you see the same logging and error messages that you would see in the terminal. And result.check_returncode() will throw an error when the simulation was not successful.\nAfter running the model, read back the results:\n\ndf_basin = pd.read_feather(datadir / \"basic/results/basin.arrow\")\ndf_basin_wide = df_basin.pivot_table(\n    index=\"time\", columns=\"node_id\", values=[\"storage\", \"level\"]\n)\nax = df_basin_wide[\"level\"].plot()\nax.set_ylabel(\"level [m]\");\n\n\n\n\n\n\n\n\n\ndf_flow = pd.read_feather(datadir / \"basic/results/flow.arrow\")\ndf_flow[\"edge\"] = list(zip(df_flow.from_node_id, df_flow.to_node_id))\ndf_flow[\"flow_m3d\"] = df_flow.flow_rate * 86400\nax = df_flow.pivot_table(index=\"time\", columns=\"edge\", values=\"flow_m3d\").plot()\nax.legend(bbox_to_anchor=(1.3, 1), title=\"Edge\")\nax.set_ylabel(\"flow [m³day⁻¹]\");",
+    "text": "import shutil\nfrom pathlib import Path\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom ribasim import Allocation, Model, Node\nfrom ribasim.nodes import (\n    basin,\n    continuous_control,\n    discrete_control,\n    flow_boundary,\n    level_boundary,\n    level_demand,\n    linear_resistance,\n    manning_resistance,\n    outlet,\n    pid_control,\n    pump,\n    tabulated_rating_curve,\n    user_demand,\n)\nfrom shapely.geometry import Point\n\n\ndatadir = Path(\"data\")\nshutil.rmtree(datadir, ignore_errors=True)\n\n\nmodel = Model(starttime=\"2020-01-01\", endtime=\"2021-01-01\", crs=\"EPSG:4326\")\n\nSetup the basins:\n\ntime = pd.date_range(model.starttime, model.endtime)\nday_of_year = time.day_of_year.to_numpy()\nseconds_per_day = 24 * 60 * 60\nevaporation = (\n    (-1.0 * np.cos(day_of_year / 365.0 * 2 * np.pi) + 1.0) * 0.0025 / seconds_per_day\n)\nrng = np.random.default_rng(seed=0)\nprecipitation = (\n    rng.lognormal(mean=-1.0, sigma=1.7, size=time.size) * 0.001 / seconds_per_day\n)\n\n# Convert steady forcing to m/s\n# 2 mm/d precipitation, 1 mm/d evaporation\n\nbasin_data = [\n    basin.Profile(area=[0.01, 1000.0], level=[0.0, 1.0]),\n    basin.Time(\n        time=pd.date_range(model.starttime, model.endtime),\n        drainage=0.0,\n        potential_evaporation=evaporation,\n        infiltration=0.0,\n        precipitation=precipitation,\n    ),\n    basin.State(level=[1.4]),\n]\n\nbasin1 = model.basin.add(Node(1, Point(0.0, 0.0)), basin_data)\nbasin3 = model.basin.add(Node(3, Point(2.0, 0.0)), basin_data)\nbasin6 = model.basin.add(Node(6, Point(3.0, 2.0)), basin_data)\nbasin9 = model.basin.add(Node(9, Point(5.0, 0.0)), basin_data)\n\nSetup linear resistance:\n\nlinear_resistance10 = model.linear_resistance.add(\n    Node(10, Point(6.0, 0.0)),\n    [linear_resistance.Static(resistance=[5e3])],\n)\nlinear_resistance12 = model.linear_resistance.add(\n    Node(12, Point(2.0, 1.0)),\n    [linear_resistance.Static(resistance=[3600.0 * 24.0 / 100.0])],\n)\n\nSetup Manning resistance:\n\nmanning_resistance2 = model.manning_resistance.add(\n    Node(2, Point(1.0, 0.0)),\n    [\n        manning_resistance.Static(\n            length=[900], manning_n=[0.04], profile_width=[6.0], profile_slope=[3.0]\n        )\n    ],\n)\n\nSet up rating curve nodes:\n\nq = 10 / 86400  # 10 m³/day\ntabulated_rating_curve4 = model.tabulated_rating_curve.add(\n    Node(8, Point(3.0, -1.0)),\n    [\n        tabulated_rating_curve.Static(\n            level=[0.0, 1.0],\n            flow_rate=[0.0, 0.6 * q],\n        )\n    ],\n)\ntabulated_rating_curve5 = model.tabulated_rating_curve.add(\n    Node(5, Point(3.0, 1.0)),\n    [\n        tabulated_rating_curve.Static(\n            level=[0.0, 1.0],\n            flow_rate=[0.0, 0.3 * q],\n        )\n    ],\n)\ntabulated_rating_curve8 = model.tabulated_rating_curve.add(\n    Node(4, Point(4.0, 0.0)),\n    [\n        tabulated_rating_curve.Static(\n            level=[0.0, 1.0],\n            flow_rate=[0.0, 0.1 * q],\n        )\n    ],\n)\n\nSetup pump:\n\npump7 = model.pump.add(Node(7, Point(4.0, 1.0)), [pump.Static(flow_rate=[0.5 / 3600])])\n\nSetup level boundary:\n\nlevel_boundary11 = model.level_boundary.add(\n    Node(11, Point(2.0, 2.0)), [level_boundary.Static(level=[0.5])]\n)\nlevel_boundary17 = model.level_boundary.add(\n    Node(17, Point(6.0, 1.0)), [level_boundary.Static(level=[1.5])]\n)\n\nSetup flow boundary:\n\nflow_boundary15 = model.flow_boundary.add(\n    Node(15, Point(3.0, 3.0)), [flow_boundary.Static(flow_rate=[1e-4])]\n)\nflow_boundary16 = model.flow_boundary.add(\n    Node(16, Point(0.0, 1.0)), [flow_boundary.Static(flow_rate=[1e-4])]\n)\n\nSetup terminal:\n\nterminal14 = model.terminal.add(Node(14, Point(3.0, -2.0)))\n\nSetup the edges:\n\nmodel.edge.add(basin1, manning_resistance2)\nmodel.edge.add(manning_resistance2, basin3)\nmodel.edge.add(\n    basin3,\n    tabulated_rating_curve8,\n)\nmodel.edge.add(\n    basin3,\n    tabulated_rating_curve5,\n)\nmodel.edge.add(\n    basin3,\n    tabulated_rating_curve4,\n)\nmodel.edge.add(tabulated_rating_curve5, basin6)\nmodel.edge.add(tabulated_rating_curve8, basin9)\nmodel.edge.add(\n    tabulated_rating_curve4,\n    terminal14,\n)\nmodel.edge.add(basin6, pump7)\nmodel.edge.add(pump7, basin9)\nmodel.edge.add(basin9, linear_resistance10)\nmodel.edge.add(level_boundary11, linear_resistance12)\nmodel.edge.add(linear_resistance12, basin3)\nmodel.edge.add(flow_boundary15, basin6)\nmodel.edge.add(flow_boundary16, basin1)\nmodel.edge.add(linear_resistance10, level_boundary17)\n\nLet’s take a look at the model:\n\nmodel.plot()\n\n\n\n\n\n\n\n\nWrite the model to a TOML and GeoPackage:\n\ntoml_path = datadir / \"basic/ribasim.toml\"\nmodel.write(toml_path)\n\nPosixPath('data/basic/ribasim.toml')\n\n\n\n\nNow run the model. You can open a terminal and run it from there. For example, to run the basic model, input:\nribasim basic/ribasim.toml\nFrom Python you can run it with:\nimport subprocess\nresult = subprocess.run([cli_path, toml_path], capture_output=True, encoding=\"utf-8\")\nprint(result.stderr)\nresult.check_returncode()\nWhere cli_path is a string with either the full path to the Ribasim executable, like r\"c:\\ribasim_windows\\ribasim\", or just \"ribasim\" in case you added the ribasim_windows folder to your PATH.\nThe print(result.stderr) ensures you see the same logging and error messages that you would see in the terminal. And result.check_returncode() will throw an error when the simulation was not successful.\nAfter running the model, read back the results:\n\ndf_basin = pd.read_feather(datadir / \"basic/results/basin.arrow\")\ndf_basin_wide = df_basin.pivot_table(\n    index=\"time\", columns=\"node_id\", values=[\"storage\", \"level\"]\n)\nax = df_basin_wide[\"level\"].plot()\nax.set_ylabel(\"level [m]\");\n\n\n\n\n\n\n\n\n\ndf_flow = pd.read_feather(datadir / \"basic/results/flow.arrow\")\ndf_flow[\"edge\"] = list(zip(df_flow.from_node_id, df_flow.to_node_id))\ndf_flow[\"flow_m3d\"] = df_flow.flow_rate * 86400\nax = df_flow.pivot_table(index=\"time\", columns=\"edge\", values=\"flow_m3d\").plot()\nax.legend(bbox_to_anchor=(1.3, 1), title=\"Edge\")\nax.set_ylabel(\"flow [m³day⁻¹]\");",
     "crumbs": [
       "How-to guides",
       "Examples"