def S_cons(Q, MP): ret = zeros(NV) P = State(Q, MP) ρ = P.ρ ret[2:5] = P.f_body() if VISCOUS: ψ = P.ψ() θ1_1 = P.θ1_1() ret[5:14] = -ψ.ravel() * θ1_1 if THERMAL: H = P.H() θ2_1 = P.θ2_1() ret[14:17] = -ρ * H * θ2_1 if REACTIVE: K = P.K() ret[17] = -ρ * K return ret
def riemann_constraints(Q, sgn, MP): M = M_prim(Q, 0, MP) λ, L = eig(M, left=True, right=False) λ = λ.real L = L.T Lhat = L[λ.argsort()] Lhat[:n1] *= 0 P = State(Q, MP) σρ = P.dσdρ() σA = P.dσdA() Lhat[:3, 0] = -σρ[0] Lhat[0, 1] = 1 for i in range(3): Lhat[:3, 5 + 3 * i:8 + 3 * i] = -σA[0, :, i] if THERMAL: Lhat[3, 0] = P.dTdρ() Lhat[3, 1] = P.dTdp() Lhat[-n1:, 2:5] *= -sgn if THERMAL: Lhat[-n1:, 14] *= -sgn return Lhat
def S_prim(SYS, Q, MP): """ The source terms of the primitive system NOTE: Uses typical ordering """ ret = zeros(NV) P = State(Q, MP) ρ = P.ρ dEdp = P.dEdp() cs2 = c_s2(ρ, MP) dcs2dρ = dc_s2dρ(ρ, MP) if VISCOUS: ψ = P.ψ() θ1_1 = P.θ1_1() ret[1] = (1 / dEdp - ρ**2 / cs2 * dcs2dρ) * L2_2D(ψ) * θ1_1 ret[5:14] = -ψ.ravel() * θ1_1 if THERMAL: H = P.H() θ2_1 = P.θ2_1() ret[1] += 1 / dEdp * L2_1D(H) * θ2_1 ret[14:17] = -H * θ2_1 if REACTIVE: K = P.K() ret[17] = - K return ret
def check_star_convergence(QL_, QR_, MPL, MPR): PL_ = State(QL_, MPL) if MPR.EOS > -1: # not a vacuum PR_ = State(QR_, MPR) ρ0 = min(MPL.ρ0, MPR.ρ0) b02 = min(MPL.b02, MPR.b02) cond = amax(abs(PL_.Σ()[0] - PR_.Σ()[0])) / (b02 * ρ0) < STAR_TOL cond &= abs(PL_.v[0] - PR_.v[0]) / sqrt(b02) < STAR_TOL else: ρ0 = MPL.ρ0 b02 = MPL.b02 cond = amax(abs(PL_.Σ()[0])) / (b02 * ρ0) < STAR_TOL if THERMAL: if MPR.EOS > -1: q0 = min(q_dims(MPL), q_dims(MPR)) T0 = min(MPL.T0, MPR.T0) cond &= abs(PL_.q()[0] - PR_.q()[0]) / q0 < STAR_TOL cond &= abs(PL_.T() - PR_.T()) / T0 < STAR_TOL else: q0 = q_dims(MPL) cond &= abs(PL_.q()[0]) / q0 < STAR_TOL return cond
def Pvec(Q, MP): """ Vector of primitive variables NOTE: Uses atypical ordering """ P = State(Q, MP) ret = Q.copy() ret[1] = P.p() ret[2:5] /= P.ρ if THERMAL: ret[14:17] /= P.ρ return ret
def F_cons(Q, d, MP): ret = zeros(NV) P = State(Q, MP) ρ = P.ρ p = P.p() E = P.E v = P.v vd = v[d] ρvd = ρ * vd ret[0] = ρvd ret[1] = ρvd * E + p * vd ret[2:5] = ρvd * v ret[2 + d] += p if VISCOUS: A = P.A σ = P.σ() σd = σ[d] ret[1] -= dot(σd, v) ret[2:5] -= σd Av = dot(A, v) ret[5 + d] = Av[0] ret[8 + d] = Av[1] ret[11 + d] = Av[2] if THERMAL: J = P.J T = P.T() q = P.q() ret[1] += q[d] ret[14:17] = ρvd * J ret[14 + d] += T if MULTI: λ = P.λ ret[17] = ρvd * λ return ret
def test(Q, d, CONS, MP): from numpy import amax, sort from numpy.linalg import eigvals from gpr.misc.structures import State P = State(Q, MP) l, L, R = eigen(P, d, CONS, MP) n = 17 if THERMAL else 14 if CONS: from gpr.sys.conserved import M_cons M = M_cons(Q, d, MP)[:n, :n] else: from gpr.sys.primitive import M_prim M = M_prim(Q, d, MP)[:n, :n] print("Λ:", amax(abs(sort(eigvals(M)) - sort(l)))) for i in range(n): print(i) print('L:', amax(abs(dot(L[i], M) - (l[i] * L[i]))[L[i] != 0])) print('R:', amax( abs(dot(M, R[:, i]) - (l[i] * R[:, i]))[R[:, i] != 0]))
def M_cons(Q, d, MP): """ Returns the Jacobian in the dth direction """ P = State(Q, MP) DFDP = dFdP(P, d, MP) DPDQ = dPdQ(P, MP) return dot(DFDP, DPDQ) + B_cons(Q, d, MP)
def systems(Q, d, MP): P = State(Q, MP) DQDP = dQdP(P, MP) M1 = M_prim(Q, d, MP) M2 = M_cons(Q, d, MP) M3 = solve(DQDP, dot(M2, DQDP)) return M1, M2, M3
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
def gauge_plot(uList, MPs): dt = 5e-6 / 100 x = [0.0018125 + 0.006 + 0.003625 * i for i in range(5)] n = len(uList) nx, ny = uList[0].shape[:2] x_ = linspace(0, 5e-6, n) vy = zeros([5, n]) py = zeros([5, n]) ρy = zeros([5, n]) Σy = zeros([5, n]) # j0 = int(ny / 2) j0 = 0 for j in range(n): for i in range(5): i0 = int(x[i] / 0.03 * nx) Q = uList[j][i0, j0] P = State(Q, MPs[1]) vy[i, j] = P.v[0] py[i, j] = P.p() ρy[i, j] = P.ρ Σy[i, j] = P.Σ()[0, 0] x[i] += P.v[0] * dt figure(1) for i in range(5): plot(x_, vy[i]) figure(2) for i in range(5): plot(x_, py[i]) figure(3) for i in range(5): plot(x_, ρy[i]) figure(4) for i in range(5): plot(x_, -Σy[i])
def generate_vecs(MP): A = rand(3, 3) A /= sign(det3(A)) ρ = det3(A) * MP.ρ0 p = rand() v = rand(3) J = rand(3) Q = Cvec(ρ, p, v, MP, A, J) P = State(Q, MP) return Q, P
def TAT_test(d, MP): Q = generate_vector(MP) P = State(Q, MP) Ξ1 = Xi1(P, d, MP) Ξ2 = Xi2(P, d, MP) TAT_py = dot(Ξ1, Ξ2) TAT_cp = GPRpy.system.thermo_acoustic_tensor(Q, d, MP) print("TAT ", check(TAT_cp, TAT_py)) return TAT_cp, TAT_py
def check_star_convergence(QL_, QR_, MPL, MPR, STAR_TOL=1e-6): PL_ = State(QL_, MPL) PR_ = State(QR_, MPR) cond1 = amax(abs(PL_.Σ()[0] - PR_.Σ()[0])) < STAR_TOL cond2 = abs(PL_.T() - PR_.T()) < STAR_TOL return cond1 and cond2
def obj_eul(x, WwL, WwR, dt, MPL, MPR): nX = NT * NV qL = x[0:nX].reshape([NT, NV]) qR = x[nX:2 * nX].reshape([NT, NV]) ρvL = x[2 * nX:2 * nX + 3 * N].reshape([N, 3]) ρvR = x[2 * nX + 3 * N:2 * nX + 6 * N].reshape([N, 3]) ret = zeros(2 * nX + 6 * N) ret[0:nX] = (dot(U, qL) - rhs(qL, WwL, dt, MPL, 0)).ravel() ret[nX:2 * nX] = (dot(U, qR) - rhs(qR, WwR, dt, MPR, 0)).ravel() qL_ = dot(ENDVALS[:, 1], qL.reshape([N, N, NV])) qR_ = dot(ENDVALS[:, 0], qR.reshape([N, N, NV])) qL_[:, 2:5] += ρvL qR_[:, 2:5] += ρvR vL_ = zeros([N, 3]) vR_ = zeros([N, 3]) ΣL_ = zeros([N, 3]) ΣR_ = zeros([N, 3]) for i in range(N): PL_ = State(qL_[i], MPL) PR_ = State(qR_[i], MPR) vL_[i] = PL_.v vR_[i] = PR_.v ΣL_[i] = PL_.Σ()[0] ΣR_[i] = PR_.Σ()[0] ret[2 * nX:2 * nX + 3 * N] = (vL_ - vR_).ravel() ret[2 * nX + 3 * N:2 * nX + 6 * N] = (ΣL_ - ΣR_).ravel() return ret
def max_eig(Q, d, MP): """ Returns maximum absolute value of the eigenvalues of the GPR system """ P = State(Q, MP) vd = P.v[d] Ξ1 = Xi1(P, d, MP) Ξ2 = Xi2(P, d, MP) O = dot(Ξ1, Ξ2) lam = sqrt(eigvals(O).max().real) if vd > 0: return vd + lam else: return lam - vd
def plot_compound(u, MPs, style, x, lab, col, title, sci, attr, plotType, vmin, vmax, i=None, j=None, takeNorm=False, offset=0, symaxis=-1, excludeMats=[]): shape = u.shape[:-1] n = prod(shape) y = zeros(n) nmat = len(MPs) for ii in range(n): Q = u.reshape([n, -1])[ii] ind = get_material_index(Q, nmat) MP = MPs[ind] if MP.EOS > -1 and ind not in excludeMats: # not a vacuum P = State(Q, MP) if isinstance(getattr(P, attr), MethodType): var = getattr(P, attr)() else: var = getattr(P, attr) if i is not None: if j is None: var = var[i] else: var = var[i,j] if takeNorm: var = norm(var) if isnan(var): print('Warning: nan in cell', ii) else: y[ii] = var else: y[ii] = nan y += offset if u.ndim - 1 == 1: plot1d(y, style, x, lab, col, title, sci=sci) else: plot2d(y.reshape(shape), plotType, vmin=vmin, vmax=vmax, lsets=[u[:, :, -(i+1)] for i in range(nmat-1)], symaxis=symaxis)
def check_star_convergence(QL_, QR_, MPL, MPR): PL_ = State(QL_, MPL) PR_ = State(QR_, MPR) cond1 = amax(abs(PL_.Σ()[0] - PR_.Σ()[0])) < STAR_TOL if THERMAL: cond2 = abs(PL_.T() - PR_.T()) < STAR_TOL else: cond2 = True return cond1 and cond2
def star_stepper(QL_, QR_, MPL, MPR, interfaceType): """ Iterates to the next approximation of the star states. NOTE: the material on the right may be a vacuum. """ PL = State(QL_, MPL) _, RL = riemann_constraints(PL, 1, MPL) if THERMAL: xL = concatenate([PL.Σ()[0], [PL.T()]]) else: xL = PL.Σ()[0] cL = zeros(n6) if MPR.EOS > -1: # not a vacuum PR = State(QR_, MPR) _, RR = riemann_constraints(PR, -1, MPR) if THERMAL: xR = concatenate([PR.Σ()[0], [PR.T()]]) else: xR = PR.Σ()[0] cR = zeros(n6) if interfaceType == 'stick': x_ = stick_bcs(RL, RR, PL, PR, xL, xR) elif interfaceType == 'slip': x_ = slip_bcs(RL, RR, PL, PR, xL, xR) cL[:n1] = x_ - xL cR[:n1] = x_ - xR PRvec = Pvec(PR) PR_vec = dot(RR, cR) + PRvec QR_ = Pvec_to_Cvec(reorder(PR_vec), MPR) else: cL[:n1] = - xL if THERMAL: YL = RL[14, :4] cL[3] = (dot(YL[:3], PL.Σ()[0]) - PL.J[0]) / YL[3] QR_ = zeros(n6) PLvec = Pvec(PL) PL_vec = dot(RL, cL) + PLvec QL_ = Pvec_to_Cvec(reorder(PL_vec), MPL) return QL_, QR_
def star_stepper(QL, QR, dt, MPL, MPR, SL=None, SR=None): d = 0 PL = State(QL, MPL) PR = State(QR, MPR) LL, RL = riemann_constraints(PL, 1, MPL) LR, RR = riemann_constraints(PR, -1, MPR) YL = RL[11:15, :4] YR = RR[11:15, :4] xL = concatenate([PL.Σ()[d], [PL.T()]]) xR = concatenate([PR.Σ()[d], [PR.T()]]) Ξ1L = Xi1(PL, d, MPL) Ξ2L = Xi2(PL, d, MPL) OL = dot(Ξ1L, Ξ2L) Ξ1R = Xi1(PR, d, MPR) Ξ2R = Xi2(PR, d, MPR) OR = dot(Ξ1R, Ξ2R) _, QL_1 = eig(OL) _, QR_1 = eig(OR) if SL is not None: cL = dot(LL, reorder(SL, order='atypical')) cR = dot(LR, reorder(SR, order='atypical')) XL = dot(QL_1, cL[4:8]) XR = dot(QR_1, cR[4:8]) yL = concatenate([PL.v, [PL.J[d]]]) yR = concatenate([PR.v, [PR.J[d]]]) x_ = solve(YL - YR, yR - yL - dt * (XL + XR) + dot(YL, xL) - dot(YR, xR)) else: yL = concatenate([PL.v, [PL.J[d]]]) yR = concatenate([PR.v, [PR.J[d]]]) x_ = solve(YL - YR, yR - yL + dot(YL, xL) - dot(YR, xR)) cL[:4] = x_ - xL cR[:4] = x_ - xR PLvec = reorder(Pvec(PL, MPL.THERMAL), order='atypical') PRvec = reorder(Pvec(PR, MPR.THERMAL), order='atypical') PL_vec = dot(RL, cL) + PLvec PR_vec = dot(RR, cR) + PRvec QL_ = Pvec_to_Cvec(reorder(PL_vec), MPL) QR_ = Pvec_to_Cvec(reorder(PR_vec), MPR) return QL_, QR_
def star_states_stiff(QL, QR, dt, MPL, MPR): PL = State(QL, MPL) PR = State(QR, MPR) x0 = zeros(42) x0[:21] = concatenate([QL, PL.Σ()[0], [PL.q()[0]]]) x0[21:] = concatenate([QR, PR.Σ()[0], [PR.q()[0]]]) def obj(x): return star_stepper_obj(x, QL, QR, dt, MPL, MPR) ret = newton_krylov(obj, x0).reshape([2, 21]) return ret[0, :17], ret[1, :17]
def B_cons(Q, d, MP): ret = zeros([NV, NV]) if VISCOUS: P = State(Q, MP) v = P.v vd = v[d] for i in range(5, 14): ret[i, i] = vd ret[5 + d, 5:8] -= v ret[8 + d, 8:11] -= v ret[11 + d, 11:14] -= v for i in range(1, LSET + 1): ret[-i, -i] = vd return ret
def star_stepper_obj(x, QL, QR, dt, MPL, MPR): X = x.reshape([2, 21]) ret = zeros([2, 21]) QL_ = X[0, :17] QR_ = X[1, :17] PL = State(QL, MPL) PR = State(QR, MPR) PL_ = State(QL_, MPL) PR_ = State(QR_, MPR) pL = Cvec_to_Pvec(QL, MPL) pR = Cvec_to_Pvec(QR, MPR) pL_ = Cvec_to_Pvec(QL_, MPL) pR_ = Cvec_to_Pvec(QR_, MPR) ML = riemann_constraints2(PL, 'L', MPL)[:17, :17] MR = riemann_constraints2(PR, 'R', MPR)[:17, :17] xL_ = X[0, 17:] xR_ = X[1, 17:] xL = zeros(4) xR = zeros(4) xL[:3] = PL.Σ()[0] xR[:3] = PR.Σ()[0] xL[3] = PL.q()[0] xR[3] = PR.q()[0] ret[0, :4] = dot(ML[:4], pL_ - pL) - (xL_ - xL) ret[1, :4] = dot(MR[:4], pR_ - pR) - (xR_ - xR) SL = source_prim(QL, MPL)[:17] SR = source_prim(QR, MPR)[:17] SL_ = source_prim(QL_, MPL)[:17] SR_ = source_prim(QR_, MPR)[:17] ret[0, 4:17] = dot(ML[4:], (pL_ - pL) - dt / 2 * (SL + SL_)) ret[1, 4:17] = dot(MR[4:], (pR_ - pR) - dt / 2 * (SR + SR_)) bR = zeros(4) bL = zeros(4) bL[:3] = PL_.v bR[:3] = PR_.v bL[3] = PL_.T() bR[3] = PR_.T() ret[0, 17:] = xL_ - xR_ ret[1, 17:] = bL - bR return ret.ravel()
def cons_to_class(QL, QR, QL_, QR_, MPs): PL = State(QL, MPs[0]) PR = State(QR, MPs[1]) PL_ = State(QL_, MPs[0]) PR_ = State(QR_, MPs[1]) return PL, PR, PL_, PR_
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
def star_stepper(QL, QR, MPL, MPR, NV=17): PL = State(QL, MPL) PR = State(QR, MPR) LhatL = riemann_constraints(QL, -1, MPL) LhatR = riemann_constraints(QR, 1, MPR) cL = zeros(NV) cR = zeros(NV) if STICK: YL = Y_matrix(PL, MPL, -1) YR = Y_matrix(PR, MPR, 1) if THERMAL: xL = concatenate([PL.Σ()[0], [PL.T()]]) xR = concatenate([PR.Σ()[0], [PR.T()]]) yL = concatenate([PL.v, PL.J[:1]]) yR = concatenate([PR.v, PR.J[:1]]) else: xL = PL.Σ()[0] xR = PR.Σ()[0] yL = PL.v yR = PR.v x_ = solve(YL - YR, yR - yL + dot(YL, xL) - dot(YR, xR)) else: # slip conditions - only implemented for non-thermal if THERMAL: YL = Y_matrix(PL, MPL, -1)[[0, 3]] YR = Y_matrix(PR, MPR, 1)[[0, 3]] xL = array([PL.Σ()[0], PL.T()]) xR = array([PR.Σ()[0], PR.T()]) yL = array([PL.v[0], PL.J[0]]) yR = array([PR.v[0], PR.J[0]]) M = YL[:, [0, -1]] - YR[:, [0, -1]] x_ = solve(M, yR - yL + dot(YL, xL) - dot(YR, xR)) x_ = array([x_[0], 0, 0, x_[1]]) else: YL = Y_matrix(PL, MPL, -1)[0] YR = Y_matrix(PR, MPR, 1)[0] xL = PL.Σ()[0] xR = PR.Σ()[0] yL = PL.v[0] yR = PR.v[0] x_ = (yR - yL + dot(YL, xL) - dot(YR, xR)) / (YL - YR)[0] x_ = array([x_, 0, 0]) cL[:n1] = x_ - xL cR[:n1] = x_ - xR PLvec = Pvec(QL, MPL) PRvec = Pvec(QR, MPR) PL_vec = solve(LhatL, cL) + PLvec PR_vec = solve(LhatR, cR) + PRvec QL_ = Pvec_to_Cvec(PL_vec, MPL) QR_ = Pvec_to_Cvec(PR_vec, MPR) return QL_, QR_