Exemple #1
0
def FT2D(Nx, Ny, dt, theta):

    # ==============================================================================
    # Declaration of physical variables for the problem. A positive value in X means
    # going to the right and a positive value in Y means going up
    # ==============================================================================

    X0 = 0.  # Initial x point (m)
    XL = 5.  # Final y point (m)
    Y0 = 0.  # Initial y point (m)
    YL = 5.  # Final y point (m)
    Dx = 0.08  # Diff coeff x (m2/s)
    Dy = 0.08  # Diff coeff y (m2/s)
    u = 0.7  # Horizontal velocity (m/s)
    v = 0.3  # Vertical velocity (m/s)
    M = 2.  # Mass injected (g)
    xC0 = 0.0  # x injection coordinate
    yC0 = 0.0  # y injection coordinate
    t0 = 1.  # Initial time (s)
    A = (XL - X0) * (YL - Y0)  # Domain area (m2)

    # =============================================================================
    # Numerical parameters for the program.
    # theta = 1 fully implicit
    # theta = 0 fully explicit
    # =============================================================================

    T = 5  # Total sim. time (s)
    #    dt = 0.01                                       # timestep size (s)
    #    Nx = 21                                         # Nodes in x direction
    #    Ny = 21                                         # Nodes in y direction
    #    theta = 0.5                                     # Crank-Nicholson ponderation

    # Calculation of initial parameters
    nT = int(np.ceil((T - t0) / dt))  # Number of timesteps
    dx = (XL - X0) / (Nx - 1)  # dx (m)
    dy = (YL - Y0) / (Ny - 1)  # dy (m)

    # Generating spatial mesh
    x = np.linspace(X0, XL, Nx)  # 1D array style
    y = np.linspace(Y0, YL, Ny)  # 1D array style
    X, Y = np.meshgrid(x, y)  # Meshgrid for plotting
    del (x, y)  # Deleting useless arrays

    # Generating error vectors (for svaing and comparing results)
    errt = np.zeros(int(nT))  # Error evolution in time

    # ==============================================================================
    # Calculation of nondimensional parameters of the ADE (Sx, Sy, CFLx and CFLy)
    # ==============================================================================

    Sx = Dx * dt / (dx**2)
    Sy = Dy * dt / (dy**2)
    CFLx = u * dt / dx
    CFLy = v * dt / dy

    SM.show_sc(Sx, Sy, CFLx, CFLy)

    # Matrix assembly for diffusive implicit part
    LHS = AUX.Mat_ass(Sx, Sy, Nx, Ny)

    # ==============================================================================
    # Imposing initial condition as an early analytical solution of the ADE equation
    # It is C(x0, y0, t0).
    # ==============================================================================

    C0 = AN.difuana(M, A, Dx, Dy, u, v, xC0, yC0, X, Y, t0)

    # Estimating Cmax for plotting purposes
    Cmax = np.max(C0)

    # ==============================================================================
    # First time step. Forward Euler for advective part, and Crank-Nicholson for
    # diffusive term
    # ==============================================================================

    # First fractional step part for timestep 1 - advective term

    # Calculating analytical solution for first timestep
    Ca = AN.difuana(M, A, Dx, Dy, u, v, xC0, yC0, X, Y, t0 + dt)

    # Evaluating space derivative just for advections
    sp0 = AUX.ev_sp(C0, 0, 0, dx, dy, u, v, Nx, Ny)

    # Making first advection step
    C1s = C0 + dt * sp0

    # Imposing boundary conditions (domain is a 2D array)

    C1s[0, :] = Ca[0, :]  # Bottom boundary
    C1s[Ny - 1, :] = Ca[Ny - 1, :]  # Top boundary
    C1s[:, 0] = Ca[:, 0]  # Left boundary
    C1s[:, Nx - 1] = Ca[:, Nx - 1]  # Right boundary

    # Second fractional step part for timestep 1 - diffusive term

    # Explicit part - evaluating diffusion just in space
    sp0 = AUX.ev_sp(C1s, Dx, Dy, dx, dy, 0, 0, Nx, Ny)

    C1e = C1s + dt * sp0

    # Implicit part
    C1i = spsolve(LHS, np.reshape(C1s, (Nx * Ny, 1)))

    C1 = theta * C1i.reshape(Nx, Ny) + (1 - theta) * C1e

    # Error checking
    errt[0] = np.linalg.norm(C1 - Ca)

    # Second array declaration
    C2s = np.zeros((Ny, Nx))
    err = np.zeros((Ny, Nx))

    # Starting time loop
    for I in range(2, nT + 1):

        # Calculating analytical solution for the time step
        Ca = AN.difuana(M, A, Dx, Dy, u, v, xC0, yC0, X, Y, t0 + I * dt)

        # Calculating C* - only advection with Adams Bashforth Order 2

        # Spatial function evaluated in t - 1
        sp0 = AUX.ev_sp(C0, 0, 0, dx, dy, u, v, Nx, Ny)

        # Spatial function evaluated in t
        sp1 = AUX.ev_sp(C1, 0, 0, dx, dy, u, v, Nx, Ny)

        # Implementing 2nd order Adams-Bashforth
        C2s = C1 + (dt / 2) * (3 * sp0 - sp1)

        # Imposing Boundary conditions
        C2s[0, :] = Ca[0, :]
        C2s[Ny - 1, :] = Ca[Ny - 1, :]
        C2s[:, 0] = Ca[:, 0]
        C2s[:, Nx - 1] = Ca[:, Nx - 1]

        # Calculating C2 with the values of C* - explicit FE
        C2sp = AUX.ev_sp(C2s, Dx, Dy, dx, dy, 0, 0, Nx, Ny)
        C2e = C2s + dt * C2sp

        # Calculating C2 with C* - implicit BE
        C2i = spsolve(LHS, np.reshape(C2s, (Nx * Ny, 1)))

        # Making Crank-Nicholson ponderation
        C2 = theta * C2i.reshape(Nx, Ny) + (1 - theta) * C2e

        # Calculating error for the timestep given
        err = np.abs(C2 - Ca)
        errt[I - 1] = np.linalg.norm(C2e - Ca)

        # Updating concentration fields
        C0 = C1
        C1 = C2
        C2 = np.zeros((Ny, Nx))

    return errt
# Generating error vectors (for svaing and comparing results)
errt = np.zeros(int(nT))  # Error evolution in time

# ==============================================================================
# Calculation of nondimensional parameters of the ADE (Sx, Sy, CFLx and CFLy)
# ==============================================================================

Sx = Dx * dt / (dx**2)
Sy = Dy * dt / (dy**2)
CFLx = u * dt / dx
CFLy = v * dt / dy

SM.show_sc(Sx, Sy, CFLx, CFLy)

# Matrix assembly for diffusive implicit part
LHS = AUX.Mat_ass(Sx, Sy, Nx, Ny)

# ==============================================================================
# Imposing initial condition as an early analytical solution of the ADE equation
# It is C(x0, y0, t0).
# ==============================================================================

C0 = AN.difuana(M, A, Dx, Dy, u, v, xC0, yC0, X, Y, t0)

# Estimating Cmax for plotting purposes
Cmax = np.max(C0)

# ==============================================================================
# First time step. Forward Euler for advective part, and Crank-Nicholson for
# diffusive term
# ==============================================================================