Skip to content

External forcings file

The external forcing .ext file contains the forcing data for a D-Flow FM model. This includes open boundaries, lateral discharges and meteorological forcings. The documentation below only concerns the 'new' format (ExtForceFileNew in the MDU file).

Model

Boundary (INIBasedModel) pydantic-model

A [Boundary] block for use inside an external forcings file, i.e., a ExtModel.

All lowercased attributes match with the boundary input as described in UM Sec.C.5.2.1.

check_nodeid_or_locationfile_present(values: Dict) classmethod

Verifies that either nodeid or locationfile properties have been set.

Parameters:

Name Type Description Default
values Dict

Dictionary with values already validated.

required

Exceptions:

Type Description
ValueError

When none of the values are present.

Returns:

Type Description
Dict

Validated dictionary of values for Boundary.

Source code in hydrolib/core/io/ext/models.py
@root_validator
@classmethod
def check_nodeid_or_locationfile_present(cls, values: Dict):
    """
    Verifies that either nodeid or locationfile properties have been set.

    Args:
        values (Dict): Dictionary with values already validated.

    Raises:
        ValueError: When none of the values are present.

    Returns:
        Dict: Validated dictionary of values for Boundary.
    """
    node_id = values.get("nodeid", None)
    location_file = values.get("locationfile", None)
    if str_is_empty_or_none(node_id) and not isinstance(location_file, Path):
        raise ValueError(
            "Either nodeId or locationFile fields should be specified."
        )
    return values

forcing: ForcingBase property readonly

Retrieves the corresponding forcing data for this boundary.

Returns:

Type Description
ForcingBase

The corresponding forcing data. None when this boundary does not have a forcing file or when the data cannot be found.

Generic attribute for models that have children fields that could contain files.

Source code in hydrolib/core/io/ext/models.py
def is_intermediate_link(self) -> bool:
    return True

ExtGeneral (INIGeneral) pydantic-model

The external forcing file's [General] section with file meta data.

ExtModel (INIModel) pydantic-model

The overall external forcings model that contains the contents of one external forcings file (new format).

This model is typically referenced under a FMModel.external_forcing.extforcefilenew.

Attributes:

Name Type Description
general ExtGeneral

[General] block with file metadata.

boundary List[Boundary]

List of [Boundary] blocks for all boundary conditions.

lateral List[Lateral]

List of [Lateral] blocks for all lateral discharges.

Lateral (INIBasedModel) pydantic-model

A [Lateral] block for use inside an external forcings file, i.e., a ExtModel.

All lowercased attributes match with the lateral input as described in UM Sec.C.5.2.2.

validate_coordinates(field_value: List[int], values: Dict) -> List[int] classmethod

Method to validate whether the given coordinates match in number to the expected value given for numcoordinates.

Parameters:

Name Type Description Default
field_value List[int]

Coordinates list (x or y)

required
values Dict

Properties already 'validated' for Lateral class.

required

Exceptions:

Type Description
ValueError

When the number of coordinates does not match expectations.

Returns:

Type Description
List[int]

Validated list of coordinates.

Source code in hydrolib/core/io/ext/models.py
@validator("xcoordinates", "ycoordinates")
@classmethod
def validate_coordinates(cls, field_value: List[int], values: Dict) -> List[int]:
    """
    Method to validate whether the given coordinates match in number
    to the expected value given for numcoordinates.

    Args:
        field_value (List[int]): Coordinates list (x or y)
        values (Dict): Properties already 'validated' for Lateral class.

    Raises:
        ValueError: When the number of coordinates does not match expectations.

    Returns:
        List[int]: Validated list of coordinates.
    """
    num_coords = values.get("numcoordinates", None)
    if num_coords is None:
        raise ValueError(
            "numCoordinates should be given when providing xCoordinates or yCoordinates."
        )
    assert num_coords == len(
        field_value
    ), "Number of coordinates given ({}) not matching the numCoordinates value {}.".format(
        len(field_value), num_coords
    )
    return field_value

validate_location_dependencies(values: Dict) -> Dict classmethod

Once all the fields have been evaluated, we verify whether the location given for this Lateral matches the expectations.

Parameters:

Name Type Description Default
values Dict

Dictionary of Laterals validated fields.

required

Exceptions:

Type Description
ValueError

When neither nodeid, branchid or coordinates have been given.

ValueError

When either x or y coordinates were expected but not given.

ValueError

When locationtype should be 1d but other was specified.

Returns:

Type Description
Dict

Validated dictionary of Lateral fields.

Source code in hydrolib/core/io/ext/models.py
@root_validator
@classmethod
def validate_location_dependencies(cls, values: Dict) -> Dict:
    """
    Once all the fields have been evaluated, we verify whether the location
    given for this Lateral matches the expectations.

    Args:
        values (Dict): Dictionary of Laterals validated fields.

    Raises:
        ValueError: When neither nodeid, branchid or coordinates have been given.
        ValueError: When either x or y coordinates were expected but not given.
        ValueError: When locationtype should be 1d but other was specified.

    Returns:
        Dict: Validated dictionary of Lateral fields.
    """

    def validate_coordinates(coord_name: str) -> None:
        if values.get(coord_name.lower(), None) is None:
            raise ValueError("{} should be given.".format(coord_name))

    # If nodeid or branchid and Chainage are present
    node_id: str = values.get("nodeid", None)
    branch_id: str = values.get("branchid", None)
    n_coords: int = values.get("numcoordinates", 0)
    chainage: float = values.get("chainage", None)

    # First validation - at least one of the following should be specified.
    if str_is_empty_or_none(node_id) and (str_is_empty_or_none(branch_id)):
        if n_coords == 0:
            raise ValueError(
                "Either nodeId, branchId (with chainage) or numCoordinates (with xCoordinates and yCoordinates) are required."
            )
        else:
            # Second validation, coordinates should be valid.
            validate_coordinates("xCoordinates")
            validate_coordinates("yCoordinates")
        return values
    else:
        # Third validation, chainage should be given with branchid
        if not str_is_empty_or_none(branch_id) and chainage is None:
            raise ValueError(
                "Chainage should be provided when branchId is specified."
            )
        # Fourth validation, when nodeid, or branchid specified, expected 1d.
        location_type = values.get("locationtype", None)
        if str_is_empty_or_none(location_type):
            values["locationtype"] = "1d"
        elif location_type.lower() != "1d":
            raise ValueError(
                "LocationType should be 1d when nodeId (or branchId and chainage) is specified."
            )

    return values

validate_location_type(v: str) -> str classmethod

Method to validate whether the specified location type is correct.

Parameters:

Name Type Description Default
v str

Given value for the locationtype field.

required

Exceptions:

Type Description
ValueError

When the value given for locationtype is unknown.

Returns:

Type Description
str

Validated locationtype string.

Source code in hydrolib/core/io/ext/models.py
@validator("locationtype")
@classmethod
def validate_location_type(cls, v: str) -> str:
    """
    Method to validate whether the specified location type is correct.

    Args:
        v (str): Given value for the locationtype field.

    Raises:
        ValueError: When the value given for locationtype is unknown.

    Returns:
        str: Validated locationtype string.
    """
    possible_values = ["1d", "2d", "all"]
    if v.lower() not in possible_values:
        raise ValueError(
            "Value given ({}) not accepted, should be one of: {}".format(
                v, ", ".join(possible_values)
            )
        )
    return v
Back to top