2

我正在尝试编写一个分子动力学程序,并且我认为 Boost.Units 是变量的逻辑选择,并且我还认为 Boost.Multiprecision 提供了比舍入误差更好的double选择long double。两者的结合似乎相当简单,直到我尝试使用一个常数,然后它就崩溃了。

#include <boost/multiprecision/gmp.hpp>
#include <boost/units/io.hpp>
#include <boost/units/pow.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/systems/si.hpp>
#include <boost/units/systems/si/codata/physico-chemical_constants.hpp>

namespace units = boost::units;
namespace si = boost::si;
namespace mp = boost::multiprecision;

units::quantity<si::mass, mp::mpf_float_50> mass = 1.0 * si::kilogram;
units::quantity<si::temperature, mp::mpf_float_50> temperature = 300. * si::kelvin;
auto k_B = si::constants::codata::k_B;  // Boltzmann constant
units::quantity<si::velocity, mp::mpf_float_50> velocity = units::root<2>(temperature * k_B / mass);
std::cout << velocity << std::endl;

输出将是1 M S^-1. 如果我使用long double代替mp::mpf_float_50,那么结果是2.87818e-11 m s^-1。我知道问题在于常量和其他数据之间的转换,因为常量默认为double. 我曾考虑过创建自己的玻尔兹曼常数,但如果可能,我更喜欢使用预定义的值。

因此,我的问题是,当我从 Boost.Units 中预定义常量时,如何使用 Boost.Multiprecision?如果我必须承认使用doubleor long double,那么我会,但我怀疑存在一种方法可以在常量上转换或利用另一个。

我正在使用 Mac OS X 10.7、Xcode 4.6.2、Clang 3.2、Boost 1.53.0 和 C++11 扩展。

我很感激可以提供的任何帮助。

4

1 回答 1

1

我建议您不要在分子动力学模拟中使用多精度算法,因为时间步长积分会非常缓慢。如果目标是尽可能地保留总能量,那么只需使用 Verlet 或任何其他辛积分器。不过,多精度算术(或long double,或使用 plain 的补偿求和double)可能对聚合整体平均值很有用。

此外,如果您使用无量纲(缩减)单位编写模拟代码,您还将摆脱对 Boost.Units 的依赖。

于 2013-05-11T00:03:02.577 回答