Пример #1
0
def viscous_shock_exact(x, Ms, MP, μ, center=0):
    """ Returns the density, pressure, and velocity of the viscous shock
        (Mach number Ms) at x
    """
    x -= center
    γ = MP.γ
    ρ0 = 1
    p0 = 1 / γ

    if Ms == 2:
        L = 0.3
    elif Ms == 3:
        L = 0.13

    x = min(x, L)
    x = max(x, -L)

    c0 = c_0(ρ0, p0, eye(3), MP)
    a = 2 / (Ms**2 * (γ + 1)) + (γ - 1) / (γ + 1)
    Re = ρ0 * c0 * Ms / μ
    c1 = ((1 - a) / 2)**(1 - a)
    c2 = 3 / 4 * Re * (Ms**2 - 1) / (γ * Ms**2)

    def f(z):
        return (1 - z) / (z - a)**a - c1 * exp(c2 * -x)

    vbar = brentq(f, a + 1e-16, 1)
    p = p0 / vbar * (1 + (γ - 1) / 2 * Ms**2 * (1 - vbar**2))
    ρ = ρ0 / vbar
    v = Ms * c0 * vbar
    v = Ms * c0 - v  # Shock travelling into fluid at rest

    return ρ, p, v
Пример #2
0
def Xi2(P, d, MP):

    ρ = P.ρ
    p = P.p()
    A = P.A
    c0 = c_0(ρ, p, A, MP)

    if THERMAL:
        ret = zeros([5, 4])
    else:
        ret = zeros([5, 3])

    ret[0, 0] = ρ
    ret[1, d] = ρ * c0**2

    if VISCOUS:
        σ = P.σ()
        dσdρ = P.dσdρ()
        ret[1, :3] += σ[d] - ρ * dσdρ[d]
        ret[2:, :3] = A

    if THERMAL:
        T = P.T()
        dTdp = P.dTdp()
        ch = c_h(ρ, T, MP)
        ret[1, 3] = ρ * ch**2 / dTdp

    return ret
Пример #3
0
def c0_star(p_, P, MP):

    r = P.ρ
    p = P.p()
    y = MP.γ
    pINF = MP.pINF
    c0 = c_0(r, p, eye(3), MP)
    return c0 * pow((p_ + pINF) / (p + pINF), (y - 1) / (2 * y))
Пример #4
0
def Y_matrix(P, MP, sgn):

    ρ = P.ρ
    A = P.A
    σρ = P.dσdρ()
    σA = P.dσdA()

    e0 = array([1, 0, 0])
    Π1 = σA[0, :, :, 0]

    tmp = zeros([5, 5])
    tmp[:3, 0] = -σρ[0]
    tmp[0, 1] = 1
    tmp[:3, 2:5] = -Π1

    if THERMAL:

        tmp[3, 0] = P.dTdρ()
        tmp[3, 1] = P.dTdp()
        tmp[4, 0] = -1 / ρ
        tmp[4, 2:5] = inv(A)[0]

    else:

        p = P.p()
        σ = P.σ()
        c0 = c_0(ρ, p, A, MP)

        B = zeros([2, 3])
        B[0, 0] = ρ
        B[1] = σ[0] - ρ * σρ[0]
        B[1, 0] += ρ * c0**2

        rhs = column_stack((-σρ[0], e0))
        C = solve(Π1, rhs)

        BA_1 = dot(B, inv(A))
        Z = eye(2) - dot(BA_1, C)
        W = concatenate([eye(2), -BA_1], axis=1)
        tmp[3:5] = solve(Z, W)

    b = zeros([5, n1])
    b[:n1, :n1] = eye(n1)
    X = solve(tmp, b)

    Ξ1 = Xi1(P, 0, MP)
    Ξ2 = Xi2(P, 0, MP)

    Ξ = dot(Ξ1, Ξ2)
    w, vr = eig(Ξ)

    D_1 = diag(1 / sqrt(w.real))
    Q_1 = vr
    Q = inv(Q_1)

    Y0 = dot(Q_1, dot(D_1, Q))

    return sgn * dot(Y0, dot(Ξ1, X))
Пример #5
0
def f1(z, P, MP):

    r = P.ρ
    p = P.p()
    y = MP.γ
    pINF = MP.pINF
    c0 = c_0(r, p, eye(3), MP)

    if (z > p):
        temp = sqrt(A0(r, y) / (z + B(p, y, pINF)))
        return (1 - (z - p) / (2 * (z + B(p, y, pINF)))) * temp
    else:
        temp = pow((z + pINF) / (p + pINF), -(y + 1) / (2 * y))
        return temp * c0 / (y * (p + pINF))
