Skip to main content

statistical-mechanics

Statistical mechanics fundamentals including ensembles, partition functions, phase transitions, Monte Carlo methods, and non-equilibrium dynamics for physics applications.

Source facts

Repository
ffsshhttiikk/opencode-agents-skills
Last source activity
February 28, 2026 at 22:53
Detected SKILL.md language
English
Stars
3
Forks
2

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
statistical-mechanics
description
Statistical mechanics fundamentals including ensembles, partition functions, phase transitions, Monte Carlo methods, and non-equilibrium dynamics for physics applications.
category
physics
tags
["physics","statistical-mechanics","ensembles","partition-functions","phase-transitions","monte-carlo","non-equilibrium","thermodynamics"]
difficulty
advanced
author
neuralblitz
# Statistical Mechanics ## What I do I provide comprehensive expertise in statistical mechanics, the bridge between microscopic physics and thermodynamics. I enable you to apply ensemble theory, calculate partition functions, analyze phase transitions, implement Monte Carlo simulations, and model non-equilibrium dynamics. My knowledge spans from foundational statistical foundations to modern computational methods essential for condensed matter physics, soft matter, biological physics, and materials science. ## When to use me Use statistical mechanics when you need to: derive thermodynamic properties from microscopic models, analyze critical phenomena and phase transitions, simulate many-body systems using Monte Carlo, calculate equation of state for gases and materials, understand transport phenomena and fluctuations, model magnetic systems and spin models, or connect molecular dynamics to macroscopic observables. ## Core Concepts - **Microstates and Macrostates**: Microscopic configurations and their macroscopic aggregations with entropy S = k_B ln Ω. - **Phase Space**: Complete specification of particle positions and momenta for classical systems. - **Ensembles**: Collections of microstates with different constraints (microcanonical, canonical, grand canonical). - **Partition Functions**: Z = Σ exp(-βE) encoding all thermodynamic information. - **Thermodynamic Relations**: Connecting partition functions to free energy, entropy, and equations of state. - **Phase Transitions**: Qualitative changes in system behavior with singularities in derivatives of free energy. - **Mean-Field Theory**: Approximate treatment replacing interactions with effective fields. - **Critical Phenomena**: Universal behavior near phase transitions characterized by critical exponents. - **Fluctuation-Dissipation**: Connecting response functions to equilibrium fluctuations. - **Non-Equilibrium Dynamics**: Time evolution toward equilibrium and current flows. ## Code Examples ### Ensembles and Partition Functions ```python import numpy as np def boltzmann_factor(E, T): """exp(-E/k_B T)""" kB = 1.38e-23 return np.exp(-E / (kB * T)) def canonical_partition_function(energies, T): """Z = Σ exp(-βE_i)""" beta = 1 / (1.38e-23 * T) return np.sum(np.exp(-beta * np.array(energies))) def canonical_expectation(E, Z, T): """⟨E⟩ = (1/Z) Σ E_i exp(-βE_i)""" beta = 1 / (1.38e-23 * T) weights = np.exp(-beta * np.array(E)) return np.sum(E * weights) / Z def heat_capacity(energies, T, Cv): """Cv = (⟨E²⟩ - ⟨E⟩²) / (k_B T²)""" beta = 1 / (1.38e-23 * T) Z = canonical_partition_function(energies, T) E_avg = canonical_expectation(energies, Z, T) E2_avg = canonical_expectation([E**2 for E in energies], Z, T) return (E2_avg - E_avg**2) / ((1.38e-23) * T**2) # Example: Two-level system E0, E1 = 0, 0.001 # Energy levels in J (corresponds to ~72 K) energies = [E0, E1] print("Two-level system:") for T in [10, 50, 100, 300, 1000]: Z = canonical_partition_function(energies, T) E_avg = canonical_expectation(energies, Z, T) print(f" T = {T:4d} K: Z = {Z:.4f}, ⟨E⟩ = {E_avg*1e21:.2f} × 10⁻²¹ J") # Partition function for harmonic oscillator def harmonic_oscillator_z(T, omega): """Z = exp(-βℏω/2) / (1 - exp(-βℏω))""" hbar = 1.055e-34 beta = 1 / (1.38e-23 * T) if omega * hbar * beta > 100: return np.exp(-omega * hbar * beta / 2) return np.exp(-omega * hbar * beta / 2) / (1 - np.exp(-omega * hbar * beta)) # Free particle partition function (classical limit) def free_partition_function_1D(V, T, m=1.67e-27): """Z = V / λ³ where λ = h/√(2πmkT)""" h = 6.626e-34 kB = 1.38e-23 lam = h / np.sqrt(2 * np.pi * m * kB * T) return V / lam**3 # 3D ideal gas def ideal_gas_pressure(N, T, V, m=1.67e-27): """P = NkT/V (ideal gas law)""" kB = 1.38e-23 return N * kB * T / V N_A = 6.022e23 V = 0.0224 # 1 mole at STP T = 273 P = ideal_gas_pressure(N_A, T, V) print(f"\nIdeal gas at STP: P = {P/1e5:.2f} bar") # Grand canonical ensemble def grand_canonical_partition_function(grand_mu, T, single_particle_states): """Ξ = Π_k (1 + exp(-β(ε_k - μ))) for fermions""" beta = 1 / (1.38e-23 * T) Xi = 1 for eps in single_particle_states: Xi *= (1 + np.exp(-beta * (eps - grand_mu))) return Xi # Fermi-Dirac and Bose-Einstein occupation def fermi_dirac_occupation(eps, mu, T): """f(ε) = 1/(exp((ε-μ)/kT) + 1)""" kB = 1.38e-23 return 1 / (np.exp((eps - mu) / (kB * T)) + 1) def bose_einstein_occupation(eps, mu, T): """n(ε) = 1/(exp((ε-μ)/kT) - 1)""" kB = 1.38e-23 if mu >= eps: return np.inf return 1 / (np.exp((eps - mu) / (kB * T)) - 1) print(f"\nFermi-Dirac occupation (ε-μ = 0.1 eV, T=300K):") delta_E = 0.1 * 1.6e-19 # 0.1 eV f = fermi_dirac_occupation(delta_E, 0, 300) print(f" f(ε_F + 0.1 eV) = {f:.4f}") ``` ### Ising Model and Phase Transitions ```python import numpy as np class IsingModel: def __init__(self, L, J=1, h=0): """2D Ising model on L×L lattice.""" self.L = L self.J = J self.h = h self.N = L * L self.spins = np.random.choice([-1, 1], size=(L, L)) def energy(self): """Calculate total energy.""" E = 0 for i in range(self.L): for j in range(self.L): # Periodic boundaries right = self.spins[(i+1) % self.L, j] down = self.spins[i, (j+1) % self.L] E -= self.J * self.spins[i, j] * (right + down) E -= self.h * self.spins[i, j] return E / 2 # Each bond counted twice def magnetization(self): """Total magnetization.""" return np.sum(self.spins) def metropolis_step(self, T): """Single Metropolis sweep.""" kB = 1.0 # Units where kB = 1 for _ in range(self.N): # Random spin flip i = np.random.randint(self.L) j = np.random.randint(self.L) # Calculate energy change neighbors = (self.spins[(i-1) % self.L, j] + self.spins[(i+1) % self.L, j] + self.spins[i, (j-1) % self.L] + self.spins[i, (j+1) % self.L]) dE = 2 * self.spins[i, j] * (self.J * neighbors + self.h) # Metropolis criterion if dE < 0 or np.random.random() < np.exp(-dE / (kB * T)): self.spins[i, j] *= -1 def equilibrate(self, T, n_sweeps=1000): """Equilibrate at given temperature.""" for _ in range(n_sweeps): self.metropolis_step(T) def simulate(self, T, n_sweeps=10000): """Run simulation and return observables.""" self.equilibrate(T, n_sweeps) mags = [] eners = [] for _ in range(n_sweeps): self.metropolis_step(T) mags.append(self.magnetization()) eners.append(self.energy()) return np.mean(mags)/self.N, np.std(mags)/self.N, np.mean(eners)/self.N, np.std(eners)/self.N # Critical temperature for 2D Ising (Onsager solution: kB Tc/J ≈ 2.269) L = 20 ising = IsingModel(L) print("2D Ising model simulation:") temperatures = [1.0, 2.0, 2.2, 2.269, 2.3, 2.5, 3.0] for T in temperatures: m, dm, E, dE = ising.simulate(T, n_sweeps=5000) print(f" T = {T:.2f}: m = {m:.4f} ± {dm:.4f}, E = {E/L**2:.4f} ± {dE/L**2:.4f}") # Binder cumulant def binder_cumulant(mags): """U = 1 - ⟨m⁴⟩/(3⟨m²⟩²)""" m2 = np.mean(np.array(mags)**2) m4 = np.mean(np.array(mags)**4) return 1 - m4 / (3 * m2**2) print(f"\nBinder cumulant at Tc ≈ 2.27:") for T in [2.2, 2.269, 2.3]: ising2 = IsingModel(20) ising2.equilibrate(T, 5000) mags = [ising2.magnetization() for _ in range(5000)] U = binder_cumulant(mags) print(f" U(T={T}) = {U:.4f}") ``` ### Mean-Field Theory ```python import numpy as np def mean_field_ising(T, J, h=0, max_iter=100, tol=1e-6): """Mean-field solution of Ising model.""" kB = 1.0 # Units where kB = 1 beta = 1 / T # Initial magnetization m = 0.1 for iteration in range(max_iter): m_new = np.tanh(beta * (J * 6 * m + h)) # z=6 for 3D if abs(m_new - m) < tol: break m = m_new return m def solve_self_consistent(T, J): """Solve MF equations numerically.""" from scipy.optimize import brentq def equation(m): kB = 1.0 return m - np.tanh(m * J * 6 / (kB * T)) # Below Tc, look for non-zero solution Tc_mf = J * 6 # Mean-field Tc if T > Tc_mf: return 0 # Find root try: m = brentq(equation, 1e-6, 1.0) return m except: return 0 # Critical exponents Tc_mf = 6.0 # For J=1 print("Mean-field Ising critical behavior:") print(f" Mean-field Tc = {Tc_mf:.3f} J/kB") # Below Tc, magnetization follows m ∝ (Tc - T)^β with β = 0.5 for T in [0.5, 1.0, 2.0, 4.0, 5.0, 5.5, 5.9, 5.99]: m = solve_self_consistent(T, 1.0) if T < Tc_mf: beta_mf = np.log(m) / np.log((Tc_mf - T) / Tc_mf) print(f" T = {T:.2f}: m = {m:.4f}, effective β = {beta_mf:.3f}") else: print(f" T = {T:.2f}: m = 0") # Landau theory def landau_free_energy(m, a, b, T): """F(m) = a(T-Tc)m² + bm⁴ + hm""" return a * (T - Tc_mf) * m**2 + b * m**4 # Susceptibility def susceptibility(T, Tc, chi0=1): """χ ∝ |T-Tc|^(-γ) with γ = 1 (MF)""" if T > Tc: return chi0 / (T - Tc) return chi0 / (T_c - T) print(f"\nMean-field susceptibility divergence:") for T in [2.0, 1.1, 1.01, 1.001]: chi = susceptibility(T, 1.0) print(f" T = {T:.3f}: χ = {chi:.1f}") ``` ### Monte Carlo Methods ```python import numpy as np def metropolis_sampling(pdf, proposal_std, n_samples, x0): """Metropolis-Hastings sampling from arbitrary PDF.""" samples = [x0] x = x0 for _ in range(n_samples): x_proposed = x + np.random.normal(0, proposal_std) alpha = pdf(x_proposed) / pdf(x) if np.random.random() < alpha: x = x_proposed samples.append(x) return np.array(samples) def wolff_cluster_update(spins, J, T): """Wolff single-cluster Monte Carlo update.""" L = len(spins) visited = np.zeros(L, dtype=bool) # Start new cluster site = np.random.randint(L) cluster = [site] visited[site] = True S_cluster = spins[site] # Grow cluster i = 0 while i < len(cluster): current = cluster[i] P_add = 1 - np.exp(-2 * J / T)
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub