Ejemplo n.º 1
0
def setup_and_run_fdm(gridpar, k, rch, axis=1):

    Lx, wx, Ly, wy, D, d = gridpar

    x = np.linspace(-Lx, Lx, int(2 * Lx / wx) + 1)
    y = np.linspace(-Ly, Ly, int(2 * Ly / wy) + 1)
    z = np.linspace(-D, D, int(2 * D / d) + 1)
    gr = mfgrid.Grid(x, y, z)

    K = gr.const(k)
    FH = gr.const(0.)
    FQ = gr.Volume * rch

    IBOUND = gr.const(1)

    if axis == 0:
        IBOUND[[0, -1], :, :] = -1
    elif axis == 1:
        IBOUND[:, [0, -1], :] = -1
    elif axis == 2:
        IBOUND[:, :, [0, -1]] = -1
    else:
        print("axis must be 0, 1, or 2, not {}".format(axis))

    # Solve for the heads:
    Out = fdm.fdm3(gr, (K, K, K), FQ, FH, IBOUND)

    return Out, gr, IBOUND
Ejemplo n.º 2
0
def setup_and_run_fdm(gridpar, k, Q):

    Lx, wx, Ly, wy, D, d = gridpar

    x = np.linspace(-Lx, Lx, int(2 * Lx / wx) + 1)
    y = np.linspace(-Ly, Ly, int(2 * Ly / wy) + 1)
    z = np.linspace(-D, D, int(2 * D / d) + 1)
    gr = mfgrid.Grid(x, y, z)

    K = gr.const(k)  # * np.random.rand(gr.Nod).reshape(gr.shape)
    FH = gr.const(0.)
    FQ = gr.const(0.)

    IBOUND = gr.const(1)
    IBOUND[[0, -1], :, :] = -1
    IBOUND[:, [0, -1], :] = -1
    IBOUND[:, :, [0, -1]] = -1

    icx, icy, icz = gr.ixyz(0., 0., 0.)

    FQ[icy, icx, icz] = Q

    # Solve for the heads:
    Out = fdm.fdm3(gr, (K, K, K), FQ, FH, IBOUND)

    return Out, gr, IBOUND
Ejemplo n.º 3
0
def set_up_and_run_fdm(gridpar, k, hbound, axis=None):

    Lx, wx, Ly, wy, D, d = gridpar

    x = np.linspace(-Lx, Lx, int(2 * Lx / wx) + 1)
    y = np.linspace(-Ly, Ly, int(2 * Ly / wy) + 1)
    z = np.linspace(-D , D,  int(2 *  D /  d) + 1)
    gr = mfgrid.Grid(x, y, z)

    K = gr.const(k) # * np.random.rand(gr.Nod).reshape(gr.shape)
    FH = gr.const(0.)
    FQ = gr.const(0.)

    IBOUND = gr.const(1)

    if axis == 0:
        IBOUND[[0, -1], :, :] = -1
        FH[0, :, :] = hbound[0]
        FH[-1, :,:] = hbound[1]
    elif axis == 1:
        IBOUND[:,[0, -1], :] = -1
        FH[:,  0, :] = hbound[0]
        FH[:, -1, :] = hbound[1]
    elif axis == 2:
        IBOUND[:, :, [0, -1]] = -1
        FH[:, :,  0] = hbound[0]
        FH[:, :, -1] = hbound[1]
    else:
        print("axis must be 0, 1, or to, not {}".format(axis))
        raise ValueError()

    # Solve for the heads:
    Out = fdm.fdm3(gr, (K, K, K), FQ, FH, IBOUND)

    return Out, gr, IBOUND
