{ "cells": [ { "cell_type": "markdown", "id": "d80ed8da", "metadata": {}, "source": [ "# Start- and stop costs for river flow\n", "\n", "This example demonstrates how start- and stop costs can be applied to [river](river) flow to avoid gates having to start and stop flowing repeatedly, as this can be costly. The start cost can be set through the attributes [flow_start_cost](river:flow_start_cost) and [flow_start_cost_const](river:flow_start_cost_const). If both attributes are set, the timeseries attribute will be preferred. The stop cost can be set through the attributes [flow_stop_cost](river:flow_stop_cost) and [flow_stop_cost_const](river:flow_stop_cost_const) . \n", "\n", "The constraints that are needed for applying the start- and stop costs are similar to the commitment constraints for generators and pumps. The unit commitment constraints for generators are explained [here](generator_unit_commitment). \n", "\n", "To build the constraints for applying the river flow start- and stop costs, a minimum allowed flow must be given through the [min_allowed_flow](river:min_allowed_flow) attribute in order to properly decide if water is flowing or not. Additionally, a value for the absolute maximum flow in the river must be set through the [absolute_max_flow](river:absolute_max_flow) attribute." ] }, { "cell_type": "code", "execution_count": 1, "id": "5065091c", "metadata": {}, "outputs": [], "source": [ "#Necessary imports \n", "import pandas as pd\n", "import plotly.graph_objs as go\n", "\n", "from pyshop import ShopSession\n", "\n", "#Functions used in this example for building a SHOP modeland running it\n", "from river import build_model, run_model" ] }, { "cell_type": "markdown", "id": "b1f4c904", "metadata": {}, "source": [ "## Create SHOP session and import model\n", "\n", "Our example model has one river connecting two reservoirs, and a downstream plant." ] }, { "cell_type": "code", "execution_count": 2, "id": "2638fd7d", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "%3\n", "\n", "\n", "\n", "reservoir_Reservoir1\n", "\n", "Reservoir1\n", "\n", "\n", "\n", "river_River1\n", "\n", "River1\n", "\n", "\n", "\n", "reservoir_Reservoir1->river_River1\n", "\n", "\n", "\n", "\n", "reservoir_Reservoir2\n", "\n", "Reservoir2\n", "\n", "\n", "\n", "river_River1->reservoir_Reservoir2\n", "\n", "\n", "\n", "\n", "plant_Plant1\n", "\n", "Plant1\n", "\n", "\n", "\n", "reservoir_Reservoir2->plant_Plant1\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#Create a standard ShopSession\n", "shop=ShopSession()\n", "\n", "#Build SHOP model\n", "build_model(shop)\n", "\n", "#Display topology to the screen\n", "display(shop.model.build_connection_tree())" ] }, { "cell_type": "markdown", "id": "2af44510", "metadata": {}, "source": [ "## Run model without any river flow start- or stop costs\n", "\n", "We start by running the model without any start- or stop costs, and plot the resulting flow in the river. As the plot shows, the flow is stopped and started several times during the optimization period." ] }, { "cell_type": "code", "execution_count": 3, "id": "95bb5a2b", "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "type": "bar", "x": [ "2018-02-27T00:00:00", "2018-02-27T01:00:00", "2018-02-27T02:00:00", "2018-02-27T03:00:00", "2018-02-27T04:00:00", "2018-02-27T05:00:00", "2018-02-27T06:00:00", "2018-02-27T07:00:00", "2018-02-27T08:00:00", "2018-02-27T09:00:00", "2018-02-27T10:00:00", "2018-02-27T11:00:00", "2018-02-27T12:00:00", "2018-02-27T13:00:00", "2018-02-27T14:00:00", "2018-02-27T15:00:00", "2018-02-27T16:00:00", "2018-02-27T17:00:00", "2018-02-27T18:00:00", "2018-02-27T19:00:00", "2018-02-27T20:00:00", "2018-02-27T21:00:00", "2018-02-27T22:00:00", "2018-02-27T23:00:00" ], "y": [ 13.888888888888099, 57.90903153880971, 62.21451999342035, 18.194377343498743, 0.0, 0.0, 0.0, 41.68207112427116, 90.0, 69.15896443786443, 20.841035562135588, 0.0, 26.963717368159745, 26.963717368159745, 0.0, 0.0, 36.07256526368051, 90.0, 71.96371736815975, 18.036282631840262, 0.0, 0.0, 0.0, 0.0 ] } ], "layout": { "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "fillpattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "autotypenumbers": "strict", "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "sequentialminus": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "text": "River flow" }, "xaxis": { "title": { "text": "Time" } }, "yaxis": { "title": { "text": "Upstream flow" } } } }, "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Run model\n", "run_model(shop)\n", "\n", "# Get river flow\n", "river = shop.model.river.River1\n", "flow = river.upstream_flow.get()\n", "\n", "# Plot results\n", "fig = go.Figure()\n", "fig.add_trace(go.Bar(x=flow.index, y=flow.values))\n", "fig.update_layout(xaxis_title=\"Time\", yaxis_title=\"Upstream flow\", title = \"River flow\")\n", "fig.show()" ] }, { "cell_type": "markdown", "id": "df91680e", "metadata": {}, "source": [ "## Add flow start- and stop costs and rerun model\n", "\n", "We now add a start cost and a stop cost for the river, set the [flow_commitment_mip_flag](river:flow_commitment_mip_flag) to 1, and rerun the model. As the resulting plot shows, the river avoids starting and stopping by flowing the minimum allowed amount instead." ] }, { "cell_type": "code", "execution_count": 4, "id": "560e7e78", "metadata": {}, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "type": "bar", "x": [ "2018-02-27T00:00:00", "2018-02-27T01:00:00", "2018-02-27T02:00:00", "2018-02-27T03:00:00", "2018-02-27T04:00:00", "2018-02-27T05:00:00", "2018-02-27T06:00:00", "2018-02-27T07:00:00", "2018-02-27T08:00:00", "2018-02-27T09:00:00", "2018-02-27T10:00:00", "2018-02-27T11:00:00", "2018-02-27T12:00:00", "2018-02-27T13:00:00", "2018-02-27T14:00:00", "2018-02-27T15:00:00", "2018-02-27T16:00:00", "2018-02-27T17:00:00", "2018-02-27T18:00:00", "2018-02-27T19:00:00", "2018-02-27T20:00:00", "2018-02-27T21:00:00", "2018-02-27T22:00:00", "2018-02-27T23:00:00" ], "y": [ 13.888888888888099, 57.909031538809714, 52.21451999342051, 13.19437734349889, 5.0, 5.0, 5.0, 41.68207112427096, 90.0, 66.65896443786453, 18.341035562135488, 5.0, 24.463717368159784, 19.463717368159784, 5.0, 5.0, 36.07256526368048, 90.0, 61.96371736815976, 8.036282631840244, 5.0, 5.0, 5.0, 5.0 ] } ], "layout": { "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 }, "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "pattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "fillpattern": { "fillmode": "overlay", "size": 10, "solidity": 0.2 }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "autotypenumbers": "strict", "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ], "sequentialminus": [ [ 0.0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1.0, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "text": "River flow" }, "xaxis": { "title": { "text": "Time" } }, "yaxis": { "title": { "text": "Upstream flow" } } } }, "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#Create a new ShopSession\n", "shop=ShopSession()\n", "\n", "#Build SHOP model\n", "build_model(shop)\n", "\n", "river = shop.model.river.River1\n", "\n", "# Add start- and stop costs\n", "river.flow_start_cost_const.set(10)\n", "river.flow_stop_cost_const.set(10)\n", "\n", "# Set the minimum allowed flow and the absolute max flow\n", "river.min_allowed_flow.set(5)\n", "river.absolute_max_flow.set(100)\n", "river.flow_commitment_mip_flag.set(1)\n", "\n", "# Run model\n", "run_model(shop)\n", "\n", "# Get river flow\n", "flow = river.upstream_flow.get()\n", "\n", "# Plot results\n", "fig = go.Figure()\n", "fig.add_trace(go.Bar(x=flow.index, y=flow.values))\n", "fig.update_layout(xaxis_title=\"Time\", yaxis_title=\"Upstream flow\", title = \"River flow\")\n", "fig.show()" ] }, { "cell_type": "markdown", "id": "1ce4d4fe", "metadata": {}, "source": [ "## Start and stop costs for the first time step\n", "\n", "If no historical flow data is provided, no start- or stop costs will be applied for the first timestep. However, if historical flow data is provided through the [past_upstream_flow](river:past_upstream_flow) attribute, the river flow state before the optimization period is used to build the constraints for the first time step. \n", "\n", "## Binary variables\n", "\n", "The default behaviour is to not use binary variables for the river flow commitment constraints. The use of binary variables can be turned on by the [flow_commitment_mip_flag](river:flow_commitment_mip_flag) attribute, as shown in the example. The start and stop costs are still modelled with continuous variables when the mip flag is 0 (or not set at all), which means that the minimum allowed flow limit can be violated by taking a fractional start or stop cost.\n", "\n", "In the same way as the generator commitment variables are locked in the incremental iterations, the river flow commitment variables can be locked by the [lock_river_flow_commitment ](lock_river_flow_commitment) command. If the on/off decisions are not locked, binary variables will be used in incremental iterations if the flow_commitment_mip_flag is active.\n", "\n", "## river.py" ] }, { "cell_type": "code", "execution_count": 5, "id": "525f59b5", "metadata": { "Collapsed": "false", "tags": [ "remove-input" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "import pandas as pd\n", "import plotly.offline as py\n", "import plotly.graph_objs as go\n", "from plotly.subplots import make_subplots\n", "import numpy as np\n", "\n", "def build_model(shop):\n", " starttime = pd.Timestamp('2018-02-27')\n", " endtime = pd.Timestamp('2018-02-28')\n", " starttime = pd.Timestamp('2018-02-27')\n", " endtime = pd.Timestamp('2018-02-28')\n", " shop.set_time_resolution(starttime=starttime, endtime=endtime, timeunit='hour')\n", "\n", " # Add topology\n", " rsv1 = shop.model.reservoir.add_object('Reservoir1')\n", " rsv1.max_vol.set(12)\n", " rsv1.lrl.set(90)\n", " rsv1.hrl.set(100)\n", " rsv1.vol_head.set(pd.Series([90, 100, 101], index=[0, 12, 14], name=0))\n", " rsv1.flow_descr.set(pd.Series([0, 1000], index=[100, 101], name=0))\n", "\n", " river1 = shop.model.river.add_object('River1')\n", " river1.upstream_elevation.set(90)\n", " \n", " rsv2 = shop.model.reservoir.add_object('Reservoir2')\n", " rsv2.max_vol.set(1)\n", " rsv2.lrl.set(85)\n", " rsv2.hrl.set(86)\n", " rsv2.vol_head.set(pd.Series([85, 86, 87], index=[0, 1, 2]))\n", " rsv2.flow_descr.set(pd.Series([0, 1000], index=[86, 87]))\n", "\n", " plant1 = shop.model.plant.add_object('Plant1')\n", " plant1.outlet_line.set(40)\n", " plant1.main_loss.set([0.0002])\n", " plant1.penstock_loss.set([0.0001])\n", "\n", " p1g1 = shop.model.generator.add_object('Plant1_G1')\n", " plant1.connect_to(p1g1)\n", " p1g1.penstock.set(1)\n", " p1g1.p_min.set(15)\n", " p1g1.p_max.set(100)\n", " p1g1.p_nom.set(100)\n", " p1g1.startcost.set(500)\n", " p1g1.gen_eff_curve.set(pd.Series([95, 98], index=[0, 100]))\n", " p1g1.turb_eff_curves.set([pd.Series([70, 80, 95, 90], index=[10, 25, 90, 100], name=45),\n", " pd.Series([72, 82, 98, 92], index=[10, 25, 90, 100], name=55)])\n", "\n", " # Connect objects\n", " rsv1.connect_to(river1)\n", " river1.connect_to(rsv2)\n", " rsv2.connect_to(plant1)\n", "\n", " rsv1.start_head.set(94)\n", " rsv2.start_head.set(85.95)\n", " rsv1.energy_value_input.set(38.6)\n", " rsv2.energy_value_input.set(38.6)\n", "\n", " shop.model.market.add_object('Day_ahead')\n", " da = shop.model.market.Day_ahead\n", " da.max_buy.set(9999)\n", " da.max_sale.set(9999)\n", " shop.model.market.Day_ahead.sale_price.set(pd.DataFrame([30,80,80,30,30,30,30,30,40,40,30,30,40,30,30,30,30,40,40,30,30,30,30,30],index=[starttime+ pd.Timedelta(hours=i) for i in range(0,24)]))\n", " shop.model.market.Day_ahead.buy_price.set(shop.model.market.Day_ahead.sale_price.get()+0.002)\n", "\n", " # add gate\n", " river1.width_depth_curve.set(pd.Series([0,5],index=[2,2],name=0))\n", " river1.gate_opening_curve.set(pd.Series([0,10],index=[0,1],name=0))\n", " river1.mip_flag.set(1)\n", "\n", " rsv1.inflow.set(pd.DataFrame([101, 50], index=[starttime, starttime + pd.Timedelta(hours=1)]))\n", " return shop\n", "\n", "def run_model(shop):\n", " shop.start_sim([],['3'])\n", " shop.set_code(['inc'],[])\n", " shop.start_sim([],['3'])\n" ] } ], "source": [ "with open('river.py', 'r') as f:\n", " print(f.read())" ] } ], "metadata": { "jupytext": { "text_representation": { "extension": ".md", "format_name": "myst", "format_version": 0.13, "jupytext_version": "1.17.2" } }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.13" }, "source_map": [ 12, 22, 31, 37, 46, 52, 65, 71, 100, 114 ] }, "nbformat": 4, "nbformat_minor": 5 }