From 39ba3efdf418c23af26f52041d2a93110b42013f Mon Sep 17 00:00:00 2001 From: FBumann <117816358+FBumann@users.noreply.github.com> Date: Wed, 15 Jul 2026 17:01:01 +0200 Subject: [PATCH] docs(notebooks): run example notebooks under the v1 convention MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Opt every example notebook into the strict v1 arithmetic convention (linopy.options["semantics"] = "v1") and fix the code that relied on legacy alignment: - creating-variables: wrap the transport mask in a labelled DataArray so the (6, 6) array pairs unambiguously with the (from, to) dims. - creating-expressions: mismatched shared-dim labels now raise; show the error and resolve it with join="outer" / join="override". - coordinate-alignment: rewrite the intro that taught legacy superset-fill and same-shape positional alignment to teach v1 label-matching — mismatches raise and are resolved via .sel/.reindex/.assign_coords or an explicit join=. The join sections are kept; the summary table now reflects v1 defaults. The two remote notebooks (solve-on-oetc, solve-on-remote) carry the opt-in too; both are marked nbsphinx execute:never, and solve-on-remote keeps its committed outputs (nbstripout-excluded). Co-Authored-By: Claude Opus 4.8 (1M context) --- doc/release_notes.rst | 4 + examples/coordinate-alignment.ipynb | 88 ++++++++++++------- .../create-a-model-with-coordinates.ipynb | 2 + examples/create-a-model.ipynb | 3 + examples/creating-constraints.ipynb | 3 + examples/creating-expressions.ipynb | 87 +++++++++++------- examples/creating-variables.ipynb | 4 + examples/infeasible-model.ipynb | 2 + examples/manipulating-models.ipynb | 4 +- examples/migrating-from-pyomo.ipynb | 2 + examples/piecewise-inequality-bounds.ipynb | 2 + examples/piecewise-linear-constraints.ipynb | 2 + examples/solve-on-oetc.ipynb | 3 + examples/solve-on-remote.ipynb | 3 + examples/testing-framework.ipynb | 4 +- examples/transport-tutorial.ipynb | 2 + 16 files changed, 148 insertions(+), 67 deletions(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index f8464a7d2..8c74293ce 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -23,6 +23,10 @@ Upcoming Version * ``add_variables(binary=True, ...)`` now accepts ``lower``/``upper`` bounds, as long as they are 0 or 1. Previously binary bounds could only be set via the ``.lower``/``.upper`` setters after creation. (https://github.com/PyPSA/linopy/issues/776) * ``add_piecewise_formulation`` gained an ``active_fill`` parameter that gates a partial ``active`` (defined over a subset of the indexed dimension, or masked) as always-active (``1``) or always-off (``0``); without it, a partial ``active`` — which was previously zeroed silently — now raises. Useful when one formulation mixes gated and ungated entities (e.g. committable and non-committable units sharing a ``status``). ``active_fill`` is transitional and will be removed once v1 semantics make ``active.reindex(coords).fillna(value)`` sufficient. (https://github.com/PyPSA/linopy/issues/796) +*Documentation* + +* The example notebooks now opt into the v1 arithmetic convention (``linopy.options["semantics"] = "v1"``). The coordinate-alignment and expression tutorials were reworked to teach strict label-based alignment: a mismatch on a shared dimension raises rather than silently filling or pairing by position, and is resolved explicitly with ``.sel`` / ``.reindex`` / ``.assign_coords`` or an explicit ``join=`` on the named ``.add`` / ``.mul`` / ``.le`` / … methods. + **Performance** * ``LinearExpression.groupby(...).sum()`` now scatters terms directly into the padded result arrays via ``xarray.apply_ufunc``, avoiding intermediate copies and speeding up the grouping. A single kernel covers both numpy and chunked (dask) data, the latter staying lazy. On representative models this lowers build and export peak memory by up to ~3x. diff --git a/examples/coordinate-alignment.ipynb b/examples/coordinate-alignment.ipynb index 54de243a5..f99e2362c 100644 --- a/examples/coordinate-alignment.ipynb +++ b/examples/coordinate-alignment.ipynb @@ -6,7 +6,7 @@ "source": [ "# Coordinate Alignment\n", "\n", - "Since linopy builds on xarray, coordinate alignment matters when combining variables or expressions that live on different coordinates. By default, linopy aligns operands automatically and fills missing entries with sensible defaults. This guide shows how alignment works and how to control it with the ``join`` parameter." + "Since linopy builds on xarray, coordinate alignment matters when combining variables or expressions that live on different coordinates. Under the **v1 convention**, linopy aligns strictly by coordinate *label*: operands that share a dimension must carry the same labels on it, and a genuine mismatch raises rather than being silently patched over. This guide shows how that strict alignment works and how to resolve mismatches explicitly with the ``join`` parameter." ] }, { @@ -19,16 +19,18 @@ "import pandas as pd\n", "import xarray as xr\n", "\n", - "import linopy" + "import linopy\n", + "\n", + "linopy.options[\"semantics\"] = \"v1\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Default Alignment Behavior\n", + "## Alignment by label\n", "\n", - "When two operands share a dimension but have different coordinates, linopy keeps the **larger** (superset) coordinate range and fills missing positions with zeros (for addition) or zero coefficients (for multiplication)." + "When two operands **share a dimension**, linopy requires them to carry the same coordinate labels on it. Labels align by name, never by position, and non-shared dimensions broadcast freely. If the shared labels differ — a different set, or even the same labels in a different order — the operation raises a ``ValueError``; linopy never silently drops, reorders, or invents coordinates, because in an optimization model a dropped coordinate is a dropped term or constraint." ] }, { @@ -50,7 +52,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Adding ``x`` (5 time steps) and ``y`` (3 time steps) gives an expression over all 5 time steps. Where ``y`` has no entry (time 3, 4), the coefficient is zero — i.e. ``y`` simply drops out of the sum at those positions." + "``x`` spans ``time`` 0–4 and ``y`` spans 0–2. Because ``time`` is shared but the label sets differ, adding them directly raises:" ] }, { @@ -59,14 +61,17 @@ "metadata": {}, "outputs": [], "source": [ - "x + y" + "try:\n", + " x + y\n", + "except ValueError as e:\n", + " print(e)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The same applies when multiplying by a constant that covers only a subset of coordinates. Missing positions get a coefficient of zero:" + "The same holds for a constant that covers only a subset of the coordinates — a ``DataArray`` on ``time`` 0–2 shares the dimension but not the full label set, so multiplying by it raises too:" ] }, { @@ -76,14 +81,19 @@ "outputs": [], "source": [ "factor = xr.DataArray([2, 3, 4], dims=[\"time\"], coords={\"time\": [0, 1, 2]})\n", - "x * factor" + "try:\n", + " x * factor\n", + "except ValueError as e:\n", + " print(e)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Adding a constant subset also fills missing coordinates with zero:" + "### Resolving a mismatch\n", + "\n", + "To combine mismatched operands, tell linopy how. Either bring them onto shared coordinates first — ``.sel`` / ``.isel`` / ``.reindex`` — relabel one side with ``.assign_coords``, or pass an explicit ``join=`` to the named ``.add`` / ``.mul`` / … methods (covered below). For instance, select ``x`` down to ``factor``'s coordinates and multiply on the shared range:" ] }, { @@ -92,16 +102,16 @@ "metadata": {}, "outputs": [], "source": [ - "x + factor" + "x.sel(time=[0, 1, 2]) * factor" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Constraints with Subset RHS\n", + "### Constraints follow the same rule\n", "\n", - "For constraints, missing right-hand-side values are filled with ``NaN``, which tells linopy to **skip** the constraint at those positions:" + "A comparison (``<=``, ``>=``, ``==``) aligns its two sides exactly like ``+`` does. So a right-hand side that covers only a subset of the constraint's coordinates is a shared-dimension mismatch, and raises:" ] }, { @@ -111,24 +121,35 @@ "outputs": [], "source": [ "rhs = xr.DataArray([10, 20, 30], dims=[\"time\"], coords={\"time\": [0, 1, 2]})\n", - "con = x <= rhs\n", - "con" + "try:\n", + " x <= rhs\n", + "except ValueError as e:\n", + " print(e)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The constraint only applies at time 0, 1, 2. At time 3 and 4 the RHS is ``NaN``, so no constraint is created." + "Build the constraint only where the RHS is defined by aligning first — either select the shared range, or use an explicit ``join`` (below). Selecting ``x`` down to the RHS coordinates:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x.sel(time=[0, 1, 2]) <= rhs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Same-Shape Operands: Positional Alignment\n", + "### No positional shortcut\n", "\n", - "When two operands have the **same shape** on a shared dimension, linopy uses **positional alignment** by default — coordinate labels are ignored and the left operand's labels are kept. This is a performance optimization but can be surprising:" + "Legacy linopy had a special case: two operands of the **same shape** on a shared dimension were paired by position, ignoring their labels. The v1 convention removes this — alignment is always by label, whatever the shapes. So an operand whose labels differ from ``x`` raises even when the shapes match:" ] }, { @@ -140,14 +161,17 @@ "offset_const = xr.DataArray(\n", " [10, 20, 30, 40, 50], dims=[\"time\"], coords={\"time\": [5, 6, 7, 8, 9]}\n", ")\n", - "x + offset_const" + "try:\n", + " x + offset_const\n", + "except ValueError as e:\n", + " print(e)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Even though ``offset_const`` has coordinates ``[5, 6, 7, 8, 9]`` and ``x`` has ``[0, 1, 2, 3, 4]``, the result uses ``x``'s labels. The values are aligned by **position**, not by label. The same applies when adding two variables or expressions of identical shape:" + "If you genuinely want **positional** pairing — ignoring that the labels differ — ask for it explicitly with ``join=\"override\"``, which relabels the right operand onto the left's coordinates. It still requires the shared dimension to match in size:" ] }, { @@ -157,16 +181,14 @@ "outputs": [], "source": [ "z = m.add_variables(lower=0, coords=[pd.RangeIndex(5, 10, name=\"time\")], name=\"z\")\n", - "x + z" + "x.add(z, join=\"override\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "``x`` (time 0–4) and ``z`` (time 5–9) share no coordinate labels, yet the result has 5 entries under ``x``'s coordinates — because they have the same shape, positions are matched directly.\n", - "\n", - "To force **label-based** alignment, pass an explicit ``join``:" + "``x`` (time 0–4) and ``z`` (time 5–9) share no labels; ``override`` pairs them by position and keeps ``x``'s labels. For **label-based** alignment over the union instead, use ``join=\"outer\"``:" ] }, { @@ -182,7 +204,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "With ``join=\"outer\"``, the result spans all 10 time steps (union of 0–4 and 5–9), filling missing positions with zeros. This is the correct label-based alignment. The same-shape positional shortcut is equivalent to ``join=\"override\"`` — see below." + "With ``join=\"outer\"``, the result spans all 10 time steps (union of 0–4 and 5–9); each non-overlapping position keeps whichever operand is present there, the missing side contributing its additive identity (``0``). The next section walks through every ``join`` value." ] }, { @@ -365,7 +387,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "With ``join=\"left\"``, the result covers all of ``a``'s coordinates (i=0, 1, 2). At i=2, where the RHS has no value, the RHS becomes ``NaN`` and the constraint is masked out.\n", + "With ``join=\"left\"``, the result covers all of ``a``'s coordinates (i=0, 1, 2). At i=2, where the RHS has no value, it is filled with ``0``, so the row becomes ``a[2] ≤ 0``.\n", "\n", "The same methods work on expressions:" ] @@ -476,15 +498,15 @@ "source": [ "## Summary\n", "\n", - "| ``join`` | Coordinates | Fill behavior |\n", + "| ``join`` | Coordinates | Non-overlapping positions |\n", "|----------|------------|---------------|\n", - "| ``None`` (default) | Auto-detect (keeps superset) | Zeros for arithmetic, NaN for constraint RHS |\n", - "| ``\"inner\"`` | Intersection only | No fill needed |\n", - "| ``\"outer\"`` | Union | Fill with operation identity (0 for add, 0 for mul) |\n", - "| ``\"left\"`` | Left operand's | Fill right with identity |\n", - "| ``\"right\"`` | Right operand's | Fill left with identity |\n", - "| ``\"override\"`` | Left operand's (positional) | Positional alignment, ignore labels |\n", - "| ``\"exact\"`` | Must match exactly | Raises error if different |" + "| ``None`` (default) | Must match by label **and order** (v1 uses ``exact``) | Raises on any mismatch |\n", + "| ``\"inner\"`` | Intersection only | — (nothing to fill) |\n", + "| ``\"outer\"`` | Union | Missing side filled with the operation's identity |\n", + "| ``\"left\"`` | Left operand's | Right's extras dropped; right's gaps filled with identity |\n", + "| ``\"right\"`` | Right operand's | Left's extras dropped; left's gaps filled with identity |\n", + "| ``\"override\"`` | Left operand's (positional) | Requires equal size on shared dims |\n", + "| ``\"exact\"`` | Must match by label **and order** | Raises on mismatch |" ] } ], diff --git a/examples/create-a-model-with-coordinates.ipynb b/examples/create-a-model-with-coordinates.ipynb index 56c374811..fd82b0f13 100644 --- a/examples/create-a-model-with-coordinates.ipynb +++ b/examples/create-a-model-with-coordinates.ipynb @@ -51,6 +51,8 @@ "source": [ "import linopy\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "m = linopy.Model()" ] }, diff --git a/examples/create-a-model.ipynb b/examples/create-a-model.ipynb index 943029d6b..55afe1a88 100644 --- a/examples/create-a-model.ipynb +++ b/examples/create-a-model.ipynb @@ -54,8 +54,11 @@ "metadata": {}, "outputs": [], "source": [ + "import linopy\n", "from linopy import Model\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "m = Model()" ] }, diff --git a/examples/creating-constraints.ipynb b/examples/creating-constraints.ipynb index d504deb34..2827202d7 100644 --- a/examples/creating-constraints.ipynb +++ b/examples/creating-constraints.ipynb @@ -22,8 +22,11 @@ "metadata": {}, "outputs": [], "source": [ + "import linopy\n", "from linopy import Model\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "m = Model()" ] }, diff --git a/examples/creating-expressions.ipynb b/examples/creating-expressions.ipynb index cb41a2c66..bad684970 100644 --- a/examples/creating-expressions.ipynb +++ b/examples/creating-expressions.ipynb @@ -53,6 +53,8 @@ "\n", "import linopy\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "time = pd.Index(range(10), name=\"time\")\n", "port = pd.Index(list(\"abcd\"), name=\"port\")\n", "\n", @@ -162,7 +164,7 @@ "metadata": {}, "source": [ ".. important::\n", - " When combining variables or expressions with dimensions of the same name and size, the first object determines the coordinates of the resulting expression. For example:" + " Under the v1 convention, operands that share a dimension must carry the **same coordinate labels** on it — linopy aligns by label, never by position. Combining objects whose labels differ on a shared dimension raises a ``ValueError`` instead of silently overwriting coordinates. For example:" ] }, { @@ -183,7 +185,7 @@ "id": "15", "metadata": {}, "source": [ - "`b` has the same shape as `x`, but they have different coordinates. When we combine `x` and `b` the coordinates on dimension `time` will be taken from the first object and the coordinates of the subsequent object will be ignored:" + "`b` has the same shape as `x`, but their `time` labels differ (`x` spans 0–9, `b` spans 10–19). Because `time` is shared, combining them directly raises:" ] }, { @@ -193,13 +195,34 @@ "metadata": {}, "outputs": [], "source": [ - "x + b" + "try:\n", + " x + b\n", + "except ValueError as e:\n", + " print(e)" ] }, { "cell_type": "markdown", "id": "17", "metadata": {}, + "source": [ + "To combine them anyway, say how the coordinates should be reconciled — e.g. an outer join over the union of both time ranges, where each position keeps whichever operand is defined there (the missing side contributes 0):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18", + "metadata": {}, + "outputs": [], + "source": [ + "x.add(b, join=\"outer\")" + ] + }, + { + "cell_type": "markdown", + "id": "19", + "metadata": {}, "source": [ ".. tip::\n", " For explicit control over how coordinates are aligned during arithmetic, use the ``.add()``, ``.sub()``, ``.mul()``, and ``.div()`` methods with a ``join`` parameter (``\"inner\"``, ``\"outer\"``, ``\"left\"``, ``\"right\"``). See the :doc:`coordinate-alignment` guide for details." @@ -208,7 +231,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "18", + "id": "20", "metadata": {}, "source": [ "## Using `.loc` to select a subset\n", @@ -221,7 +244,7 @@ { "cell_type": "code", "execution_count": null, - "id": "19", + "id": "21", "metadata": {}, "outputs": [], "source": [ @@ -231,7 +254,7 @@ { "cell_type": "code", "execution_count": null, - "id": "20", + "id": "22", "metadata": {}, "outputs": [], "source": [ @@ -241,7 +264,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "21", + "id": "23", "metadata": {}, "source": [ "which is the same as" @@ -250,7 +273,7 @@ { "cell_type": "code", "execution_count": null, - "id": "22", + "id": "24", "metadata": {}, "outputs": [], "source": [ @@ -261,26 +284,26 @@ { "attachments": {}, "cell_type": "markdown", - "id": "23", + "id": "25", "metadata": {}, "source": [ - "In combination with the overwrite of the coordinates, this is useful when you need to combine different selections, like" + "Sometimes you deliberately want to combine two different selections **positionally** — pairing them by order rather than by label. Since their `time` labels differ, ask for it explicitly with ``join=\"override\"``, which adopts the left operand's coordinates:" ] }, { "cell_type": "code", "execution_count": null, - "id": "24", + "id": "26", "metadata": {}, "outputs": [], "source": [ - "x.loc[:4] + y.loc[5:]" + "x.loc[:4].add(y.loc[5:], join=\"override\")" ] }, { "attachments": {}, "cell_type": "markdown", - "id": "25", + "id": "27", "metadata": {}, "source": [ "## Using `.where` to select active variables or expressions\n", @@ -293,7 +316,7 @@ { "cell_type": "code", "execution_count": null, - "id": "26", + "id": "28", "metadata": {}, "outputs": [], "source": [ @@ -304,7 +327,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "27", + "id": "29", "metadata": {}, "source": [ "We can use this to make a conditional summation:" @@ -313,7 +336,7 @@ { "cell_type": "code", "execution_count": null, - "id": "28", + "id": "30", "metadata": {}, "outputs": [], "source": [ @@ -322,7 +345,7 @@ }, { "cell_type": "markdown", - "id": "29", + "id": "31", "metadata": {}, "source": [ "Sometimes `.where` may lead to a situation where some of the variables are completely masked" @@ -331,7 +354,7 @@ { "cell_type": "code", "execution_count": null, - "id": "30", + "id": "32", "metadata": {}, "outputs": [], "source": [ @@ -344,7 +367,7 @@ }, { "cell_type": "markdown", - "id": "31", + "id": "33", "metadata": {}, "source": [ "In this example you can see that many of the elements of the LinearExpression are None. If you want to remove all the None terms, you can use `.where(.., drop=True)`" @@ -353,7 +376,7 @@ { "cell_type": "code", "execution_count": null, - "id": "32", + "id": "34", "metadata": {}, "outputs": [], "source": [ @@ -363,7 +386,7 @@ }, { "cell_type": "markdown", - "id": "33", + "id": "35", "metadata": {}, "source": [ "That looks nicer!
" @@ -371,7 +394,7 @@ }, { "cell_type": "markdown", - "id": "34", + "id": "36", "metadata": {}, "source": [ "You may notice that the variable `x` is not used at all. The expression still contains two terms (one of them is unused) but it only has one variable `y`" @@ -380,7 +403,7 @@ { "cell_type": "code", "execution_count": null, - "id": "35", + "id": "37", "metadata": {}, "outputs": [], "source": [ @@ -390,7 +413,7 @@ { "cell_type": "code", "execution_count": null, - "id": "36", + "id": "38", "metadata": {}, "outputs": [], "source": [ @@ -399,7 +422,7 @@ }, { "cell_type": "markdown", - "id": "37", + "id": "39", "metadata": {}, "source": [ "You can get rid of the unused term with `.simplify()`" @@ -408,7 +431,7 @@ { "cell_type": "code", "execution_count": null, - "id": "38", + "id": "40", "metadata": {}, "outputs": [], "source": [ @@ -419,7 +442,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "39", + "id": "41", "metadata": {}, "source": [ "## Using `.shift` to shift the Variable along one dimension\n", @@ -432,7 +455,7 @@ { "cell_type": "code", "execution_count": null, - "id": "40", + "id": "42", "metadata": {}, "outputs": [], "source": [ @@ -442,7 +465,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "41", + "id": "43", "metadata": {}, "source": [ "## Using `.groupby` to group by a key and apply operations on the groups\n", @@ -455,7 +478,7 @@ { "cell_type": "code", "execution_count": null, - "id": "42", + "id": "44", "metadata": {}, "outputs": [], "source": [ @@ -466,7 +489,7 @@ { "attachments": {}, "cell_type": "markdown", - "id": "43", + "id": "45", "metadata": {}, "source": [ "## Using `.rolling` to perform a rolling operation\n", @@ -479,7 +502,7 @@ { "cell_type": "code", "execution_count": null, - "id": "44", + "id": "46", "metadata": {}, "outputs": [], "source": [ diff --git a/examples/creating-variables.ipynb b/examples/creating-variables.ipynb index 1c8b53d06..474a270bb 100644 --- a/examples/creating-variables.ipynb +++ b/examples/creating-variables.ipynb @@ -26,8 +26,11 @@ "import pandas as pd\n", "import xarray as xr\n", "\n", + "import linopy\n", "from linopy import Model\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "m = Model()" ] }, @@ -512,6 +515,7 @@ "\n", "mask = np.ones((len(ports), len(ports)), dtype=bool)\n", "np.fill_diagonal(mask, False)\n", + "mask = xr.DataArray(mask, coords=[port_from, port_to])\n", "mask" ] }, diff --git a/examples/infeasible-model.ipynb b/examples/infeasible-model.ipynb index 8766ac785..55468de9e 100644 --- a/examples/infeasible-model.ipynb +++ b/examples/infeasible-model.ipynb @@ -24,6 +24,8 @@ "\n", "import linopy\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "m = linopy.Model()\n", "\n", "time = pd.RangeIndex(10, name=\"time\")\n", diff --git a/examples/manipulating-models.ipynb b/examples/manipulating-models.ipynb index bd86399ea..2a1eb4607 100644 --- a/examples/manipulating-models.ipynb +++ b/examples/manipulating-models.ipynb @@ -22,7 +22,9 @@ "import pandas as pd\n", "import xarray as xr\n", "\n", - "import linopy" + "import linopy\n", + "\n", + "linopy.options[\"semantics\"] = \"v1\"" ] }, { diff --git a/examples/migrating-from-pyomo.ipynb b/examples/migrating-from-pyomo.ipynb index c3535a40f..314a235ca 100644 --- a/examples/migrating-from-pyomo.ipynb +++ b/examples/migrating-from-pyomo.ipynb @@ -21,6 +21,8 @@ "\n", "import linopy\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "m = linopy.Model()\n", "coords = pd.RangeIndex(10), [\"a\", \"b\"]\n", "x = m.add_variables(0, 100, coords, name=\"x\")\n", diff --git a/examples/piecewise-inequality-bounds.ipynb b/examples/piecewise-inequality-bounds.ipynb index 59ec23b9a..0cadf1f69 100644 --- a/examples/piecewise-inequality-bounds.ipynb +++ b/examples/piecewise-inequality-bounds.ipynb @@ -43,6 +43,8 @@ "\n", "import linopy\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "# Silence the evolving-API warning for cleaner tutorial output.\n", "warnings.filterwarnings(\"ignore\", category=linopy.EvolvingAPIWarning)" ] diff --git a/examples/piecewise-linear-constraints.ipynb b/examples/piecewise-linear-constraints.ipynb index ef26a55b1..c1a0e1729 100644 --- a/examples/piecewise-linear-constraints.ipynb +++ b/examples/piecewise-linear-constraints.ipynb @@ -43,6 +43,8 @@ "\n", "import linopy\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "# Silence the evolving-API warning for cleaner tutorial output.\n", "warnings.filterwarnings(\"ignore\", category=linopy.EvolvingAPIWarning)\n", "\n", diff --git a/examples/solve-on-oetc.ipynb b/examples/solve-on-oetc.ipynb index 28e1c04d8..bc3448f6b 100644 --- a/examples/solve-on-oetc.ipynb +++ b/examples/solve-on-oetc.ipynb @@ -55,8 +55,11 @@ "from numpy import arange\n", "from xarray import DataArray\n", "\n", + "import linopy\n", "from linopy import Model\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "# Create a medium-sized optimization problem\n", "N = 50\n", "m = Model()\n", diff --git a/examples/solve-on-remote.ipynb b/examples/solve-on-remote.ipynb index 73e6346bf..fc2a89c8d 100644 --- a/examples/solve-on-remote.ipynb +++ b/examples/solve-on-remote.ipynb @@ -92,8 +92,11 @@ "from numpy import arange\n", "from xarray import DataArray\n", "\n", + "import linopy\n", "from linopy import Model\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "N = 10\n", "m = Model()\n", "coords = [arange(N), arange(N)]\n", diff --git a/examples/testing-framework.ipynb b/examples/testing-framework.ipynb index 5517557dd..6bd3c6c8d 100644 --- a/examples/testing-framework.ipynb +++ b/examples/testing-framework.ipynb @@ -19,7 +19,9 @@ "import pandas as pd\n", "\n", "import linopy\n", - "from linopy.testing import assert_conequal, assert_linequal, assert_varequal" + "from linopy.testing import assert_conequal, assert_linequal, assert_varequal\n", + "\n", + "linopy.options[\"semantics\"] = \"v1\"" ] }, { diff --git a/examples/transport-tutorial.ipynb b/examples/transport-tutorial.ipynb index 8fdfbe9b9..ffbda9ca2 100644 --- a/examples/transport-tutorial.ipynb +++ b/examples/transport-tutorial.ipynb @@ -84,6 +84,8 @@ "\n", "import linopy\n", "\n", + "linopy.options[\"semantics\"] = \"v1\"\n", + "\n", "# Creation of a Model\n", "m = linopy.Model()" ]