Simulation in SHOP#

Introduction#

The main purpose of SHOP is to build and solve an optimization problem. However, SHOP also includes a simulator that does not involve trying to optimize any decisions related to hydropower scheduling. The simulator takes all decisions as input, such as power generation schedules, and calculates the physical response of the hydropower system with a very fine time resolution. All non-linear physical relationships, such as tunnel network flow and the hydropower production function, can be accurately handled in the simulator since there is no optimization problem to solve. A simulation is also typically much faster than an optimization run. This is a powerful tool that is mainly used for two things:

  1. Validating that production plans and other operational decisions are physically feasible, see the simulated production plan example.

  2. Calculating historical inflow to all reservoirs based on historical production schedules and reservoir levels, see the the simulated inflow example.

Note that the simulator does not consider any operating constraints that are normally included in a SHOP optimization run (ramping constraints, tactical reservoir limits, etc.), it will simply simulate the physical response of the system given the input data and topology.

The commands and input attributes that constitute the SHOP simulator are licensed under the SHOP_SIMULATION license.

How it works#

The SHOP simulator is based on a simple forward Euler method for calculating the reservoir volume trajectories based on the input unit data (production schedules etc.), and was first described in [32]. Simply put, the flow through all generators, pumps, tunnels, and rivers are first calculated based on the unit schedules and initial reservoir levels of the system. This may involve calculating generator discharge from generator production and simulating tunnel network flow. The reservoir volumes \(V\) are then updated by assuming the calculated flows \(Q\) are constant over a short time interval \(\Delta t\):

\(V_{t+1} = V_t + \Delta t\cdot Q^{net}_t(V_t).\)

New flows are then calculated for the next time step based on updated reservoir states and input data. This approach is possible since the amount of production/discharge on each unit in the system is fixed before simulation. Simulating a production plan for the whole system will then yield simulated reservoir trajectories that will likely deviate slightly from the optimization that originally created the production plan. The simulator could then also show what will happen to the physical system if the optimized production plan is slightly changed due to intra-day trading or reserve activation.

Using the simulator for inflow calculations requires historical reservoir level measurements. The historical reservoir levels can be compared to the simulated levels with no inflow, and the difference in volume must be the resulting historical inflow.

Simulation time resolution#

The simulator works with a much finer time resolution compared to the typical SHOP optimization run, and the default internal time step length of the simulator is 20 seconds. There are three different time scales to consider in the simulator: the input data time resolution, the resolution of the internal simulation, and the resolution of the output attributes.

Internal time scale#

The short step size of the internal simulation calculations decide the internal time resolution. The default value of 20 seconds can be changed with the command set simtimestep <value> before the simulation starts. This could be necessary when simulating tunnel networks where tiny creek intakes are coupled to larger reservoirs, as the flow and pressure changes rapidly. Lowering the internal step size will increase calculation time of the simulator, while increasing it will impact the accuracy of the results. The internal time step size is constant over the whole simulation horizon.

Input time scale#

The start and end times of the simulation horizon and the time resolution of the input data is the same as the regular optimization resolution that has a defined start time, end time, time unit, and time step length. The following section describes the required input data for the various objects before performing a simulation, and the input TXY attributes are given in the input time scale. If the input time scale is 24 hours long with a 15 minute resolution, there will be 45 internal simulation time steps of length 20 seconds for each time step in the input data. This allows the simulator to calculate the changes in reservoir trajectories, generator discharge, etc over each 15 min interval.

Output time scale#

The output attributes from the simulation are calculated for each internal time step. Since this can create a lot of data for simulations over longer time periods, the default behaviour is to save hourly output data in the form of TXYs. The calculated output attributes (e.g. sim_production) are therefore averaged over the output time scale, except for the reservoir levels that are instantaneous values at the interval changes. It is possible to change the output time step length of the simulator in the start shopsim /<option> <value> command by specifying the number of whole seconds in the output time steps as the “<value>”. Note that the output time step length can’t be lower than the internal time step length of the simulator, and it is also constant over the whole simulation horizon.

Figure 1: Illustration of the three different time resolutions to consider in the SHOP simulator. The regular time horizon in SHOP corresponds to the input data resolution, which is 15 min in the figure. The internal time resolution of the simulator itself is set to 1 second in the figure above, and the blue curve shows the internal calculations of some simulated value. The internal values in blue are not directly returned by the simulator, rather the averaged red curve (5 minute resolution in the figure) is returned as the output TXY attributes.

Input data#

