--- tags: Mathematical modeling and optimization title: 4.2 Characteristics in the internal gas dynamics --- ## 4.2. Characteristics in the internal gas dynamics Gas dyanmics refers to the discipline of compressible flows, which describes the behavior of gases when the density changes significantly in response to pressure variations. This is a common occurrence in e.g. propulsion systems, gas pipelines and pneumatic applications. Unlike incompressible flow, where the density is constant, compressible flow requires accounting for changes in density, pressure, and temperature. [__Speed of sound__](https://en.wikipedia.org/wiki/Speed_of_sound) ($a$) is a specific physical property in the compressible flow scop, which denotes the pressure change over density change in the isentropic condition, derived from the continuety and momentum conservation over a wave front. This yields to $$ c^2 = \left(\frac{\partial p}{\partial \rho}\right)_s $$ In the combination of isentropic process ($\ p v^\gamma = \text{const}$) and ideal gas law ($\ p = \rho \ R\ T$), speed of sound has a simple expression as $c = \sqrt{\gamma \ R\ T}$. The speed of sound concept allows the Mach number ($M$) to quantify its ratio to the gas (or related to gas) velocity, written as $$ M = \frac{u}{c}\quad . $$ [__Stagnation state__](https://en.wikipedia.org/wiki/Stagnation_temperature) (subscript $_0$) is another concept which well applied in the regime of gas dynamics. The stagnation state denotes the condition where no dynamics (velocity) is taken into account. Accordingly, the condition with dynamic expression is name as _static_ state. Thus, $$ \begin{align} \underbrace{h_0}_{\text{stagnation enthalpy}} = \underbrace{h}_{\text{static enthalpy}} +\underbrace{\frac{1}{2}\ \ u^2}_{\text{kinematic energy}} \end{align} $$ Involving the Mach number and speed of sound definition, the enthalpy can be represented in another form: $$ h_0 = h + \frac{\gamma -1}{2}M^2 \ c_p \ T = (1 + \frac{\gamma -1}{2} M^2 ) \ h $$ and further reduced due to calorific perfect gas assumption $(\ h = c_p \ T\ )$ to $$ \frac{T_0}{T} = (1 + \frac{\gamma -1}{2} M^2 ) $$ where $\gamma$ is the ratio of specific heat capacity ${c_p}/{c_v}$. This relation can be interpreted as: _for a given stagnation temperature $(T_0)$, the static temperature $(T)$ on any point is in a simple behavior to its Mach number incorporated with its themrmodynamic property $\gamma$ of the gas._ ### 4.2.1 Isentropic flow and de Laval nozzle The concept of isentropic process $(pv^\gamma = \text{const})$ futher brings up the $M$ representations between static and stagnation state to other phyiscal properties. Involving the ideal gas law, the pressure and density relation to stagnation states yield $$ \begin{align} \frac{p_0}{p} = \left(\frac{T_0}{T}\right)^{\gamma / (\gamma -1)}= \left(1 + \frac{\gamma -1}{2} M^2 \right)^{\gamma / (\gamma -1)}\\ \\ \frac{\rho_0}{\rho} = \left(\frac{T_0}{T}\right)^{1 / (\gamma -1)}= \left(1 + \frac{\gamma -1}{2} M^2 \right)^{1 / (\gamma -1)}\\ \end{align} $$ The starting points for internal compressible flow are the continuity and momentum equation for one-dimenional state. They present in the form of mass flow rate and Euler's equation, where $$ \begin{align} \dot{m} = \rho \ u\ A\ = & \ \text{const},\\ \\ \frac{1}{\rho} \ dp + \frac{1}{2} d u^2 \ &= \ 0 \end{align} $$ where, - $\rho$ is the gas density - $u$ is the flow velocity, and - $A$ is the cross section area The further handling takes the derivative on both sides, the governing equations become $$ \begin{align} d(\rho uA) =\ Au\ d\rho + \rho u \ dA+ \rho A \ du &= d(\text{const}) = \ 0 \\ \to \ \frac{d\rho}{\rho} + \frac{dA}{A} + \frac{du}{u} &= 0 \\ \\ d(\rho \ u^2 + p )= \ d(\text{const}) & = 0\\ \to du = -\frac{dp}{\rho\ u} \end{align} $$ In alignment to the speed of sound definition, the cominition of continuity-momentum equation results to $$ \begin{align} \frac{d\rho}{\rho}\ =& \ \frac{M^2}{1 - M^2} \frac{dA}{A}.\\ \\ \frac{du}{u}\ =& -\frac{1}{1-M^2} \frac{dA}{A}\\ \\ dp\ = & \ \rho u^2 \frac{1}{1-M^2} \frac{dA}{A} \end{align} $$ These relation provide the baseline rules for analysis in the 1-D dominant flow patterns, such as - For subsonic state $(M < 1)$, __decreasing of cross section area $(dA < 0)$__ leads to - increase of velocity $(du >0)$ and Mach number, - decrease of pressure $(dp < 0)$, - decrease of density $(d \rho < 0)$ and - decrease of temperature $(dT < 0)$, vice versa. - For supersonic state $(M > 1)$, __increase of cross section area $(dA > 0)$__ leads to - increase of velocity $(du > 0)$ and Mach number, - decrease of pressure $(dp < 0)$, - decrease of density $(d \rho < 0)$ and - decrease of temperature $(dT < 0)$, vice versa. It is found that the velocity reaches its maximum for a converging pipe at speed of sound, where $M = 1$. A further speed up can only be achieved in a diverging shape $(dA > 0)$. This is a common strategy to gain the kinetic energy out of the nozzle, well applied in rocket design. #### Sonic (critical) state when $M = 1$, flow _chokes_, denoting that the maximal mass flow is reached. The choke state is usually symbolized with the superscript $(^*)$. The physical relation to the stagnation state read $$ \begin{align} \frac{T^*}{T_0}\ =& \ \frac{2}{\gamma +1} \\ \frac{p^*}{p_0}\ =& \ \left(\frac{2}{\gamma +1} \right)^{\gamma / (\gamma -1)} \\ \frac{\rho^*}{\rho_0}\ =& \ \left(\frac{2}{\gamma +1} \right)^{1 / (\gamma -1)} \end{align} $$ and further, the throat area relation reveals the Mach number at the end of the nozzle, which $$ \frac{A}{A^*} \ = \frac{1}{M}\ \left( \frac{2}{\gamma +1}\left(1+\frac{\gamma -1}{2}M^2\right)\right)^{\frac{\gamma+1}{2(\gamma-1)}} $$ #### [De Laval (Convergent-Divergent) Nozzle](https://en.wikipedia.org/wiki/De_Laval_nozzle) <img style="float: right;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Nozzle_de_Laval_diagram.svg/800px-Nozzle_de_Laval_diagram.svg.png" width = 40%> Based on this understanding, convergent-divergent nozzle (also called de Laval nozzle) is created to generate internal flows in supersonic state. The behavior of physical properties within the nozzle can be then described exactly based on the shape of nozzle, i.e. the nozzle cross area. During the whole process in the convergent-divergent nozzle, the pressure is descreasing. If the pressure level on the exit of nozzle does not match the environment pressure, [shock](https://en.wikipedia.org/wiki/Thermodynamic_relations_across_normal_shocks) occurs. Shock can be regarded as the non-kontineous interface between two pressure levels. The shock front can be in the divergent section, can also be outside of the nozzle. Physics and effects of the normal shock in or outside of the internal flow are one of the central topics inw the discipline of gas dynamics. Nevertheless, the pressure relation provides a usful function to determine the nozzle throat state and further evaluate the mass flow rate over the nozzle system. <img src="https://media.springernature.com/m685/springer-static/image/art%3A10.1038%2Fs41598-024-53680-2/MediaObjects/41598_2024_53680_Fig1_HTML.png" width="95%"> #### Convergent nozzle and back pressure impact The decreasing pressure also reveals significant technical insights. Say, if the pressure level outside of the nozzle ($p_b$, also called back pressure) is less than the critical pressure ($p^*$), the flow chokes ($M=1$) on the nozzle throat, e.g. state C, D, E, F on the upper diagram. Cutting the convergent-divergent nozzle on the nozzle troat, the situation becomes easier. The 6 scenarios are reduced to 3. For back pressure higher than scenario 3, i.e. $(p_b > p^*)$ scenario A, B, the Mach number on the nozzle throat, or better said nozzle exit (with subscript "$_e$"), $M_e$ can be calculated using the stagnation relation $$ \frac{p_0}{p_b} = \left(1 + \frac{\gamma -1}{2} M_e^2 \right)^{\gamma / (\gamma -1)}\qquad.\\ $$ For back pressure lower than scenario 3 $(p_b < p^*)$, $M_e = 1$. [Expansion waves](https://aerospaceweb.org/question/propulsion/q0224.shtml) occurs behind the nozzle exit. Summarizing the two scenarios, an unified formulation yields: $$ M_e = \text{min}\left\{ \ \left( \frac{2}{\gamma - 1} \right)^{\frac{1}{2}}\ \left[ \left( \frac{p_t}{p_b} \right)^{\frac{\gamma -1}{\gamma }} -1 \right]^{\frac{1}{2}}, \ 1.0 \right\} $$ <!-- <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSd4xVNf8sr-wqar6UisRzDYl3GODo-yTkpGQ&s" width="65%"> --> The convergent nozzle can also be regarded as valve in the technical applications. By using this formulation, the mass flow releasing from a system can be described, as $$ \dot{m} = \rho_e \ A_e \ u_e= \rho_t \ A_e \ M_e \ c_e \qquad . $$ This is the counterpart description for compressible gas to the Hagen-Poiseuelli equation / Bernoulli equation of the incompressinle fluid. #### Scenario -- Cartridge Gas releasing mechanism Combining the energy representation within a gas system with the mass/energy releasing throughout the nozzle, we can describe a dynamic process by focuing the system as a controll volume. The mass and energy flow rate out of the nozzle/valve are the loss terms in the mass and energy conservation. <img src="https://live.staticflickr.com/65535/53904972165_23096376f7.jpg" width = 70%> $$ \begin{align} \frac{d}{d t} \ m (t) &= -\dot{m}_e(t) \qquad &\text{Mass conservation}\\ \\ \frac{d}{d t}\ \left( c_v\ m(t) \ T(t)\right) &= - \dot{m}_e c_p T_e(t) - \frac{1}{2} \dot{m}_e u_e^2 -\dot{Q}(T, t)\qquad &\text{Energy conservation}\\ \\ P(t) &= \rho(t) \ R \ T(t) \qquad &\text{Equation of state}\\ \\ \dot{m}_e &= \rho_e \ c_e\ M_e \ A \end{align} $$ with $\dot{m}_e$, $T_e$, and $u_e$ as the mass flow rate, temperature and the velocity outwards of the nozzle exit, as the $Q$ as the heat loss of the system. (mostly due to the heat transfer.) One can also involve the temperature dependent specific heat capacity ($c_p(T)$ and $c_v(T)$) towards the real gas correction. A daily example is the gas filling tank, where pressurized gas is filled in a container. Once the valve is opened, the high pressurized gas flees due to the pressure drop. We applied this mechanism to pump up the tire or inflate a ballon. Airbag also rely on such mechanism, the stored gas inflators are exactly designed in this way. Here is a scenario: _A stored gas inflator cartridge of 150cc volume is filled with Nitrogen of 50bar. The cartridge is equipped with a vent of 1.5mm diameter._ _Once the vent is opened,_ _1. how long does it take to release the stored gas completely? 2. what is the temperature level in the bottle at the end of inflation? 3. What if the gas is changed to He?_ A python implementation for this reads ``` #! PYTHON v3.7 SCRIPT from numpy import pi, sqrt, square from scipy.optimize import newton, fsolve import matplotlib.pyplot as plt #-------------------------------------------------------------------------# # Task: # A cartridge of 150cc volume is filled with Nitrogen of 50bar. The Cartridge is equipped with a vent of 1.5mm diameter. Once the vent is opened, # 1. how long does it take to release stored gas completely? # 2. what is the temperature level in the bottle at the end of inflation? # 3. What if the gas is changed to H2? #-------------------------------------------------------------------------# # Assumption: # - caloric perfect gas, ideal gas law # - constant cp, cv and gamma (no temperature dependency obtained) # - no discharge on vent, cross area perfectly used # - no heat loss considered #><><><><><><><><><><><><><>< Functions ><><><><><><><><><><><><><><# # ----------------------------------------------------------------------- # def calc_cross_area(diameter): area = 1.0/4.0*pi*diameter**2.0 return area # ----------------------------------------------------------------------- # def calc_Mach_number(stagnation_pressure, back_pressure, gamma): if gamma != 0.0 : Mach_formula = sqrt(max(2.0/(gamma -1.0)*((stagnation_pressure/ back_pressure)**((gamma -1.0)/gamma) - 1.0 ),0.0)) Mach = min(1.0, Mach_formula) else: Mach = 0.0 return Mach # ----------------------------------------------------------------------- # def calc_nozzle_properties(stagnation_pressure, stagnation_temerature, stagnation_density, stagnation_gamma, back_pressure): Mach = calc_Mach_number(stagnation_pressure, back_pressure, stagnation_gamma) temperature = stagnation_temerature/(((stagnation_gamma-1.0)*Mach**2.0)/2.0+1.0) density = stagnation_density/(((stagnation_gamma-1.0)*Mach**2.0)/2.0+1.0)**(1.0/(stagnation_gamma-1.0)) pressure = stagnation_pressure /(((stagnation_gamma-1.0)*Mach**2.0)/2.0+1.0)**(stagnation_gamma/(stagnation_gamma-1.0)) gamma = stagnation_gamma speedOfSound = sqrt(gamma* Ru/molar_weight* temperature) velocity = speedOfSound*Mach return Mach, temperature, density, pressure, velocity # ----------------------------------------------------------------------- # # ------------------- Equation solver ----------------# # ----------------------------------------------------------------------- # def solv_system_Temperature(Temp_system , internalEnergy_previous, energy_supply, mass_system): internal_energy_system = mass_system * cv * Temp_system error = internal_energy_system - (internalEnergy_previous - energy_supply) return (error) #><><><><><><><><><><><><><>< Gas Properties ><><><><><><><><><><><><><><# Ru = 8.314 #J/(K mole) universal gas constant #====================== Nitrogen =======================# molar_weight = 28*1e-3 #[kg] cp = 1040 #J/(kg K) ''' #====================== CO2 =======================# molar_weight = 44*1e-3 #[kg] cp = 846 #J/(kg K) ''' R = Ru/molar_weight #=======================================================================# cv = cp - Ru/molar_weight gamma = cp/cv #><><><><><><><><><><><><><>< Physical properties ><><><><><><><><><><><><><><# pressure_environment = 1.013*1e5 #[Pa] temperature_environment = 23+273 #[K] volume_system = 150*1e-6 #[m^3] pressure_system = 30*1e5 #[Pa] temperature_system = temperature_environment diameter_nozzle = 1.0*1e-3 #[m] discharge = 0.5 #[-] area_nozzle = discharge* calc_cross_area(diameter_nozzle) #><><><><><><><><><><><><><>< numerical properties ><><><><><><><><><><><><><><# ent_time = 10.0 #[s] timeStep = 1e-5 #[s] outputInterval =1e-2 #[s] status = "go" iterationNumber = int(ent_time/timeStep) outputIteration = int(outputInterval/timeStep) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Main %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%# #---------------------- initial condition ------------------------# pressure_initial = pressure_system temperature_initial = temperature_environment mass_initial = pressure_initial*volume_system*molar_weight/(Ru * temperature_initial) print(f"initial gas weight: {mass_initial*1e3:.3f} g") #---------------------- creating output file -------------------------# IO_time = [] IO_pressure = [] IO_temperature = [] IO_mass = [] IO_massFlowRate = [] IO_Mach = [] for i in range(0, iterationNumber): currentTime = i * timeStep density_initial = mass_initial/volume_system internal_energy_initial = mass_initial * cv * temperature_initial #--------------------- calculate exit mass and energy ------------------------# Mach_exit, temperature_exit, density_exit, pressure_exit, velocity_exit = \ calc_nozzle_properties(pressure_initial, temperature_initial, density_initial, gamma, pressure_environment) massFlowRate_exit = velocity_exit* density_exit* area_nozzle massAmount_exit = massFlowRate_exit* timeStep enthalpy_exit = 0.5 * massAmount_exit * square(velocity_exit) +\ massAmount_exit * cp * temperature_exit mass_initial = mass_initial - massAmount_exit temperature_system = newton(solv_system_Temperature, temperature_initial, maxiter = 300, tol=1.0e-10, \ args=(internal_energy_initial, enthalpy_exit, mass_initial)) #temperature_system = (internal_energy_initial - enthalpy_exit)/(cv*mass_initial) pressure_system = mass_initial/volume_system * R * temperature_system pressure_initial = pressure_system temperature_initial = temperature_system if pressure_system <= pressure_environment and status == "go" : status = "stop" print(f"complete released at {currentTime:.3f} s") print(f"temperature: {temperature_system-273:.3f} °C") break if i % outputIteration == 0 : IO_time.append(currentTime) IO_pressure.append((pressure_system-101300)/1e5) IO_temperature.append(temperature_initial-273) IO_mass.append(mass_initial*1e3) IO_massFlowRate.append(massFlowRate_exit) IO_Mach.append(Mach_exit) fig, (ax1, ax2) = plt.subplots(2) fig.suptitle('Gas release characteristics') ax1.plot(IO_time, IO_pressure) ax1.grid(True) ax1.set_ylabel("pressure [bar]") ax2.plot(IO_time, IO_temperature) ax2.grid(True) ax2.set_xlabel("time [ms]") ax2.set_ylabel("temperature [°C]") ax3.plot(IO_time, IO_Mach) ax3.grid(True) ax3.set_xlabel("time [ms]") ax3.set_ylabel("Mach number [-]") fig.show() ``` ### 4.2.2 Solid propellant deflagration and interior ballistics Interior ballistics is a discipline studying the dynamics of pressure condition in one or multiple closed systems, which further utilized to e.g. trigger projectiles in a gun/barrel or serve as propulsion system for rocket movement. <img src="https://d3i71xaburhd42.cloudfront.net/04e2d66d9d75b2d8575ee35bfb323710a2486888/14-Figure1.4-1.png" width=55%> <img src="https://www.researchgate.net/publication/348035213/figure/fig1/AS:11431281090011087@1665852823265/Basic-components-and-structure-of-the-solid-propellant-rocket-engine.jpg" width=35%> Imagine the high velocity of a projectile or the movement of a heavy rocket, all these applications require very high pressure level to push the objectives into demanded dynamics. The pressure level are commonly achieved by deflagration of propellent, which creates huge amount of gas and heat very rapidly (in millisecond scale). These mechanisms involve the chemical reactions, i.e. the fuel-oxidizer behavior, the propellant shape and the combination chamber design. #### Solid propellant deflagration The word _deflagration_ denotes rapid combustion, which requires the homogeneous mixing of fuel and oxidizers. If one thinks on the combustion process in e.g. in the internal combustion engine, the oxidizer is always taken from the environment, i.e. air. Differ to that, the characteristics of solid proepellant is the premixing of fuel and oxidizer in the solid form. Thus, the solid propellant devices can be deployed in deep see, as well as in outer space. The chemical reaction process during the deflagration process is very complex. It involves several intermediate steps to reach the equilibrium state. Fortunately, there are [_database_](http://www.jpyro.co.uk/wp-content/uploads/j01_11_htfsr.pdf) and [_calculatuon tools_](https://rocketworkbench.sourceforge.net/equil.phtml) for common composites. An example is shown in the figure below for balck powder composition. <img src="https://live.staticflickr.com/65535/53906981904_e76f0709fa_c.jpg"> <br/> <br/> Purposing in quantifying the system performance, the most important information are the _gas yield, species composition_ and the _heat of combustion_ at the final equilibrium state. These are the representative information serve as the source terms in the mass and energy conservation. _For the black powder example, the CO, CO2 and N2 are the main products obtaining ~70% gas yield, shown in the Figure. The combustion enthalpy is calculated as 3494 kJ/kg, as [exothermic process](https://en.wikipedia.org/wiki/Exothermic_reaction)._ #### Burn rate and Vieille's law The combustion of solid propellant always occurs on the surface of the solid body, stated in [__Piobert's law__](https://en.wikipedia.org/wiki/Piobert%27s_law). The propellant design is all based on this statement. Shape of the propellant affects to different burning dynamics, which supports diverse applications. <img src="https://www.nakka-rocketry.net/th_pix/grains1.gif"> [__Vieille's law__](https://www.nakka-rocketry.net/burnrate.html) is another puzzle to complete the mass and energy production rate in the transport process. This is a simplified way to determine the propellant burn rate, in the dimension of [mm/s]. As a rule of thumb, the burn rate of the solid propellant is exponentially proportional to the pressure state, which $$ \dot{\gamma} = \ a \ p^n $$ where - $\dot{\gamma}$ is the burn rate, dimensioned in [mm/s] - $p$ is the pressure, usually dimensioned in [MPa] - $a$, $n$ are the empirical material parameters, which are determined by e.g. [closed vessel tests](https://www.sciencedirect.com/science/article/abs/pii/0010218075900899) #### Solid rocket motor (SRM) application Solid rocket motor is one of the classical applications working with solid propellant. For which, PEP calculation tool also provides the rocket nozzle specific results such as nozzle throat behavior, $c^*$ and Isp, etc. <img src="https://live.staticflickr.com/65535/53907271670_68ea6c8f24_z.jpg" width="70%"> [__Thrust__](https://www.grc.nasa.gov/www/k-12/airplane/rockth.html) is the key performance characteristics for rocket relevant applications. The thrust Equation read: $$ F=\dot{m}\ u_e+(p_e−p_a)A_e $$ where - $F$ is the thrust. - $\dot{m}$ is the mass flow rate of the exhaust. - $u_e$, $p_e$ and $A_e$ are the velocity, pressure and area at the nozzle exit. - $P_a$ is the ambient pressure. Based on the thrust, some analysis indices are further defined. - $\pmb{A_e/A_t}$ ratio is the ratio of the exit area to the throat area of the nozzle, acquired by the isentropic behavior as listed in the last subsection. - $\pmb c^*$ is the characteristic exhaust velocity, defined as $$ c^∗=\dot{m}\ p_c​\ A_t = \ \sqrt{\frac{R\ T_c}{\gamma}} \left( \frac{2}{\gamma + 1} \right)^{(\gamma + 1)/\left(2(\gamma -1)\right)} $$ where - $A_t$ is the throat Area (the narrowest part of the rocket nozzle, where the cross-sectional area is minimized). This is where the exhaust gases reach their highest velocity (assuming choked flow). - $T_c$ is the temperature in the combustion chamber, which is dominated by the chemical reaction, i.e. combustion temperature. - Specific Impulse [__*Isp*__](https://www.grc.nasa.gov/www/k-12/airplane/specimp.html) is the ratio of _total impulse_ to _total weight_, defined by $$ \textit{Isp}=\frac{\int F \ dt}{g_0 \ \int \dot{m}\ dt}= \frac{F}{\dot{m}\ g_0} $$ with $g_0$ as the gravitational acceleration. <br/> <br/> <br/> #### Numerical Approach Tracing back to describe a solid rocket propulsion system within a solid inner space as control volume. It results to the equation system: <img style="float: right;" src="https://live.staticflickr.com/65535/53907044578_0cd50fa4cc_w.jpg" width ="18%"> $$ \begin{align} &\text{Mass conservation (solid)}:\\ & \qquad \frac{d m_s}{d t} = -\rho_s \dot{\gamma} A(t) \\ \\ &\text{Mass conservation (gas)}:\\ & \qquad \frac{d m_g}{d t} = \frac{d}{dt} (\rho_g V_g) = \rho_s \dot{\gamma} A(t) \ \eta - \dot{m}_e \\ \\ &\text{Energy conservation}:\\ & \qquad \frac{d E_g}{d t} = \frac{d}{dt} (\rho_g V_g e_g) = \rho_s \dot{\gamma} A(t) \ \eta \ h_c - (\dot{m}_e h_e + \frac{1}{2} \dot{m}_e u_e^2) - \dot{Q}\\ \end{align} $$ with - Internal energy: $\displaystyle e_g = \sum_{i}^{n}\ \phi_i\ c_{v_i}\ T$ - Equation of state (ideal gas law): $\displaystyle p = \rho_g \ R \ T$ - Mass flow rate $\displaystyle \dot{m}_e = \rho_t \ c_t M_t \ A ,\qquad c_t = \sqrt{\gamma R T_t}$ - Gas yield ($\eta$), specific heat capacity in constant volume ($c_v$)/ pressure ($c_p$) - Thrust force $F=\dot{m_e}\ u_e+(p_e−p_a)A_e$ Example: _Configuration of an Ariane4 Solid Rocket Motor filled with Ammonium Nitrate (AN) in a hollow column propellant form. Nozzle of the rocket is applied in the expansion ratio Ae/At as 8.3:1 with the exit diameter 0.96 m. The configuration of Ariane 4 and AN properties reads:_ <img style="float: right;" src="https://live.staticflickr.com/65535/53907035113_a0e7a37ff9.jpg" width="70%"> - _Motor chamber inner-diameter: 1.07 [m]_ - _Motor chamber inner-height: 11.32 [m]_ - _Propellant hollow column inner-diameter: 0.718 [m]_ - _Propellant mass: 9640 [kg]_ - _Density AN: 1724 [kg/m^3]_ - _Burn rate AN:_ - _b0_AN = 0.05*25.4_ - _n0_AN = 0.88_ - _bor_AN = 30_ - _b1_AN = 0.32*25.4_ - _b1_AN = 0.33_ - _Gas yield AN: 100% [-]_ - _$c_p$ of AN combustion production: 1760 [J/(kg.K)]_ - _$c_v$ of AN combustion production: 1390 [J/(kg.K)]_ - _molar weight AN combustion production: 22.85 #[g/mole]_ - _combustion enthalpy: 1825 #[kJ/kg]_ _Assuming the combustion chamber has been heat up to 200°C for a proper ignition of AN, and no air portion in the expelling gas considered._ Assignments: - _The $A_e/A_t$ ratio is 8.3, what is the expected Mach number on the exit side?_ - _What is the pressure, temperature and thrust evolution in the combustion chamber during the entire flight time?_ - _How long does the combustion last?_ - _Is the temperature in the chamber identical to the combustion temperature? If not, why is it?_ A python implementation for this system can be: ``` #! PYTHON 3.7 SCRIPT #------------------------------------------------------# # Task 04 --Solid Rocket motor # Configuration of an Arian4 Solid Rocket Motor filled with Ammonium Nitrate in a hollow column propellant form. # Nozzle of the rocket is applied in the expansion ratio Ae/At as 8.3:1 with the exit diameter 0.96 m. # The configuration of Ariane 4 reads: # Motor chmaber inner-diameter: 1.07 #[m] # Motor chamber inner-height: 11.32 #[m] # Propellant hollow colume inner-diameter: 0.718 #[m] # Propellant mass: 9640 #[kg] # Density AN: 1724 [kg/m^3] # Burn rate AN: # a0_AN = 0.05*25.4 # n0_AN = 0.88 # bor_AN = 30 # a1_AN = 0.32*25.4 # n1_AN = 0.33 from numpy import pi, sqrt, square from scipy.optimize import newton, fsolve import time, sys Ru = 8.314 #universal gas constant #================== Air =================== molar_weight_air = 28.964*1e-3 #[kg/mole] cp_air =1000 #[J/kg.K] cv_air = 718 #[J/kg.K] gamma_air = 1.4 #%%%%%%%%%%%% Universal constants %%%%%%%%%%%%% #================== Propellant =================== density_propellant = 1.724*1e3 #[kg/m^3] gas_yield_weight = 1.0 gas_yield_volumetric = 1.0 diameter_outer_propellant = 1.07 #[m] diameter_inner_propellant = 0.718 #[m] height_propellant = 11.32 #[m] burnrate_AN = [1.27, 0.88, 30.0e6, 8.13, 0.33] cp_gas = 1760 #[J/kg.K] cv_gas = 1390 #[J/kg.K] gamma_gas = cp_gas/cv_gas molar_weight_gas = 22.85*1e-3 #[kg/mole] combustion_enthalpy = 1825.4*1e3 #[J/kg] temperature_initial = 200+273 #[K] pressure_initial = 1.597*1e5 #[Pa] ratio_nozzle = 8.3 #[-] crossArea_throat = 0.087 #[m^2] crossArea_exit = crossArea_throat*ratio_nozzle #================== Environment =================== volume_vessel_default = 10.17 #[m^3] temperature_environment = 23+273 #[K] pressure_environment = 1.013*1e5 #[Pa] area_vessel_surface = 38.033 #[m^2] heat_conduct_coefficient = 0#1.5*1e3 #[J/(K m^2)] #================== Numerical Setups ============ startTime = 0 #[s] timeStep = 1e-5 #[s] outputInterval = 0.5 #[s] endTime = 200.0 #[s] numberOfIteration = int((endTime-startTime)/timeStep) ouputIteration = int(outputInterval/timeStep) outputFile = "results.dat" writeOutput = open(outputFile, "w") # %%%%%%%%%%%%%%%%%%%%%%%%%% Functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # ----------------------------------------------------------------------- # # ------------------- OS environmental ------------------------# # ----------------------------------------------------------------------- # def print_no_newline(string): sys.stdout.write(string) sys.stdout.flush() # ========================================================================# # ----------------------------------------------------------------------- # # --------------------- State functions ------------------------# # ----------------------------------------------------------------------- # def cal_pressure(mass_gas, mass_air, volume_vessel, temperature): # ideal gas following Dalton's law law pressure_air = mass_air/volume_vessel *Ru/molar_weight_air * temperature pressure_gas = mass_gas/volume_vessel *Ru/molar_weight_gas * temperature pressure = pressure_air + pressure_gas return pressure #---------------------------------------------- def cal_temperature(internal_energy, energy_supply, mass_gas, mass_air): # 1st law of thermodynamics temperature = (internal_energy + energy_supply)/(mass_gas* cv_gas + mass_air* cv_air) return temperature #---------------------------------------------- def cal_internalEnergy(mass_gas, mass_air, temperature): internalEnergy = (mass_gas* cv_gas + mass_air* cv_air)* temperature return internalEnergy # ========================================================================# # ----------------------------------------------------------------------- # # --------------------- Geometric functions ------------------------# # ----------------------------------------------------------------------- # def calc_area_type2(diameter, height): area_surface = pi*diameter*height return area_surface #---------------------------------------------- def calc_volume_type2(diameter_inner, diameter_outer, height): volume = pi/4.0*(diameter_outer**2.0 - diameter_inner**2.0) *height return volume #---------------------------------------------- def evol_geometric_type2(cylinder_geometry, burning_velocity, time_step): diameter_inner_before, diameter_outer,height = cylinder_geometry volume_before = calc_volume_type2(diameter_inner_before, diameter_outer, height) surfaceArea_before = calc_area_type2(diameter_inner_before, height) volume_burnt = min(surfaceArea_before * burning_velocity * time_step , volume_before) diameter_inner_after = max(diameter_inner_before + 2.0 * burning_velocity * time_step , 0.0) volume_after = calc_volume_type2(diameter_inner_after, diameter_outer, height) area_after = calc_area_type2(diameter_inner_after, height) cylinder_geometry = diameter_inner_after, diameter_outer, height return (volume_burnt, volume_after, cylinder_geometry) # ========================================================================# # ----------------------------------------------------------------------- # # --------------------- Propellant functions ------------------------# # ----------------------------------------------------------------------- # def calc_burning_rate(pressure, b_0, n_0, border_pressure, b_1, n_1): if pressure <= border_pressure: burning_rate = 1e-3*b_0 * (pressure/1e6)**n_0 #[m/s] else: burning_rate = 1e-3*b_1 * (pressure/1e6)**n_1 #[m/s] return burning_rate # ========================================================================# # ----------------------------------------------------------------------- # # ------------------- Transition properties ----------------# # ----------------------------------------------------------------------- # def calc_throat_Mach_number(stagnation_pressure, back_pressure, gamma): if gamma != 0.0 : Mach_formula = sqrt(max(2.0/(gamma -1.0)*((stagnation_pressure/ back_pressure)**((gamma -1.0)/gamma) - 1.0 ),0.0)) Mach = min(1.0, Mach_formula) else: Mach = 0.0 return Mach # ========================================================================# def calc_troat_properties(stagnation_pressure, stagnation_temperature, stagnation_density, stagnation_gamma, molar_weight, back_pressure): Mach = calc_throat_Mach_number(stagnation_pressure, back_pressure, stagnation_gamma) temperature = stagnation_temperature/(((stagnation_gamma-1.0)*Mach**2.0)/2.0+1.0) density = stagnation_density/(((stagnation_gamma-1.0)*Mach**2.0)/2.0+1.0)**(1.0/(stagnation_gamma-1.0)) pressure = stagnation_pressure /(((stagnation_gamma-1.0)*Mach**2.0)/2.0+1.0)**(stagnation_gamma/(stagnation_gamma-1.0)) speedOfSound = sqrt(stagnation_gamma* Ru/molar_weight* temperature) velocity = speedOfSound*Mach return Mach, temperature, density, pressure, velocity # ========================================================================# def solv_exit_Mach_number(Mach_exit, ratio_area, Mach_throat, gamma): rhs =Mach_exit/ Mach_throat * ((1.0+((gamma - 1.0)/2.0)*Mach_throat**2.0) / (1.0+((gamma - 1.0)/2.0)*Mach_exit**2.0) )**((gamma+1.0)/(2.0*(gamma-1.0))) lhs = 1.0/ratio_area error = lhs - rhs return error # ========================================================================# def calc_exit_velocity(Mach_throat, Mach_exit, temperature_throat, molar_weight, gamma): temperature_exit = temperature_throat * ((1.0+((gamma-1.0)/2.0)*Mach_throat**2.0)/(1.0+((gamma-1.0)/2.0)*Mach_exit**2.0)) speedOfSound_exit = sqrt(gamma* Ru/molar_weight* temperature_exit ) velocity_exit = Mach_exit*speedOfSound_exit return velocity_exit # ========================================================================# def calc_exit_presure(Mach_throat, Mach_exit, pressure_throat, gamma): pressure_exit = pressure_throat * ((1.0+((gamma-1.0)/2.0)*Mach_throat**2.0)/(1.0+((gamma-1.0)/2.0)*Mach_exit**2.0))**(gamma/(gamma-1.0)) return pressure_exit # %%%%%%%%%%%%%%%%%%%%%%%%%% Main %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # ========================================================================# # ----------------------------------------------------------------------- # # ------------------- initial condition ----------------# # ----------------------------------------------------------------------- # volume_propellant = calc_volume_type2(diameter_inner_propellant, diameter_outer_propellant, height_propellant) volume_vessel_current = volume_vessel_default - volume_propellant temperature_current = temperature_initial pressure_current = pressure_initial density_air = pressure_current/(Ru/molar_weight_air * temperature_current) mass_air =density_air * volume_vessel_current mass_gas = 0.0 burnt_volume = 0.0 writeOutput.write("#time"+" "+"Pressure"+" "+"Temperature"+" "+"diameter"+" "+"height"+" "+"surface_area"+" "+\ "burnt_volume"+" "+"rest_volume"+"\n") writeOutput.write("#[s]"+" "+"[bar]"+" "+"[K]"+" "+"[mm]"+" "+"[mm]"+" "+"[mm^2]"+" "+\ "[mm^3]"+" "+"[mm^3]"+"\n") print("pressure",pressure_current/1e6, "MPa") for i in range(0, numberOfIteration): currentTime = i*timeStep + startTime internalEnergy = cal_internalEnergy(mass_gas, mass_air, temperature_current) gasDensity_current = mass_gas/volume_vessel_current mass_supply = 0.0 energy_supply = 0.0 #================================ transitional properties ==================================# #---------------------------- assuming all the expelled gas are propellant producted -----------# #-------------------------------------------------------------------------------------------------# [Mach_throat, temperature_throat, density_throat, pressure_throat, velocity_throat] = \ calc_troat_properties(pressure_current, temperature_current, gasDensity_current, gamma_gas, molar_weight_gas, pressure_environment) massFlowRate_throat = density_throat * velocity_throat* crossArea_throat massAmount_throat = min(massFlowRate_throat* timeStep, mass_gas) energyAmount_throat = 0.5 * massAmount_throat * square(velocity_throat) +\ massAmount_throat * cp_gas * temperature_throat mass_supply = mass_supply - massAmount_throat energy_supply = energy_supply - energyAmount_throat #--------------------------- exit properties --------------------------------------------------# if Mach_throat < 1.0: Mach_exit = newton(solv_exit_Mach_number, 0.7, args=(ratio_nozzle, Mach_throat, gamma_gas)) else: Mach_exit = newton(solv_exit_Mach_number, 3.0, args=(ratio_nozzle, Mach_throat, gamma_gas)) velocity_exit = calc_exit_velocity(Mach_throat, Mach_exit, temperature_throat, molar_weight_gas, gamma_gas) pressure_exit = calc_exit_presure(Mach_throat, Mach_exit, pressure_throat, gamma_gas) thrust = massFlowRate_throat * velocity_exit +max((pressure_exit - pressure_environment),0.0)*crossArea_exit #================================ propellant deflagration ==================================# burnrate = calc_burning_rate(pressure_current, burnrate_AN[0], burnrate_AN[1], burnrate_AN[2], burnrate_AN[3], burnrate_AN[4]) propellant_geometry = diameter_inner_propellant, diameter_outer_propellant, height_propellant volume_burnt_current, volume_rest_propellant, propellant_geometry_after = \ evol_geometric_type2(propellant_geometry, burnrate, timeStep) diameter_inner_propellant, diameter_outer_propellant, height_propellant = propellant_geometry_after #=================================================================================================# heatLoss = area_vessel_surface* (temperature_current - temperature_environment)*heat_conduct_coefficient *timeStep mass_supply = mass_supply+ volume_burnt_current* density_propellant* gas_yield_weight energy_supply = energy_supply + volume_burnt_current* density_propellant* gas_yield_weight *combustion_enthalpy energy_supply = energy_supply - heatLoss #================================= update state ===========================================# burnt_volume = burnt_volume +volume_burnt_current volume_vessel_current = volume_vessel_current + volume_burnt_current* gas_yield_volumetric mass_gas = mass_gas + mass_supply temperature_current = cal_temperature(internalEnergy, energy_supply, mass_gas, mass_air) pressure_current = cal_pressure(mass_gas, mass_air, volume_vessel_current, temperature_current) if i % ouputIteration == 0 : print_no_newline(">>"+str("%.2f" % (currentTime))+"s") writeOutput.write(str(currentTime)+" "+str(pressure_current/1e5)+" "+str(temperature_current)+" "+\ str(thrust/1e3)+" "+str(Mach_throat)+" "+str(Mach_exit)+" "+\ str(burnt_volume*1e6)+" "+str(volume_rest_propellant*1e6)+"\n") ``` [__BACK TO CONTENT__](https://hackmd.io/@SamuelChang/H1LvI_eYn)