Пример #1
0
def simulate(case):
    """
    Radial flow by well injection into or extracting from the central cell
    of the model.
    The model is cubic, with cubic cells and the number of cells are teh same
    in each direction.
    All walls of the cubic model obtain prescribed head equal to zero.

    The finite difference model is run to get the flows across the cell faces.
    Together with the effecive porosity (and an implicit retardation of 1),
    the particles are tracked.

    The particles are initially on a sphere with given radius.
    Their track should be radial and there location expressed in
    terms of distance form the center of the model is easily verified
    by the analytically computed distance as a function of the times given.

    The two cases use the same flow but with opposite signs.
    The starting radius of the second case is equal to the analytically
    computed end radius of the first case and vice versa, to ease comparison
    of the analytical with the numerical solutions.

    @ TO161116
    """
    # Parameters to set up a grid for the model
    #          Lx    wx     Ly     wy    D     d
    gridpar = (1050., 100., 1050., 100., 1050., 100.)

    crit = 0.05
    k = 10.
    peff = 0.35

    T = np.linspace(0., 720., 21)

    Q = [0.5e6, -0.5e6]  # two cases

    # run fdm model
    out, gr, IBOUND = setup_and_run_fdm(gridpar, k, Q[case])

    #### Particle tracking

    r = [
        217.,  # with Q = -0.5e6 rechage in 720 d from r1
        634.
    ]  # with Q =  0.5e6 reached in 720 d from r0

    # The x,y and z ditributd regularly over a sphere of given radius
    xyz = xyz_radial(r[case])

    Peff = gr.const(0.35)

    pcl = mfpath.particle_tracker(gr, out, Peff, T, xyz)
    #mfpath.visualize(gr, pcl, ugrid=False, phi=out.Phi[:,:,0])
    #mfpath.visualize(gr, pcl, ugrid=True)

    R_sim = np.sqrt(pcl.x**2 + pcl.y**2 + pcl.z**2)
    R_analytic = rad(r[case], Q[case], T, peff)

    return np.mean(R_sim, axis=0), R_analytic, crit, pcl, out
Пример #2
0
def simulate(case):
    """
    Test example:
        Tesing particle tracking with varable velocity but only in one
        direction. Like it is the case for a fully penetrating well in a
        confined aquifer.
        We take a cubic model with cubic cells and install a linear
        screen in its center like pencel, fully penetrating.
        The heads on the opposite sites are kept constant at zero.
        The flow should be axial and can be computed analytically.
        Constant velocity between opposite cell faces in x, y and z

        There are 3 directions to compare both for an infiltrating and
        an exfiltrating well.

        @ TO161115
    """

        # Parameters to set up a grid for the model
    #          Lx    wx     Ly     wy    D     d
    gridpar= (1050., 100., 1050., 100., 1050., 100.) # odd number of cells

    crit = 0.05
    Np = 25
    k = 10.
    peff = 0.35
    T = np.arange(0., 750., 30)

    # the six test cases:
    Q = 1.5e6 * np.array([1, -1, 1, -1, 1, -1], dtype=float)
    well_axis =          [2,  2, 0,  0, 1,  1]

    # run fdm model
    out, gr, IBOUND = set_up_and_run_fdm(gridpar, k, Q[case], well_axis[case])

    Peff = gr.const(0.35)

    # initial distance for each case
    # starting at 200 will bring the particles at 726 after 750 days if Q>0
    # starting at 726 will bring the particles at 200 after 750 days if Q<0
    r = [200, 726, 200, 726, 200, 726] # initial distances

    # The x,y and z of the particles are computed vorm u, v and w norm.coords.
    xyz = xyz_points(r[case], Np, well_axis[case])

    # Track particles
    pcl = mfpath.particle_tracker(gr, out, Peff, T, xyz)
    #mfpath.visualize(gr, pcl, ugrid=False, phi=out.Phi[:,:,0])
    #mfpath.visualize(gr, pcl, ugrid=True)

    if well_axis[case] == 2:  # i.e. z
        R_sim =  np.sqrt(pcl.x**2 + pcl.y**2)
        H = sum(gr.dz)
