Note
Go to the end to download the full example code or to run this example in your browser via JupyterLite.
Gouy and Stodola: lost work (1889-1905)#
Georges Gouy (1889) asked how much work a system can deliver when the only
other body available is the environment at \(T_0\). He showed that every
irreversibility costs work equal to \(T_0\) times the entropy it
generates. Aurel Stodola reached the same result independently for steam
turbines, in the editions of Die Dampfturbinen from 1898 to 1905. The
Gouy-Stodola theorem, \(W_{lost} = T_0 S_{gen}\)
(exergy_destruction()), lets an
engineer rank the losses of a plant in a single currency. The example prices
three irreversibilities: heat crossing a temperature difference, a
throttling valve, and an imperfect turbine.
import matplotlib.pyplot as plt
import numpy as np
from engineeringkit.thermodynamics import carnot_efficiency, exergy_destruction, steam_properties
T0 = 298.15
Heat across a temperature difference#
One kilowatt flows from a furnace at 1200 K into boiling water at 600 K. The entropy generated is \(\dot Q(1/T_2 - 1/T_1)\). The lost work equals the difference between what a Carnot engine could have made from the heat at each temperature.
Q, T1, T2 = 1000.0, 1200.0, 600.0
S_gen = Q / T2 - Q / T1
lost = exergy_destruction(T0, S_gen)
print(f"heat transfer: S_gen = {S_gen:.4f} W/K, lost work {lost:.0f} W")
assert np.isclose(lost, Q * (carnot_efficiency(T1, T0) - carnot_efficiency(T2, T0)))
heat transfer: S_gen = 0.8333 W/K, lost work 248 W
A throttling valve#
Steam at 3 MPa and 300 °C is throttled to 0.5 MPa. Its enthalpy is unchanged, so the first law sees no loss at all. The second law does: the entropy rises, and the drop in flow exergy \(h - T_0 s\) equals the lost work.
inlet = steam_properties(3e6, 573.15)
outlet = steam_properties(0.5e6, h=inlet.h)
s_gen = outlet.s - inlet.s
lost_valve = exergy_destruction(T0, s_gen)
exergy_drop = (inlet.h - T0 * inlet.s) - (outlet.h - T0 * outlet.s)
print(f"valve: {inlet.T - 273.15:.0f} °C to {outlet.T - 273.15:.1f} °C, s_gen = {s_gen:.1f} J/(kg K)")
print(f"lost work {lost_valve / 1e3:.1f} kJ/kg, drop in flow exergy {exergy_drop / 1e3:.1f} kJ/kg")
assert np.isclose(lost_valve, exergy_drop)
valve: 300 °C to 266.0 °C, s_gen = 793.9 J/(kg K)
lost work 236.7 kJ/kg, drop in flow exergy 236.7 kJ/kg
A turbine with 85% isentropic efficiency#
The same steam expands to 10 kPa. The real turbine delivers 85% of the isentropic enthalpy drop. Its lost work is less than the 15% of work it misses: part of the extra enthalpy left in the exhaust could still be used.
ideal = steam_properties(10e3, s=inlet.s)
w_ideal = inlet.h - ideal.h
real = steam_properties(10e3, h=inlet.h - 0.85 * w_ideal)
lost_turbine = exergy_destruction(T0, real.s - inlet.s)
print(f"turbine: work {0.85 * w_ideal / 1e3:.0f} of {w_ideal / 1e3:.0f} kJ/kg, lost work {lost_turbine / 1e3:.0f} kJ/kg")
print(f"exhaust quality {real.x:.3f} instead of {ideal.x:.3f}")
assert lost_turbine < 0.15 * w_ideal
assert np.isclose(lost_turbine, (inlet.h - T0 * inlet.s) - (real.h - T0 * real.s) - 0.85 * w_ideal)
turbine: work 785 of 923 kJ/kg, lost work 129 kJ/kg
exhaust quality 0.844 instead of 0.786
Lost work against isentropic efficiency#
eta = np.linspace(0.6, 1.0, 41)
lost_curve = [exergy_destruction(T0, steam_properties(10e3, h=inlet.h - e * w_ideal).s - inlet.s) / 1e3 for e in eta]
fig, ax = plt.subplots(figsize=(6, 3.5))
ax.plot(eta, lost_curve, label="lost work, T₀ s_gen")
ax.plot(eta, (1 - eta) * w_ideal / 1e3, "--", label="work not delivered")
ax.set(xlabel="isentropic efficiency", ylabel="[kJ/kg]", title="Turbine from 3 MPa, 300 °C to 10 kPa")
ax.legend()
fig.tight_layout()
assert np.isclose(lost_curve[-1], 0, atol=1e-6) and np.all(np.diff(lost_curve) < 0)
plt.show()

Total running time of the script: (0 minutes 0.037 seconds)