Пример #6
0
def f0(z, P, MP):

    r = P.ρ
    p = P.p()
    y = MP.γ
    pINF = MP.pINF
    c0 = c_0(r, p, eye(3), MP)

    if (z > p):
        temp = sqrt(A0(r, y) / (z + B(p, y, pINF)))
        return (z - p) * temp
    else:
        temp = pow((z + pINF) / (p + pINF), (y - 1) / (2 * y))
        return 2 * c0 / (y - 1) * (temp - 1)
Пример #7
0
def M_prim(Q, d, MP):
    """ The system jacobian of the primitive system
        NOTE: Uses typical ordering
    """
    P = State(Q, MP)

    ρ = P.ρ
    p = P.p()
    A = P.A
    v = P.v

    c0 = c_0(ρ, p, A, MP)

    ret = v[d] * eye(NV)
    ret[0, 2 + d] = ρ
    ret[1, 2 + d] = ρ * c0**2
    ret[2 + d, 1] = 1 / ρ

    if VISCOUS:

        σ = P.σ()
        dσdρ = P.dσdρ()
        dσdA = P.dσdA()

        ret[1, 2:5] += σ[d] - ρ * dσdρ[d]
        ret[2:5, 0] = -1 / ρ * dσdρ[d]
        ret[2:5, 5:14] = -1 / ρ * dσdA[d].reshape([3, 9])

        ret[5 + d, 2:5] = A[0]
        ret[8 + d, 2:5] = A[1]
        ret[11 + d, 2:5] = A[2]

    if THERMAL:

        dTdρ = P.dTdρ()
        dTdp = P.dTdp()
        T = P.T()
        ch = c_h(ρ, T, MP)

        ret[1, 14 + d] = ρ * ch**2 / dTdp
        ret[14 + d, 0] = dTdρ / ρ
        ret[14 + d, 1] = dTdp / ρ

    return ret
Пример #8
0
def riemann_constraints(P, sgn, MP, left=False):
    """ K=R: sgn = -1
        K=L: sgn = 1
        NOTE: Uses atypical ordering

        Extra constraints are:
        dΣ = dΣ/dρ * dρ + dΣ/dp * dp + dΣ/dA * dA
        dT = dT/dρ * dρ + dT/dp * dp
        v*L = v*R
        J*L = J*R
    """
    _, Lhat, Rhat = eigen(P, 0, False, MP, values=False, right=True, left=left,
                          typical_order=False)

    if left:
        Lhat = left_riemann_constraints(P, Lhat, sgn)

    ρ = P.ρ
    A = P.A
    σρ = P.dσdρ()
    σA = P.dσdA()

    e0 = array([1, 0, 0])
    Π1 = σA[0, :, :, 0]

    tmp = zeros([5, 5])
    tmp[:3, 0] = -σρ[0]
    tmp[0, 1] = 1
    tmp[:3, 2:5] = -Π1

    if THERMAL:

        tmp[3, 0] = P.dTdρ()
        tmp[3, 1] = P.dTdp()
        tmp[4, 0] = -1 / ρ
        tmp[4, 2:5] = inv(A)[0]

    else:

        p = P.p()
        σ = P.σ()
        c0 = c_0(ρ, p, A, MP)

        B = zeros([2, 3])
        B[0, 0] = ρ
        B[1] = σ[0] - ρ * σρ[0]
        B[1, 0] += ρ * c0**2

        rhs = column_stack((-σρ[0], e0))
        C = solve(Π1, rhs)

        BA_1 = dot(B, inv(A))
        Z = eye(2) - dot(BA_1, C)
        W = concatenate([eye(2), -BA_1], axis=1)
        tmp[3:5] = solve(Z, W)

    b = zeros([5, n1])
    b[:n1, :n1] = eye(n1)
    X = solve(tmp, b)

    Rhat[:5, :n1] = X

    Ξ1 = Xi1(P, 0, MP)
    Ξ2 = Xi2(P, 0, MP)
    Q, Q_1, _, D_1 = decompose_Ξ(Ξ1, Ξ2)
    Y0 = dot(Q_1, dot(D_1, Q))

    Rhat[11:n5, :n1] = -sgn * dot(Y0, dot(Ξ1, X))
    Rhat[:11, n1:n2] = 0
    Rhat[11:n5, n1:n2] = sgn * dot(Q_1, D_1)

    return Lhat, Rhat
