You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »


DOCUMENTATION IN DEVELOPMENT

Introduction

The Integrated Reservoir Model is a General Adapter module written in Java, developed by Deltares. The model class is part of the Delft-FEWS code base.

The Reservoir model is developed and designed as a relatively straightforward reservoir routing model, that simulates flow through a reservoir with a level-outflow table defined. Specifically, the model is able to precisely replicate  the uncontrolled outlet reservoir behaviour of the legacy Deltares RTC-Tools 1 codebase, which is no longer developed and supported. Because the adapter model is based on Java, it can run on Windows/Linux systems.

 The model is introduced in the 2021.01 BoM Delft-FEWS version. The model adapter will be part of the Delft-FEWS code base of Delft-FEWS versions 2023.01 and onwards with in-memory options, to be set in the General Adapter configuration. 

Directory structure

The data directories and configuration files that are required for operating the FEWS Reservoir Model Adapter are shown below.

FEWS_SA
+---Config
|   +---ColdStateFiles
|   |   |       namoi_keepit_KeepReservoir_Historical_IRM Default.zip........coldState file
|   +---IdMapFiles
|   |       IdExportIRMReservoir.xml
|   |       IdImportIRMReservoir.xml.........................................custom mappings for the IRM variables and locations
|   |         
|   +---ModuleConfigFiles 
|   |   |   Reservoir_1h_Forecast_IRM.xml....................................main configuration file of the adapter
|   |           
|   +---ModuleDataSetFiles
|   |   |   Reservoir_Exe.zip................................................zipped IRM bin files, transported to Modules\reservoir directory
|   |   |   
|   |   |   namoi_IRM_Reservoir_Forecast.zip.................................zipped IRM model files for a specific reservoir, transported to Modules\Reservoir directory
|               
+---Modules
|   +---delft-adapters........................................................directory which contains all IRM adapter java files
|   |   |       
|   +---reservoir
|   |   +---Keep_IRM
|   |   |       diag.xml......................................................output FEWS-PI diagnostics file, imported by Delft-FEWS
|   |   |       export.xml....................................................output FEWS-PI time series files, imported by Delft-FEWS
|   |   |       exportState.xml...............................................FEWS-PI state output time series file, imported by Delft-FEWS
|   |   |       import.xml....................................................input FEWS-PI time series files, exported by Delft-FEWS
|   |   |       importState.xml...............................................FEWS-PI state input time series file, exported by Delft-FEWS
|   |   |       Keep_IntegratedReservoirModel.xml.............................IRM model file
|   |   |       run_info.xml..................................................a file generated by FEWS containing paths, run options
|   |   |       statePI.xml...................................................PI State file (definition)
|   |   |  


General Adapter configuration

The General Adapter defines forms the interface between the Delft-FEWS system and the Reservoir model. 

The data is provided in a standardized XML interface format, the FEWS Published Interface. For more details about general structure of the General Adapter please check 05 General Adapter Module.


general

Configuring a pi-version 1.8 is required for the diagnostics of the model.

IDmapping

The location/parameters used in Delft-FEWS can be transformed to model variableId locations/parameters by ID-mapping. The configuration files for ID-mapping can be of a general form, as long as the reservoir model have been set up with identical variables for the inputs/outputs. The model will look for the required variables (as configured in the IRM model file) in the parameter field of the PI timeseries. 

IdMapping is dependent on how the variables have been defined in the model. The Reservoir Model code will try to parse the configured model variables (like IIn, QOut, etc) from the parameterId of the PI timeseries, the locationId is not used. This means that the parameterId's of all the input timeseries need to be unique (and identical to the model variables). When writing the output timeseries, the locationId used in the import PI xml files will be used as the locationId in the output PI xml files. 

exportStateActivity

The Reservoir model can work with a stateConfigFile, exported from Delft-FEWS. This file should follow the conventions and list the read/write locations. When defined, the model will write an output state timeseries file for the complete run period, for all model export variables. 

exportTimeSeriesActivity

The reservoir model requires at a minimum the following timeseries:

  • level or state value (at model start time)
  • inflow timeseries (complete run period)
  • outflow timeseries (optional)   

exportRunFileActivity

A run_info file is required input for the Reservoir model, so an exportRunFileActivity needs to be configured in the General Adapter. The Reservoir Model expects a model property in the run_info file, that specifies the name of the actual Reservoir model to be run.


      <exportFile>run_info.xml</exportFile>
        <properties>
            <string key="model" value="$RESERVOIR$_IntegratedReservoirModel.xml"/>
        </properties>
    </exportRunFileActivity>

A typical run_info.xml file will contain the following information:

executeActivity

