{ "cells": [ { "cell_type": "markdown", "id": "65a3ce1a", "metadata": {}, "source": [ "(discharge_group)=\n", "# discharge_group\n", "The sum discharge of the objects connected to a discharge_group is restricted by the constraints defined in the discharge_group\n", "\n", "| | |\n", "|---|---|\n", "|Input connections|{ref}`plant`, {ref}`gate`, {ref}`tunnel`, {ref}`river`|\n", "|Output connections|{ref}`plant`, {ref}`gate`, {ref}`river`, {ref}`tunnel`|\n", "|License|SHOP_OPEN|\n", "|Release version|13.0.0.a|\n", "\n", "```{contents}\n", ":local:\n", ":depth: 1\n", "```\n", "\n", "## Introduction\n", "\n", "The discharge group functionality was originally created to model complex discharge restrictions in Swedish rivers with shared ownership. The functionality has since evolved to become more versatile, and can be used to add several types of sum discharge restrictions to a collection of different objects in SHOP. The discharge group object is a simple object which represents one or several sum discharge restrictions. All objects that are connected to a discharge group contribute to the total sum discharge which has to abide by the restrictions defined on the discharge group.\n", "\n", "|![](./img/illustration.png)|\n", "|---|\n", "| Figure 1: A representation of a discharge group connected to two [plants](plant) and one [gate](gate). |\n", "\n", "\n", "## 1 Necessary input and basic behavior\n", "\n", "There are no strictly necessary input attributes for the discharge_group object. To have any impact on the optimization problem, the discharge_group has to be connected to at least one physical object (see the valid connection list at the top of this page) and at least one constraint must be defined. The resulting total discharge in the discharge_group is found on the output TXY attribute [actual_discharge_m3s](discharge_group:actual_discharge_m3s), which is simply the sum of the discharge of all objects connected to the discharge_group.\n", "\n", "## 2 Simple sum discharge constraints\n", "\n", "The simplest sum discharge constraints that can be defined on a discharge_group are minimum and maximum discharge limits. These constraints can be specified with the [min_discharge_m3s](discharge_group:min_discharge_m3s) and [max_discharge_m3s](discharge_group:max_discharge_m3s) TXY attributes. The penalty cost for breaking these min and max limits can be specified with the [min_discharge_penalty_cost](discharge_group:min_discharge_penalty_cost) and [max_discharge_penalty_cost](discharge_group:max_discharge_penalty_cost) TXY attributes, otherwise the penalty cost is set by the global [discharge_group_penalty_cost](global_settings:discharge_group_penalty_cost) attribute on the [global_settings](global_settings) object. Any incurred penalties are saved to the [min_discharge_penalty](discharge_group:min_discharge_penalty) and [max_discharge_penalty](discharge_group:max_discharge_penalty) output TXY attributes.\n", "\n", "Basic ramping constraints for the sum discharge can also be defined through the TXY attributes [ramping_up_m3s](discharge_group:ramping_up_m3s) and [ramping_down_m3s](discharge_group:ramping_down_m3s), these dictate how much the sum discharge can change in one hour in either direction. Note that the unit of the ramping attributes is m3/s per hour, which is converted internally in SHOP to account for the length of each time step in the current optimization run. No ramping constraints are added for the initial time step. Accompanying TXY attributes to define the penalty cost for breaking the ramping constraints are available as [ramping_up_penalty_cost](discharge_group:ramping_up_penalty_cost) and [ramping_down_penalty_cost](discharge_group:ramping_down_penalty_cost). The global [discharge_group_penalty_cost](global_settings:discharge_group_penalty_cost) is again used as penalty cost if no penalty cost attributes are given. If the ramping constraints are broken, the resulting penalty is saved to the [ramping_up_penalty](discharge_group:ramping_up_penalty) and [ramping_down_penalty](discharge_group:ramping_down_penalty) output TXY attributes.\n", "\n", "\n", "## 3 Modelling accumulated volume constraints with slack\n", "\n", "Some discharge constraints are formulated as a discharge profile with a certain tolerances for deviating from the accumulated discharged volume specified by the profile. This can be modelled by a discharge_group with the [weighted_discharge_m3s](discharge_group:weighted_discharge_m3s) attribute defining the discharge profile. The maximal accumulated volume deviation from this profile that is tolerated is then specified with the [max_accumulated_deviation_mm3_up](discharge_group:max_accumulated_deviation_mm3_up) and [max_accumulated_deviation_mm3_down](discharge_group:max_accumulated_deviation_mm3_down) attributes. If these tolerances are zero at all times, the discharge profile must be followed exactly to avoid incurring any penalties. Otherwise, the sum discharge can deviate from the profile as long as the total discharged volume is within the specified bounds. Any initial accumulated deviation at the start of the optimization period can be specified with the [initial_deviation_mm3](discharge_group:initial_deviation_mm3) double attribute. The [accumulated_deviation_mm3](discharge_group:accumulated_deviation_mm3) output TXY is the resulting accumulated volume deviation of the discharge_group, while [upper_slack_mm3](discharge_group:upper_slack_mm3) and [lower_slack_mm3](discharge_group:lower_slack_mm3) calculate the distance from the values in accumulated_deviation_mm3 to the upper and lower limits. Note that all of the attributes related to volume (name ends with '_mm3') represent values at the end of each time step. That means that the first value in accumulated_deviation_mm3 is the accumulated deviation at the *end* of the first time step, not the deviation at the start (which would be equal to initial_deviation_mm3). [penalty_cost_up_per_mm3](discharge_group:penalty_cost_up_per_mm3) and [penalty_cost_down_per_mm3](discharge_group:penalty_cost_down_per_mm3) specify the penalty cost for breaking the accumulated discharge restriction, and the [upper_penalty_mm3](discharge_group:upper_penalty_mm3) and [lower_penalty_mm3](discharge_group:lower_penalty_mm3) attributes save the incurred penalty. An illustration of these restrictions and their impact on the optimization results are shown in Figure 2. The topology used is the one illustrated in Figure 1.\n", "\n", "|![](./img/acc_dev.png)|\n", "|---|\n", "| Figure 2: Two cases where the penalty for breaking the accumulated deviation tolerances are low (first row) and high (second row). The initial deviation is set to -0.01 Mm3, and the deviation tolerances are set to 0.02 Mm3 in both directions. The discharge in the case where without any discharge_group is also shown as a yellow line. The sum discharge adapts to the discharge profile when penalties are low, but the accumulated volume deviation is often outside the specified tolerances. When the penalties are set higher, the accumulated discharge stays within the tolerances for all time steps. |\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "## Attributes" ] }, { "cell_type": "code", "execution_count": 1, "id": "8dbdfb0b", "metadata": { "tags": [ "remove-input", "full-width" ] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.core.display import HTML\n", "HTML(\"\"\"
\n", "\n", "\"\"\")" ] }, { "cell_type": "markdown", "id": "c72957fe", "metadata": {}, "source": [ "(discharge_group:initial_deviation_mm3)=\n", "### initial_deviation_mm3\n", "The initial volume deviation for the discharge group before the optimization period. The positive value refers to the upward deviation from weighted discharge while the negative value refers to the downward deviation from weighted discharge. (xUnit: MM3, yUnit: MM3)\n", "\n", "\n", "(discharge_group:max_accumulated_deviation_mm3_up)=\n", "### max_accumulated_deviation_mm3_up\n", "Maximum accumulated upward volume deviation (Mm3) for the discharge group (xUnit: NO_UNIT, yUnit: MM3)\n", "\n", "\n", "(discharge_group:max_accumulated_deviation_mm3_down)=\n", "### max_accumulated_deviation_mm3_down\n", "Maximum accumulated downward volume deviation (Mm3) for the discharge group (xUnit: NO_UNIT, yUnit: MM3)\n", "\n", "\n", "(discharge_group:weighted_discharge_m3s)=\n", "### weighted_discharge_m3s\n", "Weighted discharge target for the discharge group (xUnit: NO_UNIT, yUnit: M3/S)\n", "\n", "\n", "(discharge_group:penalty_cost_up_per_mm3)=\n", "### penalty_cost_up_per_mm3\n", "Given penalty cost for discharging more than the allowed max accumulated deviation for the discharge group (xUnit: NO_UNIT, yUnit: NOK/MM3)\n", "\n", "\n", "(discharge_group:penalty_cost_down_per_mm3)=\n", "### penalty_cost_down_per_mm3\n", "Given penalty cost for discharging less than the allowed max accumulated deviation for the discharge group (xUnit: NO_UNIT, yUnit: NOK/MM3)\n", "\n", "\n", "(discharge_group:min_discharge_m3s)=\n", "### min_discharge_m3s\n", "Minimal sum discharge allowed in the discharge group (xUnit: NO_UNIT, yUnit: M3/S)\n", "\n", "\n", "(discharge_group:max_discharge_m3s)=\n", "### max_discharge_m3s\n", "Maximal sum discharge allowed in the discharge group (xUnit: NO_UNIT, yUnit: M3/S)\n", "\n", "\n", "(discharge_group:min_discharge_penalty_cost)=\n", "### min_discharge_penalty_cost\n", "Penalty cost for violating the minimum discharge constraint of the discharge group. (xUnit: NO_UNIT, yUnit: NOK/H/M3/S)\n", "\n", "\n", "(discharge_group:max_discharge_penalty_cost)=\n", "### max_discharge_penalty_cost\n", "Penalty cost for violating the maximum discharge constraint of the discharge group. (xUnit: NO_UNIT, yUnit: NOK/H/M3/S)\n", "\n", "\n", "(discharge_group:ramping_up_m3s)=\n", "### ramping_up_m3s\n", "Maximal discharge ramping of the total discharge allowed in the upward direction (xUnit: NO_UNIT, yUnit: M3SEC_HOUR)\n", "\n", "\n", "(discharge_group:ramping_down_m3s)=\n", "### ramping_down_m3s\n", "Maximal discharge ramping of the total discharge allowed in the downward direction (xUnit: NO_UNIT, yUnit: M3SEC_HOUR)\n", "\n", "\n", "(discharge_group:ramping_up_penalty_cost)=\n", "### ramping_up_penalty_cost\n", "Penalty cost for violating the upward discharge ramping constraint in the discharge group (xUnit: NO_UNIT, yUnit: NOK/H/M3/S)\n", "\n", "\n", "(discharge_group:ramping_down_penalty_cost)=\n", "### ramping_down_penalty_cost\n", "Penalty cost for violating the downward discharge ramping constraint in the discharge group (xUnit: NO_UNIT, yUnit: NOK/H/M3/S)\n", "\n", "\n", "(discharge_group:min_average_discharge)=\n", "### min_average_discharge\n", "Minimum average discharge of group. T gives time the constraint is active from, X the duration of the constraint in minutes, and Y the discharge limit. (xUnit: MINUTE, yUnit: M3/S)\n", "\n", "\n", "(discharge_group:max_average_discharge)=\n", "### max_average_discharge\n", "Maximum average discharge of group. T gives time the constraint is active from, X the duration of the constraint in minutes, and Y the discharge limit. (xUnit: MINUTE, yUnit: M3/S)\n", "\n", "\n", "(discharge_group:min_average_discharge_penalty_cost)=\n", "### min_average_discharge_penalty_cost\n", "Penalty cost for violating the minimum average discharge constraint of the discharge group. (xUnit: NOK/H/M3/S, yUnit: NOK/H/M3/S)\n", "\n", "\n", "(discharge_group:max_average_discharge_penalty_cost)=\n", "### max_average_discharge_penalty_cost\n", "Penalty cost for violating the maximum average discharge constraint of the discharge group. (xUnit: NOK/H/M3/S, yUnit: NOK/H/M3/S)\n", "\n", "\n", "(discharge_group:actual_discharge_m3s)=\n", "### actual_discharge_m3s\n", "Resulting discharge for the discharge group (xUnit: NO_UNIT, yUnit: M3/S)\n", "\n", "\n", "(discharge_group:accumulated_deviation_mm3)=\n", "### accumulated_deviation_mm3\n", "Resulting accumulated volume deviation for the discharge group (xUnit: NO_UNIT, yUnit: MM3)\n", "\n", "\n", "(discharge_group:upper_penalty_mm3)=\n", "### upper_penalty_mm3\n", "Resulting penalty when the maximum accumulated upward volume deviation for the discharge group is violated (xUnit: NO_UNIT, yUnit: MM3)\n", "\n", "\n", "(discharge_group:lower_penalty_mm3)=\n", "### lower_penalty_mm3\n", "Resulting penalty when the maximum accumulated downward volume deviation for the discharge group is violated (xUnit: NO_UNIT, yUnit: MM3)\n", "\n", "\n", "(discharge_group:upper_slack_mm3)=\n", "### upper_slack_mm3\n", "Resulting slack when the maximum accumulated upward volume deviation for the discharge group is not reached (xUnit: NO_UNIT, yUnit: MM3)\n", "\n", "\n", "(discharge_group:lower_slack_mm3)=\n", "### lower_slack_mm3\n", "Resulting slack when the maximum accumulated downward volume deviation for the discharge group is not reached (xUnit: NO_UNIT, yUnit: MM3)\n", "\n", "\n", "(discharge_group:min_discharge_penalty)=\n", "### min_discharge_penalty\n", "Resulting penalty when the minimum discharge constraint in the discharge group is violated (xUnit: NO_UNIT, yUnit: NOK)\n", "\n", "\n", "(discharge_group:max_discharge_penalty)=\n", "### max_discharge_penalty\n", "Resulting penalty when the maximum discharge constraint in the discharge group is violated (xUnit: NO_UNIT, yUnit: NOK)\n", "\n", "\n", "(discharge_group:ramping_up_penalty)=\n", "### ramping_up_penalty\n", "Resulting penalty when the upward discharge ramping constraint in the discharge group is violated (xUnit: NO_UNIT, yUnit: NOK)\n", "\n", "\n", "(discharge_group:ramping_down_penalty)=\n", "### ramping_down_penalty\n", "Resulting penalty when the downward discharge ramping constraint in the discharge group is violated (xUnit: NO_UNIT, yUnit: NOK)" ] } ], "metadata": { "jupytext": { "text_representation": { "extension": ".md", "format_name": "myst", "format_version": 0.13, "jupytext_version": "1.13.8" } }, "kernelspec": { "display_name": "Python 3", "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.12.9" }, "source_map": [ 11, 64, 76 ] }, "nbformat": 4, "nbformat_minor": 5 }