Skip to main content

HydReservoir is a Python library for hydrological calculations related to reservoirs.

Project description

HydReservoir

PyPI Version Python Compatibility License

Overview

HydReservoir is a comprehensive Python library for advanced hydrological calculations and water reservoir management.

Key Features

  • Detailed water balance calculations
  • Complex hydraulic system modeling
  • Support for multiple hydraulic components:
    • Pumps
    • Box culverts
    • Circular culverts
    • Gated spillways
    • Free spillways
    • Unknown discharge sources
  • Advanced reservoir regulation utilities

Installation

Install HydReservoir quickly using pip:

pip install hydreservoir

Getting Started

1. Water Balance Calculation

import pandas as pd

from hydreservoir.water_balance.v2.hydraulic_component import BoxCulvert
from hydreservoir.water_balance.v2.hydraulic_component import CircularCulvert
from hydreservoir.water_balance.v2.hydraulic_component import CircularCulvertV2
from hydreservoir.water_balance.v2.hydraulic_component import FreeSpillway
from hydreservoir.water_balance.v2.hydraulic_component import Pump
from hydreservoir.water_balance.v2.hydraulic_component import Unknown
from hydreservoir.water_balance.v2.hydraulic_component import GatedSpillway
from hydreservoir.water_balance.v2.wb import WB

df = pd.read_csv('data.csv')

free_spillway = FreeSpillway(
    'FS1', 109.3, 19.0
)

gated_spillway = GatedSpillway(
    'GS1', 109.3, 19.0,
    df['GatedA'].to_numpy(), free_spillway
)

circular_culvert = CircularCulvert(
    'CC1', 102.5, 0.4, df['CircularA'].to_numpy(), free_spillway,
    discharge_coefficient=0.9, contraction_coefficient=1.0
)

circular_culvert_v2 = CircularCulvertV2(
    'CC2', 102.5, 0.4, df['CircularA'].to_numpy(), free_spillway,
    discharge_coefficient=0.9, contraction_coefficient=1.0
)

box_culvert = BoxCulvert(
    'BC1', 102.5, 0.4, df['BoxA'].to_numpy(), free_spillway
)

pump = Pump(
    'P1', df['P'].to_numpy()
)

unknown = Unknown(
    'U1', df['P'].to_numpy()
)

timeseries = pd.to_datetime(df['Timeseries'])

wb = WB(
    timeseries.to_numpy(),
    df['WaterLevel'].astype(float).to_numpy(),
    df['Capacity'].astype(float).to_numpy(),
)

(wb.add_component(circular_culvert_v2).add_component(free_spillway)
 .add_component(pump).add_component(box_culvert))

wb.calculate().to_csv('result.csv', index=False)

Result DataFrame Columns

The water balance calculation returns a detailed DataFrame with the following columns:

Column Name Description Unit Example
Timeseries Timestamp for the measurement Datetime 2022-01-01
WaterLevel Current water level in the reservoir Meters (m) 109.3
Capacity Reservoir capacity corresponding to the current water level Cubic meters (10^6m³) 2.53
Delta Change in water level since the previous measurement Meters (m) 0.0
Interval Time interval between consecutive measurements Seconds 86400
FreeSpillway.<Free Spillway ID>.<uuid> Flow rate through the free spillway with the specified ID Cubic meters per second (m³/s) 0.0
GatedSpillway.<Gated Spillway ID>.<uuid> Flow rate through a gated spillway port with the specified ID Cubic meters per second (m³/s) 0.0
CircularCulvert.<Circular Culvert ID>.<uuid> Flow rate through the circular culvert with the specified ID Cubic meters per second (m³/s) 4.046643
CircularCulvertV2.<Circular Culvert ID>.<uuid> Flow rate through the updated circular culvert with the specified ID Cubic meters per second (m³/s) 0.131839
BoxCulvert.<Box Culvert ID>.<uuid> Flow rate through the box culvert with the specified ID Cubic meters per second (m³/s) 0.573937
Pump.<Pump ID>.<uuid> Discharge rate for the pump with the specified ID Cubic meters per second (m³/s) 0.0
Unknown.<Unknown Source ID>.<uuid> Discharge rate for an unknown source with the specified ID Cubic meters per second (m³/s) 0.0
Inflow Total inflow into the reservoir Cubic meters per second (m³/s) 4.75242
Outflow Total outflow from all components Cubic meters per second (m³/s) 4.75242

2. Custom Hydraulic Components

import numpy as np

from hydreservoir.water_balance.v2.hydraulic_component import BaseFreeSpillway, BaseGatedSpillway, BaseCircularCulvert,\
    BaseBoxCulvert, SimpleDischarge
from hydreservoir.water_balance.v2.hydraulic_component.core import Core


class CustomFromScratch(Core):

    def provide_discharge(self, water_level: np.ndarray[float], capacity: np.ndarray[float]) -> np.ndarray[float]:
        return np.zeros(len(water_level))


