First Law & Energy
The first law of thermodynamics is simply conservation of energy: energy is never created or destroyed, only converted. When you compress the gas in a bicycle pump and it gets warm, when steam expands and pushes a piston — the first law is keeping the books. It is the single most-used equation in all of energy engineering.
In this lesson we'll track heat, work, and internal energy through a closed system, and build Python tools to compute them for every common process.
Energy, Work, and Heat
Energy crosses a system boundary in only two forms:
Sponsored
70% of India's auto industry trusts Skill-Lync
For training their engineers in CAD, CAE & simulation
- Heat $Q$ — energy transfer driven by a temperature difference.
- Work $W$ — energy transfer by any other means (a moving piston, a rotating shaft).
Sign Conventions
We use the classic thermodynamics convention:
| Quantity | Positive when... |
|---|
| Heat $Q$ | added to the system |
| Work $W$ | done by the system (on the surroundings) |
So a gas that absorbs heat and expands has $Q > 0$ and $W > 0$.
The First Law for a Closed System
For a closed system undergoing a process, the change in internal energy equals heat in minus work out:
Sponsored
Gaurav Jadhav is now a CAE Engineer
Practical projects and mock interviews made the difference
$$\Delta U = Q - W$$
On a per-unit-mass basis:
$$\Delta u = q - w$$
Sponsored
Ranjith switched from IT to core automotive industry
His inspiring career transition story with video
For a cycle, the system returns to its initial state, so $\Delta U = 0$ and therefore:
$$Q_\text{net} = W_\text{net}$$
This is why an engine's net work output over a cycle equals the net heat it absorbs.
Boundary Work
When a piston moves, the gas does boundary work. For a quasi-static process:
$$W = \int_1^2 p\,dV$$
The work is the area under the process curve on a p–V diagram. The result depends on the path:
| Process | Condition | Work $W = \int p\,dV$ |
|---|
| Isochoric | $V$ = const | $0$ |
| Isobaric | $p$ = const | $p(V_2 - V_1)$ |
| Isothermal (ideal gas) | $T$ = const | $mRT\,\ln(V_2/V_1)$ |
| Polytropic | $pV^n$ = const | $\dfrac{p_2 V_2 - p_1 V_1}{1 - n}$ |
| Adiabatic (ideal gas) | $pV^\gamma$ = const, $Q=0$ | $\dfrac{p_2 V_2 - p_1 V_1}{1 - \gamma}$ |
A polytropic process follows $pV^n = \text{const}$; special cases are $n=0$ (isobaric), $n=1$ (isothermal for an ideal gas), $n=\gamma$ (adiabatic), and $n\to\infty$ (isochoric).
Internal Energy, Enthalpy, and Specific Heats
Enthalpy is a convenient combination that appears whenever flow work matters:
$$H = U + pV, \qquad h = u + pv$$
The specific heats tell us how much energy raises a substance's temperature by one degree:
- $c_v$ — at constant volume: $\;du = c_v\,dT$
- $c_p$ — at constant pressure: $\;dh = c_p\,dT$
For an ideal gas, $u$ and $h$ depend only on temperature, and the specific heats are linked by:
$$c_p - c_v = R, \qquad \gamma = \frac{c_p}{c_v}$$
For air at room temperature, $c_p \approx 1005$, $c_v \approx 718$ J/(kg·K), and $\gamma \approx 1.4$.
Computing Work for Each Process
Let's compute the boundary work for an ideal gas (air) expanding from 1 bar, 0.01 m³ to 0.03 m³ via several process paths.
import numpy as np
R = 287.0 # J/(kg K) for air
gamma = 1.4
P1, V1 = 1.0e5, 0.01 # initial state (Pa, m^3)
V2 = 0.03 # final volume (m^3)
# Mass and initial temperature from ideal gas law
# (assume T1 = 300 K to fix mass)
T1 = 300.0
m = P1 * V1 / (R * T1)
# 1. Isobaric: p constant -> p2 = p1
W_isobaric = P1 * (V2 - V1)
# 2. Isothermal: W = m R T ln(V2/V1)
W_isothermal = m * R * T1 * np.log(V2 / V1)
# 3. Polytropic with n = 1.2: pV^n = const
n = 1.2
P2_poly = P1 * (V1 / V2) ** n
W_poly = (P2_poly * V2 - P1 * V1) / (1 - n)
# 4. Adiabatic: pV^gamma = const
P2_adia = P1 * (V1 / V2) ** gamma
W_adia = (P2_adia * V2 - P1 * V1) / (1 - gamma)
print(f"Mass of air: {m*1e3:.3f} g")
print(f"Isobaric work: {W_isobaric:.1f} J")
print(f"Isothermal work: {W_isothermal:.1f} J")
print(f"Polytropic (n=1.2): {W_poly:.1f} J")
print(f"Adiabatic work: {W_adia:.1f} J")
Output:
Mass of air: 0.116 g
Isobaric work: 2000.0 J
Isothermal work: 1098.6 J
Polytropic (n=1.2): 951.7 J
Adiabatic work: 783.1 J
The work decreases as $n$ rises — the steeper the pressure drop during expansion, the less area under the curve, hence less work.
Plotting a Polytropic p–V Diagram
import numpy as np
import matplotlib.pyplot as plt
P1, V1 = 1.0e5, 0.01
V2 = 0.03
gamma = 1.4
V = np.linspace(V1, V2, 200)
for n, color, label in [(0, 'g', 'Isobaric (n=0)'),
(1, 'b', 'Isothermal (n=1)'),
(1.2, 'm', 'Polytropic (n=1.2)'),
(gamma, 'r', 'Adiabatic (n=1.4)')]:
P = P1 * (V1 / V) ** n
plt.plot(V * 1e3, P / 1e5, color, lw=2, label=label)
plt.xlabel('Volume V (L)')
plt.ylabel('Pressure p (bar)')
plt.title('Expansion Paths on a p-V Diagram')
plt.legend(); plt.grid(True, alpha=0.3)
plt.show()
The area under each curve is the boundary work — isobaric (the flat top line) clearly encloses the most.
First-Law Energy-Balance Solver
Now let's apply $\Delta U = Q - W$. For an ideal-gas process, $\Delta U = m\,c_v\,(T_2 - T_1)$, so once we know the work, the first law gives the heat.
import numpy as np
def first_law_ideal_gas(m, cv, T1, T2, W):
"""Return (dU, Q) for a closed-system ideal-gas process.
Sign convention: W > 0 = work done BY gas, Q > 0 = heat INTO gas."""
dU = m * cv * (T2 - T1)
Q = dU + W # from dU = Q - W
return dU, Q
R, cv, gamma = 287.0, 718.0, 1.4
m = 0.116e-3 # kg (from previous example)
# Adiabatic expansion: Q = 0, find T2 from T V^(gamma-1) = const
T1 = 300.0
V1, V2 = 0.01, 0.03
T2_adia = T1 * (V1 / V2) ** (gamma - 1)
W_adia = m * cv * (T1 - T2_adia) # for adiabatic, W = -dU = m cv (T1 - T2)
dU, Q = first_law_ideal_gas(m, cv, T1, T2_adia, W_adia)
print(f"Adiabatic: T2 = {T2_adia:.1f} K")
print(f" dU = {dU:.2f} J, W = {W_adia:.2f} J, Q = {Q:.4f} J (should be ~0)")
# Isobaric heating from 300 K to 450 K, find Q and W
T1b, T2b = 300.0, 450.0
W_isob = m * R * (T2b - T1b) # p dV = mR dT at constant p
dU_b, Q_b = first_law_ideal_gas(m, cv, T1b, T2b, W_isob)
cp = cv + R
print(f"Isobaric heating 300->450 K:")
print(f" W = {W_isob:.2f} J, dU = {dU_b:.2f} J, Q = {Q_b:.2f} J")
print(f" Check Q = m cp dT = {m*cp*(T2b-T1b):.2f} J")
Output:
Adiabatic: T2 = 208.0 K
dU = -7.66 J, W = 7.66 J, Q = 0.0000 J (should be ~0)
Isobaric heating 300->450 K:
W = 4.99 J, dU = 12.50 J, Q = 17.49 J
Check Q = m cp dT = 17.49 J
Two satisfying checks: the adiabatic process gives $Q = 0$, and the isobaric heat matches $m\,c_p\,\Delta T$ exactly — a direct confirmation of $c_p - c_v = R$.
Common Pitfalls
- Sign-convention slips: in this convention $W$ is work done by the system. Engineering software sometimes flips it — state your convention.
- Using $\int p\,dV$ for non-quasi-static processes: boundary-work integration assumes quasi-equilibrium.
- Confusing $c_p$ and $c_v$: use $c_v$ for $\Delta U$ and $c_p$ for $\Delta H$ (or for $Q$ in a constant-pressure process).
- Forgetting $\Delta U = 0$ for a cycle: net heat equals net work only around a complete cycle, not a single process.
Key Takeaways
- The first law for a closed system is $\Delta U = Q - W$ — conservation of energy.
- Sign convention: $Q > 0$ into the system, $W > 0$ done by the system.
- Boundary work $W = \int p\,dV$ is the area under the p–V curve and is path-dependent.
- Polytropic processes ($pV^n$ = const) unify isobaric, isothermal, and adiabatic cases.
- For an ideal gas, $\Delta U = m c_v \Delta T$, $\Delta H = m c_p \Delta T$, and $c_p - c_v = R$.
Next, we open the boundary and analyze flowing systems with the steady-flow energy equation.