Source code for imod.prepare.hfb

from itertools import pairwise
from typing import TYPE_CHECKING, List, Tuple

from imod.typing import PolygonType
from imod.util.imports import MissingOptionalModule

if TYPE_CHECKING:
    import shapely
else:
    try:
        import shapely
    except ImportError:
        shapely = MissingOptionalModule("shapely")


def _line_to_square_zpolygon(
    x: Tuple[float, float], y: Tuple[float, float], z: Tuple[float, float]
) -> PolygonType:
    """
    Creates polygon as follows::

        xy0,z0 -- xy1,z0
           |         |
           |         |
           |         |
        xy0,z1 -- xy1,z1
    """
    return shapely.Polygon(
        (
            (x[0], y[0], z[0]),
            (x[0], y[0], z[1]),
            (x[1], y[1], z[1]),
            (x[1], y[1], z[0]),
        ),
    )


[docs] def linestring_to_square_zpolygons( barrier_x: List[float], barrier_y: List[float], barrier_ztop: List[float], barrier_zbottom: List[float], ) -> List[PolygonType]: """ Create square vertical polygons from linestrings, with a varying ztop and zbottom over the line. Note: If the lists of x and y values of length N, the list of z values need to have length N-1. These are shaped as follows:: xy0,zt0 -- xy1,zt0 | | | xy1,zt1 ---- xy2,zt1 | | | xy0,zb0 -- xy1,zb0 | | | | | xy1,zb1 ---- xy2,zb1 Parameters ---------- barrier_x: list of floats x-locations of barrier, length N barrier_y: list of floats y-locations of barrier, length N barrier_ztop: list of floats top of barrier, length N-1 barrier_zbot: list of floats bottom of barrier, length N-1 Returns ------- List of polygons with z dimension. Examples -------- >>> x = [-10.0, 0.0, 10.0] >>> y = [10.0, 0.0, -10.0] >>> ztop = [10.0, 20.0] >>> zbot = [-10.0, -20.0] >>> polygons = linestring_to_square_zpolygons(x, y, ztop, zbot) You can use these polygons to construct horizontal flow barriers: >>> geometry = gpd.GeoDataFrame(geometry=polygons, data={ >>> "resistance": [1e3, 1e3], >>> }, >>> ) >>> hfb = imod.mf6.HorizontalFlowBarrierResistance(geometry, print_input) """ n = len(barrier_x) expected_lengths = (n, n, n - 1, n - 1) actual_lengths = ( len(barrier_x), len(barrier_y), len(barrier_ztop), len(barrier_zbottom), ) if expected_lengths != actual_lengths: raise ValueError( "Lengths of barrier data, not properly made. For lengths: (x, y," f" ztop, zbottom). Expected lengths: {expected_lengths}, received" f" lengths: {actual_lengths}" ) x_pairs = pairwise(barrier_x) y_pairs = pairwise(barrier_y) z_pairs = zip(barrier_ztop, barrier_zbottom) return [ _line_to_square_zpolygon(x, y, z) for x, y, z in zip(x_pairs, y_pairs, z_pairs) ]
def _line_to_trapezoid_zpolygon( x: Tuple[float, float], y: Tuple[float, float], zt: Tuple[float, float], zb: Tuple[float, float], ) -> PolygonType: """ Creates polygon as follows:: xy0,zt0 | \ | \ | xy1,zt1 | | | | | xy1,zb1 | / | / xy0,zb0 """ return shapely.Polygon( ( (x[0], y[0], zt[0]), (x[0], y[0], zb[1]), (x[1], y[1], zt[1]), (x[1], y[1], zb[0]), ), )
[docs] def linestring_to_trapezoid_zpolygons( barrier_x: List[float], barrier_y: List[float], barrier_ztop: List[float], barrier_zbottom: List[float], ) -> List[PolygonType]: """ Create trapezoid vertical polygons from linestrings, with a varying ztop and zbottom over the line. These are shaped as follows:: xy0,zt0 xy2,zt2 | \ / | | \ / | | xy1,zt1 | | | | | | | | xy1,zb1 -- xy2,zb2 | / | / xy0,zb0 Parameters ---------- barrier_x: list of floats x-locations of barrier, length N barrier_y: list of floats y-locations of barrier, length N barrier_ztop: list of floats top of barrier, length N barrier_zbot: list of floats bottom of barrier, length N Returns ------- List of polygons with z dimension. Examples -------- >>> x = [-10.0, 0.0, 10.0] >>> y = [10.0, 0.0, -10.0] >>> ztop = [10.0, 20.0, 15.0] >>> zbot = [-10.0, -20.0, 0.0] >>> polygons = linestring_to_trapezoid_zpolygons(x, y, ztop, zbot) You can use these polygons to construct horizontal flow barriers: >>> geometry = gpd.GeoDataFrame(geometry=polygons, data={ >>> "resistance": [1e3, 1e3], >>> }, >>> ) >>> hfb = imod.mf6.HorizontalFlowBarrierResistance(geometry, print_input) """ n = len(barrier_x) expected_lengths = (n, n, n, n) actual_lengths = ( len(barrier_x), len(barrier_y), len(barrier_ztop), len(barrier_zbottom), ) if expected_lengths != actual_lengths: raise ValueError( "Lengths of barrier data, not properly made. For lengths: (x, y," f" ztop, zbottom). Expected lengths: {expected_lengths}, received" f" lengths: {actual_lengths}" ) x_pairs = pairwise(barrier_x) y_pairs = pairwise(barrier_y) zt_pairs = pairwise(barrier_ztop) zb_pairs = pairwise(barrier_zbottom) return [ _line_to_trapezoid_zpolygon(x, y, zt, zb) for x, y, zt, zb in zip(x_pairs, y_pairs, zt_pairs, zb_pairs) ]