2013-05-10 34 views
1

我試圖編寫一個分子動力學程序,我認爲Boost.Units是變量的邏輯選擇,並且我還決定Boost.Multiprecision提供了一個比double更好的選項或關於舍入誤差的long double。兩者的結合似乎相當直接,直到我試圖使用一個常量,然後崩潰。使用Boost.Units和Boost.Multiprecision

#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?如果我必須承認使用doublelong double,那麼我會,但我懷疑存在一種方法來轉換或利用常量上的其他方法。

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

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

回答

1

我建議你不要使用多精度算法進行分子動力學模擬,因爲時間步長積分將會非常緩慢。如果目標是儘可能地保留總能量,那麼只需使用Verlet或任何其他辛積分器。儘管如此,多精度算術(或者long double,或者使用普通的double進行補償的總和)對於彙總總體平均值可能是有用的。此外,如果您使用無量綱(減小)單位編寫模擬代碼,您也將擺脫對Boost.Units的依賴關係。

+0

感謝您的意見。我喜歡Boost.Units的想法,作爲一種手段來跟蹤一切,尤其是對於打印輸出,但我沒有考慮到多精度的影響。理論上,這聽起來不錯,我知道有人用C語言編寫了一個使用GMP的分子動力學套件。我只是認爲額外的精度可能是有用的,但你有一個好點,特別是如果我希望速度和準確性。謝謝。 – Tim 2013-05-11 00:26:01

+1

根據我的經驗,即使是對於相對簡單的電位(雙井,Müller-Brown等)的恆定能量的二維分子動力學模擬,如果要計算收斂良好的總體平均數,需要相當大的計算能力,因此我的建議。 – jmbr 2013-05-11 00:36:20