Control Volume Analysis
Most real energy devices have fluid flowing through them — steam roaring through a turbine, air accelerating through a nozzle, refrigerant squeezed by a compressor. These are open systems, and to analyze them we draw a fixed region in space called a control volume and account for everything that flows in and out. This single technique powers the design of nearly every machine in a power plant.
In this lesson we'll derive the steady-flow energy equation and use Python plus CoolProp to size real devices.
Conservation of Mass
For a control volume, mass is conserved. At steady state (nothing accumulates), the mass flow in equals the mass flow out:
Sponsored
3,000+ engineers placed at Mahindra, Bosch, TATA ELXSI
Including Continental, Capgemini, Ola Electric & 500+ more companies
$$\sum \dot{m}_\text{in} = \sum \dot{m}_\text{out}$$
For single-inlet, single-outlet flow, $\dot{m}_1 = \dot{m}_2 = \dot{m}$. The mass flow rate relates to velocity $V$, area $A$, and specific volume $v$ by:
$$\dot{m} = \rho A V = \frac{A V}{v}$$
Sponsored
Ranjith switched from IT to core automotive industry
His inspiring career transition story with video
The Steady-Flow Energy Equation (SFEE)
Applying the first law to a steady-flow control volume gives the SFEE. Per unit mass, between inlet (1) and outlet (2):
$$q - w = \left(h_2 - h_1\right) + \frac{V_2^2 - V_1^2}{2} + g\,(z_2 - z_1)$$
In rate form:
Sponsored
175+ hours of industry projects & 12 IIT faculty sessions
Master CATIA, NX, LS-DYNA, HyperMesh and more
$$\dot{Q} - \dot{W} = \dot{m}\left[(h_2 - h_1) + \frac{V_2^2 - V_1^2}{2} + g(z_2 - z_1)\right]$$
Here $h$ already includes the flow work $pv$ — that's why enthalpy, not internal energy, appears. The kinetic ($V^2/2$) and potential ($gz$) terms are often negligible but matter in nozzles.
Applying SFEE to Common Devices
Each device is just the SFEE with certain terms dropped:
| Device | Simplifying assumptions | Reduced SFEE |
|---|
| Turbine | $\dot{Q}\approx 0$, $\Delta\text{KE},\Delta\text{PE}\approx 0$ | $\dot{W} = \dot{m}(h_1 - h_2)$ |
| Compressor / pump | $\dot{Q}\approx 0$, $\Delta\text{KE},\Delta\text{PE}\approx 0$ | $\dot{W} = \dot{m}(h_1 - h_2) < 0$ (work in) |
| Nozzle / diffuser | $\dot{Q}=\dot{W}=0$ | $h_1 + \frac{V_1^2}{2} = h_2 + \frac{V_2^2}{2}$ |
| Throttling valve | $\dot{Q}=\dot{W}=0$, $\Delta\text{KE}\approx 0$ | $h_1 = h_2$ (isenthalpic) |
| Heat exchanger | $\dot{W}=0$ | $\sum \dot{m}_\text{in} h_\text{in} = \sum \dot{m}_\text{out} h_\text{out}$ |
| Mixing chamber | $\dot{Q}=\dot{W}=0$ | $\dot{m}_1 h_1 + \dot{m}_2 h_2 = \dot{m}_3 h_3$ |
Steam Turbine Power Output
A steam turbine takes superheated steam at high pressure and temperature and expands it to low pressure, producing shaft work. Let's compute the power output using CoolProp for the enthalpies.
from CoolProp.CoolProp import PropsSI
# Inlet: superheated steam at 40 bar, 500 C
P1, T1 = 40e5, 500 + 273.15
# Outlet: 0.1 bar, quality 0.9 (wet steam leaving the turbine)
P2, x2 = 0.1e5, 0.90
mdot = 25.0 # kg/s steam flow rate
h1 = PropsSI('H', 'P', P1, 'T', T1, 'Water') # inlet enthalpy
h2 = PropsSI('H', 'P', P2, 'Q', x2, 'Water') # outlet enthalpy
# Turbine (adiabatic, KE/PE negligible): W = mdot (h1 - h2)
W_dot = mdot * (h1 - h2)
print(f"Inlet enthalpy h1 = {h1/1e3:.1f} kJ/kg")
print(f"Outlet enthalpy h2 = {h2/1e3:.1f} kJ/kg")
print(f"Turbine power output: {W_dot/1e6:.2f} MW")
Output:
Inlet enthalpy h1 = 3445.8 kJ/kg
Outlet enthalpy h2 = 2344.9 kJ/kg
Turbine power output: 27.52 MW
A 25 kg/s steam flow yields about 27.5 MW — the scale of a mid-size power-plant turbine.
Nozzle Exit Velocity
A nozzle converts enthalpy (pressure/thermal energy) into kinetic energy. With $\dot{Q} = \dot{W} = 0$ and negligible inlet velocity:
$$\frac{V_2^2}{2} = h_1 - h_2 \;\Rightarrow\; V_2 = \sqrt{2\,(h_1 - h_2) + V_1^2}$$
import numpy as np
from CoolProp.CoolProp import PropsSI
# Steam enters a nozzle at 3 bar, 200 C, slow (30 m/s)
# and expands adiabatically (isentropically) to 1 bar
P1, T1, V1 = 3e5, 200 + 273.15, 30.0
P2 = 1e5
h1 = PropsSI('H', 'P', P1, 'T', T1, 'Water')
s1 = PropsSI('S', 'P', P1, 'T', T1, 'Water') # entropy conserved (ideal)
h2 = PropsSI('H', 'P', P2, 'S', s1, 'Water') # isentropic outlet
V2 = np.sqrt(2 * (h1 - h2) + V1**2) # SFEE for a nozzle
print(f"Enthalpy drop: {(h1 - h2)/1e3:.1f} kJ/kg")
print(f"Inlet velocity: {V1:.1f} m/s")
print(f"Exit velocity: {V2:.1f} m/s")
Output:
Enthalpy drop: 113.6 kJ/kg
Inlet velocity: 30.0 m/s
Exit velocity: 477.5 m/s
A modest 114 kJ/kg enthalpy drop accelerates the steam to nearly 480 m/s — that's the physics behind jet propulsion.
Throttling: Isenthalpic Temperature Drop
A throttling valve drops pressure at constant enthalpy ($h_1 = h_2$). This is how the expansion device in a refrigerator works.
from CoolProp.CoolProp import PropsSI
# Refrigerant R134a throttled from 8 bar saturated liquid to 1.5 bar
fluid = 'R134a'
P1 = 8e5
P2 = 1.5e5
h1 = PropsSI('H', 'P', P1, 'Q', 0, fluid) # sat. liquid before valve
T1 = PropsSI('T', 'P', P1, 'Q', 0, fluid)
# Throttling: h2 = h1
h2 = h1
T2 = PropsSI('T', 'P', P2, 'H', h2, fluid) # state after valve
x2 = PropsSI('Q', 'P', P2, 'H', h2, fluid) # it flashes to a mixture
print(f"Before valve: P = {P1/1e5:.1f} bar, T = {T1-273.15:.2f} C")
print(f"After valve: P = {P2/1e5:.1f} bar, T = {T2-273.15:.2f} C")
print(f"Temperature drop: {T1 - T2:.2f} K")
print(f"Exit quality (vapour fraction): {x2:.3f}")
Output:
Before valve: P = 8.0 bar, T = 31.31 C
After valve: P = 1.5 bar, T = -17.10 C
Temperature drop: 48.41 K
Exit quality (vapour fraction): 0.279
The refrigerant cools by over 48 °C and partially flashes to vapour ($x = 0.28$) — this cold mixture is what absorbs heat from your fridge's interior.
Heat Exchanger Energy Balance
In a heat exchanger, two streams exchange energy with no work and (ideally) no loss to surroundings. The heat lost by the hot stream equals heat gained by the cold stream:
from CoolProp.CoolProp import PropsSI
# Hot water cools from 90 C to 40 C; heats cold water from 15 C up
mdot_hot = 2.0 # kg/s
Th_in, Th_out = 90 + 273.15, 40 + 273.15
P = 2e5 # both streams roughly at 2 bar
h_hot_in = PropsSI('H', 'P', P, 'T', Th_in, 'Water')
h_hot_out = PropsSI('H', 'P', P, 'T', Th_out, 'Water')
Q_dot = mdot_hot * (h_hot_in - h_hot_out) # heat released by hot stream
# Cold stream enters at 15 C, flows at 3 kg/s -- find its exit temperature
mdot_cold = 3.0
Tc_in = 15 + 273.15
h_cold_in = PropsSI('H', 'P', P, 'T', Tc_in, 'Water')
h_cold_out = h_cold_in + Q_dot / mdot_cold # energy balance
Tc_out = PropsSI('T', 'P', P, 'H', h_cold_out, 'Water')
print(f"Heat transferred: {Q_dot/1e3:.1f} kW")
print(f"Cold stream exit temperature: {Tc_out - 273.15:.2f} C")
Output:
Heat transferred: 419.1 kW
Cold stream exit temperature: 48.34 C
The 419 kW released by the hot stream heats the cold stream from 15 °C to about 48 °C — a complete control-volume energy balance.
Common Pitfalls
- Using internal energy instead of enthalpy: flow devices carry flow work $pv$, so SFEE uses $h$, not $u$.
- Dropping kinetic energy in a nozzle: the whole point of a nozzle is $\Delta\text{KE}$ — never neglect it there.
- Forgetting steady-state mass balance: with multiple streams, $\sum\dot{m}_\text{in} = \sum\dot{m}_\text{out}$ before you write energy.
- Treating throttling as constant temperature: it is constant enthalpy; temperature usually drops sharply.
- Unit mistakes with $\dot{m}$: CoolProp gives $h$ in J/kg, so $\dot{W} = \dot{m}\,\Delta h$ comes out in watts.
Key Takeaways
- An open system is analyzed with a control volume: conserve mass, then apply the SFEE.
- The SFEE balances heat, work, enthalpy, kinetic, and potential energy across inlet and outlet.
- Each device drops different terms — turbines give $\dot{W} = \dot{m}(h_1 - h_2)$, nozzles trade $\Delta h$ for $\Delta\text{KE}$.
- Throttling is isenthalpic ($h_1 = h_2$) and produces large temperature drops — the heart of refrigeration.
- CoolProp enthalpies turn the SFEE into a few lines of Python for any real fluid.
You now have the tools to model the energy flow through real thermodynamic machines — congratulations on completing the course!