API

Subpackages

snl_d3d_cec_verify package

class snl_d3d_cec_verify.CaseStudy(dx=1, dy=1, sigma=3, x0=0, x1=18, y0=1, y1=5, bed_level=- 2, dt_max=1, dt_init=1, turb_pos_x=6, turb_pos_y=3, turb_pos_z=- 1, discharge=6.0574, bed_roughness=0.023, horizontal_eddy_viscosity=1e-06, horizontal_eddy_diffusivity=1e-06, vertical_eddy_viscosity=1e-06, vertical_eddy_diffusivity=1e-06, simulate_turbines=True, turbine_turbulence_model='delft', beta_p=1.0, beta_d=1.84, c_epp=0.77, c_epd=0.13, horizontal_momentum_filter=True, stats_interval=None, restart_interval=0)

Class for defining variables for single or multiple case studies.

When defining multiple values for multiple variables, the given sequences must be the same length, e.g.:

>>> cases = CaseStudy(dx=[1, 2, 3, 4],
...                   dy=[4, 5, 6, 7])
>>> print(cases) 
CaseStudy(dx=[1, 2, 3, 4], dy=[4, 5, 6, 7], sigma=3, ...

The above example will generate an object representing 4 cases, which can then be iterated:

>>> for case in cases: 
...     print(case)
CaseStudy(dx=1, dy=4, ...
CaseStudy(dx=2, dy=5, ...
CaseStudy(dx=3, dy=6, ...
CaseStudy(dx=4, dy=7, ...
Parameters:
Raises:

ValueError – if variables with multiple values have different lengths

dx: Union[int, float, Sequence[Union[int, float]]] = 1

grid spacing in x-direction, in meters

dy: Union[int, float, Sequence[Union[int, float]]] = 1

grid spacing in y-direction, in meters

sigma: Union[int, float, Sequence[Union[int, float]]] = 3

number of vertical layers

x0: Union[int, float, Sequence[Union[int, float]]] = 0

minimum x-value, in metres

x1: Union[int, float, Sequence[Union[int, float]]] = 18

maximum x-value, in metres

y0: Union[int, float, Sequence[Union[int, float]]] = 1

minimum y-value, in metres

y1: Union[int, float, Sequence[Union[int, float]]] = 5

maximum y-value, in metres

bed_level: Union[int, float, Sequence[Union[int, float]]] = -2

uniform bed level, in metres

dt_max: Union[int, float, Sequence[Union[int, float]]] = 1

maximum time step, in seconds. Applies to the 'fm' model only

dt_init: Union[int, float, Sequence[Union[int, float]]] = 1

initial time step, in seconds. For the 'structured' model, this is the fixed time step

turb_pos_x: Union[int, float, Sequence[Union[int, float]]] = 6

turbine x-position, in meters

turb_pos_y: Union[int, float, Sequence[Union[int, float]]] = 3

turbine y-position, in meters

turb_pos_z: Union[int, float, Sequence[Union[int, float]]] = -1

turbine z-position, in meters

discharge: Union[int, float, Sequence[Union[int, float]]] = 6.0574

inlet boundary discharge, in cubic meters per second

bed_roughness: Union[int, float, Sequence[Union[int, float]]] = 0.023

uniform bed roughness coefficient, as a Manning number, in seconds over metres cube rooted

horizontal_eddy_viscosity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform horizontal eddy viscosity, in metres squared per second

horizontal_eddy_diffusivity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform horizontal eddy diffusivity, in metres squared per second

vertical_eddy_viscosity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform vertical eddy viscosity, in metres squared per second

vertical_eddy_diffusivity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform vertical eddy diffusivity, in metres squared per second

simulate_turbines: Union[bool, Sequence[bool]] = True

simulate turbines

turbine_turbulence_model: Union[str, Sequence[str]] = 'delft'

turbine turbulence model. Set to 'delft' for the default model or 'canopy' to use the Réthoré (2009) canopy model.

beta_p: Union[int, float, Sequence[Union[int, float]]] = 1.0

turbine turbulence canopy model “production” coefficient, \(\beta_p\). Applies to the 'canopy' turbine turbulence model only.

beta_d: Union[int, float, Sequence[Union[int, float]]] = 1.84

turbine turbulence canopy model “dissipation” coefficient, \(\beta_d\). Applies to the 'canopy' turbine turbulence model only.

c_epp: Union[int, float, Sequence[Union[int, float]]] = 0.77

turbine turbulence canopy model “production” closure coefficient, \(C_{\varepsilon p}\). Applies to the 'canopy' turbine turbulence model only.

c_epd: Union[int, float, Sequence[Union[int, float]]] = 0.13

turbine turbulence canopy model “dissipation” closure coefficient, \(C_{\varepsilon d}\). Applies to the 'canopy' turbine turbulence model only.

horizontal_momentum_filter: Union[bool, Sequence[bool]] = True

use high-order horizontal momentum filter. Applies to the 'fm' model only

stats_interval: Union[int, float, None, Sequence[Optional[Union[int, float]]]] = None

interval for simulation progress output, in seconds. Applies to the 'fm' model only

restart_interval: Union[int, float, Sequence[Union[int, float]]] = 0

interval for restart file output, in seconds

class property fields: List[str]

Returns field names

Return type:

List[str]

property values: List[Any]

Returns field values

Return type:

List[Any]

get_case(index=0)

Return a unit case study, from the given index

Parameters:

index (int) – Index of study, defaults to 0

Return type:

CaseStudy

classmethod from_yaml(path)

Create a new instance from a YAML file

Parameters:

path (Union[str, Path]) – path of the existing YAML file

Return type:

TypeVar(C, bound= CaseStudy)

to_yaml(path)

Export object as a YAML file

Parameters:

path (Union[str, Path]) – path of created YAML file

is_equal(other, ignore_fields=None)

Test equality of another object

Use the ignore_fields argument to ignore fields when comparing CaseStudy objects:

>>> case = CaseStudy(dx=1)
>>> other = CaseStudy(dx=2)
>>> other.is_equal(case, ignore_fields=["dx"])
True
Parameters:
  • other (object) – the object to test for equality

  • ignore_fields (Optional[Iterable[str]]) – a sequence of field names to ignore

Return type:

bool

class snl_d3d_cec_verify.LiveRunner(d3d_bin_path, omp_num_threads=1)

A class for running Delft3D models which allow reuse of settings across multiple projects with real time output. Automatically detects if the model uses a flexible or structured mesh and then calls the appropriate function from the runner package.

Call the LiveRunner object with the project path to execute the Delft3D model and read the output line by line, like a generator

>>> runner = LiveRunner("path/to/Delft3D/src/bin",
...                     omp_num_threads=8)
>>> for line in runner("path/to/project"): 
...     print(line)

Currently only available for Windows and Linux.

Parameters:
  • d3d_bin_path (Union[str, Path]) – path to the bin folder generated when compiling Delft3D

  • omp_num_threads (int) – The number of computational threads to use for 'fm' models, defaults to 1

__call__(project_path)

Run a simulation, given a prepared model, and yield stdout and stdin streams.

Parameters:

project_path (Union[str, Path]) – path to Delft3D project folder

Raises:
  • OSError – if function is called on an unsupported operating system

  • FileNotFoundError – if the Delft3D entry point or model file could not be found (or is not unique)

  • RuntimeError – if the Delft3D simulation outputs to stderr, for any reason

Return type:

Iterator[str]

d3d_bin_path: Union[str, Path]

path to the bin folder generated when compiling Delft3D

omp_num_threads: int = 1

The number of computational threads to use for fm models

class snl_d3d_cec_verify.MycekStudy(dx=1, dy=1, sigma=3, dt_max=1, dt_init=1, discharge=6.0574, bed_roughness=0.023, horizontal_eddy_viscosity=1e-06, horizontal_eddy_diffusivity=1e-06, vertical_eddy_viscosity=1e-06, vertical_eddy_diffusivity=1e-06, simulate_turbines=True, turbine_turbulence_model='delft', beta_p=1.0, beta_d=1.84, c_epp=0.77, c_epd=0.13, horizontal_momentum_filter=True, stats_interval=None, restart_interval=0)

Class for defining cases corresponding to the Mycek study. Subclass of CaseStudy with the domain and turbine position fixed.

Parameters:
Raises:

ValueError – if variables with multiple values have different lengths

x0: Union[int, float, Sequence[Union[int, float]]] = 0

minimum x-value, in metres

x1: Union[int, float, Sequence[Union[int, float]]] = 18

maximum x-value, in metres

y0: Union[int, float, Sequence[Union[int, float]]] = 1

minimum y-value, in metres

y1: Union[int, float, Sequence[Union[int, float]]] = 5

maximum y-value, in metres

bed_level: Union[int, float, Sequence[Union[int, float]]] = -2

uniform bed level, in metres

turb_pos_x: Union[int, float, Sequence[Union[int, float]]] = 6

turbine x-position, in meters

turb_pos_y: Union[int, float, Sequence[Union[int, float]]] = 3

turbine y-position, in meters

turb_pos_z: Union[int, float, Sequence[Union[int, float]]] = -1

turbine z-position, in meters

bed_roughness: Union[int, float, Sequence[Union[int, float]]] = 0.023

uniform bed roughness coefficient, as a Manning number, in seconds over metres cube rooted

beta_d: Union[int, float, Sequence[Union[int, float]]] = 1.84

turbine turbulence canopy model “dissipation” coefficient, \(\beta_d\). Applies to the 'canopy' turbine turbulence model only.

beta_p: Union[int, float, Sequence[Union[int, float]]] = 1.0

turbine turbulence canopy model “production” coefficient, \(\beta_p\). Applies to the 'canopy' turbine turbulence model only.

c_epd: Union[int, float, Sequence[Union[int, float]]] = 0.13

turbine turbulence canopy model “dissipation” closure coefficient, \(C_{\varepsilon d}\). Applies to the 'canopy' turbine turbulence model only.

c_epp: Union[int, float, Sequence[Union[int, float]]] = 0.77

turbine turbulence canopy model “production” closure coefficient, \(C_{\varepsilon p}\). Applies to the 'canopy' turbine turbulence model only.

discharge: Union[int, float, Sequence[Union[int, float]]] = 6.0574

inlet boundary discharge, in cubic meters per second

dt_init: Union[int, float, Sequence[Union[int, float]]] = 1

initial time step, in seconds. For the 'structured' model, this is the fixed time step

dt_max: Union[int, float, Sequence[Union[int, float]]] = 1

maximum time step, in seconds. Applies to the 'fm' model only

dx: Union[int, float, Sequence[Union[int, float]]] = 1

grid spacing in x-direction, in meters

dy: Union[int, float, Sequence[Union[int, float]]] = 1

grid spacing in y-direction, in meters

fields = ['dx', 'dy', 'sigma', 'x0', 'x1', 'y0', 'y1', 'bed_level', 'dt_max', 'dt_init', 'turb_pos_x', 'turb_pos_y', 'turb_pos_z', 'discharge', 'bed_roughness', 'horizontal_eddy_viscosity', 'horizontal_eddy_diffusivity', 'vertical_eddy_viscosity', 'vertical_eddy_diffusivity', 'simulate_turbines', 'turbine_turbulence_model', 'beta_p', 'beta_d', 'c_epp', 'c_epd', 'horizontal_momentum_filter', 'stats_interval', 'restart_interval']
classmethod from_yaml(path)

Create a new instance from a YAML file

Parameters:

path (Union[str, Path]) – path of the existing YAML file

Return type:

TypeVar(C, bound= CaseStudy)

get_case(index=0)

Return a unit case study, from the given index

Parameters:

index (int) – Index of study, defaults to 0

Return type:

CaseStudy

horizontal_eddy_diffusivity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform horizontal eddy diffusivity, in metres squared per second

horizontal_eddy_viscosity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform horizontal eddy viscosity, in metres squared per second

horizontal_momentum_filter: Union[bool, Sequence[bool]] = True

use high-order horizontal momentum filter. Applies to the 'fm' model only

is_equal(other, ignore_fields=None)

Test equality of another object

Use the ignore_fields argument to ignore fields when comparing CaseStudy objects:

>>> case = CaseStudy(dx=1)
>>> other = CaseStudy(dx=2)
>>> other.is_equal(case, ignore_fields=["dx"])
True
Parameters:
  • other (object) – the object to test for equality

  • ignore_fields (Optional[Iterable[str]]) – a sequence of field names to ignore

Return type:

bool

restart_interval: Union[int, float, Sequence[Union[int, float]]] = 0

interval for restart file output, in seconds

sigma: Union[int, float, Sequence[Union[int, float]]] = 3

number of vertical layers

simulate_turbines: Union[bool, Sequence[bool]] = True

simulate turbines

stats_interval: Union[int, float, None, Sequence[Optional[Union[int, float]]]] = None

interval for simulation progress output, in seconds. Applies to the 'fm' model only

to_yaml(path)

Export object as a YAML file

Parameters:

path (Union[str, Path]) – path of created YAML file

turbine_turbulence_model: Union[str, Sequence[str]] = 'delft'

turbine turbulence model. Set to 'delft' for the default model or 'canopy' to use the Réthoré (2009) canopy model.

property values: List[Any]

Returns field values

Return type:

List[Any]

vertical_eddy_diffusivity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform vertical eddy diffusivity, in metres squared per second

vertical_eddy_viscosity: Union[int, float, Sequence[Union[int, float]]] = 1e-06

uniform vertical eddy viscosity, in metres squared per second

class snl_d3d_cec_verify.Report(width=None, date_format=None)

Class for creating a report in Pandoc markdown format

The final report can be viewed by printing the Report object, for example:

>>> report = Report(70, "%d %B %Y")
>>> report.title = "Test"
>>> report.authors = ["Me", "You"]
>>> report.date = "1916-04-24"
>>> report.content.add_text("Lorem ipsum dolor sit amet, consectetur "
...                         "adipiscing elit. Maecenas vitae "
...                         "scelerisque magna.")
>>> print(report)
1: % Test
2: % Me; You
3: % 24 April 1916
4:
5: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas
6: vitae scelerisque magna.
7:

Note that line numbers are also printed. The report can also be saved to file, by iterating through each line:

>>> with open("report.md", "wt") as f: 
...     for line in report:
...         f.write(line) 
Parameters:
content: Content

Container for the main body of the document. See the Content documentation for usage.

property width

The maximum paragraph width, in characters. Set to None for no limit.

Type:

Optional[int]

property date_format

format for document date as passed to datetime.date.strftime(). Set to None to use ISO 8601 format

Type:

Optional[str]

property title

Title for the document. Set to None to remove.

Type:

Optional[str]

property authors

The authors of the document, as a list. Set to None to remove.

Type:

Optional[List[str]]

property date

The date of the document. Can be set using ISO 8601 format or can be given as “today” to use the current date. Set to None to remove.

Type:

Optional[str]

class snl_d3d_cec_verify.Result(project_path)

Class for capturing the results of executed case studies. Contains metadata from the simulation. Automatically detects if the model uses a flexible or structured mesh and then populates edge and face data in the edges and faces attributes, where appropriate.

>>> data_dir = getfixture('data_dir')
>>> result = Result(data_dir)
>>> result.x_lim
(0.0, 18.0)
>>> result.edges.extract_sigma(-1, 0.5) 
                                           geometry            u1  ...   n0   n1
0     LINESTRING (0.00000 1.00000, 0.00000 2.00000)  9.753143e-01  ...  1.0 -0.0
...
Parameters:

project_path (Union[str, Path]) – path to the Delft3D project directory

property x_lim: Tuple[float, float]

Domain limits in the x-direction, in metres

>>> data_dir = getfixture('data_dir')
>>> result = Result(data_dir)
>>> result.x_lim
(0.0, 18.0)
Return type:

Tuple[float, float]

property y_lim: Tuple[float, float]

Domain limits in the y-direction, in metres

>>> data_dir = getfixture('data_dir')
>>> result = Result(data_dir)
>>> result.y_lim
(1.0, 5.0)
Return type:

Tuple[float, float]

property times: ndarray[Any, dtype[datetime64]]

Time steps of the Delft3D simulation

>>> data_dir = getfixture('data_dir')
>>> result = Result(data_dir)
>>> result.times
array(['2001-01-01T00:00:00.000000000', '2001-01-01T01:00:00.000000000'],
dtype='datetime64[ns]')
Return type:

ndarray[Any, dtype[datetime64]]

property edges: Optional[Edges]

Results on the grid edges for flexible mesh ('fm') models . See the Edges documentation for usage.

Return type:

Optional[Edges]

property faces: Faces

Results on the grid faces. See the Faces documentation for usage.

Return type:

Faces

class snl_d3d_cec_verify.Runner(d3d_bin_path, omp_num_threads=1, show_stdout=False)

A class for running Delft3D models which allow reuse of settings across multiple projects. Automatically detects if the model uses a flexible or structured mesh and then calls the appropriate function from the runner package.

Call the Runner object with the project path to execute the Delft3D model

>>> runner = Runner("path/to/Delft3D/src/bin",
...                  omp_num_threads=8)
>>> runner("path/to/project") 

Currently only available for Windows and Linux.

Parameters:
  • d3d_bin_path (Union[str, Path]) – path to the bin folder generated when compiling Delft3D

  • omp_num_threads (int) – The number of computational threads to use for 'fm' models, defaults to 1

  • show_stdout (bool) – show Delft3D logging to stdout in console, defaults to False

__call__(project_path)

Run a simulation, given a prepared model.

Parameters:

project_path (Union[str, Path]) – path to Delft3D project folder

Raises:
  • OSError – if function is called on an unsupported operating system

  • FileNotFoundError – if the Delft3D entry point or model file could not be found (or is not unique)

  • RuntimeError – if the Delft3D simulation outputs to stderr, for any reason

d3d_bin_path: Union[str, Path]

path to the bin folder generated when compiling Delft3D

omp_num_threads: int = 1

The number of computational threads to use for fm models

show_stdout: bool = False

show Delft3D logging to stdout in console

class snl_d3d_cec_verify.Template(template_type='fm', template_path=None, exist_ok=False, no_template=<factory>)

Class for creating Delft3D projects from templates

Utilises the copier and grid subpackages to generate Delft3D models from templates and type-specific grid generation routines. Note that the template files are copied on initialization, therefore changes to the template source will not affect the object’s output.

Call a Template object with a length one CaseStudy object and a path at which to create a flexible-mesh Delft3D project. For example:

>>> import pprint
>>> import tempfile
>>> from pathlib import Path
>>> template = Template()
>>> with tempfile.TemporaryDirectory() as tmpdirname:
...     template(CaseStudy(), tmpdirname)
...     inputdir = Path(tmpdirname) / "input"
...     pprint.pprint(sorted([x.name for x in inputdir.iterdir()]))
['Discharge.bc',
 'FlowFM.mdu',
 'FlowFM_bnd.ext',
 'FlowFM_net.nc',
 'Inlet.pli',
 'Outlet.pli',
 'WaterLevel.bc',
 'curves.trb',
 'turbines.ini']

Note that for the 'structured' model, if the turbine is located on a grid line then it will be shifted very slightly in order to avoid a bug in SNL-Delft3D-CEC.

Parameters:
  • template_type

    type of Delft3D project to generate. Valid options are:

    • 'fm': create a flexible mesh model

    • 'structured': create a structured mesh model

    Defaults to 'fm'

  • template_path – optional path to the Delft3D project template

  • exist_ok – if True, allow an existing path to be overwritten, defaults to False

  • no_template – variables to ignore in the given CaseStudy objects when filling templates, defaults to ["dx", "dy"]

Raises:

ValueError – if template_type has an invalid value

__call__(case, project_path, exist_ok=None)

Create a new Delft3D project from the given CaseStudy object, at the given path.

Note that boolean values are converted to integers and Nones are converted to empty strings.

Parameters:
Raises:
template_type: InitVar[str] = 'fm'
template_path: InitVar[StrOrPath] = None
exist_ok: bool = False

if True, allow an existing path to be overwritten

no_template: List[str]

variables to ignore in the given CaseStudy objects when filling templates

class snl_d3d_cec_verify.Validate(case=None, data_dir=None)

Store for Transect objects

Print the object to see the descriptions and indices of the stored Transect objects.

>>> validate = Validate()
>>> print(validate)
Validate(0: Centreline velocity (3\% TI)
         1: Centreline velocity (15\% TI)
         2: Axial velocity at $x^*=5$ (3\% TI)
         3: Axial velocity at $x^*=5$ (15\% TI)
         4: Centreline turbulence intensity (3\% TI)
         5: Centreline turbulence intensity (15\% TI))
>>> validate[0].to_xarray() 
<xarray.DataArray '$u_0$' (dim_0: 10)>
array([0.40064647, 0.40064647, 0.39288889, 0.38189899, 0.39806061,
       0.44460606, 0.49309091, 0.54610101, 0.56614141, 0.60622222])
Coordinates:
    $z$      ... 0
    $x$      (dim_0) float64 0.84 1.4 2.1 2.8 3.5 4.2 4.9 5.6 6.3 7.0
    $y$      (dim_0) float64 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
...

Use a CaseStudy object to translate the origin of the transects to the turbine position.

>>> from snl_d3d_cec_verify import MycekStudy
>>> case = MycekStudy()
>>> validate = Validate(case)
>>> validate[0].to_xarray() 
<xarray.DataArray '$u_0$' (dim_0: 10)>
array([0.40064647, 0.40064647, 0.39288889, 0.38189899, 0.39806061,
       0.44460606, 0.49309091, 0.54610101, 0.56614141, 0.60622222])
Coordinates:
    $z$      ... -1
    $x$      (dim_0) float64 6.84 7.4 8.1 8.8 9.5 10.2 10.9 11.6 12.3 13.0
    $y$      (dim_0) float64 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0
...
Parameters:
  • case – Case study from which to get turbine position

  • data_dir – path to folder containing YAML files representing transects. Each file must have the attrs.description key set. Defaults to Path("./mycek2014")

Raises:

FileNotFoundError – if data_dir is not a directory