{ "cells": [ { "cell_type": "markdown", "id": "c8938c83", "metadata": {}, "source": [ "(generator)=\n", "# generator\n", "A hydropower generating unit consisting of a hydropower turbine and a generator which uses falling water to generate electricity\n", "\n", "| | |\n", "|---|---|\n", "|Input connections|{ref}`plant`, {ref}`needle_combination`, {ref}`reserve_group`, {ref}`commit_group`, {ref}`busbar`, {ref}`gen_reserve_capability`|\n", "|Output connections|{ref}`plant`, {ref}`reserve_group`, {ref}`commit_group`, {ref}`needle_combination`, {ref}`busbar`, {ref}`gen_reserve_capability`|\n", "|License|SHOP_OPEN|\n", "|Release version|13.0.0.a|\n", "\n", "```{contents}\n", ":local:\n", ":depth: 1\n", "```\n", "\n", "## Introduction\n", "The generator object is one of the most fundamental building blocks in any SHOP model. The generator represents the combination of a generator and turbine, which is why attributes such as the [generator efficiency](generator:gen_eff_curve) and the [turbine efficiency](generator:turb_eff_curves) are both located on the generator object. The fundamental equation that governs the generation of electricity from flowing water is handled on the generator level in SHOP:\n", "\n", "```{math}\n", "p = \\rho \\cdot g \\cdot h \\cdot q \\cdot \\eta_{gen}(p) \\cdot \\eta_{turb}(q, h),\n", "```\n", "\n", "where $p$ is the power, $\\rho$ is the density of water, $g$ is the acceleration due to gravity, $h$ is the effective head of the generator, $q$ is the flow of water through the turbine, $\\eta_{gen}$ is the efficiency of the generator and $\\eta_{turb}$ is the efficiency of the turbine. See the [PQ curve tutorial](pq-tutorial) for more details on how this relationship is handled by SHOP.\n", "\n", "## Required input\n", "A generator must always be connected to a [](plant) object, and the plant object is then connected to reservoirs/tunnels/rivers/etc upstream and downstream. The [penstock number](generator:penstock) is required to specify which of the penstocks in the plant the generator is connected to, since each penstock has its own [loss coefficient](plant:penstock_loss) and could be shared between several units. The operating range of the generator must also be specified. The rated static [minimum production](generator:p_min) and [maximum production](generator:p_max) must be defined to set the legal production range of the generator. The [nominal production](generator:p_nom) should also be specified, but is only used for droop calculations when the generator delivers [FCR reserves](reserves). The legal discharge range for the generator is defined through the highest and lowest discharge points in the [turbine efficiency curves](generator:turb_eff_curves) for the given effective head in each hour in the optimization. Since the turbine efficiency is head dependent, the discharge limits are also head dependent.\n", "\n", "## Pelton turbines\n", "Pelton turbines have different operating characteristics compared to Francis and Kaplan turbines. The production and discharge limits of Pelton turbines are determined by which combination of needles are used to push water through the nozzle. This can be modelled in SHOP by connecting several [](needle_combination) objects to the generator. The input attributes [p_min](needle_combination:p_min), [p_max](needle_combination:p_max), [p_nom](needle_combination:p_nom), and [turb_eff_curves](needle_combination:turb_eff_curves) on each needle_combination will determine the operating ranges, and SHOP will optimize which needle_combination will be used in each time step of the optimization. Please see the [Pelton example](pelton) for more modelling details. \n", "\n", "## Generators with forbidden operating regions\n", "The Pelton functionality can also be used to model Francis and Kaplan turbines with forbidden operating regions. This is discussed in the [Pelton example](pelton).\n", "\n", "## Reversible turbines\n", "Some turbines can be reversed and operated as pumps, either as a single pump-turbine machine or as a ternary set of one turbine and one pump. Both of these types of reversible turbines are modelled in SHOP as two separate generator and [](pump) objects located in the same power plant. If the reversible turbine is a single machine that cannot produce and consume power at the same time, two [](commit_group) objects must be used to ensure that the generator and pump never operate at the same time. The [reversible turbine example](reversible-turbine-example) shows how this is done in practice. Ternary sets that can run in hydraulic short circuit do not require any commit_group modelling. \n", "\n", "## Reserve capacity\n", "Many of the attributes on the generator object are related to the delivery of different types of reserve capacity. To be able to deliver reserve capacity, a generator must either: have defined a fixed reserve schedule (such as [frr_up_schedule](generator:frr_up_schedule)), be connected to a [](reserve_group) object with a reserve obligation (such as [frr_up_obligation](reserve_group:frr_up_obligation)), or be connected to a reserve_group that is itself connected to a reserve capacity [](market). The [reserve tutorial](reserves) gives an overview of the reserve functionality in SHOP, and several examples are related to this topic. The [reserve obligation example](reserve-example) shows how generators cooperate to optimally distribute the reserve obligation defined in the reserve_groups.\n", "\n", "## Unit commitment\n", "The unit commitment decision is the choice of whether a unit should be on or off. This decision is part of the optimization problem in SHOP in full iterations. When one changes to incremental iterations, the unit commitment decisions of all units in the system is locked to either on or off. This allows SHOP to refine the problem and accurately estimate head losses. However, the unit commitment decision is not simple to solve as it is non-convex, and accurate modelling comes with higher computational costs.\n", "\n", "### Binary variables\n", "Binary variables must be used to ensure that a generator is either off or operating within its legal limits. Otherwise, fractional starts with operation below minimum production and/or discharge may occur. In the realm of optimization, a binary variable can only take on the values of 0 or 1, while a regular variable is continuous between its upper and lower bound. The illustrative equations below shows how the binary variable $u$ constrains both the production variable $p$ and discharge variable $q$ of the generator. If $u = 0$, both $p$ and $q$ also have to be zero, while $u = 1$ constrain $p$ and $q$ to be within their operating limits:\n", "\n", "```{math}\n", "P^{min}\\cdot u \\leq p \\leq P^{max}\\cdot u \\\\\n", "Q^{min}\\cdot u \\leq q \\leq Q^{max}\\cdot u\n", "```\n", "\n", "The default behaviour in SHOP is to relax this binary variable to be continuous between 0 and 1, which allows operation below $P^{min}$ and $Q^{min}$. This is due to the increased calculation time that is associated with binary variables and Mixed Integer Linear Programming (MILP). The [mip_flag](plant:mip_flag) attribute on the plant object can be used to specify when binary variables should be used instead of the relaxed default behaviour. It is typical to set the flag to 1 (active) for the first day(s) in the optimization horizon to get more accurate results closer to real time. Using binary variables is especially important for Pelton units that require one binary variable per needle_combination, and for generators that could deliver spinning reserve capacity (FCR and FRR).\n", "\n", "### Fractional starts and cut-off limits\n", "As mentioned earlier, the unit commitment decision must be made for all units in all time steps when switching from full to incremental iterations in SHOP. If binary variables have been used in a time step the full iterations, the unit commitment decision will be completely decided by the value of the binary variable. For time steps where the binary variables have been relaxed, the decision to turn on or off the unit is decided by the global [gen_turn_off_limit](global_settings:gen_turn_off_limit) or the generator-specific attribute [gen_turn_off_limit](generator:gen_turn_off_limit). The gen_turn_off_limit specifies how fractional the relaxed binary variable can be before the unit is considered off. The default value is 0.5, which means that the unit is considered off if $q$ is less than 50% of $Q^{min}$. Otherwise, the unit is considered on and must operate within its range in the following incremental iterations.\n", "\n", "### Start and stop costs\n", "Turning generators on and off is usually associated with some loss of water, wear and tear, and manual labour, and therefore a cost. For this to be reflected in the optimization and unit commitment decision, the attributes [startcost](generator:startcost) and [stopcost](generator:stopcost) can be set. These costs will be applied when the unit goes from off to on and vice versa. \n", "\n", "## Examples\n", " - [](best-profit)\n", " - [](best-profit-basic-example)\n", " - [](discrete-droop)\n", " - [](maintenance-example)\n", " - [](min_uptime_downtime)\n", " - [](reserve-example)\n", " - [](pelton)\n", " - [](reversible-turbine-example)\n", " - [](pq-example)\n", " \n", "\n", "## References\n", " - An overview on formulations and optimization methods for the unit-based short-term hydro scheduling problem {cite}`Kong2020`\n", " - Dynamic incorporation of nonlinearity into MILP formulation for short-term hydro scheduling {cite}`Skjelbred2020`\n", " - A comparison of linear interpolation and spline interpolation for turbine efficiency curves in short-term hydropower scheduling problems {cite}`Zhang2019`\n", " - Calculation of power compensation for a pumped storage hydropower plant with hydraulic short-circuit operation {cite}`Skjelbred2017b`\n", " \n", "\n", "## Attributes" ] }, { "cell_type": "code", "execution_count": 1, "id": "2259fd3c", "metadata": { "tags": [ "remove-input", "full-width" ] }, "outputs": [ { "data": { "text/html": [ "