Ejemplo n.º 4
0
def example_De_Glee():
    """Axial symmetric example, well in semi-confined aquifer (De Glee case)
    De Glee was a Dutch engineer/groundwater hydrologist and later the
    first director of the water company of the province of Groningen.
    His PhD (1930) solved the axial symmetric steady state flow to a well
    in a semi confined aquifer using the Besselfunctions of the second kind,
    known as K0 and K1.
    The example computes the heads in the regional aquifer below a semi confining
    layer with a fixed head above. It uses two model layers a confining one in
    which the heads are fixed and a semi-confined aquifer with a prescribed
    extraction at r=r0. If r0>>0, both K0 and K1 Bessel functions are needed.
    The grid is signaled to use inteprete the grid as axially symmetric.
    """
    K0 = lambda x: scipy.special.kn(0, x
                                    )  # Bessel function second kind, order 0
    K1 = lambda x: scipy.special.kn(1, x
                                    )  # Bessel function second kind, order 1
    Q = -1200.0  # m3/d, well extraction
    r0 = 100.  # m, well radius
    R = 2500.  # m, outer radius of model
    d = 10.  # m, thickness of confining top layer
    D = 50.  # m, thickness of regional aquifer
    c = 250  # d, vertical resistance of confining top layer
    k1 = d / c  # m/d conductivity of confining top layer
    k2 = 10.  # m/d conductivity of regional aquifer
    kD = k2 * D  # m2/d, transmissivity of regional aquifer
    lam = np.sqrt(kD * c)  # spreading length of regional aquifer
    r = np.hstack((r0 + 0.001, np.logspace(np.log10(r0), np.log10(R),
                                           41)))  # distance to well center
    y = None  # dummy, ignored because problem is axially symmetric
    z = np.array([0, -d,
                  -d - D])  # m, elevation of tops and bottoms of model layers
    gr = mfgrid.Grid(r, y, z, axial=True)  # generate grid
    FQ = gr.const(0.)
    FQ[-1, 0, 0] = Q  # m3/d fixed flows
    IH = gr.const(0.)  # m, initial heads
    IBOUND = gr.const(1)
    IBOUND[0, :, :] = -1  # modflow like boundary array
    K = gr.const([k1 / 2., k2])  # full 3D array of conductivities
    Out = fdm3(gr, K, FQ, IH, IBOUND)  # run model
    plt.figure()
    plt.setp(plt.gca(), 'xlabel', 'r [m]', 'ylabel', 'head [m]',\
             'title', 'De Glee, well extraction, axially symmetric', 'xscale', 'log', 'xlim', [1.0, R])
    plt.plot(gr.xm, Out.Phi[-1, 0, :], 'ro-', label='fdm3')
    plt.plot(gr.x,
             Q / (2 * np.pi * kD) * K0(gr.x / lam) / (r0 / lam * K1(r0 / lam)),
             'bx-',
             label='analytic')
    plt.legend()
Ejemplo n.º 5
0
def set_up_and_run_fdm(gridpar, k, Q, well_axis):

    Lx, wx, Ly, wy, D, d = gridpar

    x = np.linspace(-Lx, Lx, int(2 * Lx / wx) + 1)
    y = np.linspace(-Ly, Ly, int(2 * Ly / wy) + 1)
    z = np.linspace(-D , D,  int(2 *  D /  d) + 1)
    gr = mfgrid.Grid(x, y, z)

    K = gr.const(k) # * np.random.rand(gr.Nod).reshape(gr.shape)
    FH = gr.const(0.)
    FQ = gr.const(0.)

    # Cell indices of center of model: hard wired here
    x0, y0, z0 = 0., 0., 0.
    icx, icy, icz = gr.ixyz(x0, y0, z0)
     # Covner to int to prevent shape errors with FQ below
    icx = int(icx); icy=int(icy); icz=int(icz)

    if well_axis == 2: # i.e. z
        # screen in z direction, flow in xy plane
        IBOUND = gr.const(1)
        IBOUND[[0,-1], :, :] = -1
        IBOUND[:, [0,-1], :] = -1
        FQ[icy, icx, :] = Q * gr.dz / np.sum(gr.dz)
    elif well_axis == 0:  # i.e. y
        # screen in x direction, flow in zx plane
        IBOUND = gr.const(1)
        IBOUND[:, [0,-1], :] = -1
        IBOUND[:, :, [0,-1]] = -1
        FQ[:, icx, icz] = Q * gr.dy / np.sum(gr.dy)
    elif well_axis == 1: # i.e. x
        # screen in y direction, flow in yz plane
        IBOUND = gr.const(1)
        IBOUND[[0,-1], :, :] = -1
        IBOUND[:, :, [0,-1]] = -1
        FQ[icy, :, icz] = Q * gr.dx / np.sum(gr.dx)
    else:
        print("well_axis must be 0, 1, or 2, not {}".format(well_axis))

    # Solve for the heads:
    Out = fdm.fdm3(gr, (K, K, K), FQ, FH, IBOUND)

    return Out, gr, IBOUND