Пример #3
0
def simulate(case):
    """
    Simulates particle tracking with variable velocity.

    The particles move parelle to each of the axes in turn.
    The variable velocity is obtained by means of recharge.

    The model has cobic shape and so has all its cells. It is symmetric
    in all three axis directions.

    The recharge is divided uniformly over all cells of the model

    The flow along one axis is created by setting the head fixed at two
    of the opposite model faces in turn.

    Flow inward and outward is created by using positive and negative
    specific recharge.

    The displacement results are compared with the analytical solution.

    @ TO161115
    """

    global t_hand, t_sim

    print("I'm Testing the code.")
    print("Setting up the test.")

    Np = 25
    crit = 0.05

    # Parameters to set up a grid for the model
    #          Lx    wx     Ly     wy    D     d
    gridpar = (1050., 100., 1050., 100., 1050., 100.)  # odd number of cells

    k = 10.
    peff = 0.35

    T = np.arange(0., 750., 30.)

    rch = 0.0005  # [1/d] specific rechare i.e recharge/aqufier thickness
    spec_rech = np.array([0, -1, 0, -1, 0, -1
                          ]) * rch  # spec. recharge for all 6 cases
    axis = [0, 0, 1, 1, 2, 2]  # for each case

    # run fdm model
    out, gr, IBOUND = setup_and_run_fdm(gridpar,
                                        k,
                                        spec_rech[case],
                                        axis=axis[case])

    #### particle tracking
    Peff = gr.const(0.35)

    s1 = 200.  # with this rch particles starting at 200 m end at 723 m after 720d
    s2 = 720.  # with this rch particles starting at 723 m end at 200 m after 720 d
    s0 = [s1, s2, s1, s2, s1, s2]  # for each case

    xyz = get_particles(gr, Np, s0[case], axis=axis[case])

    pcl = mfpath.particle_tracker(gr, out, Peff, T, xyz)
    #mfpath.visualize(gr, pcl, ugrid=False, phi=out.Phi[:,:,0])
    #mfpath.visualize(gr, pcl, ugrid=True)

    print('Finished')
    #
    # expected distances, sa is the analytically computed particle position
    sa = analytic_travel_pos(spec_rech[case], T, s0[case], peff)

    # sn is the simulated particle position along the axis of the flow
    if axis[case] == 0:
        sn = pcl.y