The executeActivity runs the model. The model runs of the Delft-FEWS JRE, so the ReservoirModelAdapter binaries can be specified within the binDir element. The class itself is called nl.deltares.fews.reservoirmodel.ReservoirModelAdapter. It is required to provide the path of the run_info file as an argument to the model.


            <executeActivity>
                <description>Run Reservoir module</description>
                <command>
                    <className>nl.deltares.fews.reservoirmodel.ReservoirModelAdapter</className>
                    <binDir>$REGION_HOME$/Modules/delft-adapters/fews-reservoirmodel-adapter-bin</binDir>
                </command>
                <arguments>
                    <argument>%ROOT_DIR%/run_info.xml</argument>
                </arguments>
                <timeOut>100000</timeOut>
                <ignoreDiagnostics>true</ignoreDiagnostics>
            </executeActivity>

importActivity

The model results (typically consisting of level, storage, inflow and outflow timeseries) can be imported using the importActivities. The importFile name configured will be written to the run_info file and consequently be created by the Reservoir model. Note that specific idImport configuration is required.      

Model

The model definition for the reservoir can be configured in file that follows the Integrated Reservoir Model schema. The model options are described below.

Schema


An example Integrated Reservoir Model file is attached.

<IntegratedReservoirModel xmlns="http://www.wldelft.nl/fews" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.wldelft.nl/fews https://fewsdocs.deltares.nl/schemas/version1.0/adapter-schemas/IntegratedReservoirModel.xsd">
    <general>
        <missingValue>-999</missingValue>
    </general>
    <reservoir id="H555001">
        <general>
            <description>reservoir management H555001</description>
            <poolRoutingScheme>levelPoolMethod</poolRoutingScheme>
            <dynamicInterpolation>true</dynamicInterpolation>
            <elevationInterpolationMethod>linear interpolation</elevationInterpolationMethod>
            <elevationInterval>0.00005</elevationInterval>
        </general>
        <!--Height (LGH) vs. Storage (m3)-->
        <storageCharacteristics>
            <storageTable>
                <elevationStorageRecord elevation="292.9" storage="0"/>
                <elevationStorageRecord elevation="293.0" storage="500"/>
                ...
                <elevationStorageRecord elevation="335.4" storage="720992000"/>
                <elevationStorageRecord elevation="335.6" storage="732795000"/>
            </storageTable>
        </storageCharacteristics>
        <!--Height (LGH) vs Spill (m3/s-->
        <uncontrolledOutlet id="outlet">
            <capacityCharacteristics>
                <outletTable>
                    <elevationOutletRecord elevation="292.9" outlet="0"/>
                    <elevationOutletRecord elevation="293.0" outlet="0"/>
					...
                    <elevationOutletRecord elevation="335.4" outlet="9768"/>
                    <elevationOutletRecord elevation="335.6" outlet="10278"/>
                </outletTable>
            </capacityCharacteristics>
            <input>
                <release>QOut</release>
            </input>
            <output>
                <release>QOut</release>
            </output>
        </uncontrolledOutlet>
        <input>
            <inflow>IIn</inflow>
            <level>HIn</level>
        </input>
        <output>
            <inflow>IOut</inflow>
            <release>QOut</release>
            <storage>SOut</storage>
            <level>HOut</level>
        </output>
    </reservoir>
</IntegratedReservoirModel>

general

In the general section, a missingValue element needs to be configured. It is important to match the missingValue as defined in the Delft-FEWS General Adapter configuration for the model run.

reservoir

The reservoir element contains the following sections:

  • general
    • poolRoutingScheme
    • dynamicInterpolation
    • elevationInterpolationMethod
    • elevationInterval
    • storageCharacteristics
  • uncontrolledOutlet
  • input
  • output

poolRoutingScheme

for the poolRoutingScheme element, one can choose the following options:

  • levelPoolMethod
  • backwardsEulerMethod
levelPoolMethod

The Level Pool method is a well known method for reservoir routing. in FEWS the method described in Applied hydrology from V.T.Chow is used. The level pool routing method is also referred to as Storage routing, the Storage-Indication method, or the Modified Puls method.

 This basis of this method is the following function:

 ((2S_(t+1))/Δt+Q_(t+1) )=(I_t+I_(t+1))+((2S_t)/Δt-Q_t )

In order to compute the outflow Qt, a storage-outflow function relating 2S/∆t+Q and Q is needed, this is the G(h) function. The elevation-storage-outflow table can be computed using this function:

 (h)=(2S(h))/Δt+Q(h)

In routing the flow through time, all terms in the right hand side of the above function are known, and so the values ((2S_(t+1))/Δt+Q_(t+1) ) can be computed. The value Qt+1 can be determined from the storage outflow function 2S/∆t+Q versus Q by linear interpolation of the tabular values. To set up the data required for the next time interval, the value K(t), ((2S_(t+1))/Δt-Q_(t+1) ) is calculated by:

 ((2S_(t+1))/Δt-Q_(t+1) )=((2S_(t+1))/Δt+Q_(t+1) )-2Q_(t+1)

The reservoir routing procedure in the Level Pool method is as follows:

 

  1. Loop over all time intervals from t=1 to t=tend.
  2. If t=1 then:
    1. S(1) = Qout(1) = K(1) = 0, the reservoir is initially empty.
    2. G(t+1) is computed with G(t+1)=[Q_in (t)+Q_in (t+1)]+K(t)
    3. Compute Qout(t+1) by linear interpolating the table using Qout(h) and G(h).
    4. K(t+1) = G(t+1) – 2 Qout(t+1)
  3. If t>1 then
    1. G(t+1) is computed with G(t+1)=[Q_in (t)+Q_in (t+1)]+K(t)
    2. Compute Qout(t+1) by linear interpolating the table using Qout(h) and G(h).
    3. K(t+1) = G(t+1) – 2 Qout(t+1)
backwardEulerMethod

The backward Euler reservoir routing scheme is an implicit scheme that uses the backward difference approximation for the derivative. The equation for the backward Euler reservoir routing scheme can be written as follows:

Q[t+1] = Q[t] + Δt * I[t+1]

where:

Q[t+1] represents the reservoir outflow at the next time step (n+1).
Q[t] is the reservoir outflow at the current time step (n).
Δt represents the time step.
I[t+1] is the inflow into the reservoir at the next time step (n+1).

In this scheme, the outflow at the next time step is calculated by adding the product of the time step and the difference between the inflow and evaporation at the next time step to the current outflow. 

dynamicInterpolation

When the dynamicInterpolation element is set to true, the level/storage and level/outlet tables are dynamically (every timestep) interpolated to the precise value, using the elevationInterpolationMethod. In this case, the elevationInterval element is ignored. 

When the dynamicInterpolation element is set to false, the level/storage and level/outlet tables are precalculated (only once) using the elevationInterpolationMethod, to the specified elevationInterval. Note that the level output at each timestep is processed to that elevationInterval. When a value needs to be determined from the table the largest entry that is still smaller than the precalculated table elements is used (the model always rounds down). The consequence is that reservoir inflows/outflows at a timestep that result in level/storage changes that are smaller than the interval/resolution will not be taken into account. This means that the model will underestimate the flow and water balance will not be closed.   

elevationInterpolationMethod

Linear interpolation is the only available interpolation method

elevationInterval

The elevationInterval or elevation resolution at which the configured level/storage and level/outlet tables need to be recalculated.

storageCharacteristics

strictly increasing, same number of elements

uncontrolled outlet

same number of elements

input / output files

The naming convention of the input and output timeseries files are free, the model will determine which files to read for the input based on the inputTimeSeriesFile filed in the run_info file. The following two input timeseries files are suggested:

  • importState.xml
    • level values, or
    • storage values
  • import.xml
    • Inflow
    • outflow (optional)

The startDateTime and endDateTime in the run_info file are used by the model to determine the start (startDateTime) and end (endDateTime) of the model run. The model will pick the starting (state) value for level/storage (level has precedent in case of an inconsistency), inflow, release from the inputTimeSeriesFiles at the specific .

If a starting level value is missing, the model will use the starting storage value. If both starting level/storage cannot be determined from the input files, the model will throw an error.

inflow and outflow values at the starting time are not required at the first timestep. When they are not found, a value of 0 is used.

Reservoir Model specifics

  • The model can be considered "timestep ending", similar the the timestep definition of Delft-FEWS.
  • No calculations/processing is performed at the first timestep (t=0, startDateTime as set in the run_info.xml file)


Ensembles

The Reservoir Model can be run in parallel from Delft-FEWS. The runInLoop element of the workflow should be set to false. The general section of the General Adapter configuration should contain the %TEMP_DIR% property as the model rootDir. And lastly, to enable the parallel running of ensemble members the runInLoopParallelProcessorCount entry must be set in the global properties file. Here you either specify the number of cores to use or specify 100 to use all available cores.


In the workflow

    <activity>
        <runIndependent>true</runIndependent>
        <workflowId>Reservoir_Forecast</workflowId>
        <ensemble>
            <ensembleId>ENSEMBLE</ensembleId>
            <runInLoop>false</runInLoop>
        </ensemble>
    </activity>

The general section of the General Adapter configuration

<general>
  <rootDir>%TEMP_DIR%</rootDir>
  <workDir>%ROOT_DIR%/work</workDir>
  ...
</general>

In the global properties

Config Example

# to use 4 cores/cpu's:
runInLoopParallelProcessorCount=4

See the following page for more details.

In-Memory execution

From Delft-FEWS version 2023.01 onwards, it will be porssible to run the Reservoir Model adapter "in-memory" from Delft-FEWS, using the inMemoryFileTransfer element of the general section set to True.  In that case, all exported and imported files are transferred in memory between Delft-FEWS and the executed Reservoir Model.

  • No labels