首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >辛积分器的帮助

辛积分器的帮助
EN

Stack Overflow用户
提问于 2010-09-10 04:00:30
回答 3查看 4.6K关注 0票数 12

我正在尝试开发一个物理模拟,我想实现一个四阶symplectic integration方法。问题是我一定是把数学搞错了,因为我的模拟在使用辛积分器时根本不工作(与四阶Runge-Kutta积分器相比,它在模拟中工作得相当好)。我已经在谷歌上搜索了很久,我能找到的都是关于这个主题的科学文章。我试着改写文章中使用的方法,但没有成功。我想知道是否有人有利用辛积分器进行模拟的源代码,最好是用来模拟引力场,但任何辛积分器都可以。源代码是什么语言并不太重要,但我会喜欢使用C风格语法的语言。谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-10 10:07:16

正如您所要求的源代码:您可以从HERE下载用于哈密顿系统的辛方法和用于可逆问题的对称方法的MATLAB和FORTRAN代码。还有很多处理diff方程的其他方法。

THIS的论文中,你可以找到算法的描述。

编辑

如果你使用Mathematica,this可能也会有所帮助。

票数 7
EN

Stack Overflow用户

发布于 2013-08-18 18:35:29

下面是基于Verlet方案的四阶合成方法的源代码。$\log_{10}(\Δt)$与$\log_{10}(错误)$的线性回归将显示斜率为4,正如理论所预期的那样(见下图)。更多信息可以在hereherehere上找到。

代码语言:javascript
复制
#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
EN

Stack Overflow用户

发布于 2013-08-02 19:26:00

我从事的是加速器物理(同步加速器光源)领域,在模拟穿过磁场的电子时,我们经常使用辛积分器。我们的基本主力是一个4阶辛积分器。正如上面的评论所指出的,不幸的是,这些代码并没有那么好地标准化,也没有那么容易获得。

一个基于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编写的,带有指向Matlab的MEX链接。由于电子是相对论的,动力学和势项看起来与非相对论情况略有不同,但人们仍然可以将哈密顿量写成H=H1+H2,其中H1是漂移,H2是踢(例如来自四极磁铁或其他磁场)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3680136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档