Exemplo 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
Exemplo 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
Exemplo 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
Exemplo 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.
    """
    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
    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[0, 0, -1] = 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 = fdm.fdm3(gr, K, FQ, IH, IBOUND)  # run model

    numerical = out.Phi[0, :, -1]
    analytic = de_glee(Q, kD, c, r0, gr.xm)

    #==============================================================================
    #     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, numerical, 'ro-', label='fdm3')
    #     plt.plot(gr.xm, analytic , 'bx-',label='analytic')
    #     plt.legend()
    #
    #==============================================================================
    return numerical, analytic, out
Exemplo 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
Exemplo 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
Exemplo 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
Exemplo n.º 8
0
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()

# visualize
title = 'Cross section Axial={0}, Q={1} {2}'.format(
    axial, Q, 'm3/d' if axial else 'm2/d')
ax = plt.figure().add_subplot(111)
xlim = gr.x[[0, -1]]
ax.set(xlabel='x [m]', ylabel=['z [m]'], title=title, xlim=xlim)

ax.contour(gr.xm, gr.zm, Out.Phi[0].T, 30)
ax.contour(gr.xp, gr.zp, Psi, 30)
#plt.show()