【微磁学:扒一扒mumax3的内核】LLG方程的多种求解方法

embedded/2024/9/22 21:12:05/

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、LLG方程和微磁学模拟之间的联系
  • 二、LLG方程的形式
  • 三、微磁学模拟中的LLG方程求解部分
  • 四、代码部分
  • 五、总结


前言

最近我很想把现微磁学模拟器的内容拆开看一遍,就像小时候拆收音机一样。目前感兴趣的微磁学模拟器为mumax3,现下免费且GPU加速,微磁学科研普遍使用的软件。会开一些文章记录细节,欢迎同道中人一起交流!!
第一篇给LLG方程。
本篇内容将讲解LLG方程的求解,给出不同的求解方式,并且用一个例子可视化LLG方程求解的过程。

一、LLG方程和微磁学模拟之间的联系

LLG方程是描述磁矩动态行为的基本方程,本质上就是一个偏微分方程,描述磁化矢量的时空变化中的表达方式。
微磁学模拟是一种计算方法,用于模拟磁性材料的微观磁性行为。在微磁学模拟中,材料被划分为许多小单元(通常是有限差分网格),每个单元内的磁矩被假定为均匀的。微磁学模拟通过求解在每个网格点上的LLG方程来模拟磁性材料的磁化过程。成熟的微磁学模拟器比如mumax3还会给出数据处理的结果。
一言以蔽之,微磁学模拟本质上就是解LLG方程,且在很多个格子内求解多个LLG方程。
LLG方程说:“微磁学模拟器是解千千万万个我构成的。”

二、LLG方程的形式

d m d t = − γ ( m × H e f f ) + α m × ( m × H e f f ) \frac{\mathrm{d} \mathbf{m} }{\mathrm{d} t} = -\gamma (\mathbf{m}\times\mathbf{H_{eff} })+ \alpha\mathbf{m}\times(\mathbf{m}\times\mathbf{H_{eff}}) dtdm=γ(m×Heff)+αm×(m×Heff)

这个表达式含有两个主要项。

  1. 进动项。描述了磁矩向量 m \mathbf{m} m在有效场 H e f f \mathbf{H_{eff}} Heff中的进动。 γ \gamma γ是旋磁比,代表磁矩对磁场的响应强度。 因为进动项的存在,磁矩将在有效磁场的作用下进行旋转。
  2. 阻尼项。磁矩在进动时,还有一个与上面提到的项的叉积成比例的阻尼作用力。作用为减小磁矩的进动速率,最后使得磁矩趋于稳定在有效磁场的方向。

三、微磁学模拟中的LLG方程求解部分

对于LLG方程的求解,微磁学模拟软件往往会给出不同的求解算法以求得更快更好的解,比如在mumax3设计的文章《The design and verification of Mumax3》中有提到:

在这里插入图片描述
在mumax3的api中我们可以找到如何设置不同的求解器:
在这里插入图片描述

四、代码部分

