include_rainevap Scheme Example

This example shows how to use the ReservoirModel.include_rainevap() scheme when modelling a single reservoir model.

Note

For details about the full model file structure please see Basic Single Reservoir.

We consider a reservoir with a single inflow, Q_in, and an outflow Q_out. Q_out is comprised of two components, a spillway, Q_sluice, and a turbine Q_turbine. Flow through the sluice should be 4m3/s and flow through the turbine should be 1m3/s. Rainfall and evaporation should be accounted for.

\[ \begin{align}\begin{aligned}\begin{split}Q_{out} = Q_{turbine}+Q_{sluice}\\\end{split}\\\begin{split}Q_{sluice} = 4\\\end{split}\\\begin{split}Q_{turbine} = 1\\\end{split}\end{aligned}\end{align} \]

The ReservoirModel.include_rainevap() and ReservoirModel.set_q() schemes can be applied to model these operations.

Main Model (python) File

An example of the main model file rainevap_example.py is given below.

 1"""Example that illustrates how to create a basic model."""
 2
 3from pathlib import Path
 4
 5from rtctools.util import run_simulation_problem
 6
 7from rtctools_simulation.reservoir.model import InputVar, ModelConfig, ReservoirModel
 8
 9CONFIG = ModelConfig(base_dir=Path(__file__).parent)
10
11
12class SingleReservoir(ReservoirModel):
13    """Example single reservoir model."""
14
15    def apply_schemes(self):
16        """Apply schemes for controlling the reservoir."""
17
18        # Apply schemes.
19        self.include_rainevap()
20        self.set_q(
21            target_variable=InputVar.Q_TURBINE,
22            input_type="parameter",
23            input_data=1,
24        )
25        self.set_q(
26            target_variable=InputVar.Q_SLUICE,
27            input_type="parameter",
28            input_data="Q_sluice_target",
29        )
30
31
32# Create and run the model.
33if __name__ == "__main__":
34    run_simulation_problem(SingleReservoir, config=CONFIG)

The template file mentioned in the Basic Single Reservoir will look very similar to this file, except that the apply_schemes() method still needs to be filled out.

The line

CONFIG = ModelConfig(base_dir=Path(__file__).parent)

sets the model configuration. This model configuration is defined by the base directory base_dir. In most cases, the base directory is Path(__file__).parent, which is the directory of the current file.

The line

class SingleReservoir(ReservoirModel):

defines a class SingleReservoir that inherits all properties and functionalities of the predefined class ReservoirModel. An overview of this class can be found in Reservoir API and details of the underlying model it uses can be found in Single Reservoir Model.

The method ReservoirModel.apply_schemes() is called every timestep and contains the logic for which schemes are applied. The first argument self is the SingleReservoir object itself. Since SingleReservoir inherits from ReservoirModel, self can call any of the ReservoirModel methods, such as ReservoirModel.include_rainevap(). An overview of all available ReservoirModel methods can be found in Reservoir API.

The ReservoirModel.include_rainevap() scheme is applied to include rain and evaporation in the simulation. The ReservoirModel.set_q() scheme is then applied to set flow through the sluice and the turbine.

Note

To include only rain, self.include_rainevap() and be replaced with self.include_rain(). Likewise, to include on evaporation, self.include_rainevap() and be replaced with self.include_evaporation().

Lookup tables

This model uses only the standard lookup tables h_from_v and area_from_v, for other lookup tables, defaults from the generated template files can be used.

Note

For further details about the lookup tables please see Basic Single Reservoir.

Input Data Files

The ReservoirModel.include_rainevap() scheme requires and input parameter, max_reservoir_area. This can be provided to the model via the rtcParameterConfig.xml input file.

        <parameter id="max_reservoir_area">
        	<dblValue>5868679</dblValue>
        </parameter>

The scheme also requires rainfall and evaporation data supplied via the timeseries_import.xml, for evaporation data,

    <series>
      <header>
        <type>instantaneous</type>
        <moduleInstanceId>reservoir</moduleInstanceId>
        <locationId>reservoir</locationId>
        <parameterId>evaporation.obs</parameterId>
        <timeStep unit="second" multiplier="3600"/>
        <startDate date="2022-06-07" time="06:00:00"/>
        <endDate date="2022-06-27" time="06:00:00"/>
        <forecastDate date="2022-06-07" time="06:00:00"/>
        <missVal>-999.0</missVal>
        <stationName>Reservoir1</stationName>
        <units>mm/hour</units>
    </header>
      <event date="2022-06-07" time="06:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="07:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="08:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="09:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="10:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="11:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="12:00:00" value="1" flag="8"/>

and rain data.

    <series>
      <header>
        <type>instantaneous</type>
        <moduleInstanceId>reservoir</moduleInstanceId>
        <locationId>reservoir</locationId>
        <parameterId>rain.obs</parameterId>
        <timeStep unit="second" multiplier="3600"/>
        <startDate date="2022-06-07" time="06:00:00"/>
        <endDate date="2022-06-27" time="06:00:00"/>
        <forecastDate date="2022-06-07" time="06:00:00"/>
        <missVal>-999.0</missVal>
        <stationName>Reservoir1</stationName>
        <units>mm/hour</units>
    </header>
      <event date="2022-06-07" time="06:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="07:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="08:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="09:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="10:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="11:00:00" value="1" flag="8"/>
      <event date="2022-06-07" time="12:00:00" value="1" flag="8"/>

This additional input data is mapped to the internal variables, mm_rain_per_hour, and mm_evaporation_per_hour using the rtcDataConfig.xml.

    <timeSeries id="mm_evaporation_per_hour">
        <PITimeSeries>
            <locationId>reservoir</locationId>
            <parameterId>evaporation.obs</parameterId>
        </PITimeSeries>
    </timeSeries>
    <timeSeries id="mm_rain_per_hour">
        <PITimeSeries>
            <locationId>reservoir</locationId>
            <parameterId>rain.obs</parameterId>
        </PITimeSeries>
    </timeSeries>

In this example, the ReservoirModel.set_q() has been used to set outflows based on an input parameter Q_sluice_target. This parameter is also provided to the model via the rtcParameterConfig.xml.

        <parameter id="Q_sluice_target">
        	<dblValue>4.0</dblValue>
        </parameter>

Note

For further details about input file structure please see Basic Single Reservoir.

Output Data

The results of the simulation will appear in the output folder in a file called timeseries_export.xml. The data is linked to model variables via the rtcDataConfig.xml in the same way as with timeseries_import.xml.

Automatic Plotting

You can optionally include a plot_table.csv in the input folder. This is used by the rtc-tools-interfaces module (automatically installed with this package) to plot the model output. For more details on how to use this file and visualize results, see RTC-Tools-Interface.

The results of the simulation run can be seen in the plot below. It can be seen that Q_evap varies with time as it is dependent on the surface area of the reservoir, even though the evaporation per unit area is constant. Q_out is the sum of Q_turbine and Q_sluice.