4.2 Fronts

Fronts are boundaries between air masses of different temperature and humidity. They are zones of enhanced weather activity including precipitation, wind shifts, and temperature changes.

Types of Fronts

Cold Front

Cold air advances, lifts warm air. Steep slope (~1:50-1:100). Narrow band of intense weather.

Weather: towering cumulus, thunderstorms, heavy rain, wind shift

Warm Front

Warm air advances, rides over cold air. Gentle slope (~1:200-1:300). Wide band of weather.

Weather: cirrus → altostratus → nimbostratus, steady rain

Occluded Front

Cold front catches warm front, lifting warm sector aloft.

Can be cold or warm occlusion depending on relative temperatures

Stationary Front

Neither air mass advancing. Prolonged weather along front.

Frontal Slope

$$\tan\alpha \approx \frac{f \Delta v}{g \frac{\Delta T}{T}}$$

Slope depends on temperature contrast and wind shear

Python: Front Cross-Section

#!/usr/bin/env python3
"""
fronts.py - Visualize frontal structures

Run: python3 fronts.py
Requires: pip install numpy matplotlib
"""
import numpy as np
import matplotlib.pyplot as plt

# Create cross-section for cold and warm fronts
fig, axes = plt.subplots(1, 2, figsize=(14, 6))

# Cold front (steep slope)
ax1 = axes[0]
x = np.linspace(0, 500, 200)  # km
# Frontal surface
z_front_cold = 100 * (500 - x) / 500  # steep slope
z_front_cold = np.where(z_front_cold > 0, z_front_cold, 0)
z_front_cold = np.where(x < 500, z_front_cold * 10, 0)  # scale to realistic

# Fill regions
ax1.fill_between(x, 0, np.minimum(z_front_cold, 10000), color='blue', alpha=0.3, label='Cold air')
ax1.fill_between(x, z_front_cold, 10000, where=(x < 480), color='red', alpha=0.3, label='Warm air')
ax1.plot(x, z_front_cold, 'b-', linewidth=3, label='Cold front')

# Add clouds
for xc in [420, 440, 460]:
    ax1.scatter([xc], [z_front_cold[np.argmin(np.abs(x-xc))] + 500], s=2000, c='gray', alpha=0.5, marker='o')

# Arrows showing air motion
ax1.annotate('', xy=(350, 3000), xytext=(450, 3000), arrowprops=dict(arrowstyle='->', color='blue', lw=2))
ax1.annotate('', xy=(460, 5000), xytext=(430, 3500), arrowprops=dict(arrowstyle='->', color='red', lw=2))

ax1.set_xlabel('Distance (km)', fontsize=12)
ax1.set_ylabel('Height (m)', fontsize=12)
ax1.set_title('Cold Front Cross-Section', fontsize=14)
ax1.set_xlim(300, 520)
ax1.set_ylim(0, 10000)
ax1.legend(loc='upper left')
ax1.text(350, 2000, 'COLD', fontsize=14, color='blue', fontweight='bold')
ax1.text(480, 6000, 'WARM', fontsize=14, color='red', fontweight='bold')

# Warm front (gentle slope)
ax2 = axes[1]
# Frontal surface (much gentler slope)
z_front_warm = 20 * x / 500  # gentle slope, scaled
z_front_warm = np.where(z_front_warm < 10000, z_front_warm * 50, 10000)

# Fill regions
ax2.fill_between(x, 0, z_front_warm, color='blue', alpha=0.3, label='Cold air')
ax2.fill_between(x, z_front_warm, 10000, color='red', alpha=0.3, label='Warm air')
ax2.plot(x, z_front_warm, 'r-', linewidth=3, label='Warm front')

# Add layered clouds
cloud_types = ['Ns', 'As', 'Cs', 'Ci']
cloud_x = [50, 150, 300, 450]
cloud_z = [1500, 4000, 6000, 8000]
for xc, zc, ctype in zip(cloud_x, cloud_z, cloud_types):
    ax2.scatter([xc], [zc], s=3000, c='gray', alpha=0.4, marker='o')
    ax2.text(xc, zc-500, ctype, ha='center', fontsize=10, color='black')

ax2.set_xlabel('Distance (km)', fontsize=12)
ax2.set_ylabel('Height (m)', fontsize=12)
ax2.set_title('Warm Front Cross-Section', fontsize=14)
ax2.set_xlim(0, 500)
ax2.set_ylim(0, 10000)
ax2.legend(loc='upper left')
ax2.text(100, 500, 'COLD', fontsize=14, color='blue', fontweight='bold')
ax2.text(400, 8500, 'WARM', fontsize=14, color='red', fontweight='bold')

# Add cloud type labels
ax2.text(300, 500, '← Surface front', fontsize=10, ha='center')

plt.tight_layout()
plt.savefig('fronts.png', dpi=150, bbox_inches='tight')
plt.show()

print("Front Characteristics:")
print("-" * 50)
print("Cold Front:")
print("  Slope: ~1:50 to 1:100")
print("  Speed: 20-35 kt")
print("  Weather band: 50-100 km")
print("  Precipitation: heavy, short duration")
print()
print("Warm Front:")
print("  Slope: ~1:150 to 1:300")
print("  Speed: 10-20 kt")
print("  Weather band: 200-500 km")
print("  Precipitation: light-moderate, long duration")