1.3 Solar Radiation
The Sun provides virtually all the energy that drives Earth's climate system. Understanding how solar radiation is absorbed, scattered, and reflected is fundamental to atmospheric science.
Solar Constant
S₀ = 1361 W/m²
Total solar irradiance at Earth's mean orbital distance
Average Insolation
$$\bar{S} = \frac{S_0}{4} = 340 \text{ W/m}^2$$
Factor of 4 from spherical geometry
Solar Luminosity
$$L_\odot = 3.83 \times 10^{26} \text{ W}$$
Total power output of the Sun
Absorption & Scattering
Rayleigh Scattering
Scattering by molecules (λ ≪ particle size). Blue light scattered more than red → blue sky.
$\sigma \propto \lambda^{-4}$
Mie Scattering
Scattering by aerosols (λ ~ particle size). More forward scattering, less wavelength dependent.
Absorption
O₃ absorbs UV (200-320 nm). H₂O and CO₂ absorb infrared. O₂ absorbs far UV (<200 nm).
Earth's Energy Budget
~30%
Reflected (Albedo)
~23%
Absorbed by Atmosphere
~47%
Absorbed by Surface
Effective Temperature
$$T_e = \left[\frac{S_0(1-\alpha)}{4\sigma}\right]^{1/4} = 255 \text{ K}$$
Without greenhouse effect (actual surface ~288 K, +33 K from GHG)
Python: Solar Spectrum & Energy Budget
#!/usr/bin/env python3
"""
solar_radiation.py - Solar spectrum and energy budget calculations
Run: python3 solar_radiation.py
Requires: pip install numpy matplotlib scipy
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy.constants import h, c, k, sigma
# Planck function for blackbody radiation
def planck(wavelength, T):
"""Spectral radiance B(λ,T) in W/(m² sr m)"""
wav = wavelength * 1e-9 # nm to m
return 2*h*c**2/wav**5 / (np.exp(h*c/(wav*k*T)) - 1)
# Wavelengths (nm)
wavelengths = np.linspace(100, 3000, 1000)
# Solar spectrum (T = 5778 K blackbody)
T_sun = 5778
solar_spectrum = planck(wavelengths, T_sun)
# Normalize to match solar constant
solar_spectrum = solar_spectrum / np.max(solar_spectrum)
# Atmospheric transmission (simplified model)
# UV absorbed by ozone (200-320 nm)
# IR absorbed by H2O and CO2
def atmospheric_transmission(wav):
trans = np.ones_like(wav)
# Ozone absorption (UV)
uv_mask = wav < 320
trans[uv_mask] *= np.exp(-((wav[uv_mask]-260)/40)**2)
# H2O absorption bands
for center in [940, 1140, 1380, 1870, 2700]:
h2o_mask = np.abs(wav - center) < 100
trans[h2o_mask] *= 0.3
return trans
transmission = atmospheric_transmission(wavelengths)
surface_spectrum = solar_spectrum * transmission
# Plot
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# Solar spectrum
ax1 = axes[0, 0]
ax1.fill_between(wavelengths, solar_spectrum, alpha=0.3, color='orange')
ax1.plot(wavelengths, solar_spectrum, 'orange', linewidth=2, label='Top of Atmosphere')
ax1.plot(wavelengths, surface_spectrum, 'red', linewidth=2, label='At Surface')
ax1.axvspan(380, 700, alpha=0.2, color='green', label='Visible')
ax1.set_xlabel('Wavelength (nm)')
ax1.set_ylabel('Normalized Irradiance')
ax1.set_title('Solar Spectrum')
ax1.legend()
ax1.set_xlim(0, 2500)
ax1.grid(True, alpha=0.3)
# Energy budget pie chart
ax2 = axes[0, 1]
budget = [30, 23, 47] # reflected, absorbed atm, absorbed surface
labels = ['Reflected\n(30%)', 'Absorbed by\nAtmosphere (23%)', 'Absorbed by\nSurface (47%)']
colors = ['lightgray', 'skyblue', 'forestgreen']
ax2.pie(budget, labels=labels, colors=colors, autopct='%1.0f%%', startangle=90)
ax2.set_title('Earth\'s Energy Budget')
# Rayleigh scattering
ax3 = axes[1, 0]
rayleigh = wavelengths**(-4)
rayleigh = rayleigh / np.max(rayleigh[wavelengths > 300])
ax3.plot(wavelengths, rayleigh, 'b-', linewidth=2)
ax3.axvspan(380, 700, alpha=0.2, color='green')
ax3.set_xlabel('Wavelength (nm)')
ax3.set_ylabel('Scattering Cross-section (arb.)')
ax3.set_title('Rayleigh Scattering (∝ λ⁻⁴)')
ax3.set_xlim(300, 800)
ax3.set_ylim(0, 1.2)
ax3.grid(True, alpha=0.3)
# Mark colors
for wav, color, name in [(450, 'blue', 'Blue'), (550, 'green', 'Green'), (650, 'red', 'Red')]:
ax3.axvline(wav, color=color, linestyle='--', alpha=0.7)
ax3.annotate(name, (wav, 1.1), ha='center', fontsize=10)
# Temperature calculations
ax4 = axes[1, 1]
S0 = 1361 # W/m²
albedos = np.linspace(0, 0.8, 100)
T_eff = ((S0 * (1 - albedos)) / (4 * sigma))**0.25
ax4.plot(albedos, T_eff, 'r-', linewidth=2)
ax4.axhline(255, color='blue', linestyle='--', label=f'Earth T_eff = 255 K (α=0.30)')
ax4.axhline(288, color='green', linestyle='--', label=f'Earth T_actual = 288 K')
ax4.axvline(0.30, color='gray', linestyle=':')
ax4.set_xlabel('Albedo')
ax4.set_ylabel('Effective Temperature (K)')
ax4.set_title('Effective Temperature vs Albedo')
ax4.legend()
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('solar_radiation.png', dpi=150, bbox_inches='tight')
plt.show()
print("Saved as solar_radiation.png")
# Calculate numbers
print(f"\nSolar constant: S0 = {S0} W/m²")
print(f"Average insolation: S0/4 = {S0/4:.0f} W/m²")
print(f"Effective temperature (α=0.30): {((S0*0.70)/(4*sigma))**0.25:.1f} K")
print(f"Greenhouse effect: ΔT = {288-255} K")