molecular_dynamics.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. [auto_generated]
  3. libs/numeric/odeint/examples/molecular_dynamics.cpp
  4. [begin_description]
  5. Molecular dynamics example.
  6. [end_description]
  7. Copyright 2009-2012 Karsten Ahnert
  8. Copyright 2009-2012 Mario Mulansky
  9. Distributed under the Boost Software License, Version 1.0.
  10. (See accompanying file LICENSE_1_0.txt or
  11. copy at http://www.boost.org/LICENSE_1_0.txt)
  12. */
  13. #include <boost/numeric/odeint.hpp>
  14. #include <vector>
  15. #include <iostream>
  16. #include <random>
  17. using namespace boost::numeric::odeint;
  18. using namespace std;
  19. #define tab "\t"
  20. const size_t n1 = 16;
  21. const size_t n2 = 16;
  22. struct md_system
  23. {
  24. static const size_t n = n1 * n2;
  25. typedef std::vector< double > vector_type;
  26. md_system( double a = 0.0 , // strength of harmonic oscillator
  27. double gamma = 0.0 , // friction
  28. double eps = 0.1 , // interaction strenght
  29. double sigma = 1.0 , // interaction radius
  30. double xmax = 150.0 , double ymax = 150.0 )
  31. : m_a( a ) , m_gamma( gamma )
  32. , m_eps( eps ) , m_sigma( sigma )
  33. , m_xmax( xmax ) , m_ymax( ymax )
  34. { }
  35. static void init_vector_type( vector_type &x ) { x.resize( 2 * n ); }
  36. void operator()( vector_type const& x , vector_type const& v , vector_type &a , double t ) const
  37. {
  38. for( size_t i=0 ; i<n ; ++i )
  39. {
  40. double diffx = x[i] - 0.5 * m_xmax , diffy = x[i+n] - 0.5 * m_ymax;
  41. double r2 = diffx * diffx + diffy * diffy ;
  42. double r = std::sqrt( r2 );
  43. a[ i ] = - m_a * r * diffx - m_gamma * v[ i ] ;
  44. a[ n + i ] = - m_a * r * diffy - m_gamma * v[ n + i ] ;
  45. }
  46. for( size_t i=0 ; i<n ; ++i )
  47. {
  48. double xi = x[i] , yi = x[n+i];
  49. xi = periodic_bc( xi , m_xmax );
  50. yi = periodic_bc( yi , m_ymax );
  51. for( size_t j=0 ; j<i ; ++j )
  52. {
  53. double xj = x[j] , yj = x[n+j];
  54. xj = periodic_bc( xj , m_xmax );
  55. yj = periodic_bc( yj , m_ymax );
  56. double diffx = ( xj - xi ) , diffy = ( yj - yi );
  57. double r = sqrt( diffx * diffx + diffy * diffy );
  58. double f = lennard_jones( r );
  59. a[ i ] += diffx / r * f;
  60. a[ n + i ] += diffy / r * f;
  61. a[ j ] -= diffx / r * f;
  62. a[ n + j ] -= diffy / r * f;
  63. }
  64. }
  65. }
  66. void bc( vector_type &x )
  67. {
  68. for( size_t i=0 ; i<n ; ++i )
  69. {
  70. x[ i ] = periodic_bc( x[ i ] , m_xmax );
  71. x[ i + n ] = periodic_bc( x[ i + n ] , m_ymax );
  72. }
  73. }
  74. inline double lennard_jones( double r ) const
  75. {
  76. double c = m_sigma / r;
  77. double c3 = c * c * c;
  78. double c6 = c3 * c3;
  79. return 4.0 * m_eps * ( -12.0 * c6 * c6 / r + 6.0 * c6 / r );
  80. }
  81. static inline double periodic_bc( double x , double xmax )
  82. {
  83. return ( x < 0.0 ) ? x + xmax : ( x > xmax ) ? x - xmax : x ;
  84. }
  85. double m_a;
  86. double m_gamma;
  87. double m_eps ;
  88. double m_sigma ;
  89. double m_xmax , m_ymax;
  90. };
  91. int main( int argc , char *argv[] )
  92. {
  93. const size_t n = md_system::n;
  94. typedef md_system::vector_type vector_type;
  95. std::mt19937 rng;
  96. std::normal_distribution<> dist( 0.0 , 1.0 );
  97. vector_type x , v;
  98. md_system::init_vector_type( x );
  99. md_system::init_vector_type( v );
  100. for( size_t i=0 ; i<n1 ; ++i )
  101. {
  102. for( size_t j=0 ; j<n2 ; ++j )
  103. {
  104. x[i*n2+j ] = 5.0 + i * 4.0 ;
  105. x[i*n2+j+n] = 5.0 + j * 4.0 ;
  106. v[i] = dist( rng ) ;
  107. v[i+n] = dist( rng ) ;
  108. }
  109. }
  110. velocity_verlet< vector_type > stepper;
  111. const double dt = 0.025;
  112. double t = 0.0;
  113. md_system sys;
  114. for( size_t oi=0 ; oi<100000 ; ++oi )
  115. {
  116. for( size_t ii=0 ; ii<100 ; ++ii,t+=dt )
  117. stepper.do_step( sys , std::make_pair( std::ref( x ) , std::ref( v ) ) , t , dt );
  118. sys.bc( x );
  119. std::cout << "set size square" << "\n";
  120. std::cout << "unset key" << "\n";
  121. std::cout << "p [0:" << sys.m_xmax << "][0:" << sys.m_ymax << "] '-' pt 7 ps 0.5" << "\n";
  122. for( size_t i=0 ; i<n ; ++i )
  123. std::cout << x[i] << " " << x[i+n] << " " << v[i] << " " << v[i+n] << "\n";
  124. std::cout << "e" << std::endl;
  125. }
  126. return 0;
  127. }