用Python复现平均场理论:从Ising模型到相变预测的完整代码实现

张开发
2026/4/3 12:08:47 15 分钟阅读
用Python复现平均场理论:从Ising模型到相变预测的完整代码实现
用Python复现平均场理论从Ising模型到相变预测的完整代码实现当我们在Jupyter Notebook中敲下第一行import numpy时可能不会想到这个简单的动作将带我们穿越百年物理史。1925年皮埃尔·魏斯为解释铁磁相变提出的平均场理论如今正等待着被你的Python代码唤醒。这不是普通的物理模拟——通过NumPy数组的矩阵运算我们将看到微观自旋如何集体投票决定宏观相变而matplotlib绘制的曲线将揭示临界温度的神秘面纱。1. 环境配置与基础构建在开始构建伊辛模型之前我们需要搭建一个可交互的计算环境。不同于传统物理实验需要真空装置和低温设备我们的数字实验室只需几行代码就能搭建完成。建议使用Jupyter Lab而非经典Notebook其多面板界面特别适合同时观察代码、可视化结果和理论推导。首先创建基础的模拟类框架import numpy as np import matplotlib.pyplot as plt from tqdm import tqdm plt.style.use(seaborn-v0_8-poster) class IsingModel: def __init__(self, size50, J1.0, T2.0): self.size size # 晶格尺寸 self.J J # 交换积分(相互作用强度) self.T T # 温度 self.spins np.random.choice([-1, 1], size(size, size)) self.magnetization [] def visualize(self): plt.figure(figsize(8,8)) plt.imshow(self.spins, cmapbinary) plt.title(fT{self.T:.2f}, M{np.mean(self.spins):.3f}) plt.axis(off)这个初始版本已经可以生成随机自旋构型并可视化。尝试不同温度下的初始状态model IsingModel(T1.5) model.visualize()你会看到黑白相间的随机图案——每个像素代表一个原子自旋向上(白色)或向下(黑色)。温度参数T将决定这些自旋最终会形成有序排列还是保持混沌状态。2. 平均场理论的核心方程实现平均场理论的美妙之处在于它将复杂的多体问题简化为单体问题。对于二维伊辛模型关键方程是自洽的磁化强度方程m tanh(βzJm)其中β1/(k_B T)z是配位数(二维四方晶格z4)。我们需要用迭代法求解这个超越方程def mean_field_magnetization(T, J1.0, z4, max_iter100, tol1e-6): 计算给定温度下的平均场磁化强度 beta 1.0 / T m 1.0 # 初始猜测(铁磁状态) for _ in range(max_iter): new_m np.tanh(beta * z * J * m) if np.abs(new_m - m) tol: break m new_m return m这个简单函数隐藏着深刻的物理内涵。让我们扫描温度范围观察相变temps np.linspace(0.1, 5.0, 100) m_values [mean_field_magnetization(T) for T in temps] plt.figure(figsize(10,6)) plt.plot(temps, m_values, linewidth3) plt.axvline(x2.269, colorr, linestyle--, labelCritical T (exact)) plt.xlabel(Temperature (T), fontsize14) plt.ylabel(Magnetization (m), fontsize14) plt.title(Mean Field Prediction of Phase Transition, fontsize16) plt.grid(True) plt.legend()红色虚线标记了精确解给出的临界温度Tc≈2.269J/k_B。你会注意到平均场理论高估了Tc——这是忽略涨落的典型表现但整体相变行为已被成功捕获。3. 蒙特卡洛模拟验证为了检验平均场理论的准确性我们实现更精确的Metropolis算法进行蒙特卡洛模拟class IsingModelMC(IsingModel): def metropolis_step(self): i, j np.random.randint(0, self.size, size2) delta_E 2 * self.J * self.spins[i,j] * ( self.spins[(i1)%self.size, j] self.spins[(i-1)%self.size, j] self.spins[i, (j1)%self.size] self.spins[i, (j-1)%self.size] ) if delta_E 0 or np.random.rand() np.exp(-delta_E / self.T): self.spins[i,j] * -1 def simulate(self, steps1000, eq_steps500): self.magnetization [] for _ in tqdm(range(steps)): self.metropolis_step() if _ eq_steps: self.magnetization.append(np.mean(self.spins))运行比较实验mc_m_values [] for T in temps: model IsingModelMC(size30, TT) model.simulate(steps5000) mc_m_values.append(np.mean(model.magnetization[-1000:])) plt.figure(figsize(10,6)) plt.plot(temps, m_values, labelMean Field) plt.plot(temps, np.abs(mc_m_values), --, labelMonte Carlo (30x30)) plt.xlabel(Temperature (T)) plt.ylabel(|Magnetization|) plt.legend()你会看到两种方法的曲线形状相似但临界温度不同——这正是平均场理论在二维情况下偏差的直观体现。有趣的是如果将晶格维度提高到3D或更高两者的吻合度会显著改善。4. 高级分析与可视化技巧深入理解相变需要更专业的分析工具。让我们实现有限尺寸标度分析这是研究临界现象的有力武器def finite_size_scaling(sizes[20, 30, 40, 50], n_points20): Tc_estimates [] T_range np.linspace(2.0, 2.4, n_points) for L in sizes: m_T [] for T in T_range: model IsingModelMC(sizeL, TT) model.simulate(steps3000, eq_steps2000) m_T.append(np.mean(np.abs(model.magnetization[-500:]))) Tc_estimates.append(T_range[np.argmax(np.gradient(m_T))]) plt.figure(figsize(10,6)) plt.plot(1./np.array(sizes), Tc_estimates, o-) plt.xlabel(1/L) plt.ylabel(Estimated Tc) plt.title(Finite Size Scaling) return np.polyfit(1./np.array(sizes), Tc_estimates, 1)[1] # 外推L→∞这个函数通过不同尺寸系统的模拟结果外推无限大系统的临界温度。运行它会发现结果更接近理论值展示了有限尺寸效应的影响。动态可视化能更生动展示相变过程from matplotlib.animation import FuncAnimation model IsingModelMC(size50, T2.5) fig plt.figure(figsize(8,8)) img plt.imshow(model.spins, cmapbinary, animatedTrue) plt.axis(off) def update(frame): for _ in range(100): model.metropolis_step() img.set_array(model.spins) return img, ani FuncAnimation(fig, update, frames100, interval50, blitTrue) plt.close()这段代码生成一个动画清晰展示高温下自旋的快速翻转和低温下的磁畴形成。T接近Tc时你会看到特征性的临界慢化现象——系统在有序和无序间艰难抉择。5. 性能优化与工程实践大规模模拟需要优化。我们用Numba加速关键部分from numba import jit jit(nopythonTrue) def energy_difference(spins, i, j, J, size): return 2 * J * spins[i,j] * ( spins[(i1)%size, j] spins[(i-1)%size, j] spins[i, (j1)%size] spins[i, (j-1)%size] ) class IsingModelOptimized(IsingModelMC): def metropolis_step(self): i, j np.random.randint(0, self.size, size2) delta_E energy_difference(self.spins, i, j, self.J, self.size) if delta_E 0 or np.random.rand() np.exp(-delta_E / self.T): self.spins[i,j] * -1比较优化前后的速度%timeit IsingModelMC(size50).simulate(steps1000) %timeit IsingModelOptimized(size50).simulate(steps1000)在我的测试中优化后速度提升约50倍。对于1000×1000的大系统模拟这种优化至关重要。并行化是另一个提升方向。我们可以使用多进程同时模拟不同温度点from multiprocessing import Pool def simulate_single_T(T): model IsingModelOptimized(size40, TT) model.simulate(steps5000, eq_steps3000) return np.mean(np.abs(model.magnetization[-1000:])) with Pool(4) as p: parallel_m p.map(simulate_single_T, temps)这种并行化策略特别适合参数扫描类任务能线性提升计算效率。6. 扩展应用与前沿方向平均场理论的应用远不止于伊辛模型。我们可以轻松扩展代码研究其他系统1. 时空相关函数分析def correlation_function(spins, r_max): corr np.zeros(r_max) size spins.shape[0] for r in range(r_max): corr[r] np.mean(spins * np.roll(spins, shiftr, axis0)) return corr / corr[0] # 归一化这个函数计算自旋在距离r上的关联性。近Tc时关联长度会发散——这是临界现象的另一个标志。2. 外加磁场响应修改平均场方程包含外场hdef mf_with_field(T, h, J1.0, z4): beta 1.0 / T m 1.0 for _ in range(100): new_m np.tanh(beta * (z * J * m h)) if np.abs(new_m - m) 1e-6: break m new_m return m绘制磁化曲线簇hs np.linspace(-1, 1, 5) for h in hs: plt.plot(temps, [mf_with_field(T, h) for T in temps], labelfh{h:.1f}) plt.legend()这些曲线展示了铁磁体如何随温度和磁场改变其响应特性。3. 量子伊辛模型扩展加入横向磁场实现量子相变研究class QuantumIsing(IsingModel): def __init__(self, size50, J1.0, T0.1, g0.5): super().__init__(size, J, T) self.g g # 横向场强度 def quantum_step(self): # 实现量子隧穿效应 flip_prob np.minimum(1, np.exp(-2 * self.g / self.T)) mask np.random.rand(self.size, self.size) flip_prob self.spins[mask] * -1这种扩展将我们的经典模拟带入了量子领域可以研究全新的相变类型。在Jupyter Notebook中实践这些代码时建议采用以下工作流在第一个cell定义核心类和方法创建专门的分析cell标记为温度扫描、动态可视化等使用%%time魔法命令监控计算耗时重要结果立即保存为npz文件np.savez(results.npz, tempstemps, m_valuesm_values)为复杂函数添加%prun性能剖析记得定期使用model_checkpoint pickle.dumps(model)保存中间状态。当发现有趣现象时可以快速回滚到特定状态进行更深入研究。

更多文章