Пример #4
0
def simulate(case):
    """
    Test example:
        Constant velocity between opposite cell faces in x, y and z
        directions.
        Altnernatively the fixed heads are set at two opposite planes, one
        direction at a time. Once to let the flow be along the positive axis
        direction, once to let the flow be in the opposite direction.
        To make sure that the particle velocities are constant, we start
        them at the second cell face. The particles are automatically captured
        when the reach the last-but-one cell face at the opposite side of the
        grid.
        Hence, we have 6 cases that are captured by the hound array, which
        specifies the heads in all outer planes for each case, where None means
        that no head is prescribed.

        With the boundary heads and the correcponding IBOUND set, the heads
        and the flows are computed by fdm.fdm3.

        With thes flows, the particles are tracked in each of the cases.

        The results are collected and comapared with the hand-calculated
        travel time for each case.

        While the staring position of the particles in the researched direction
        is set as described above, the positions in the other directions are
        chosen randomly within that plane. All these particles should have the
        the same travel time.

        We make the grid a pure cube, so that both times and positions can eas-
        ily be compared betweeen the directions. The must all match exactly.

        @ TO161115
    """

    global t_hand, t_sim

    print("I'm Testing the code.")
    print("Setting up the test.")

    crit = 0.01
    Np = 25

        # Parameters to set up a grid for the model
    #          Lx    wx     Ly     wy    D     d
    gridpar= (1050., 100., 1050., 100., 1050., 100.)

    k = 10.
    peff = 0.35
    T = np.arange(0., 16000., 2000.)

    #  FH  @   N     S    W   E    T     B
    hbound= np.array([[ 9, 0],
                      [ 0, 9],
                      [ 0, 9],
                      [ 9, 0],
                      [ 0, 9],
                      [ 9, 0]], dtype=float)

    flow_axis = [1, 1, 0, 0, 2, 2]
        # run fdm model
    out, gr, IBOUND = set_up_and_run_fdm(gridpar, k, hbound[case], axis=flow_axis[case])

    Peff = gr.const(0.35)

    # The x,y and z of the particles are computed vorm u, v and w norm.coords.

    # starting at -900 will bring particles to +900 in 14000 d when dh = -9 m
    # sarting  at +900 will bring particles to -900 in 14000 d when dh = +9 m
    s0 = 900 * np.array([-1, 1, -1, 1, -1, 1], dtype=float)

    xyz = get_points(gr, Np, s0[case], flow_axis[case])

    # Track particles
    pcl = mfpath.particle_tracker(gr, out, Peff, T, xyz)
    #mfpath.visualize(gr, pcl, ugrid=False, phi=out.Phi[:,:,0])
    #mfpath.visualize(gr, pcl, ugrid=True)

    print('Finished')
    #

    # sa is the analytically computed position at all t
    # sn is the numerically computed position at all t
    if case == 0:
        L = np.abs(np.diff(gr.xm[[0,-1]]))
        sa = pos(s0[case], np.diff(hbound[case]), L, k, peff, T)
        sn = pcl.x
    elif case == 1:
        L = np.abs(np.diff(gr.xm[[0,-1]]))
        sa = pos(s0[case], np.diff(hbound[case]), L, k, peff, T)
        sn = pcl.x
    elif case == 2:
        L = np.abs(np.diff(gr.ym[[0,-1]]))
        sa = pos(s0[case], -np.diff(hbound[case]), L, k, peff, T)
        sn = pcl.y
    elif case == 3:
        L = np.abs(np.diff(gr.ym[[0,-1]]))
        sa = pos(s0[case], -np.diff(hbound[case]), L, k, peff, T)
        sn = pcl.y
    elif case == 4:
        L = np.abs(np.diff(gr.zm[[0,-1]]))
        sa = pos(s0[case], -np.diff(hbound[case]), L, k, peff, T)
        sn = pcl.z
    elif case == 5:
        L = np.abs(np.diff(gr.zm[[0,-1]]))
        sa = pos(s0[case], -np.diff(hbound[case]), L, k, peff, T)
        sn = pcl.z

    return sa, np.mean(sn, axis=0), crit, pcl, out
Пример #5
0
T = np.linspace(0, 3650, 100)  #time series
if True:
    Xp = np.linspace(200, 2000., 19)
    Yp = np.zeros(Xp.shape)
    Zp = np.ones(Xp.shape) * -5.
else:
    Zp = np.linspace(-5., -95., 19)
    Yp = np.zeros(Zp.shape)
    Xp = np.ones(Zp.shape) * 1000.

#Pcl = mfpath.particle_tracker(gr, Out, por, T, Xp, Yp, Zp)
Pcl = mfpath.particle_tracker(gr,
                              Out,
                              gr.const(por),
                              T=T,
                              particles=(Xp, Yp, Zp),
                              markers='+o*.xsdph^v<>',
                              retardation=1.0,
                              sinkfrac=0.75,
                              tol=1e-12,
                              central_point=(0., 0., 0.))

mfpath.plot_particles(Pcl,
                      axes=ax,
                      first_axis='y',
                      color='green',
                      markers='o....',
                      markersize=4)

plt.show()
#R = np.sqrt(Q * T[-1] / (np.pi * por * np.sum(gr.dy)))