earthsciencekit.hydrology#
Inspectable hydrology models of water on and under land; SI units unless stated otherwise.
- earthsciencekit.hydrology.aerodynamic_resistance(wind_speed, measurement_height, displacement_height, momentum_roughness, vapor_roughness)[source]#
Aerodynamic resistance to vapour transfer above a canopy.
Turbulence in the logarithmic wind profile carries vapour away from the canopy, faster in stronger wind over rougher surfaces.
- Parameters:
wind_speed (float or array_like) – m/s, at the measurement height; constraint: positive.
measurement_height (float or array_like) – m; constraint: positive.
displacement_height (float or array_like) – m, zero-plane displacement (about two thirds of the canopy height); constraint: nonnegative.
momentum_roughness (float or array_like) – m; constraint: positive.
vapor_roughness (float or array_like) – m, often a tenth of the momentum roughness; constraint: positive.
- Returns:
Model value [s/m]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Neutral stability; the measurement height above the displacement height must exceed both roughness lengths. For FAO grass (0.12 m) at 2 m it is about
208 / wind_speed. Equation:np.log((measurement_height - displacement_height) / momentum_roughness) * np.log((measurement_height - displacement_height) / vapor_roughness) / (VON_KARMAN**2 * wind_speed). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.bulk_surface_resistance(stomatal_resistance, active_leaf_area_index)[source]#
Bulk surface (canopy) resistance from the leaf stomatal resistance.
The stomata of all leaves act as resistances in parallel, so a dense canopy offers less resistance than a single leaf.
- Parameters:
stomatal_resistance (float or array_like) – s/m, of a single well-illuminated leaf (about 100); constraint: nonnegative.
active_leaf_area_index (float or array_like) – 1, sunlit leaf area per ground area (about half the leaf area index); constraint: positive.
- Returns:
Model value [s/m]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Monteith (1965) big-leaf canopy with parallel leaves; FAO grass has about 70 s/m. Equation:
stomatal_resistance / active_leaf_area_index. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.chezy_from_manning(roughness, hydraulic_radius)[source]#
Chezy coefficient equivalent to a Manning roughness.
Manning’s formula is Chezy’s with a coefficient that grows as the sixth root of the hydraulic radius.
- Parameters:
roughness (float or array_like) – s/m^(1/3); constraint: positive.
hydraulic_radius (float or array_like) – m; constraint: positive.
- Returns:
Model value [m^0.5/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Manning (1891), SI units. Equation:
hydraulic_radius**(1 / 6) / roughness. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.chezy_velocity(chezy_coefficient, hydraulic_radius, slope)[source]#
Chezy’s mean velocity of uniform flow in an open channel.
In uniform flow the weight of the water down the slope balances bed friction that grows as the square of the velocity.
- Parameters:
chezy_coefficient (float or array_like) – m^0.5/s, typically 30-90; constraint: positive.
hydraulic_radius (float or array_like) – m; constraint: positive.
slope (float or array_like) – 1, bed (energy) slope; constraint: nonnegative.
- Returns:
Model value [m/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Chezy (1775): steady uniform turbulent flow; the coefficient is not a constant but depends on roughness and depth. Equation:
chezy_coefficient * np.sqrt(hydraulic_radius * slope). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.cooper_jacob_drawdown(pumping_rate, transmissivity, storativity, radius, time)[source]#
Cooper and Jacob’s late-time approximation to the Theis drawdown.
Late in a pumping test the drawdown grows linearly with the logarithm of time, so a straight line on a semilog plot gives the aquifer properties.
- Parameters:
pumping_rate (float or array_like) – m^3/s; constraint: real.
transmissivity (float or array_like) – m^2/s; constraint: positive.
storativity (float or array_like) – 1; constraint: positive.
radius (float or array_like) – m; constraint: positive.
time (float or array_like) – s; constraint: positive.
- Returns:
Model value [m]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Cooper and Jacob (1946): the first two terms of the Theis series, within 1% for
u < 0.01and meaningless (it goes negative) for u above about 0.56. Equation:pumping_rate / (4 * np.pi * transmissivity) * (-np.euler_gamma - np.log(radius**2 * storativity / (4 * transmissivity * time))). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.cooper_jacob_transmissivity(pumping_rate, drawdown_per_log_cycle)[source]#
Transmissivity from the slope of a Cooper-Jacob straight line.
The drawdown gained per tenfold increase in time depends only on the pumping rate and the transmissivity.
- Parameters:
pumping_rate (float or array_like) – m^3/s; constraint: positive.
drawdown_per_log_cycle (float or array_like) – m, drawdown increase per factor of ten in time; constraint: positive.
- Returns:
Model value [m^2/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Cooper and Jacob (1946), from late-time data where
u < 0.01; the storativity follows from the zero-drawdown interceptt0as2.25 * transmissivity * t0 / radius**2. Equation:np.log(10) * pumping_rate / (4 * np.pi * drawdown_per_log_cycle). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.dalton_evaporation(saturation_vapor_pressure, vapor_pressure, transfer_coefficient)[source]#
Dalton’s evaporation from a wet surface.
Evaporation is proportional to how far the air is from saturation at the temperature of the surface, and stops when the air is saturated.
- Parameters:
saturation_vapor_pressure (float or array_like) – Pa, at the surface temperature; constraint: nonnegative.
vapor_pressure (float or array_like) – Pa, of the air; constraint: nonnegative.
transfer_coefficient (float or array_like) – kg/(m^2 s Pa), a wind function that grows with wind speed; constraint: nonnegative.
- Returns:
Model value [kg/(m^2 s)], negative for condensation. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Dalton (1802), a bulk mass-transfer law; the surface temperature it needs is rarely measured. Equation:
transfer_coefficient * (saturation_vapor_pressure - vapor_pressure). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.darcy_flux(hydraulic_conductivity, head_gradient)[source]#
Darcy’s specific discharge through a porous medium.
Darcy’s filters at Dijon showed that the flow through sand is proportional to the drop in head per unit length.
- Parameters:
hydraulic_conductivity (float or array_like) – m/s; constraint: nonnegative.
head_gradient (float or array_like) – 1, change of head per unit length along the flow direction; constraint: real.
- Returns:
Model value [m/s], volume per unit cross-sectional area and time, positive down the gradient. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Darcy (1856): laminar flow with a pore Reynolds number below about 1-10 in a saturated isotropic medium. Equation:
-hydraulic_conductivity * head_gradient. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.dupuit_discharge(hydraulic_conductivity, upstream_head, downstream_head, length)[source]#
Discharge per unit width through an unconfined aquifer.
In Dupuit’s approximation the flow depends on the difference of the squared heads, not of the heads.
- Parameters:
hydraulic_conductivity (float or array_like) – m/s; constraint: nonnegative.
upstream_head (float or array_like) – m, saturated thickness; constraint: nonnegative.
downstream_head (float or array_like) – m; constraint: nonnegative.
length (float or array_like) – m; constraint: positive.
- Returns:
Model value [m^2/s], positive from upstream to downstream. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Dupuit (1863), the Dupuit-Forchheimer discharge formula, exact for the discharge even where the head profile is not. Equation:
hydraulic_conductivity * (upstream_head**2 - downstream_head**2) / (2 * length). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.dupuit_head(distance, upstream_head, downstream_head, length)[source]#
Water-table height in an unconfined aquifer between two rivers.
Treating the flow as horizontal turns the unconfined aquifer into a one-dimensional problem with a parabolic water table.
- Parameters:
distance (float or array_like) – m, from the upstream boundary; constraint: between 0 and length.
upstream_head (float or array_like) – m, saturated thickness above the impermeable base; constraint: nonnegative.
downstream_head (float or array_like) – m; constraint: nonnegative.
length (float or array_like) – m; constraint: positive.
- Returns:
Model value [m]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Dupuit (1863): no recharge, a horizontal base, and slopes small enough that the head is uniform on each vertical. Equation:
np.sqrt(upstream_head**2 - (upstream_head**2 - downstream_head**2) * distance / length). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.gardner_conductivity(pressure_head, saturated_conductivity, sorptive_number)[source]#
Gardner’s exponential unsaturated hydraulic conductivity.
Drying soil conducts water through ever thinner films and smaller pores, so its conductivity falls by orders of magnitude as suction rises.
- Parameters:
pressure_head (float or array_like) – m, negative under suction; constraint: nonpositive.
saturated_conductivity (float or array_like) – m/s; constraint: positive.
sorptive_number (float or array_like) – 1/m, Gardner’s alpha (about 1 for clay to 10 for sand); constraint: positive.
- Returns:
Model value [m/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Gardner (1958), a one-parameter fit without hysteresis; it makes the steady Richards equation solvable in closed form. Equation:
saturated_conductivity * np.exp(sorptive_number * pressure_head). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.green_ampt_rate(cumulative_infiltration, saturated_conductivity, suction_head, moisture_deficit)[source]#
Green-Ampt infiltration capacity of a ponded soil.
A sharp wetting front moves down behind a ponded surface, pulled by capillary suction that matters less and less as the wetted zone deepens.
- Parameters:
cumulative_infiltration (float or array_like) – m, depth infiltrated so far; constraint: positive.
saturated_conductivity (float or array_like) – m/s; constraint: positive.
suction_head (float or array_like) – m, capillary suction at the wetting front; constraint: positive.
moisture_deficit (float or array_like) – 1, saturated minus initial water content; constraint: between 0 (exclusive) and 1.
- Returns:
Model value [m/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Green and Ampt (1911): a piston-like front in a uniform soil with a negligible ponding depth; the rate tends to the saturated conductivity. Equation:
saturated_conductivity * (1 + suction_head * moisture_deficit / cumulative_infiltration). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.green_ampt_time(cumulative_infiltration, saturated_conductivity, suction_head, moisture_deficit)[source]#
Time for a ponded Green-Ampt soil to absorb a given depth.
Integrating the Green-Ampt rate gives the time in closed form, so the infiltrated depth follows by inverting it.
- Parameters:
cumulative_infiltration (float or array_like) – m; constraint: nonnegative.
saturated_conductivity (float or array_like) – m/s; constraint: positive.
suction_head (float or array_like) – m; constraint: positive.
moisture_deficit (float or array_like) – 1; constraint: between 0 (exclusive) and 1.
- Returns:
Model value [s], since ponding at the surface began. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Green and Ampt (1911), ponded from time zero; early on the depth grows as the square root of time. Equation:
(cumulative_infiltration - suction_head * moisture_deficit * np.log(1 + cumulative_infiltration / (suction_head * moisture_deficit))) / saturated_conductivity. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.horton_cumulative_infiltration(time, initial_rate, final_rate, decay_constant)[source]#
Depth infiltrated under Horton’s law.
The time integral of Horton’s capacity is the water the soil can take up before the steady rate dominates.
- Parameters:
time (float or array_like) – s; constraint: nonnegative.
initial_rate (float or array_like) – m/s; constraint: at least final_rate.
final_rate (float or array_like) – m/s; constraint: nonnegative.
decay_constant (float or array_like) – 1/s; constraint: positive.
- Returns:
Model value [m]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Horton (1933, 1940), with rain at or above capacity from time zero. Equation:
final_rate * time + (initial_rate - final_rate) * (1 - np.exp(-decay_constant * time)) / decay_constant. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.horton_infiltration_rate(time, initial_rate, final_rate, decay_constant)[source]#
Horton’s infiltration capacity during a storm.
Infiltration capacity falls from a high initial value to a steady one as the soil wets, and rain beyond it runs off over the surface.
- Parameters:
time (float or array_like) – s, since the soil began to infiltrate at capacity; constraint: nonnegative.
initial_rate (float or array_like) – m/s; constraint: at least final_rate.
final_rate (float or array_like) – m/s; constraint: nonnegative.
decay_constant (float or array_like) – 1/s; constraint: positive.
- Returns:
Model value [m/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Horton (1933, 1940), an empirical law for rain at or above capacity throughout. Equation:
final_rate + (initial_rate - final_rate) * np.exp(-decay_constant * time). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.hydraulic_head(elevation, pressure, density, gravity)[source]#
Hydraulic head from elevation and pore pressure.
Groundwater flows from high to low head, the sum of the elevation and pressure heads, not from high to low pressure.
- Parameters:
elevation (float or array_like) – m, above a datum; constraint: real.
pressure (float or array_like) – Pa, gauge pore pressure; constraint: real.
density (float or array_like) – kg/m^3; constraint: positive.
gravity (float or array_like) – m/s^2; constraint: positive.
- Returns:
Model value [m]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Slow flow with negligible velocity head and uniform fluid density. Equation:
elevation + pressure / (density * gravity). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.hydraulic_radius(width, depth)[source]#
Hydraulic radius of a rectangular channel.
Friction acts on the wetted perimeter while gravity acts on the cross-section, so their ratio sets the resistance of a channel.
- Parameters:
width (float or array_like) – m, bed width; constraint: positive.
depth (float or array_like) – m, flow depth; constraint: positive.
- Returns:
Model value [m], flow area over wetted perimeter. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Rectangular section; tends to the depth for a wide channel. Equation:
width * depth / (width + 2 * depth). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.manning_velocity(roughness, hydraulic_radius, slope)[source]#
Manning’s mean velocity of uniform flow in an open channel.
One roughness number per kind of channel bed predicts the velocity at any depth, which made Manning’s formula the standard of channel design.
- Parameters:
roughness (float or array_like) – s/m^(1/3), Manning’s n (about 0.012 for concrete, 0.03-0.05 for natural rivers); constraint: positive.
hydraulic_radius (float or array_like) – m; constraint: positive.
slope (float or array_like) – 1; constraint: nonnegative.
- Returns:
Model value [m/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Manning (1891), SI form; fully rough turbulent flow, steady and uniform. Equation:
hydraulic_radius**(2 / 3) * np.sqrt(slope) / roughness. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.muskingum_coefficients(storage_constant, weighting, time_step)[source]#
Muskingum routing coefficients.
Storage in a river reach is a weighted mix of inflow and outflow, which makes the outflow a fixed linear combination of the latest flows.
- Parameters:
storage_constant (float or array_like) – s, Muskingum K, about the travel time through the reach; constraint: positive.
weighting (float or array_like) – 1, Muskingum X; constraint: between 0 and 0.5.
time_step (float or array_like) – s; constraint: positive.
- Returns:
Model value [1]:
[C0, C1, C2], which sum to one.- Return type:
ndarray, shape (…, 3)
Notes
McCarthy (1938), storage
K (X I + (1 - X) O); all coefficients are nonnegative when2 K X <= time_step <= 2 K (1 - X). Equation:[time_step - 2 K X, time_step + 2 K X, 2 K (1 - X) - time_step] / (2 K (1 - X) + time_step). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.muskingum_routing(inflow, storage_constant, weighting, time_step)[source]#
Outflow hydrograph of a river reach by the Muskingum method.
Routing a flood through a reach delays and flattens its peak, the effect forecasters need downstream.
- Parameters:
inflow (array_like, shape (n,), n >= 2) – m^3/s, sampled every time step; constraint: nonnegative vector.
storage_constant (float) – s; constraint: positive scalar.
weighting (float) – 1; constraint: scalar between 0 and 0.5.
time_step (float) – s; constraint: positive scalar.
- Returns:
Model value [m^3/s], starting from a steady state
outflow[0] = inflow[0].- Return type:
ndarray, shape (n,)
Notes
McCarthy (1938):
O[j+1] = C0 I[j+1] + C1 I[j] + C2 O[j]; choose the time step so that no coefficient is negative. Equation:O[j + 1] = C0 * I[j + 1] + C1 * I[j] + C2 * O[j]. Invalid, empty, nonreal or nonfinite inputs raise ValueError.
- earthsciencekit.hydrology.nash_unit_hydrograph(time, reservoirs, storage_constant)[source]#
Instantaneous unit hydrograph of a cascade of linear reservoirs.
A catchment that drains like a chain of equal linear reservoirs turns an instant of rain into a skewed, gamma-shaped pulse of river flow.
- Parameters:
time (float or array_like) – s, since the instant of excess rainfall; constraint: nonnegative.
reservoirs (float or array_like) – 1, Nash’s n; constraint: at least 1.
storage_constant (float or array_like) – s, Nash’s k of each reservoir; constraint: positive.
- Returns:
Model value [1/s], which integrates to one; multiply by the catchment area for m^3/s per metre of excess rainfall. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Nash (1957), a gamma density with mean lag
reservoirs * storage_constant; a smooth synthetic shape for Sherman’s unit hydrograph, linear and time-invariant. Equation:time**(reservoirs - 1) * np.exp(-time / storage_constant) / (storage_constant**reservoirs * scipy.special.gamma(reservoirs)). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.penman_evaporation(net_radiation, temperature, aerodynamic_evaporation, pressure)[source]#
Penman’s combination equation for open-water evaporation.
Penman eliminated the unknown surface temperature by combining the energy balance with Dalton’s law, so evaporation follows from routine weather measurements.
- Parameters:
net_radiation (float or array_like) – W/m^2, net radiation minus heat stored below the surface; constraint: real.
temperature (float or array_like) – K, air temperature; constraint: between 180 and 330.
aerodynamic_evaporation (float or array_like) – kg/(m^2 s), Dalton’s evaporation evaluated with the air temperature,
f(u) (e_s(T_air) - e_air); constraint: real.pressure (float or array_like) – Pa; constraint: positive.
- Returns:
Model value [kg/(m^2 s)]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Penman (1948): the saturation curve is linearized between air and surface temperature, and heat and vapour share one transfer coefficient; a saturated surface (open water or wet grass). Equation:
(saturation_slope(temperature) * net_radiation / LATENT_HEAT_VAPORIZATION + psychrometric_constant(pressure) * aerodynamic_evaporation) / (saturation_slope(temperature) + psychrometric_constant(pressure)). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.penman_monteith_evaporation(available_energy, temperature, vapor_pressure_deficit, air_density, aerodynamic_resistance, surface_resistance, pressure)[source]#
Penman-Monteith evaporation from a vegetated surface.
Monteith added the resistance of the stomata to Penman’s equation, so the same formula covers open water, wet leaves and transpiring crops.
- Parameters:
available_energy (float or array_like) – W/m^2, net radiation minus ground heat flux; constraint: real.
temperature (float or array_like) – K, air temperature; constraint: between 180 and 330.
vapor_pressure_deficit (float or array_like) – Pa,
e_s(T_air) - e_air; constraint: real.air_density (float or array_like) – kg/m^3; constraint: positive.
aerodynamic_resistance (float or array_like) – s/m; constraint: positive.
surface_resistance (float or array_like) – s/m; constraint: nonnegative.
pressure (float or array_like) – Pa; constraint: positive.
- Returns:
Model value [kg/(m^2 s)]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Monteith (1965): a big-leaf canopy at one temperature, neutral stability; zero surface resistance recovers Penman with
aerodynamic_evaporation = air_density * CP_DRY_AIR * vapor_pressure_deficit / (psychrometric_constant * LATENT_HEAT_VAPORIZATION * aerodynamic_resistance). Equation:(Delta * available_energy + air_density * CP_DRY_AIR * vapor_pressure_deficit / aerodynamic_resistance) / (LATENT_HEAT_VAPORIZATION * (Delta + gamma * (1 + surface_resistance / aerodynamic_resistance))). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.psychrometric_constant(pressure)[source]#
Psychrometric constant.
It converts a temperature difference into the vapour-pressure difference that carries the same energy, as sensible rather than latent heat.
- Parameters:
pressure (float or array_like) – Pa, air pressure; constraint: positive.
- Returns:
Model value [Pa/K], about 65 Pa/K at sea level. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Dry-air heat capacity and constant latent heat; equal transfer coefficients for heat and vapour. Equation:
CP_DRY_AIR * pressure / (EPSILON_WATER * LATENT_HEAT_VAPORIZATION). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.richards_steady_head(height, flux, saturated_conductivity, sorptive_number)[source]#
Steady pressure-head profile above a water table in a Gardner soil.
With a constant flux through the unsaturated zone, Richards’s equation fixes the suction at every height: capillary rise for evaporation, a unit-gradient tail for infiltration.
- Parameters:
height (float or array_like) – m, above the water table; constraint: nonnegative.
flux (float or array_like) – m/s, positive upward (evaporation), negative downward (infiltration); constraint: greater than
-saturated_conductivity.saturated_conductivity (float or array_like) – m/s; constraint: positive.
sorptive_number (float or array_like) – 1/m, Gardner’s alpha; constraint: positive.
- Returns:
Model value [m], zero at the water table and negative above it. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Richards (1931) steady equation
flux = -K(psi) (dpsi/dz + 1)with Gardner’s (1958) conductivity; an upward flux can only be sustained belownp.log(1 + saturated_conductivity / flux) / sorptive_number. Equation:np.log(((flux + saturated_conductivity) * np.exp(-sorptive_number * height) - flux) / saturated_conductivity) / sorptive_number. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.runoff_coefficient(runoff, precipitation)[source]#
Fraction of the precipitation that leaves a catchment as river flow.
Perrault’s measurement that the Seine carries only about a sixth of the rain on its basin showed that rainfall is enough to feed rivers.
- Parameters:
runoff (float or array_like) – m, runoff depth over a period; constraint: nonnegative.
precipitation (float or array_like) – m, precipitation depth over the same period; constraint: positive.
- Returns:
Model value [1]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Both depths over the same area and period; long periods make the storage change negligible. Equation:
runoff / precipitation. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.saturation_slope(temperature)[source]#
Slope of the saturation vapour-pressure curve.
The steepness of the Clausius-Clapeyron curve converts a surface-to-air temperature difference into a vapour-pressure difference.
- Parameters:
temperature (float or array_like) – K; constraint: between 180 and 330.
- Returns:
Model value [Pa/K]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Derivative of
earthsciencekit.atmosphere.saturation_vapor_pressure()(constant latent heat 2.5e6 J/kg). Equation:saturation_vapor_pressure(temperature) * LATENT_HEAT_VAPORIZATION / (R_VAPOR * temperature**2). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.seepage_velocity(darcy_flux, porosity)[source]#
Mean velocity of water in the pores.
Water moves only through the connected pores, so a tracer travels faster than the Darcy flux suggests.
- Parameters:
darcy_flux (float or array_like) – m/s; constraint: real.
porosity (float or array_like) – 1, effective porosity; constraint: between 0 (exclusive) and 1.
- Returns:
Model value [m/s]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Average linear velocity; dispersion spreads tracers about it. Equation:
darcy_flux / porosity. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.simulate_infiltration(saturated_conductivity, suction_head, moisture_deficit, rainfall_rate, time)[source]#
Infiltration and runoff during steady rain on a Green-Ampt soil.
- Parameters:
saturated_conductivity (float) – Positive scalar [m/s].
suction_head (float) – Positive scalar wetting-front suction [m].
moisture_deficit (float) – Scalar saturated minus initial water content, in (0, 1] [1].
rainfall_rate (float) – Nonnegative scalar rain intensity [m/s].
time (array_like) – Nonnegative strictly increasing times; the rain starts at the first sample [s].
- Returns:
Cumulative infiltration [m], infiltration rate [m/s] and infiltration-excess runoff rate [m/s].
- Return type:
Notes
Mein and Larson (1973): the soil absorbs all the rain until the Green-Ampt capacity
K (1 + psi dtheta / F)falls to the rain rate, atF = K psi dtheta / (r - K), and infiltrates at capacity afterwards, so dF/dt = min(r, capacity). Rain no faster than K never ponds. The excess runs off at once; surface storage, redistribution and a water table are neglected.
- earthsciencekit.hydrology.stream_length(order, first_order_length, length_ratio)[source]#
Mean length of the streams of a given order.
Streams grow longer geometrically with order, Horton’s companion to his law of stream numbers.
- Parameters:
order (float or array_like) – 1, stream order; constraint: at least 1.
first_order_length (float or array_like) – m, mean length of first-order streams; constraint: positive.
length_ratio (float or array_like) – 1, typically 1.5-3.5; constraint: positive.
- Returns:
Model value [m]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Horton’s law of stream lengths (1945), an empirical average over a network. Equation:
first_order_length * length_ratio**(order - 1). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.stream_number(order, highest_order, bifurcation_ratio)[source]#
Number of streams of a given order in a drainage network.
Horton found that stream counts fall geometrically with order, so a whole river network is summarized by one bifurcation ratio.
- Parameters:
order (float or array_like) – 1, stream order; constraint: at least 1.
highest_order (float or array_like) – 1, order of the main stream; constraint: at least order.
bifurcation_ratio (float or array_like) – 1, typically 3-5; constraint: positive.
- Returns:
Model value [1], one stream of the highest order. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Horton’s law of stream numbers (1945), an empirical average; Strahler’s (1952) ordering is the usual convention. Equation:
bifurcation_ratio**(highest_order - order). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.theis_drawdown(pumping_rate, transmissivity, storativity, radius, time)[source]#
Drawdown around a well pumping a confined aquifer.
Theis took the heat-conduction solution for a line sink and found that the cone of depression keeps growing as the well draws water from storage.
- Parameters:
pumping_rate (float or array_like) – m^3/s; constraint: real.
transmissivity (float or array_like) – m^2/s; constraint: positive.
storativity (float or array_like) – 1; constraint: positive.
radius (float or array_like) – m, from the well axis; constraint: positive.
time (float or array_like) – s, since pumping began; constraint: positive.
- Returns:
Model value [m], positive downward. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Theis (1935): constant rate, a fully penetrating well of negligible radius in an infinite, homogeneous, isotropic confined aquifer with water released instantly from storage. Equation:
pumping_rate / (4 * np.pi * transmissivity) * scipy.special.exp1(radius**2 * storativity / (4 * transmissivity * time)). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.topmodel_baseflow(saturated_transmissivity, mean_index, mean_deficit, scaling_depth)[source]#
TOPMODEL subsurface drainage from the catchment-mean deficit.
Baseflow falls exponentially as the catchment dries, the recession behaviour TOPMODEL is built on.
- Parameters:
saturated_transmissivity (float or array_like) – m^2/s, transmissivity when the soil is saturated to the surface; constraint: positive.
mean_index (float or array_like) – 1, catchment mean of
ln(a / tan(beta))with a in metres; constraint: real.mean_deficit (float or array_like) – m; constraint: nonnegative.
scaling_depth (float or array_like) – m, TOPMODEL’s m; constraint: positive.
- Returns:
Model value [m/s], discharge per unit catchment area. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Beven and Kirkby (1979): exponential transmissivity profile, water table parallel to the surface. Equation:
saturated_transmissivity * np.exp(-mean_index) * np.exp(-mean_deficit / scaling_depth). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.topmodel_deficit(mean_deficit, topographic_index, mean_index, scaling_depth)[source]#
Local storage deficit of TOPMODEL from the catchment mean.
Each point’s deficit departs from the catchment mean in proportion to how much wetter its topographic index is than average, so one state variable maps the saturated area.
- Parameters:
mean_deficit (float or array_like) – m, catchment-mean storage deficit; constraint: nonnegative.
topographic_index (float or array_like) – 1, local
ln(a / tan(beta)); constraint: real.mean_index (float or array_like) – 1, catchment mean of the index; constraint: real.
scaling_depth (float or array_like) – m, TOPMODEL’s m, the deficit that reduces transmissivity by a factor e; constraint: positive.
- Returns:
Model value [m]; zero or negative where the ground is saturated (negative values are return flow). Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Beven and Kirkby (1979) with uniform transmissivity at saturation and quasi-steady drainage. Equation:
mean_deficit + scaling_depth * (mean_index - topographic_index). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.topographic_index(specific_area, slope)[source]#
TOPMODEL topographic wetness index.
Ground that drains a large upslope area through a gentle slope is the first to saturate, so one number from the topography maps where runoff starts.
- Parameters:
specific_area (float or array_like) – m, upslope area drained per unit contour width; constraint: positive.
slope (float or array_like) – rad, local surface slope; constraint: between 0 and pi/2, exclusive.
- Returns:
Model value [1], with the specific area in metres. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Beven and Kirkby (1979): steady recharge, a water table parallel to the surface and transmissivity falling exponentially with deficit. Equation:
np.log(specific_area / np.tan(slope)). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.unit_hydrograph_convolution(excess_rainfall, unit_hydrograph)[source]#
Storm hydrograph from excess rainfall and a unit hydrograph.
If a catchment responds linearly, the flood from any storm is the sum of unit-hydrograph responses to its successive bursts of excess rainfall, each shifted and scaled.
- Parameters:
excess_rainfall (array_like, shape (n,)) – m, excess (effective) rainfall depth in each interval; constraint: nonnegative vector.
unit_hydrograph (array_like, shape (m,)) – m^3/s per metre of excess rainfall, ordinates at the same interval; constraint: nonnegative vector.
- Returns:
Model value [m^3/s], the direct runoff at the same interval.
- Return type:
ndarray, shape (n + m - 1,)
Notes
Sherman (1932): linear superposition and time invariance; baseflow and losses are removed beforehand. Equation:
np.convolve(excess_rainfall, unit_hydrograph). Invalid, empty, nonreal or nonfinite inputs raise ValueError.
- earthsciencekit.hydrology.unsaturated_darcy_flux(conductivity, pressure_head_gradient)[source]#
Vertical Darcy-Buckingham flux in an unsaturated soil.
Richards extended Darcy’s law to unsaturated soil, where capillary suction and gravity together drive the water.
- Parameters:
conductivity (float or array_like) – m/s, at the local pressure head; constraint: nonnegative.
pressure_head_gradient (float or array_like) – 1, d(pressure_head)/dz with z upward; constraint: real.
- Returns:
Model value [m/s], positive upward. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Richards (1931): the total head is
pressure_head + zand air stays at atmospheric pressure. Equation:-conductivity * (pressure_head_gradient + 1). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.water_balance(precipitation, evapotranspiration, runoff)[source]#
Rate of change of the water stored in a catchment.
Whatever falls on a catchment and neither evaporates nor leaves by its river must be stored in its soil, aquifers and lakes.
- Parameters:
precipitation (float or array_like) – m/s, depth per unit time over the catchment; constraint: nonnegative.
evapotranspiration (float or array_like) – m/s; constraint: nonnegative.
runoff (float or array_like) – m/s, river discharge divided by the catchment area; constraint: nonnegative.
- Returns:
Model value [m/s], positive when storage grows. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
Perrault (1674): a closed catchment with no groundwater exchange across its divide; any common depth rate (such as mm/day) may be used throughout. Equation:
precipitation - evapotranspiration - runoff. Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.
- earthsciencekit.hydrology.well_function(u)[source]#
Theis well function W(u).
The drawdown around a pumped well is a universal curve of one combination of distance, time and aquifer properties.
- Parameters:
u (float or array_like) – 1,
radius**2 * storativity / (4 * transmissivity * time); constraint: positive.- Returns:
Model value [1]. Scalar input returns a NumPy scalar; arrays broadcast.
- Return type:
numpy scalar or ndarray
Notes
The exponential integral E1,
-0.5772 - ln(u) + u - ...for small u. Equation:scipy.special.exp1(u). Invalid, empty, nonreal or nonfinite inputs raise ValueError. NumPy broadcasting applies; singular and overflowing outputs raise ValueError.