Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Complex ramping on plant discharge

Open in vLab iLab Assistant

This example shows the types of complex ramping constraints that can be applied to the plant discharge in SHOP under the SHOP_COMPLEX_RAMPING license. Similar constraints can also be applied to reservoir level, as shown in this example. To understand the underlying concepts of rolling and period ramping better, the reader is referred to the complex ramping section in the brief ramping tutorial.

The model setup is available in the following formats:

Baseline run without ramping constraints

The system used in the example is a single reservoir above a plant with one generator:

Loading...

The reservoir starts half full, and has a constant inflow of 10 m3/s incoming during the 24 hour optimization horizon. The market price is above the constant water value in all hours, but the price is also linearly increasing in each hour.

First, we run the model without any complex ramping constraints. The resulting plant discharge is shown below, and we see that SHOP will wait a few hours before producing at best point.

Loading...

Adding complex ramping constraints

Now we will add rolling and period ramping constraints to the plant discharge to limit how much the average, minimum, and maximum discharge can change over certain time windows. First, we create a new SHOP session.

The plant discharge will be limited downwards by a rolling ramping constraint with a window size of 2 hours (120 min). This is a limit rolling ramping constraint in the downward direction, which means that the plant discharge in every time step is constrained by the maximal discharge value in the rolling window after subtracting the ramping limit.

The limit_discharge_rolling_ramping_down attribute is of type XYT, which makes it possible to change the ramping limit inside the optimization horizon. Note that each XY attribute (in the form of a pd.Series object in the code below) has a reference time stamp. The time stamp specifies from when the ramping constraint is valid. In this example, the ramping limit is 20 m3/s for the first 6 hours of the optimization. It is then set to ‘NaN’, which deactivates the rolling ramping constraint for the remainder of the optimization horizon. Note that only a single rolling ramping constraint with a window size of 2 hours is defined in this example, which means that each XY table has a single point. The reservoir level example shows how to model multiple rolling ramping constraints with different rolling time windows.

To limit the discharge in the upward direction, a period ramping constraint with 6 hour (360 min) long periods is added. Unlike the rolling ramping constraint, the period ramping constraint is constraining the average period discharge. This means that the average discharge in each 6 hour period is limited upward by the average discharge in the previous period.

The average_discharge_period_ramping_up attribute is used to add this constraint, and the ramping limit changes from 20 m3/s to 10 m3/s 12 hours into the optimization. Note that changing the ramping limit for period ramping constraints should only be done when a new period begins. Changing it in the middle of a period makes little sense, and an average ramping limit value will be used in those cases.

Since the optimization horizon is 24 hours and the ramping periods are 6 hours long, there will be no fractional ramping periods if the first period start at the start time of the optimization. It is not strictly necessary to define an offset for the period ramping when the offset from the start time is zero, but a warning will be printed to the log file. Therefore, the SY attribute average_discharge_period_ramping_up_offset is explicitly defined below, and the offset will be zero since the periods start at the optimization start time:

Historical discharge values are needed to add both rolling and period ramping constraints at the beginning of the optimization. The period ramping constraint requires the most historical values since the rolling ramping window is only 2 hours long. There is no fractional ramping period at the beginning of the optimization since the specified offset is zero, so it is sufficient to include 6 hours of values to the historical_discharge attribute. However, there is no harm in giving in more historical values than strictly required. 24 hours of historical discharge is randomly generated below:

Loading...

Comparing results

Now we can optimize and compare the optimization results to the initial SHOP run without ramping constraints.

As seen in the figure below, the plant discharge can’t ramp up from zero to 90 m3/s in the way the unconstrained solution suggests. Note that the historical discharge values have been appended to the optimized discharge results with ramping.

Loading...

To validate that the complex ramping constraints are not violated, we will post-calculate the rolling and period discharge values and their implied ramping bounds.

Period ramping validation

The figure below shows the plant discharge together with the average discharge in all ramping periods, including the purely historical ramping period before the optimization starts. The upper ramping limit for the average discharge in a period is calculated by adding 20 m3/s (or 10 m3/s after 12 hours) to the average of the previous period. The vertical dotted lines show the beginning of each fixed ramping period.

Loading...

The average in the first purely historical period adds an upper limit for the average discharge in the first ramping period within the optimization interval. Note that the discharge in individual hours can be above the plotted upper limit, while the average in each period stays within the bound. We see that the upward average period ramping constraint is only binding in two of the ramping periods.

Rolling ramping validation

The downward limit rolling ramping constraint is visualized in the figure below. The plant discharge is shown together with the post-calculated rolling maximal discharge value with a 2 hour window. The lower discharge limit is calculated by subtracting 20 m3/s from the rolling max for the first 6 hours, while it is set to zero afterwards since the constraint is deactivated.

Loading...

We see that the rolling ramping constraint is binding in the first hours of the optimization where the discharge is at the lower bound. As soon as the constraint is deactivated, the plant discharge drops rapidly in one hour to accommodate the upward period ramping constraint while operating at higher efficiency for longer.