Load and Run a TUFLOW Model#
The below example shows how to load a TCF, make an edit, save it, and then run the model. The example below
uses EG00_001.tcf
from the TUFLOW example models.
Loading a TUFLOW Control File (TCF)#
Loading an existing TUFLOW model can be done very simply using the TCF
class.
>>> from pytuflow import TCF
>>> tcf = TCF('path/to/EG00_001.tcf')
Navigating the TCF can best be done using TCF.find_input()
. This method will return a list of inputs
that match the given filter. For example, finding all SGS related commands:
>>> tcf.find_input('sgs')
[<SettingInput> SGS == ON, <SettingInput> SGS Sample Target Distance == 0.5]
The TCF
class will return all inputs within the model for the given filter, and not just the TCF file. For example, you can
search for "2d_zsh"
and it will return commands from the TUFLOW Geometry Control File (TGC). There are
also some convenience methods that will return the other control file instances if you want to work with them directly:
>>> tgc = tcf.tgc()
>>> tbc = tcf.tbc()
>>> bc_dbase = tcf.bc_dbase()
>>> materials = tcf.mat_file()
>>> tgc.find_input('2d_mat')
[<GisInput> Read GIS Mat == gis\2d_mat_EG00_001_R.shp]
Editing and Updating a TCF#
Let’s update the map output format command to include the NC
format, as this will be useful later for querying
the results in Python. The first step is to find the relevant command, and then we can update it by setting the
right-hand side (RHS) of the command to include "NC"
.
>>> inp = tcf.find_input('map output format')[0]
>>> print(inp)
Map Output Format == XMDF TIF
>>> inp.rhs = f'{inp.rhs} NC' # Append NC to the existing RHS
>>> print(inp)
Map Output Format == XMDF TIF NC
The change can be checked in the broader TCF by using TCF.preview()
to
print a preview of the control file to the console:
>>> tcf.preview()
! TUFLOW CONTROL FILE (.TCF) defines the model simulation parameters and directs input from other data sources
! MODEL INITIALISATION
Tutorial Model == ON ! This command allows for this model to be simulated without a TUFLOW licence
GIS Format == SHP ! Specify SHP as the output format for all GIS files
SHP Projection == ..\model\gis\projection.prj ! Sets the GIS projection for the TUFLOW Model
TIF Projection == ..\model\grid\DEM_SI_Unit_01.tif ! Sets the GIS projection for the ouput grid files
!Write Empty GIS Files == ..\model\gis\empty ! This command is commented out. It is only needed for the project establishment
! SOLUTION SCHEME
Solution Scheme == HPC ! Heavily Parallelised Compute, uses adaptive timestepping
Hardware == GPU ! Comment out if GPU card is not available or replace with "Hardware == CPU"
SGS == ON ! Switches on Sub-Grid Sampling
SGS Sample Target Distance == 0.5 ! Sets SGS Sample Target Distance to 0.5m
! MODEL INPUTS
Geometry Control File == ..\model\EG00_001.tgc ! Reference the TUFLOW Geometry Control File
BC Control File == ..\model\EG00_001.tbc ! Reference the TUFLOW Boundary Conditions Control File
BC Database == ..\bc_dbase\bc_dbase_EG00_001.csv ! Reference the Boundary Conditions Database
Read Materials File == ..\model\materials.csv ! Reference the Materials Definition File
Set IWL == 36.5 ! Define an initial 2D water level at start of simulation
Timestep == 1
Start Time == 0
End Time == 3
! OUTPUT FOLDERS
Log Folder == log ! Redirects log output files log folder
Output Folder == ..\results\EG00\ ! Specifies the location of the 2D result files
Write Check Files == ..\check\EG00\ ! Specifies the location of the 2D check files and prefixes them with the .tcf filename
Map Output Format == XMDF TIF NC ! Result file types
Map Output Data Types == h V d z0 ! Specify the output data types
TIF Map Output Data Types == h ! Specify the output data types for TIF Format
Map Output Interval == 300 ! Outputs map data every 300 seconds
TIF Map Output Interval == 0 ! Outputs only maximums for grids
Updating control files like this does not make any changes to the control file on disk until
TCF.write()
is called. But we do need to call TCF.write()
before we can run the updated model. We can overwrite the existing
TCF file if the inc
parameter is set to "inplace"
, however in this case, we will save the modified model
to a new file. Since “EG00_002.tcf” is already present in the example models, we will instead save our changes as
“EG00_001a.tcf”.
>>> tcf.write(inc='001a')
<TuflowControlFile> EG00_001a.tcf
Running the TUFLOW Model#
To run the model, it is useful to provide a location where all the TUFLOW executables are located. This only needs to be done once and can be done by registering a TUFLOW binary folder. The folder structure should match the below structure, where the folder name is the TUFLOW version number and the TUFLOW executables are located within that folder:
/path/to/tuflow/binaries
├── 2025.0.0
│ ├── TUFLOW_iSP_w64.exe
│ ├── TUFLOW_iDP_w64.exe
├── 2025.1.0
│ ├── TUFLOW_iSP_w64.exe
│ ├── TUFLOW_iDP_w64.exe
├── 2025.1.2
│ ├── TUFLOW_iSP_w64.exe
│ ├── TUFLOW_iDP_w64.exe
>>> from pytuflow import register_tuflow_binary_folder
>>> register_tuflow_binary_folder('/path/to/tuflow/binaries')
Now we can run the model using the TCF.context()
method and the TUFLOW version name.
The context method is used to pass in what event and scenario combination we want to run.
An empty context is still required even if there are no events or scenarios to run.
>>> tcf_run = tcf.context()
>>> proc = tcf_run.run('2025.1.2')
>>> proc.wait() # Wait for the model to finish running
Interrogating the Results#
With the tcf_run
instance, we can also get the output folder and output name. With this, we can access the results:
>>> from pytuflow import XMDF
>>> xmdf_path = tcf_run.output_folder_2d() / f'{tcf_run.output_name()}.xmdf'
>>> xmdf = XMDF(xmdf_path)
Currently, the XMDF class requires QGIS Python libraries to extract results (e.g. time series). However,
if the netCDF4
package is installed, we can query some of the header information without QGIS:
>>> xmdf.data_types()
['bed level',
'max depth',
'max vector velocity',
'max velocity',
'max water level',
'max z0',
'depth',
'vector velocity',
'velocity',
'water level',
'z0',
'tmax water level']
>>> xmdf.times()
[0.0,
0.08333333333333333,
0.16666666666666666,
0.25,
0.3333333333333333,
0.41666666666666663,
0.5,
...
2.833333333333333,
2.9166666666666665,
3.0]
We added the NC
map output format to the TCF, so that we could easily query the results in Python using the
NCGrid
class.
>>> from pytuflow import NCGrid
>>> ncgrid_path = tcf_run.output_folder_2d() / f'{tcf_run.output_name()}.nc'
>>> ncgrid = NCGrid(ncgrid_path)
>>> nc_grid.data_types()
['water level',
'depth',
'velocity',
'z0',
'max water level',
'max depth',
'max velocity',
'max z0',
'tmax water level']
We can extract a time series of water level results by using a point location, either in the form of a coordinate tuple
(x, y)
(or list of coordinates), or a GIS point file. You will need GDAL Python bindings installed to use the latter
approach. For simplicity, we will use a list of coordinate tuples that match the location of the features in the
2d_po_EG02_010_P.shp
file that is included as part of the example model dataset. If you have GDAL installed, you
can use a file path reference to the TUFLOW/model/gis/2d_po_EG02_010_P.shp
file instead.
Note, pnt1
starts dry and gets wet later in the simulation, so the first time steps are NaN
to indicate that
the cell is dry.
>>> points = [(293259.140, 6178013.725), (293337.612, 6178286.193)]
>>> df = ncgrid.time_series(points, 'water level')
>>> df
time water level/pnt1 water level/pnt2
0.000000 NaN 36.500000
0.083333 NaN 36.483509
0.166667 NaN 36.457958
0.250000 NaN 36.441391
0.333333 NaN 36.431271
0.416667 NaN 36.426140
0.500000 NaN 36.423336
0.583333 NaN 36.421467
0.666667 40.110428 36.420143
... ... ...
2.833333 42.804726 38.509300
2.916667 42.793350 38.429859
3.000000 42.781895 38.342941