Ejemplo n.º 6
0
def example_mazure():
    """1D flow in semi-confined aquifer example
    Mazure was Dutch professor in the 1930s, concerned with leakage from
    polders that were pumped dry. His situation is a cross section perpendicular
    to the dike of a regional aquifer covered by a semi-confining layer with
    a maintained head in it. The head in the regional aquifer at the dike was
    given as well. The head obeys the following analytical expression
    phi(x) - hp = (phi(0)-hp) * exp(-x/lam), lam = sqrt(kDc)
    To compute we use 2 model layers and define the values such that we obtain
    the Mazure result.
    """
    x = np.hstack((0.001, np.linspace(0., 2000., 101)))  # column coordinates
    y = np.array([-0.5, 0.5])  # m, model is 1 m thick
    d = 10.  # m, thickness of confining top layer
    D = 50.  # m, thickness of regional aquifer
    z = np.array([0, -d, -d - D])  # tops and bottoms of layers
    gr = mfgrid.Grid(x, y, z, axial=False)
    c = 250  # d, vertical resistance of semi-confining layer
    k1 = d / c  # m/d conductivity of the top layer
    k2 = 10.  # m/d conductivity of the regional aquifer
    kD = k2 * D  # m2/d, transmissivity of regional aquifer
    K = gr.const([k1 / 2.,
                  k2])  # k1 = 0.5 d/c because conductance from layer center
    FQ = gr.const(0)  # prescribed flows
    s0 = 2.0  # head in aquifer at x=0
    IH = gr.const(0)
    IH[:, 0, -1] = s0  # prescribed heads
    IBOUND = gr.const(1)
    IBOUND[:, :, 0] = -1
    IBOUND[:, 0, -1] = -1
    out = fdm.fdm3(gr, K, FQ, IH, IBOUND)  # compute heads, run model

    numerical = out.Phi[0, :, -1]
    analytic = vanMarzure(s0, kD, c, gr.xm)

    #==============================================================================
    #     plt.figure()
    #     plt.setp(plt.gca(), 'xlabel','x [m]', 'ylabel', 'head [m]', 'title', 'Mazure 1D flow')
    #     plt.plot(gr.xm, numerical, 'ro-', label='fdm3') # numeric solution
    #     plt.plot(gr.xm, analytic  ,'bx-', label='analytic') # analytic solution
    #     plt.legend()
    #
    #==============================================================================
    return numerical, analytic, out
Ejemplo n.º 7
0
def setupAndRunFDM_model(gridpar, k, hbound):

    Lx, wx, Ly, wy, D, d = gridpar
    hW, hE, hN, hS, hT, hB = hbound

    x = np.linspace(-Lx, Lx, int(2 * Lx / wx) + 1)
    y = np.linspace(-Ly, Ly, int(2 * Ly / wy) + 1)
    z = np.linspace(0, -D, int(D / d) + 1)
    gr = mfgrid.Grid(x, y, z)

    K = gr.const(k)  # * np.random.rand(gr.Nod).reshape(gr.shape)
    FH = gr.const(0.)
    FQ = gr.const(0.)

    IBOUND = gr.const(1)

    if not (hW is None):
        IBOUND[:, 0, :] = -1
        FH[:, 0, :] = hW
    if not hE is None:
        IBOUND[:, -1, :] = -1
        FH[:, -1, :] = hE
    if not hN is None:
        IBOUND[0, :, :] = -1
        FH[0, :, :] = hN
    if not hS is None:
        IBOUND[-1, :, :] = -1
        FH[-1, :, :] = hS
    if not hT is None:
        IBOUND[:, :, 0] = -1
        FH[:, :, 0] = hT
    if not hB is None:
        IBOUND[:, :, -1] = -1
        FH[:, :, -1] = hB

    # Solve for the heads:
    Out = fdm.fdm3(gr, (K, K, K), FQ, FH, IBOUND)

    return Out, gr, IBOUND
Ejemplo n.º 8
0
def normGrid(gr):
    up = np.arange(0., gr.Nx + 1)
    vp = np.arange(0., gr.Ny + 1)
    wp = np.arange(0., gr.Nz + 1)
    return mfgrid.Grid(up, vp, wp)
Ejemplo n.º 9
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 14 18:03:45 2016