class CustomFreeSpillway(BaseFreeSpillway):
    def calculate_free_spillway_discharge(self, water_level: float, capacity: float) -> float:
        m = self._spillway_discharge_coefficient
        g = self._gravitational_acceleration
        _B = self._dimension
        _H = water_level - self._elevation
        # do something ...
        return 0


class CustomGatedSpillway(BaseGatedSpillway):
    def calculate_gated_spillway_discharge(self, water_level: float, capacity: float, opening: float) -> float:
        # access properties
        # do something ...
        return 0


class CustomCircularCulvert(BaseCircularCulvert):
    def calculate_circular_culvert_discharge(self, water_level: float, capacity: float, opening: float) -> float:
        # access properties
        # do something ...
        return 0


class CustomBoxCulvert(BaseBoxCulvert):
    def calculate_box_culvert_discharge(self, water_level: float, capacity: float, opening: float) -> float:
        # access properties
        # do something ...
        return 0


class CustomPump(SimpleDischarge):
    def provide_discharge(
            self, water_level: np.ndarray[float], capacity: np.ndarray[float]
    ) -> np.ndarray[float]:
        return self._discharge

3. Reservoir Regulation Analysis

from hydreservoir.regulation import regulation
from hydreservoir.regulation.dataset import Dataset as RDataset

# ... calculate init components for water balance
df = wb.calculate().to_csv('result.csv', index=False)

# Regulation analysis
P = 90.0
eps = 0.1
P_n = regulation.P_n(RDataset.from_wb_df_to_dataset(df), V_c=1.0, gt_10_years=True)

print(P_n - P <= eps)

3. Mapping Functions for Water Levels and Capacities

These functions allow efficient mapping between water levels and reservoir capacities, with optional support for nearest neighbor interpolation.

get_capacity Maps a single water level to its corresponding capacity using a provided mapping dictionary. Supports optional nearest neighbor interpolation for unmatched values.

from hydreservoir.utils import get_capacity

water_level_capacity_map = {0.0: 0.0, 1.0: 100.0, 2.0: 200.0}
capacity = get_capacity(1.5, water_level_capacity_map, nearest_mapping=True)
print(capacity)  # Output: 100.0

map_capacity Maps an array of water levels to their corresponding capacities using a provided mapping dictionary. Supports optional nearest neighbor interpolation for unmatched values.

from hydreservoir.utils import map_capacity

water_level_capacity_map = {0.0: 0.0, 1.0: 100.0, 2.0: 200.0}
water_levels = [0.5, 1.5, 2.0]
capacities = map_capacity(water_levels, water_level_capacity_map, nearest_mapping=True)
print(capacities)  # Output: [0.0, 100.0, 200.0]

get_water_level Maps a single capacity to its corresponding water level using a provided mapping dictionary. Supports optional nearest neighbor interpolation for unmatched values.

from hydreservoir.utils import get_water_level

capacity_water_level_map = {0.0: 0.0, 100.0: 1.0, 200.0: 2.0}
water_level = get_water_level(150.0, capacity_water_level_map, nearest_mapping=True)
print(water_level)  # Output: 1.0

map_water_level Maps an array of capacities to their corresponding water levels using a provided mapping dictionary. Supports optional nearest neighbor interpolation for unmatched values.

from hydreservoir.utils import map_water_level

capacity_water_level_map = {0.0: 0.0, 100.0: 1.0, 200.0: 2.0}
capacities = [50.0, 150.0, 200.0]
water_levels = map_water_level(capacities, capacity_water_level_map, nearest_mapping=True)
print(water_levels)  # Output: [0.0, 1.0, 2.0]

License

This library is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hydreservoir-1.1.0.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hydreservoir-1.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file hydreservoir-1.1.0.tar.gz.

File metadata

  • Download URL: hydreservoir-1.1.0.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.4 CPython/3.12.3 Linux/6.8.0-49-generic

File hashes

Hashes for hydreservoir-1.1.0.tar.gz
Algorithm Hash digest
SHA256 d20cf0ebeed707212ab10daa69d2c5fc86e743bc029c16e8c0a9549ec2f25fc3
MD5 4123ca487ff976cd6d3b5e0203ed3265
BLAKE2b-256 cbd4f23f421a50bb992c2f176c507ac4fc24d6923fa4f31e0d2b61e87d81a2ed

See more details on using hashes here.

File details

Details for the file hydreservoir-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: hydreservoir-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.4 CPython/3.12.3 Linux/6.8.0-49-generic

File hashes

Hashes for hydreservoir-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 30596b73657e00e00dee5c5961ecce1fff1007ec47745e0e91aa3145d359dd60
MD5 3d2c09e4ef442cd18f4368f82d497cf8
BLAKE2b-256 fe28ef811f5caae9407e94a99a7820569313d94ddaa1e410aac4851e3f4d86b6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page