borehole

borehole.borehole(H, persis_info, sim_specs, _)

Wraps the borehole function

borehole.borehole_func(x)

This evaluates the Borehole function for n-by-8 input matrix x, and returns the flow rate through the Borehole. (Harper and Gupta, 1983) input:

Parameters:

x (numpy.typing.NDArray) –

x[:,0]: Tu, transmissivity of upper aquifer (m^2/year)
x[:,1]: Tl, transmissivity of lower aquifer (m^2/year)
x[:,2]: Hu, potentiometric head of upper aquifer (m)
x[:,3]: Hl, potentiometric head of lower aquifer (m)
x[:,4]: r, radius of influence (m)
x[:,5]: rw, radius of borehole (m)
x[:,6]: Kw, hydraulic conductivity of borehole (m/year)
x[:,7]: L, length of borehole (m)

Returns:

f – vector of dimension (n, 1): flow rate through the Borehole (m^3/year)

Return type:

numpy.ndarray

borehole.gen_borehole_input(n)

Generates and returns n inputs for the Borehole function, according to distributions outlined in Harper and Gupta (1983).

input:

n: number of input to generate

output:

matrix of (n, 8), input to borehole_func(x) function

borehole.py
 1import numpy as np
 2import numpy.typing as npt
 3
 4bounds = np.array(
 5    [
 6        [63070, 115600],
 7        [63.1, 116],
 8        [990, 1110],
 9        [700, 820],
10        [0, np.inf],  # Not sure if the physics have a more meaningful upper bound
11        [0.05, 0.15],  # Very low probability of being outside of this range
12        [9855, 12045],
13        [1120, 1680],
14    ]
15)
16
17
18def borehole(H, persis_info, sim_specs, _):
19    """
20    Wraps the borehole function
21    """
22    H_o = np.zeros(H["x"].shape[0], dtype=sim_specs["out"])
23    H_o["f"] = borehole_func(H["x"])
24
25    return H_o, persis_info
26
27
28def borehole_func(x: npt.NDArray):
29    """This evaluates the Borehole function for n-by-8 input
30    matrix x, and returns the flow rate through the Borehole. (Harper and Gupta, 1983)
31    input:
32
33    Parameters
34    ----------
35
36    x: numpy.typing.NDArray
37
38        .. code-block::
39
40        x[:,0]: Tu, transmissivity of upper aquifer (m^2/year)
41        x[:,1]: Tl, transmissivity of lower aquifer (m^2/year)
42        x[:,2]: Hu, potentiometric head of upper aquifer (m)
43        x[:,3]: Hl, potentiometric head of lower aquifer (m)
44        x[:,4]: r, radius of influence (m)
45        x[:,5]: rw, radius of borehole (m)
46        x[:,6]: Kw, hydraulic conductivity of borehole (m/year)
47        x[:,7]: L, length of borehole (m)
48
49    Returns
50    -------
51
52    f: numpy.ndarray
53        vector of dimension (n, 1): flow rate through the Borehole (m^3/year)
54
55    """
56
57    assert np.all(x >= bounds[:, 0]) and np.all(x <= bounds[:, 1]), "Point not within bounds"
58
59    axis = 1
60    if x.ndim == 1:
61        axis = 0
62
63    (Tu, Tl, Hu, Hl, r, rw, Kw, L) = np.split(x, 8, axis)
64
65    numer = 2 * np.pi * Tu * (Hu - Hl)
66    denom1 = 2 * L * Tu / (np.log(r / rw) * rw**2 * Kw)
67    denom2 = Tu / Tl
68
69    return ((numer / (np.log(r / rw) * (1 + denom1 + denom2))).reshape(-1))[0]
70
71
72def gen_borehole_input(n):
73    """Generates and returns n inputs for the Borehole function, according to distributions
74    outlined in Harper and Gupta (1983).
75
76    input:
77      n: number of input to generate
78    output:
79      matrix of (n, 8), input to borehole_func(x) function
80    """
81
82    Tu = np.random.uniform(63070, 115600, n)
83    Tl = np.random.uniform(63.1, 116, n)
84    Hu = np.random.uniform(990, 1110, n)
85    Hl = np.random.uniform(700, 820, n)
86    r = np.random.lognormal(7.71, 1.0056, n)
87    rw = np.random.normal(0.1, 0.0161812, n)
88    Kw = np.random.uniform(9855, 12045, n)
89    L = np.random.uniform(1120, 1680, n)
90
91    x = np.column_stack((Tu, Tl, Hu, Hl, r, rw, Kw, L))
92    return x