Пример #9
0
def left_eigenvectors(P, d, MP, typical_order):

    ρ = P.ρ
    A = P.A

    σA = P.dσdA()
    σρ = P.dσdρ()

    Π1 = σA[d, :, :, 0]
    Π2 = σA[d, :, :, 1]
    Π3 = σA[d, :, :, 2]

    Ξ1 = Xi1(P, d, MP)
    Ξ2 = Xi2(P, d, MP)
    Q, Q_1, D, D_1 = decompose_Ξ(Ξ1, Ξ2)

    n1, n2, n3, n4, n5, n6 = get_indexes()

    e0 = array([1, 0, 0])

    L = zeros([17, 17])

    tmp1 = dot(Q, Ξ1)
    tmp2 = -dot(Q[:, :3], Π2) / ρ
    tmp3 = -dot(Q[:, :3], Π3) / ρ
    tmp4 = dot(D, Q)

    L[:n1, :5] = tmp1
    L[n1:n2, :5] = tmp1
    L[:n1, 5:8] = tmp2
    L[n1:n2, 5:8] = tmp2
    L[:n1, 8:11] = tmp3
    L[n1:n2, 8:11] = tmp3
    L[:n1, 11:n5] = tmp4
    L[n1:n2, 11:n5] = -tmp4

    if THERMAL:
        tmp = inv(A)[0]
        L[8, 0] = -1 / ρ
        L[8, 2:5] = tmp
        L[8, 5:8] = dot(tmp, solve(Π1, Π2))
        L[8, 8:11] = dot(tmp, solve(Π1, Π3))
        L[15, 15] = 1
        L[16, 16] = 1

    else:
        σ = P.σ()
        p = P.p()
        c0 = c_0(ρ, p, A, MP)

        B = zeros([2, 3])
        B[0, 0] = ρ
        B[1] = σ[0] - ρ * σρ[0]
        B[1, 0] += ρ * c0**2

        C = zeros([3, 2])
        C[:, 0] = -solve(Π1, σρ[0])
        C[:, 1] = solve(Π1, e0)

        BA_1 = dot(B, inv(A))
        Z = eye(2) - dot(BA_1, C)
        X = zeros([2, 14])
        X[:, :2] = eye(2)
        X[:, 2:5] = -BA_1
        X[:, 5:8] = -dot(BA_1, solve(Π1, Π2))
        X[:, 8:11] = -dot(BA_1, solve(Π1, Π3))
        L[6:8, :14] = solve(Z, X)

    for i in range(6):
        L[n3 + i, 5 + i] = 1

    if typical_order:
        L = reorder(L.T).T

    if not THERMAL:
        L = L[:14, :14]

    return L
Пример #10
0
def exact_euler(n, t, x0, QL, QR, MPL, MPR):
    """ Returns the exact solution to the Euler equations at (x,t),
        given initial states PL for x<x0 and PR for x>x0
    """
    ret = zeros([n, len(QL)])
    PL = State(QL, MPL)
    PR = State(QR, MPR)

    ρL = PL.ρ
    ρR = PR.ρ
    uL = PL.v[0]
    uR = PR.v[0]
    pL = PL.p()
    pR = PR.p()
    c0L = c_0(ρL, pL, eye(3), MPL)
    c0R = c_0(ρR, pR, eye(3), MPR)

    p_ = p_star(PL, PR, MPL, MPR)
    u_ = u_star(p_, PL, PR, MPL, MPR)

    print('Interface:', u_ * t + x0)

    for i in range(n):
        x = (i + 0.5) / n
        S = (x - x0) / t

        if (S < u_):

            if (p_ < pL):  # Left fan
                if (S < uL - c0L):
                    ret[i] = QL
                else:
                    STL = u_ - c0_star(p_, PL, MPL)
                    if (S < STL):
                        ret[i] = Wfan(S, PL, MPL, c0L)
                    else:
                        r_ = r_star_fan(p_, PL, MPL)
                        v_ = array([u_, 0, 0])
                        ret[i] = Cvec(r_, p_, v_, MPL)

            else:  # Left shock
                SL = uL - Q(p_, PL, MPL) / ρL
                if (S < SL):
                    ret[i] = QL
                else:
                    r_ = r_star_shock(p_, PL, MPL)
                    v_ = array([u_, 0, 0])
                    ret[i] = Cvec(r_, p_, v_, MPL)

            ret[i, -1] = -1

        else:

            if (p_ < pR):  # Right fan
                if (uR + c0R < S):
                    ret[i] = QR
                else:
                    STR = u_ + c0_star(p_, PR, MPR)
                    if (STR < S):
                        ret[i] = Wfan(S, PR, MPR, -c0R)
                    else:
                        r_ = r_star_fan(p_, PR, MPR)
                        v_ = array([u_, 0, 0])
                        ret[i] = Cvec(r_, p_, v_, MPR)

            else:  # Right shock
                SR = uR + Q(p_, PR, MPR) / ρR
                if (SR < S):
                    ret[i] = QR
                else:
                    r_ = r_star_shock(p_, PR, MPR)
                    v_ = array([u_, 0, 0])
                    ret[i] = Cvec(r_, p_, v_, MPR)

            ret[i, -1] = 1

    return ret