Landau Free Energy
Expand the free energy as a function of the order parameter \(m\):
\[
F(m, T) = F_0 + a(T) m^2 + b m^4 - hm
\]
Here \(a(T) = a_0(T - T_c)\), \(b > 0\).
Equilibrium condition: \(\frac{\partial F}{\partial m} = 0\)
\[
2a(T)m + 4bm^3 = h
\]
When \(h = 0\): For \(T > T_c\), only \(m = 0\) is stable, corresponding to the paramagnetic phase. For \(T < T_c\), the solutions \(m = \pm\sqrt{-a(T)/(2b)}\) become stable, corresponding to the ferromagnetic phase.
# Requirements:
# - Python 3.9+
# - matplotlib>=3.7.0
# - numpy>=1.24.0, <2.0.0
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize_scalar
def landau_free_energy(m, T, T_c, a0, b, h):
"""Landau free energy"""
a = a0 * (T - T_c)
return a * m**2 + b * m**4 - h * m
def equilibrium_magnetization(T, T_c, a0, b, h):
"""Equilibrium magnetization (free energy minimization)"""
# Search from multiple initial values
m_candidates = []
for m_init in [-1, 0, 1]:
result = minimize_scalar(lambda m: landau_free_energy(m, T, T_c, a0, b, h),
bounds=(-2, 2), method='bounded')
m_candidates.append(result.x)
# Select solution that gives minimum free energy
F_values = [landau_free_energy(m, T, T_c, a0, b, h) for m in m_candidates]
return m_candidates[np.argmin(F_values)]
# Parameters
T_c = 500 # K
a0 = 1e-4
b = 1e-6
h_values = [0, 0.01, 0.05, 0.1]
T_range = np.linspace(300, 700, 100)
colors = ['blue', 'green', 'orange', 'red']
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# Shape of Landau potential (different temperatures)
ax1 = axes[0, 0]
m_plot = np.linspace(-1.5, 1.5, 200)
temperatures_plot = [0.8*T_c, 0.95*T_c, T_c, 1.2*T_c]
for T_val, color in zip(temperatures_plot, colors):
F_plot = [landau_free_energy(m, T_val, T_c, a0, b, 0) for m in m_plot]
ax1.plot(m_plot, F_plot, color=color, linewidth=2,
label=f'T/T_c = {T_val/T_c:.2f}')
ax1.set_xlabel('Order parameter m')
ax1.set_ylabel('Free energy F(m)')
ax1.set_title('Landau Potential (h = 0)')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Temperature dependence of equilibrium magnetization
ax2 = axes[0, 1]
for h, color in zip(h_values, colors):
m_eq = [equilibrium_magnetization(T, T_c, a0, b, h) for T in T_range]
ax2.plot(T_range / T_c, m_eq, color=color, linewidth=2,
label=f'h = {h:.2f}')
ax2.axvline(1, color='k', linestyle=':', linewidth=1, label='T_c')
ax2.set_xlabel('T / T_c')
ax2.set_ylabel('Magnetization m')
ax2.set_title('Equilibrium Magnetization')
ax2.legend()
ax2.grid(True, alpha=0.3)
# First-order transition (case with negative b)
ax3 = axes[1, 0]
# F = a m² + b m⁴ + c m⁶ (first-order transition when b < 0)
b_first_order = -2e-6
c = 1e-7
def landau_first_order(m, T, T_c, a0, b, c, h):
a = a0 * (T - T_c)
return a * m**2 + b * m**4 + c * m**6 - h * m
m_1st = np.linspace(-1.5, 1.5, 200)
T_1st = [0.95*T_c, 0.98*T_c, T_c, 1.02*T_c]
for T_val, color in zip(T_1st, colors):
F_1st = [landau_first_order(m, T_val, T_c, a0, b_first_order, c, 0) for m in m_1st]
ax3.plot(m_1st, F_1st, color=color, linewidth=2,
label=f'T/T_c = {T_val/T_c:.2f}')
ax3.set_xlabel('Order parameter m')
ax3.set_ylabel('Free energy F(m)')
ax3.set_title('First-Order Phase Transition (Double-Well Potential)')
ax3.legend()
ax3.grid(True, alpha=0.3)
# Magnetic susceptibility
ax4 = axes[1, 1]
epsilon_h = 0.001
chi_landau = []
for T in T_range:
m0 = equilibrium_magnetization(T, T_c, a0, b, 0)
m_h = equilibrium_magnetization(T, T_c, a0, b, epsilon_h)
chi = (m_h - m0) / epsilon_h
chi_landau.append(chi)
ax4.plot(T_range / T_c, chi_landau, 'purple', linewidth=2)
ax4.axvline(1, color='k', linestyle=':', linewidth=1, label='T_c')
ax4.set_xlabel('T / T_c')
ax4.set_ylabel('χ')
ax4.set_title('Magnetic Susceptibility (Diverges at T_c)')
ax4.legend()
ax4.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('stat_mech_landau_theory.png', dpi=300, bbox_inches='tight')
plt.show()
print("=== Landau Theory ===\n")
print(f"Parameters:")
print(f" T_c = {T_c} K")
print(f" a₀ = {a0}")
print(f" b = {b}\n")
print("Second-order phase transition (b > 0):")
print(f" T > T_c: m = 0 (single well)")
print(f" T < T_c: m = ±√(-a/2b) (double well)")
print(f" Critical exponent β = 1/2\n")
print("First-order phase transition (b < 0, c > 0):")
print(f" Double-well potential")
print(f" Magnetization jumps discontinuously at transition")
print(f" Latent heat exists")