我正在尝试开发物理模拟,我想实现一个四阶symplectic integration方法。问题是我必须得到错误的数学,因为我的模拟在使用辛积分器时根本不起作用(与四阶Runge-Kutta积分器相比,模拟效果相当好)。我一直在谷歌搜索这个,我能找到的只是关于这个主题的科学文章。我试图改编文章中使用的方法,但我没有运气。我想知道是否有人拥有使用辛积分器的模拟的源代码,最好是模拟引力场,但任何辛积分器都可以。源代码的语言并不重要,但我会欣赏使用C风格语法的语言。谢谢!
答案 0 :(得分:7)
正如您所要求的源代码:从HERE,您可以下载MATLAB和FORTRAN代码,用于哈密顿系统的辛方法和可逆问题的对称方法。还有许多处理diff方程的其他方法。
在THIS论文中,您可以找到算法的描述。
修改强>
如果您使用Mathematica this也可能有帮助。
答案 1 :(得分:2)
以下是基于Verlet方案的四阶合成方法的源代码。 如理论预期的那样,$ \ log_ {10}(\ Delta t)$与$ \ log_ {10}(误差)$的线性回归将显示4的斜率(参见下图)。 可以找到更多信息here,here或here。
#include <cmath>
#include <iostream>
using namespace std;
const double total_time = 5e3;
// Parameters for the potential.
const double sigma = 1.0;
const double sigma6 = pow(sigma, 6.0);
const double epsilon = 1.0;
const double four_epsilon = 4.0 * epsilon;
// Constants used in the composition method.
const double alpha = 1.0 / (2.0 - cbrt(2.0));
const double beta = 1.0 - 2.0 * alpha;
static double force(double q, double& potential);
static void verlet(double dt,
double& q, double& p,
double& force, double& potential);
static void composition_method(double dt,
double& q, double& p,
double& f, double& potential);
int main() {
const double q0 = 1.5, p0 = 0.1;
double potential;
const double f0 = force(q0, potential);
const double total_energy_exact = p0 * p0 / 2.0 + potential;
for (double dt = 1e-2; dt <= 5e-2; dt *= 1.125) {
const long steps = long(total_time / dt);
double q = q0, p = p0, f = f0;
double total_energy_average = total_energy_exact;
for (long step = 1; step <= steps; ++step) {
composition_method(dt, q, p, f, potential);
const double total_energy = p * p / 2.0 + potential;
total_energy_average += total_energy;
}
total_energy_average /= double(steps);
const double err = fabs(total_energy_exact - total_energy_average);
cout << log10(dt) << "\t"
<< log10(err) << endl;
}
return 0;
}
double force(double q, double& potential) {
const double r2 = q * q;
const double r6 = r2 * r2 * r2;
const double factor6 = sigma6 / r6;
const double factor12 = factor6 * factor6;
potential = four_epsilon * (factor12 - factor6);
return -four_epsilon * (6.0 * factor6 - 12.0 * factor12) / r2 * q;
}
void verlet(double dt,
double& q, double& p,
double& f, double& potential) {
p += dt / 2.0 * f;
q += dt * p;
f = force(q, potential);
p += dt / 2.0 * f;
}
void composition_method(double dt,
double& q, double& p,
double& f, double& potential) {
verlet(alpha * dt, q, p, f, potential);
verlet(beta * dt, q, p, f, potential);
verlet(alpha * dt, q, p, f, potential);
}
答案 2 :(得分:1)
我在加速器物理领域(同步加速器光源),在模拟电子在磁场中移动时,我们定期使用辛积分器。我们的基本主力是四阶辛积分器。正如上面的评论所指出的那样,遗憾的是这些代码的标准化程度不高,或者很容易获得。
一个基于Matlab的开源跟踪代码称为Accelerator Toolbox。有一个名为atcollab的Sourceforge项目。在这里看到一个凌乱的维基 https://sourceforge.net/apps/mediawiki/atcollab/index.php?title=Main_Page
对于集成商,您可以在这里查看: https://sourceforge.net/p/atcollab/code-0/235/tree/trunk/atintegrators/ 积分器用C语言编写,MEX链接到Matlab。 因为电子是相对论的,动力学和潜在的术语看起来与非相对论的情况略有不同,但是人们仍然可以将哈密顿量写为H = H1 + H2,其中H1是漂移而H2是踢(例如来自四极磁铁)或其他磁场)。