因为mumax3的源代码部分为GO语言,而且不同模块之间的联合看起来很复杂,这部分我得慢慢剥。为了理解LLG方程的不同算法的求解,我这里先写了一些代码去理解不同算法的求解方式,可作为参考。求解的算法对应的是上面引用的Mumax3中的solver,可作为参考。
关于求解偏微分方程的基本思路,可以看我这篇:[有限差分法的求解思路](https://blog.csdn.net/CRUSH8496052/article/details/138095763?

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3Ddef euler_step(M, H_eff, alpha, gamma, dt):"""执行单个Euler步骤。"""dM_dt = -gamma * np.cross(M, H_eff) + alpha * np.cross(M, np.cross(M, H_eff))return M + dt * dM_dtdef rk4_step(M, H_eff, alpha, gamma, dt):"""执行单个RK4步骤。"""k1 = -gamma * np.cross(M, H_eff) + alpha * np.cross(M, np.cross(M, H_eff))k2 = -gamma * np.cross(M + 0.5 * dt * k1, H_eff) + alpha * np.cross(M + 0.5 * dt * k1, np.cross(M + 0.5 * dt * k1, H_eff))k3 = -gamma * np.cross(M + 0.5 * dt * k2, H_eff) + alpha * np.cross(M + 0.5 * dt * k2, np.cross(M + 0.5 * dt * k2, H_eff))k4 = -gamma * np.cross(M + dt * k3, H_eff) + alpha * np.cross(M + dt * k3, np.cross(M + dt * k3, H_eff))return M + (dt / 6.0) * (k1 + 2 * k2 + 2 * k3 + k4)def heun_step(M, H_eff, alpha, gamma, dt):"""执行单个Heun步骤。"""# 初始斜率k1 = -gamma * np.cross(M, H_eff) + alpha * np.cross(M, np.cross(M, H_eff))# 使用Euler方法预测的终点M_euler = M + dt * k1# 校正斜率k2 = -gamma * np.cross(M_euler, H_eff) + alpha * np.cross(M_euler, np.cross(M_euler, H_eff))# 校正后的平均斜率average_k = 0.5 * (k1 + k2)return M + dt * average_kdef dormand_prince_step(M, H_eff, alpha, gamma, dt):"""执行单个Dormand-Prince步骤。"""k1 = -gamma * np.cross(M, H_eff) + alpha * np.cross(M, np.cross(M, H_eff))k2 = -gamma * np.cross(M + 0.2 * dt * k1, H_eff) + alpha * np.cross(M + 0.2 * dt * k1, np.cross(M + 0.2 * dt * k1, H_eff))# 需要更多阶段以实现完整# 简化以展示结构return M + dt * (0.2 * k1 + 0.8 * k2)def bogacki_shampine_step(M, H_eff, alpha, gamma, dt):"""执行单个Bogacki-Shampine步骤。"""k1 = -gamma * np.cross(M, H_eff) + alpha * np.cross(M, np.cross(M, H_eff))k2 = -gamma * np.cross(M + 0.5 * dt * k1, H_eff) + alpha * np.cross(M + 0.5 * dt * k1, np.cross(M + 0.5 * dt * k1, H_eff))k3 = -gamma * np.cross(M + 0.75 * dt * k2, H_eff) + alpha * np.cross(M + 0.75 * dt * k2, np.cross(M + 0.75 * dt * k2, H_eff))return M + (dt * (2 * k1 + 3 * k2 + 4 * k3) / 9)def solve_llg_equation(M0, H_eff, alpha, gamma, dt, T, method):"""使用指定的方法数值解决LLG方程。参数:M0: numpy数组,初始磁化向量H_eff: numpy数组,有效磁场向量alpha: 浮点数,自旋耗散参数gamma: 浮点数,旋磁比dt: 浮点数,时间步长T:浮点数,总时间method: 函数,要使用的数值方法(euler_step 或 rk4_step)返回:numpy数组,每个时间步骤的磁化向量"""num_steps = int(T / dt)  # 时间步数M = np.zeros((num_steps, len(M0)))  # 存储每个时间步的磁化向量M[0] = M0  # 设置初始磁化for i in range(1, num_steps):M[i] = method(M[i-1], H_eff, alpha, gamma, dt)return M# 示例使用
M0 = np.array([1, 0, 0])  # 初始磁化向量
H_eff = np.array([0, 0, 1])  # 有效磁场向量
alpha = 0.05  # 自旋耗散参数
gamma = 1.0  # 旋磁比
dt = 0.0005  # 时间步长
T = 5.0  # 总时间euler_solution = solve_llg_equation(M0, H_eff, alpha, gamma, dt, T, euler_step)
rk4_solution = solve_llg_equation(M0, H_eff, alpha, gamma, dt, T, rk4_step)
heun_solution = solve_llg_equation(M0, H_eff, alpha, gamma, dt, T, heun_step)
dormand_prince_solution = solve_llg_equation(M0, H_eff, alpha, gamma, dt, T, dormand_prince_step)
bogacki_shampine_solution = solve_llg_equation(M0, H_eff, alpha, gamma, dt, T, bogacki_shampine_step)# 绘制3D轨迹
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')# 绘制不同的解法轨迹
ax.plot(euler_solution[:, 0], euler_solution[:, 1], euler_solution[:, 2], label='RK1', color='blue')
ax.plot(heun_solution[:, 0], heun_solution[:, 1], heun_solution[:, 2], label='RK12', color='green')
ax.plot(bogacki_shampine_solution[:, 0], bogacki_shampine_solution[:, 1], bogacki_shampine_solution[:, 2], label='RK32', linestyle='--', color='red')
ax.plot(rk4_solution[:, 0], rk4_solution[:, 1], rk4_solution[:, 2], label='RK4', linestyle='-.', color='black')
ax.plot(dormand_prince_solution[:, 0], dormand_prince_solution[:, 1], dormand_prince_solution[:, 2], label='RK45', linestyle=':', color='purple')# 设置标签、图例和网格
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.legend()
ax.grid(True)# 设置视角
ax.view_init(elev=30, azim=120)# 显示图像
plt.show()
plt.show()

运行结果:

在这里插入图片描述

可以看到不同的算法求得的结果都是正确的。

五、总结

今天的总结内容主要是关于微磁学仿真器的核心部分LLG方程的解法,自己尝试了不同的求解算法,接下来需要从本身的设计构造去看。尝试扒一扒官网的源代码。


http://www.ppmy.cn/embedded/20323.html

相关文章

python在Django中使用django-mptt库来实现无限级树结构非常直观和方便

在Django中使用django-mptt库来实现无限级树结构非常直观和方便。django-mptt(Modified Preorder Tree Traversal)是一个用于Django模型的树形结构字段的库,它允许你通过递归的方式轻松地构建和操作树形结构。 下面是一个使用django-mptt和MySQL数据库实现无限级树结构的基…

java导出pdf(水印、页眉、表格、背景样式、页脚、饼图、柱图)

这里写自定义目录标题 controller层pdf模板RiskReportTemplate1(页脚、水印)多线程导出pdf数据pdf导出工具类(页眉、图片底纹、柱图、饼图、表格、一级二级标题)实体类pdf工具类(根据html生成pdf文件)页脚工具类柱图工具类饼图工具类 controller层 Post…

Docker创建镜像之--------------基于Dockerfile创建

目录 一、在编写 Dockerfile 时,有严格的格式需要遵循 二、Dockerfile 操作常用的指令 2.1ENTRYPOINT和CMD共存的情形 2.2ENTRYPOINT和CMD的区别 2.3ADD 与COPY的区别 三、Dockerfile案例 3.1构建apache镜像 3.1.1 创建镜像目录方便管理 3.1.2创建编写dock…

解决Android Studio安卓开发写入文件问题

有很多小伙伴想把文件写进安卓系统储存失败,类似下面的代码 val file File("account.txt")val writer BufferedWriter(FileWriter(file))writer.use {it.write(username "," password)} 用java方式写入读出文件但是显示成功但是找不到文件…

Python_AI库 matplotlib扩展知识

Python_AI库 matplotlib扩展知识 在数据分析和处理的领域里,可视化是一种不可或缺的手段。通过图形化的展示,我们可以更直观地理解数据的分布、趋势和关系。而matplotlib,作为Python中最为流行的数据可视化库之一,以其强大的功能…

【Linux系统编程】26.信号、kill、alarm、setitimer

目录 信号 信号共性 信号特质 产生信号 信号相关概念 默认处理动作 信号4要素 常规信号 ​编辑 注意 kill 参数pid 测试代码1 测试结果 测试代码2 测试结果 alarm 参数seconds 返回值 取消闹钟 测试代码3 测试结果1 测试结果2 ​编辑 setitimer 参数…

最最普通程序员,如何利用工资攒够彩礼,成为人生赢家

今天我们不讲如何提升你的专业技能去涨工资,不讲面试技巧如何跳槽涨工资,不讲如何干兼职赚人生第一桶金,就讲一个最最普通的程序员,如何在工作几年后,可以攒够彩礼钱,婚礼酒席钱,在自己人生大事…

力扣经典150题第四十题:同构字符串

目录 力扣经典150题第四十题:同构字符串引言题目详解解题思路代码实现示例演示复杂度分析 力扣经典150题第四十题:同构字符串 引言 本篇博客介绍了力扣经典150题中的第四十题:同构字符串。题目要求判断两个字符串 s 和 t 是否是同构的。 同…