D-Flow FM wrapper
The D-Flow FM wrapper has been developed and is maintained by our OpenDA
partner Deltares. On this page, we describe the different data objects for the
D-Flow FM wrapper. Examples based on the dcsmv5 (North Sea) model are available
from OpenDA release 3.1 in the directories examples/model_dflowfm_blackbox.
Start and end time of model runs
For Ensemble Kalman filtering, we always need a data object that reads, edits
and rewrites the start and end times of a model run. For D-Flow FM this is
stored in the so-called .mdu file (the input file for the hydrodynamic
simulation program). More information about this file can be found in Section
4.2 of the D-Flow FM documentation.
In order to use restarts of a model, OpenDA must be able to
change the model’s run period. The data object related to the start and
end times of model runs has been implemented in the Java class
org.openda.model_dflowfm.DFlowFMTimeInfo. This data object reads
TStart, TStop, Tunit and RefDate from the [time] section in
the .mdu file to create the OpenDA exchange items with ids start_date
and end_date. The run period of the model (as set in TStart and
TStop in the .mdu file) can then be changed by adapting the exchange
items. In the dflowfmModel.xml, the time exchange items are set as
<timeInfoExchangeItems start="start_time" end="end_time"/>.
Example configuration for the wrapper of this data object can be found below:
<dataObject className="org.openda.model_dflowfm.DFlowFMTimeInfo">
<file>%mdufile%</file>
<id>mdufile</id>
</dataObject>
See for example the file model_dflowfm_blackbox/tests/dcsmv5_kalman_rst/stochModel/dflowfmWrapper.xml.
Model state
In order to change the model state, the Java class
org.openda.model_dflowfm.DFlowFMRestartFileWrapper is used. It will read,
edit and rewrite either a *map.nc file or a *_rst.nc file.
*map.nc files relate to older functionality and are mostly used to store
model results in grid format for all time steps in a run. While they can be used
for restarting, the preferred option is to use *_rst.nc files.
These files contain more complete data for only one time step (the one used for
restarting), making them more efficient.
More information about map files can be found in Section 5.6.2 of the D-Flow
FM documentation, and more
information about the _rst.nc file can be found in Section 5.6.3 of the
same D-Flow FM documentation, and
below.
The previously mentioned Java class will create exchange items for each variable with the variable name as “exchange item id”. An example configuration for this data object is:
<dataObject className="org.openda.model_dflowfm.DFlowFMRestartFileWrapper">
<file>%mapfile%</file>
<id>mapfile</id>
</dataObject>
For reading NetCDF output files the general NetcdfDataObject can be used. More information can be found on the page about data objects.
Boundary files
D-Flow FM boundary files are explained in Section 7.4.1 of the D-Flow FM documentation. Here, we
describe the approach for .bc files.
In order to read, edit and rewrite boundary files in the .bc format, the
data object with class name org.openda.model_dflowfm.BcFile must be used.
As an extra argument, the file(name) of the .bc file after editing must
be provided in <arg>. If this filename is identical to the original, then
OpenDA will overwrite the original .bc file. As an example, we provide:
<dataObject className="org.openda.model_dflowfm.BcFile">
<file>boundary_conditions/flow/TielNewNoise_0001.bc</file>
<id>bcfile</id>
<arg>boundary_conditions/flow/TielNewNoise_0001.bc</arg>
</dataObject>
NetCDF concatenater
OpenDA splits longer runs into smaller parts (as we already explained in the section on restarts of a model). Therefore, lots of smaller NetCDF output files are written instead of one single NetCDF output file that contains the whole run. To prevent them from getting overwritten each time and in order to merge them together, OpenDA has a NetcdfFileConcatenater. This is general functionality available in OpenDA and can be used for many different models that create NetCDF output files. This concatenater (formally spelled as concatenator) should be configured as compute action after the compute action of the model run (see the section on compute actions for more information). It takes two arguments: the first argument is the name of the file with all concatenated data and the second argument is the file that should be concatenated to it. Since the concatenator will run after each small model run, only 1 NetCDF file has to be concatenated to the main file containing all concatenated data. If the concatenated file does not exist yet it will be created with identical content to the file that it should be concatenated with. This occurs after the first model run.
In the dflowfmWrapper.xml, of the model_dflowfm_blackbox examples, the
examples dcsmv5_kalman_rst and dcsmv5_kalman_rst_partitioning can be
seen. It works for both scalar data, like the %hisfile% and gridded data
like the %mapfile% (Sections 5.6.1 and 5.6.2 of the D-Flow FM documentation):
<action className="org.openda.exchange.dataobjects.NetcdfFileConcatenater" workingDirectory="%instanceDir%/">
<arg>%concatenated_file%</arg>
<arg>%outputDir%/%file%</arg>
</action>
Restarting from file
Since OpenDA 3.1, we support the use of D-Flow FM models that restart from
*_rst.nc files (see the Section on restarts of a model).
An example setup can be found in the folder
examples/model_dflowfm_blackbox/dcsmv5_kalman_rst.
To let this work, the argument useRstForRestart=true must be added to the
org.openda.model_dflowfm.DFlowFMTimeInfo data object. This prevents OpenDA
to change settings in the .mdu file specific for the map file (namely,
RestartFile and RestartDateTime, located at the [restart] section of the
.mdu file). An example configuration is:
<dataObject className="org.openda.model_dflowfm.DFlowFMTimeInfo">
<file>%mdufile%</file>
<id>mdufile</id>
<arg>useRstForRestart=true</arg>
</dataObject>
The DFlowFMRestartFileWrapper does not need any changes, but we do need to
add a compute action that uses
org.openda.model_dflowfm.DFlowFMRestartFilePostProcessor after running
D-Flow FM. This class will rename the newest *_rst.nc file to a constant
file name which will always be used for restarting.
We will explain how renaming and restarting works by using an example.
Therefore, we investigate a North Sea example (the model has run id dcsmv5)
that runs from January 3 2007 at midnight until January 5 2007 at midnight.
Furthermore, we assume that a restart file is written every day at midnight. At
the end of the run, the following restart files are created:
%workingDirectory%/subdir/dcsmv5_20070103_000000_rst.nc
%workingDirectory%/subdir/dcsmv5_20070104_000000_rst.nc
%workingDirectory%/subdir/dcsmv5_20070105_000000_rst.nc
The DFlowFMRestartFilePostProcessor will be looking for files with pattern
<runId>_'yyyyMMdd'_'HHmmss'_rst.nc where the <runId> is passed as an
argument and the _'yyyyMMdd'_'HHmmss'_rst.nc is hardcoded (as this is
default for D-Flow FM). The DFlowFMRestartFilePostProcessor will find all
three files and will use the dates from the file names to extract their time
stamps.
We choose the following configuration for the compute action:
<action className="org.openda.model_dflowfm.DFlowFMRestartFilePostProcessor" workingDirectory="%instanceDir%">
<arg>runId=dcsmv5</arg>
<arg>sourceRestartFileSubDir=%outputDir%</arg>
<arg>targetRestartFileNamePostFix=00000000_000000_rst.nc</arg>
<arg>deleteOlderRstFiles=true</arg>
</action>
where the following required and optional arguments are related to
DFlowFMRestartFilePostProcessor:
Required arguments for the renaming are
runId=<runId>andtargetRestartFileNamePostFix='yyyyMMdd'_'HHmmss'_rst.nc.Here,
'yyyyMMdd'_'HHmmss'should match the specific time of the configured*_rst.ncfile D-Flow FM is configured to restart from. This restart file is configured in the .mdu file (the[restart]block contains a key-value pairRestartFile = <fileName>). These two required arguments are used to identify all restart files, find the newest one and determine the file name that the newest*_rst.ncfile should be renamed to.The optional argument
sourceRestartFileSubDir=subdircan be provided when the restart files written by D-Flow FM are in a different subfolder than the*_rst.ncfile that D-Flow FM will restart from.When the optional argument
deleteOlderRstFiles=trueis provided, all older*_rst.ncfiles will be deleted to prevent the accumulation of files that are no longer needed.
Let us return to our example. The compute action will copy and rename the file
with the highest time stamp to <runId>_<targetRestartFileNamePostFix> in
the workingDirectory. This means
%workingDirectory%/subdir/dcsmv5_20070105_000000_rst.nc will be copied and
renamed to %workingDirectory%/dcsmv5_00000000_000000_rst.nc. For this
mechanism to work properly, RestartFile = dcsmv5_00000000_000000_rst.nc
should be configured in the [restart] section of the .mdu file.
This compute action is specifically designed for an operational context where external systems can store restart files of previous runs and reuse it for future runs. By using a constant filename these external systems can always work with the same file name without needing complex functionality for renaming to match the time stamps.
Partitioning
D-Flow FM splits its total model grid into smaller parts. This is done such that the model calculations can be done in parallel using multiple cores of a computer processor. This behavior is called partitioning. Since OpenDA 3.1, support for D-Flow FM models that are partitioned is added. More information on D-Flow FM partitioning can be found in Section 5.2.2 of the D-Flow FM documentation. Similar to the restarting section above, this setup is specifically designed for an operational context. An example setup can be found in
model_dflowfm_blackbox/tests/dcsmv5_kalman_rst_partitioning/stochModel/dflowfmWrapper.xml
For this to work, multiple configuration changes are needed:
For the
DFlowFMTimeInfo, an extra argument should be added specifying the number of partitions. This way, OpenDA knows it should edit an.mdufile for each partition and the changes are the same for each.mdufile:<dataObject className="org.openda.model_dflowfm.DFlowFMTimeInfo"> <file>%mdufile%</file> <id>mdufile</id> <arg>useRstForRestart=true</arg> <arg>numberOfPartitions=3</arg> </dataObject>
For the restart file, a different data object must be used for partitioning. This is because the changes that will be applied to the contents will differ for each partitioned restart file. This has been solved with the use of one data object that (in the background) will use multiple
DFlowFMRestartFileWrapperdata objects and collect all exchange items:<dataObject className="org.openda.model_dflowfm.DFlowFMPartitionedRestartFilesWrapper"> <file>%rstfile%</file> <id>rstfile</id> <arg>runId=%runid%</arg> <arg>numberOfPartitions=3</arg> </dataObject>
The exchange items that this data object creates are for each variable and each partitioning combination. So if the partitioned restart files contain a variable called
"s1", and there are three partitions, then the following exchange items will be created according to the naming<variableName>_<partitionNumber>:"s1_0000","s1_0001","s1_0002".For the
DFlowFMRestartFilePostProcessor, one extra argument specifying the number of partitions will suffice. This argument will be used in the naming pattern to find all restart files, keep the newest and delete older ones if needed:<action className="org.openda.model_dflowfm.DFlowFMRestartFilePostProcessor" workingDirectory="%instanceDir%"> <arg>runId=%runid%</arg> <arg>sourceRestartFileSubDir=%outputDir%</arg> <arg>targetRestartFileNamePostFix=00000000_000000_rst.nc</arg> <arg>deleteOlderRstFiles=true</arg> <arg>numberOfPartitions=3</arg> </action>
As an example, we revisit the same North Sea example again, using three partitions. At the end of the run, the following restart files are created:
%workingDirectory%/subdir/dcsmv5_0000_20070103_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0000_20070104_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0000_20070105_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0001_20070103_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0001_20070104_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0001_20070105_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0002_20070103_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0002_20070104_000000_rst.nc %workingDirectory%/subdir/dcsmv5_0002_20070105_000000_rst.nc
The
DFlowFMRestartFilePostProcessorwill be looking for files with pattern<runId>_<partitionNumber>_'yyyyMMdd'_'HHmmss'_rst.ncwhere the<runId>is passed as an argument and the_'yyyyMMdd'_'HHmmss'_rst.ncis hardcoded because that is default for D-Flow FM. TheDFlowFMRestartFilePostProcessorwill find all nine files and will use the dates from the file names to extract their time stamps. For each partition individually, it will copy and rename the files with the highest time stamp to<runId>_<partitionNumber>_<targetRestartFileNamePostFix>in theworkingDirectory. In the example above, this means%workingDirectory%/subdir/dcsmv5_000n_20070105_000000_rst.nc, n = 0,1,2 (the partition number), will be copied and renamed to%workingDirectory%/dcsmv5_000n_00000000_000000_rst.nc. For this mechanism to work properly,RestartFile = dcsmv5_000n_00000000_000000_rst.ncshould be configured in the[restart]section of the partitioned.mdufile.
Note: when a too-high partition number is entered, there will be a FileNotFound exception because files for the higher partitioning do not exist. When the number of partitions is set too small, then only part of the grid will be taken into account, leading to inconsistent changes which makes model runs unpredictable.