Test Theis Storage#

import numpy as np
from scipy.integrate import quad, solve_ivp
from scipy.special import exp1
Q = -100
npor = 0.3
k = 10
H = 10
T = k * H
Ss = 1e-4
S = Ss * H
def headtheis(r, t, T=T, S=S, Q=Q):
    u = r**2 * S / (4 * T * t)
    h = -Q / (4 * np.pi * T) * exp1(u)
    return h


def voltheis(r, t, T, S, Q):
    u = r**2 * S / (4 * T * t)
    h = -Q / (4 * np.pi * T) * exp1(u)
    vol = h * 2 * np.pi * r
    return vol * S
# demonstrate headtheis works correctly
quad(voltheis, a=1e-3, b=10000, args=(10, T, S, Q))  # gives 1000 m^3
(999.9999999944237, 1.4198832332112943e-06)
def volume(r, t, T=T, S=S, Q=Q):
    return quad(voltheis, a=1e-3, b=r, args=(10, T, S, Q))[0] + npor * np.pi * (r**2)
def vxytheis(t, xy):
    x, y = xy
    r = np.sqrt(x**2 + y**2)
    u = S * r**2 / (4 * T * t)
    Qr = -Q / (2 * np.pi) / r * np.exp(-u)
    vr = Qr / (H * npor)
    vx = vr * x / r
    vy = vr * y / r
    return np.array([vx, vy])
def vxytheisnew(t, xy):
    x, y = xy
    r = np.sqrt(x**2 + y**2)
    u = S * r**2 / (4 * T * t)
    Qr = -Q / (2 * np.pi) / r * np.exp(-u)
    vr = Qr / (H * (npor + S * headtheis(x, t)))
    vx = vr * x / r
    vy = vr * y / r
    return np.array([vx, vy])
# trace pathline for 10 days
path0 = solve_ivp(vxytheis, (1e-5, 10), y0=[1e-5, 0], method="DOP853")
R0 = path0.y[0, -1]
R0, np.pi * R0**2 * npor * H
(np.float64(10.300504380350029), np.float64(999.9726219155026))
path0 = solve_ivp(vxytheisnew, (1e-5, 10), y0=[1e-5, 0], method="DOP853")
R1 = path0.y[0, -1]
R1, np.pi * R1**2 * npor * H
(np.float64(10.28692090332354), np.float64(997.3369938953236))
headtheis(5, 10) * S
np.float64(0.0009076383332409223)
npor * H
3.0
R = path0.y[0, -1]
print("R, volume", R, np.pi * R**2 * npor * H)
R, volume 10.28692090332354 997.3369938953236
from scipy.integrate import quad

quad(headtheis, 1e-5, R, args=(100, T, S, Q))[0] + np.pi * R**2 * npor * H
np.float64(1009.0147425061984)
t0 = 0
t1 = 10


def vxytheis2(t, xy):
    x, y = xy
    r = np.sqrt(x**2 + y**2)
    u1 = S * r**2 / (4 * T * (t - t0))
    u2 = S * r**2 / (4 * T * (t - t1))
    Qr = -Q / (2 * np.pi) / r * np.exp(-u1)
    if t >= t1:
        Qr += 2 * Q / (2 * np.pi) / r * np.exp(-u2)
    vr = Qr / (H * npor)
    vx = vr * x / r
    vy = vr * y / r
    return np.array([vx, vy])
path1 = solve_ivp(vxytheis2, (10 + 1e-6, 20), y0=[R, 0], method="DOP853")
path1.y[0, -1]
np.float64(0.23642465667946888)
path1
  message: The solver successfully reached the end of the integration interval.
  success: True
   status: 0
        t: [ 1.000e+01  1.027e+01  1.060e+01  1.268e+01  1.700e+01
             1.878e+01  1.951e+01  1.981e+01  1.994e+01  1.999e+01
             2.000e+01]
        y: [[ 1.029e+01  1.016e+01 ...  4.482e-01  2.364e-01]
            [ 0.000e+00  0.000e+00 ...  0.000e+00  0.000e+00]]
      sol: None
 t_events: None
 y_events: None
     nfev: 194
     njev: 0
      nlu: 0
vxytheis2(12 + 1e-6, (10, 0))
array([-0.53039491, -0.        ])