@author: Theo
"""

#from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
import mfgrid

fig = plt.figure()
ax1 = fig.add_subplot(111, projection='3d')

Np = 11
x = np.arange(Np, dtype=float)
y = np.arange(Np, dtype=float)
z = np.arange(Np, dtype=float)

gr = mfgrid.Grid(x, y, z)

gr.plot_grid3d('gbr', alpha=0.5)

plt.show()
Ejemplo n.º 10
0
    def setUp(self):
        global gr, grn, tol, xTest, yTest,\
            xp, yp, zp, xpm, ypm, zpm,\
            up, vp, wp, upm, vpm, wpm,\
            U, iu, V, iv, W, iw, mustSkip

        mustSkip = False
        tol = 1e-5
        digits = int(abs(np.log10(tol)))

        x = np.array(
            [0, 6, 3.000001, -2, -1e-6, 3e-6, 4.00001, 7, 8, 11, -3, -4])
        y = x[:]

        xTest = np.unique(np.round(x, digits))
        yTest = xTest[::-1]

        Nx = len(np.unique(np.round(np.array(x), digits))) - 1
        Ny = len(np.unique(np.round(np.array(y), digits))) - 1

        # Generate a full fledged Z array with different Z in ever iy,ix
        # combination
        z = np.arange(5) * -10
        Z = np.ones((Ny, Nx, 1)) * z.reshape((1, 1, len(z)))
        Z = Z * (np.random.rand(len(z)) + 0.5).reshape((1, 1, len(z)))

        min_dz = 0.1
        gr = mfgrid.Grid(x, y, Z, min_dz=min_dz, tol=tol)

        Nz = gr.Nz

        grn = gr.norm_grid()

        Lam = lambda a, b: np.hstack((np.array(a), np.array(b)))
        """
        # Generate trial points that include all special cases like
        # points outside the model, points at grid lines and points
        # at the boundary edges of the model, next to ordinary
        # points falling within model cells.
        """

        # outside and inside the model
        up = np.array([])
        vp = np.array([])
        wp = np.array([])

        up = Lam(up, -0.5 + np.array([0., 1., 0., 0., 1., 1., 0., 1.]))
        vp = Lam(vp, -0.5 + np.array([0., 0., 1., 0., 1., 0., 1., 1.]))
        wp = Lam(wp, -0.5 + np.array([0., 0., 0., 1., 0., 1., 1., 1.]))

        up = Lam(up, Nx - 0.5 + np.array([0., 1., 0., 0., 1., 1., 0., 1.]))
        vp = Lam(vp, Ny - 0.5 + np.array([0., 0., 1., 0., 1., 0., 1., 1.]))
        wp = Lam(wp, Nz - 0.5 + np.array([0., 0., 0., 1., 0., 1., 1., 1.]))

        # points on grid lines, including all corner cases
        up = Lam(up, [0., 1., 0., 0., 1., 1., 0., 1.])
        vp = Lam(vp, [0., 0., 1., 0., 1., 0., 1., 1.])
        wp = Lam(wp, [0., 0., 0., 1., 0., 1., 1., 1.])

        up = Lam(up, Nx - np.array([0., 1., 0., 0., 1., 1., 0., 1.]))
        vp = Lam(vp, Ny - np.array([0., 0., 1., 0., 1., 0., 1., 1.]))
        wp = Lam(wp, Nz - np.array([0., 0., 0., 1., 0., 1., 1., 1.]))

        # not at grid lines, i.e. ordinary points
        up = Lam(up,
                 np.pi / 10. * Nx + np.array([0., 1., 0., 0., 1., 1., 0., 1.]))
        vp = Lam(vp,
                 np.pi / 10. * Ny + np.array([0., 0., 1., 0., 1., 0., 1., 1.]))
        wp = Lam(wp,
                 np.pi / 10. * Nz + np.array([0., 0., 0., 1., 0., 1., 1., 1.]))

        # convert these ponts to grid coordinates
        xp, yp, zp = gr.uvw2xyz(up, vp, wp)
        # verify by showing the location of these points in the two grids

        U, iu = gr.U(xp)
        V, iv = gr.V(yp)
        W, iw = gr.W(xp, yp, zp)
        up = gr.up(xp)
        vp = gr.vp(yp)
        wp = gr.wp(xp, yp, zp)
Ejemplo n.º 11
0
import numpy as np
import matplotlib.pylab as plt
import mfgrid
import fdm
import mfpath
import pdb

axial = False
Q = -2400 if axial else -240.  # m3/d if axial else m2/
por = 0.35  # [-], effective porosity

xGr = np.logspace(-1, 4, 51)
xGr = np.linspace(0, 2000, 101)
yGr = np.array([-0.5, 0.5])
zGr = np.array([0., -5, -50, -60, -100])
gr = mfgrid.Grid(xGr, yGr, zGr, axial)

IBOUND = gr.const(1)
IBOUND[:, :, 0] = -1  # head in top confining unit fixed
k = gr.const(np.array([0.01, 10., 0.01, 20.]))
FH = gr.const(0.)
FQ = gr.const(0.)
FQ[0, 0, 1] = Q  # insecond layer

# run flow model
Out = fdm.fdm3(gr, (k, k, k), FQ, FH, IBOUND)

Psi = fdm.psi(Out.Qx)

#pdb.set_trace()