The main benefit of keeping the simulator part of the SHOP source code is that all topological data is shared between the normal SHOP optimizer and the simulator. This means that simulating a production plan created by a SHOP optimization run will not suffer from any errors due to inconsistent topological data. The simulator requires all operational decisions as input time series, in addition to the initial reservoir state of the system. The necessary input data to each object is described below. Please consult the general attribute table in the documentation for a complete overview of simulation related attributes. All simulator attribute names have the “sim_” prefix to make them easy to identify and search for.

Reservoir input#

As in a normal SHOP optimization run, the initial state of the reservoir object must be defined by either the start_vol or start_head attribute before performing a simulation. If the simulation is performed to validate a production plan, the inflow to the reservoir should also be specified. The inflow attribute is not required when the simulator is run for inflow calculations (input inflow will be ignored), instead the reservoir volume or level should be set for the whole simulation period with the sim_volume_schedule or sim_level_schedule TXY attributes.

Generator input#

All generators in the system must either have a production_schedule or a discharge_schedule set for the whole simulation horizon. Note that all generators must have the same type of schedule, it is currently not possible to mix schedules of production and discharge. The type of schedule used must also match the options given to the start shopsim command when starting the simulation: The option “gen_mw_schedule” should be used when generators have production schedules, while the option “gen_m3s_schedule” is appropriate when discharge schedules are used. It is also possible to use the output production or discharge values of a SHOP optimization run directly in the simulator instead of manually specifying input schedules. The options “gen_mw_result” and “gen_m3s_result” should be used in these cases, but note that a SHOP optimization must be performed before the call to the start shopsim command for this to work.

Pump input#

Similar to generators, all pumps in the system must have either a consumption_schedule or a upflow_schedule specified before simulating the system with the “gen_mw_schedule” or “gen_m3s_schedule” options. It is not possible to have separate schedule types for generators and pumps, so all units must either have power schedules or flow schedules set. The consumption or upflow output attributes from an optimization run will be used instead of the schedules if the options “gen_mw_result” or “gen_m3s_result” are used. An exception to these rules are made for binary pumps, which can be set to just be on or off with the committed_in attribute when the option “gen_mw_schedule” is used. This will automatically calculate the upflow and consumption of the pump based on the effective head and the single operating point given in the turbine efficiency curves. Note that any consumption schedule specified for the binary pump will be preferred over the committed_in attribute. When the “gen_mw_result” option is used, the committed_out attribute is preferred over the consumption attribute for binary pumps. If upflow schedules or results are used to simulate the system, binary pumps will follow the given upflow plan.

Tunnel input#

The flow in the tunnel networks will be automatically calculated based on the unit plans and reservoir levels in each short time step of the simulation, so no input data is required for simple tunnels. However, if there exists a gate on the tunnel (a gate_opening_curve has been defined), a gate_opening_schedule must be specified before simulation. Otherwise, the gate will assumed to be completely open in the simulation and a warning will be printed to the log.

River input#

The flow in a river object can be modelled in several ways in SHOP. If an input flow_schedule is given, this will be used in the simulator no matter what other type of input data is given. If the river has some form of flow curve attached to it, either up_head_flow_curve, width_depth_curve, delta_head_ref_up_flow_curve, or delta_head_ref_down_flow_curve, the river flow will be automatically calculated in the simulator based on the reservoir levels and no additional input is required. If the river has a gate_opening_curve, a gate_opening_schedule should also be provided. If none of the mentioned attributes are present, a warning will be printed to the log and the simulator will attempt to create a flow schedule based on the output attribute flow from the optimization. If this is not present, there will be no flow in the river in the entire simulation.

Other objects#

The deprecated gate and junction objects are also handled by the simulator, but are not documented in any detail here.

Results#

The simulator produces several output attributes, a complete list can again be found in the general attribute table by filtering on output attributes with “sim_” in their attribute name. The most important output attributes are the simulated reservoir trajectories, simulated production/consumption and discharge/upflow for each generator/pump and plant, simulated flow and pressure in tunnels, and simulated river flow (both upstream and downstream in case of time delays).

In addition to the simulated physical attributes, some simplified economical values are also calculated. The net trading in the market from the net total simulated production is calculated for the first energy market object and reported as sim_sale and sim_buy. This only considers a single energy market as it is not possible to differentiate between multiple markets without doing some form of optimization. A simplified objective function value is also calculated based on the simulated results, where sim_grand_total is the total objective function value. The market income is stored as sim_market_sale_buy, while the end value of the simulated reservoir volumes is recoded in sim_rsv_end_value. Simulated start and stop costs are also calculated as sim_startup_costs, and any reservoir volume violations during the simulation is valuated as sim_rsv_penalty. It is possible to run a simulation without any markets, water value descriptions, and start- and stop costs. The objective function will simply be zero in such simulations, except for any incurred reservoir penalties.