Source code for groundwater

# -*- coding: utf-8 -*-
# =============================================================================
# This file is part of WaterGAP.

# WaterGAP is an opensource software which computes water flows and storages as
# well as water withdrawals and consumptive uses on all continents.

# You should have received a copy of the LGPLv3 License along with WaterGAP.
# if not see <https://www.gnu.org/licenses/lgpl-3.0>
# =============================================================================

"""Groundwater balance."""

# =============================================================================
# This module computes groundwater balance, including groundwater storage
# and related fluxes for all grid cells based on section 4.5 of
# (Müller Schmied et al. (2021)).
# The groundwater balance equation is solved analytically for each timestep
# of one day to prevent numerical inaccuracies. This avoids the use of very
# small timesteps which will be computationally expensive and hence lead
# to numerical problems.
# =============================================================================

import numpy as np
from numba import njit
from model.lateralwaterbalance import groundwater_adapt_net_abstraction as \
    gw_adapt_netabstr


[docs] @njit(cache=True) def groundwater_balance(x, y, aridity_or_inlandsink, groundwater_storage, diffuse_gw_recharge, potential_net_abstraction_gw, daily_unsatisfied_pot_nas, gw_dis_coeff, prev_potential_water_withdrawal_sw_irri, prev_potential_consumptive_use_sw_irri, frac_irri_returnflow_to_gw, point_source_recharge=None): """ Compute daily groundwater balance including storages and related fluxes. Parameters ---------- x : int Latitude index of cell y : int Longitude index of cell aridiity : string Compute groundwater for "Humid" or "Arid" region groundwater_storage : float Daily groundwater storage, Unit: [km^3] diffuse_gw_recharge : float Daily difuuse groundwater recharge, Unit: [km^3/day] potential_net_abstraction_gw : float Potential net abstraction from groundwater, Unit: [km^3/day] daily_unsatisfied_pot_nas : float Daily unsatisfied water use, Unit: [km^3/day] gw_dis_coeff : float Groundwater discharge coefficient (=0.01),Eqn 21 Müller Schmied et al. (2021), Unit: [1/day] prev_potential_water_withdrawal_sw_irri : float Previous potential water withdrawal from surface water for irrigation, Unit: [km^3/day] prev_potential_consumptive_use_sw_irri: float Previous potential consumptive use from irrigation using surface water, Unit: [km^3/day] point_source_recharge : float Sum of all point groundwater recharge from surface waterboides in arid regions, Unit: [km^3/day] Returns ------- groundwater_storage : float Updated daily groundwater storage, Unit: [km^3] groundwater_discharge : float Updated daily groundwater discharge, Unit: [km^3/day] actual_net_abstraction_gw: float Actual Net abstraction from groundwater, Unit: [km^3/day] """ # Index (x, y) to print out varibales of interest # e.g. if x==65 and y==137: print(prev_gw_storage) # ====================================== # || groundwaterwater balance || # ====================================== # Note components of the waterbalance in Equation 20 of Müller Schmied et # al. (2021) is calulated as follows. prev_gw_storage = groundwater_storage # ========================================================================= # Computing net groundwater recharge (netgw_in [km3]) which is defined as # diffuse recharge + point source recharge - net abstraction. # ========================================================================= # Point_source_recharge is only computed for (semi)arid surafce water # bodies but not for inlank sink or humid regions if aridity_or_inlandsink == "humid" or \ aridity_or_inlandsink == "inland sink": point_source_recharge = 0 netgw_in = diffuse_gw_recharge + point_source_recharge # Update net abstraction from groundwater if there is unsatisfied water use # from previous time step. actual_net_abstraction_gw = \ np.where(daily_unsatisfied_pot_nas != 0, gw_adapt_netabstr. update_netabs_gw(potential_net_abstraction_gw, prev_potential_water_withdrawal_sw_irri, prev_potential_consumptive_use_sw_irri, daily_unsatisfied_pot_nas, frac_irri_returnflow_to_gw, x, y), potential_net_abstraction_gw) # Updating net groundwater recharge (netgw_in [km3]) netgw_in = netgw_in - actual_net_abstraction_gw # ========================================================================= # Computing daily groundwater storage (km3) and discharge(km3/day) # ========================================================================= # Groundwater balance dS/dt = netgw_in - NAg - k*S is solved analytically # for each time step of 1 day to prevent numerical inaccuracies. # See in Equation 20 of Müller Schmied et al. (2021) current_gw_storage = prev_gw_storage * np.exp(-1 * gw_dis_coeff) +\ (netgw_in/gw_dis_coeff)*(1-np.exp(-1 * gw_dis_coeff)) groundwater_discharge = prev_gw_storage - current_gw_storage + netgw_in # Recalculate groundwater storage when groundwater discharge=0 # dS/dt = netgw_in - NAg (without k*S) -> S(t) = S(t-1) + netgw_in current_gw_storage = np.where(groundwater_discharge <= 0, prev_gw_storage + netgw_in, current_gw_storage) groundwater_discharge = np.where(groundwater_discharge <= 0, 0, groundwater_discharge) return current_gw_storage, groundwater_discharge, actual_net_abstraction_gw