2

I am attempting to write a molecular dynamics program, and I thought that Boost.Units was a logical choice for the variables, and I also decided that Boost.Multiprecision offered a better option than double or long double with respect to round off errors. A combination of the two seems fairly straight forward until I attempt to use a constant, then it breaks down.

#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;

The output will be 1 M S^-1. If I use long double in lieu of mp::mpf_float_50, then the result is 2.87818e-11 m s^-1. I know that the problem likes within the conversion between the constant and the other data because the constant defaults to a double. I have thought about creating my own Boltzmann constant, but I prefer to use the predefined value if possible.

My question, therefore, is how do I go about using Boost.Multiprecision when I have predefined constants from Boost.Units? If I must concede to using double or long double, then I will, but I suspect that a way exists to convert or utilize the other on the constants.

I am working with Mac OS X 10.7, Xcode 4.6.2, Clang 3.2, Boost 1.53.0 and the C++11 extensions.

I appreciate any help that can be offered.

Tim
  • 107
  • 1
  • 10
  • The fact that the physical constants are in double precision (and no to more precision) already tells you that there is no point in being more exact than that. It is more useful to concentrate in choosing the integration method well and doing the ensemble averages well than increasing the precision of your coordinate representation. Quoting NR Book, "Hamming’s motto, “the purpose of computing is insight, not numbers,” [...]. You should repeat this motto aloud whenever your program converges, with sixteen- digit accuracy, to the wrong (solution) of a problem..." – alfC Sep 28 '18 at 06:02

1 Answers1

1

I'd advise you not to use multiple precision arithmetic for molecular dynamics simulations because the time-step integration will be painfully slow. If the goal is to preserve total energy as much as possible, then just use Verlet or any other symplectic integrator. Multiple precision arithmetic (or long double, or compensated summation with plain double) may be useful for aggregating ensemble averages, though.

Besides, if you write your simulation code using dimensionless (reduced) units you will also get rid of the dependency on Boost.Units.

jmbr
  • 3,298
  • 23
  • 23
  • Thanks for the advice. I like the idea of Boost.Units as a means to keep track of everything especially for print outs, but I did not think about the ramifications of multiple precision. In theory, it sounds nice, and I knew someone who wrote a molecular dynamics suite in C using GMP. I simply thought that the additional precision could be useful, but you have a good point especially if I desire speed along with accuracy. Thanks. – Tim May 11 '13 at 00:26
  • 1
    In my experience, even two-dimensional Molecular Dynamics simulatons at constant energy for relatively simple potentials (double-well, Müller-Brown, etc.) require significant computing power if one wants to calculate well-converged ensemble averages, hence my suggestion. – jmbr May 11 '13 at 00:36