def OSP2P1th(P2P1, th, k=1.4): ''' Gasdynamics Module Location: GasDynamics\\CPG\\ObliqueShock Function: OSMP2P1(M,P2P1,k=1.4) Variables: T - Temperature[K] P - Pressure [Pa] P0 - Stagnation Pressure [Pa] T0 - Stagnation Temperature [K] rho - Density [kg/m^3] R - Gas constant [J/(kgK)], default value 287 J/(kgK) for air k - ratio of specific heats gamma=Cp/Cv, default value k=1.4 for diatomic gases a - speed of sound [m/s] V - local magnitude of gas velocity [m/s] M - Mach number A - Area of cross section m - mass flow rate B - beta the shock angle for a given flow deflection angle theta th - theta the flow defelection angle Numbers: 1 - upstream of the shock 2 - downstream of the shock Abbreviations: PG - Perfect Gas CPG - Calorically Perfect Gas TPG - Thermally Perfect Gas Inputs: M,P2P1,k Outputs: [M,M2,P2/P1,T2/T1,rho2/rho1,P02/P01,dS/R,th,B] Explanantion: Calculates the downstream shock properties of an attached oblique shock given M and P2P1 Usage: B=OSMP2P1(M,P2P1,k=1.4) ### ver 0 August 2020 ### Credits: Srisha Rao M V ''' M1n = InvNSP2P1(P2P1, k) M1max = InvOSthmax(th, k) Bmax = OSBmax(M1max[0], k) M2n = NSM1M2(M1n, k) T2T1n = NST2T1(M1n, k) b = M2n / M1n * math.sqrt(T2T1n) B1 = secant(residual_OSP2P1th, [0.99 * Bmax, 0.80 * Bmax], th, b, k) M = M1n / math.sin(B1[0]) M2 = M2n / math.sin(B1[0] - th) out = [ M, M2, NSP2P1(M1n, k), NST2T1(M1n, k), NSrho2rho1(M1n, k), NSP02P01(M1n, k), NSdSbyR(M1n, k), th, B1[0] ] return out
def InvF1(f1, k=1.4): ''' Gasdynamics Module Location: GasDynamics\\CPG\\Isentropic Function: InvF1(f1,k) Variables: T - Temperature [K] R - Gas constant [J/(kgK)], default value 287 J/(kgK) for air k - ratio of specific heats gamma=Cp/Cv, default value k=1.4 for diatomic gases a - speed of sound [m/s] V - local magnitude of gas velocity [m/s] M - Mach number F1 - M*(1+(k-1)/2*M^2)^(-(k+1)/(2*(k-1))) Abbreviations: PG - Perfect Gas CPG - Calorically Perfect Gas TPG - Thermally Perfect Gas Inputs: f1,k Outputs: M [Msub,Msuper,f] Explanantion: Inverts the function F1=M*(1+(k-1)/2*M^2)^(-(k+1)/(2*(k-1))) which appears in isentropic area relations of perfect gas gasdynamics relations to give Mach number given f1 and k. For any given f1, there are two possible Mach numbers one subsonic and the other supersonic, accordingly the output is a list containing the two Mach numbers and a flag indicating the success of the operation. Usage: M=InvF1(f1) # calculates M for a perfect diatomic gas including air M=InvF1(f1,k) # calculates M for a general perfect gas given M,k ### ver 0 August 2020 ### Credits: Srisha Rao M V ''' # The subsonic solution maxminsub = [0.1, 0.2] sol1 = secant(residualF1, maxminsub, f1, k) # The supersonic solution maxminsup = [1.1, 3.0] sol2 = secant(residualF1, maxminsup, f1, k) # Check for solutions if (sol1[1] > 0) and (sol2[1] > 0): return ([sol1[0], sol2[0], 1]) else: print( 'error: The function could not be solved, check the inputs given') return
def InvOSBmax(Bmax, k=1.4): ''' Gasdynamics Module Location: GasDynamics\\CPG\\ObliqueShock Function: InvOSBmax(Bmax,k=1.4) Variables: T - Temperature[K] P - Pressure [Pa] P0 - Stagnation Pressure [Pa] T0 - Stagnation Temperature [K] rho - Density [kg/m^3] R - Gas constant [J/(kgK)], default value 287 J/(kgK) for air k - ratio of specific heats gamma=Cp/Cv, default value k=1.4 for diatomic gases a - speed of sound [m/s] V - local magnitude of gas velocity [m/s] M - Mach number A - Area of cross section m - mass flow rate B - beta the shock angle for a given flow deflection angle theta th - theta the flow defelection angle Numbers: 1 - upstream of the shock 2 - downstream of the shock Abbreviations: PG - Perfect Gas CPG - Calorically Perfect Gas TPG - Thermally Perfect Gas Inputs: Bmax,k Outputs: M Explanantion: Calculates the maximum shock angle for attached solutions given M and k Usage: M=InvOSBmax(Bmax,k=1.4) ### ver 0 August 2020 ### Credits: Srisha Rao M V ''' M = np.arange(1.01, 20.01, 0.01) f = np.empty_like(M) for i in range(0, len(M)): f[i] = OSBmax(M[i], k) pass interpfn = interpolate.interp1d(f, M) M_in1 = 1.001 * interpfn(Bmax) M_in2 = 0.999 * interpfn(Bmax) return secant(residual_Bmax, [M_in1, M_in2], Bmax, k)
def InvNSP02P01(P02P01,k=1.4): ''' Gasdynamics Module Location: GasDynamics\\CPG\\NormalShock Function: InvNSP02P01(P02P01,k) Variables: T - Temperature[K] P - Pressure [Pa] P0 - Stagnation Pressure [Pa] T0 - Stagnation Temperature [K] rho - Density [kg/m^3] R - Gas constant [J/(kgK)], default value 287 J/(kgK) for air k - ratio of specific heats gamma=Cp/Cv, default value k=1.4 for diatomic gases a - speed of sound [m/s] V - local magnitude of gas velocity [m/s] M - Mach number A - Area of cross section m - mass flow rate Numbers: 1 - upstream of the shock 2 - downstream of the shock Abbreviations: PG - Perfect Gas CPG - Calorically Perfect Gas TPG - Thermally Perfect Gas Inputs: P02P01,k Outputs: M1 Explanantion: Calculates the upstream Mach number given P02/P01 across a shock Usage: M1=InvNSP02P01(P02P01,k) ### ver 0 August 2020 ### Credits: Srisha Rao M V ''' return secant(residual_P02P01,[1.1,3.0],P02P01,k)
def OSMthB(M, th, k=1.4): ''' Gasdynamics Module Location: GasDynamics\\CPG\\ObliqueShock Function: OSMthB(M,th,k=1.4) Variables: T - Temperature[K] P - Pressure [Pa] P0 - Stagnation Pressure [Pa] T0 - Stagnation Temperature [K] rho - Density [kg/m^3] R - Gas constant [J/(kgK)], default value 287 J/(kgK) for air k - ratio of specific heats gamma=Cp/Cv, default value k=1.4 for diatomic gases a - speed of sound [m/s] V - local magnitude of gas velocity [m/s] M - Mach number A - Area of cross section m - mass flow rate B - beta the shock angle for a given flow deflection angle theta th - theta the flow defelection angle Numbers: 1 - upstream of the shock 2 - downstream of the shock Abbreviations: PG - Perfect Gas CPG - Calorically Perfect Gas TPG - Thermally Perfect Gas Inputs: M1,k Outputs: Bmax Explanantion: Calculates the shock angle for attached solutions given M, th and k Usage: B=OSMthB(M,th,k=1.4) ### ver 0 August 2020 ### Credits: Srisha Rao M V ''' thmax = OSthmax(M, k) Bmax = OSBmax(M, k) mu = machangle(M) if th == thmax: return ([Bmax, Bmax, 1]) elif th > thmax: print( 'error the angle is greater than the maximum flow deflection angle for attached shock solutions' ) return ([0, 0, 0]) elif th == 0: return ([mu, math.pi / 2, 1]) else: Btemp1 = np.linspace(mu, Bmax, 100) Btemp2 = np.linspace(Bmax, math.pi / 2, 100) thtemp1 = np.empty_like(Btemp1) thtemp2 = np.empty_like(Btemp2) for i in range(0, len(Btemp1)): thtemp1[i] = OSMBth(M, Btemp1[i], k) thtemp2[i] = OSMBth(M, Btemp2[i], k) pass interpfn1 = interpolate.interp1d(thtemp1, Btemp1) Bestw1 = 0.999 * interpfn1(th) Bestw2 = 0.995 * interpfn1(th) interpfn2 = interpolate.interp1d(thtemp2, Btemp2) Bests1 = 0.999 * interpfn2(th) Bests2 = 0.995 * interpfn2(th) B1 = secant(residual_MthB, [Bestw1, Bestw2], M, th, k) B2 = secant(residual_MthB, [Bests1, Bests2], M, th, k) return ([B1[0], B2[0], 1])