spreading.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. Copyright 2011 Mario Mulansky
  3. Copyright 2012 Karsten Ahnert
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE_1_0.txt or
  6. copy at http://www.boost.org/LICENSE_1_0.txt)
  7. */
  8. /*
  9. * Example of a 2D simulation of nonlinearly coupled oscillators.
  10. * Program just prints final energy which should be close to the initial energy (1.0).
  11. * No parallelization is employed here.
  12. * Run time on a 2.3GHz Intel Core-i5: about 10 seconds for 100 steps.
  13. * Compile simply via bjam or directly:
  14. * g++ -O3 -I${BOOST_ROOT} -I../../../../.. spreading.cpp
  15. */
  16. #include <iostream>
  17. #include <fstream>
  18. #include <vector>
  19. #include <cstdlib>
  20. #include <sys/time.h>
  21. #include <boost/ref.hpp>
  22. #include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp>
  23. // we use a vector< vector< double > > as state type,
  24. // for that some functionality has to be added for odeint to work
  25. #include "nested_range_algebra.hpp"
  26. #include "vector_vector_resize.hpp"
  27. // defines the rhs of our dynamical equation
  28. #include "lattice2d.hpp"
  29. /* dynamical equations (Hamiltonian structure):
  30. dqdt_{i,j} = p_{i,j}
  31. dpdt_{i,j} = - omega_{i,j}*q_{i,j} - \beta*[ (q_{i,j} - q_{i,j-1})^3
  32. +(q_{i,j} - q_{i,j+1})^3
  33. +(q_{i,j} - q_{i-1,j})^3
  34. +(q_{i,j} - q_{i+1,j})^3 ]
  35. */
  36. using namespace std;
  37. static const int MAX_N = 1024;//2048;
  38. static const size_t KAPPA = 2;
  39. static const size_t LAMBDA = 4;
  40. static const double W = 1.0;
  41. static const double gap = 0.0;
  42. static const size_t steps = 100;
  43. static const double dt = 0.1;
  44. double initial_e = 1.0;
  45. double beta = 1.0;
  46. int realization_index = 0;
  47. //the state type
  48. typedef vector< vector< double > > state_type;
  49. //the stepper, choose a symplectic one to account for hamiltonian structure
  50. //use nested_range_algebra for calculations on vector< vector< ... > >
  51. typedef boost::numeric::odeint::symplectic_rkn_sb3a_mclachlan<
  52. state_type , state_type , double , state_type , state_type , double ,
  53. nested_range_algebra< boost::numeric::odeint::range_algebra > ,
  54. boost::numeric::odeint::default_operations > stepper_type;
  55. double time_diff_in_ms( timeval &t1 , timeval &t2 )
  56. { return (t2.tv_sec - t1.tv_sec)*1000.0 + (t2.tv_usec - t1.tv_usec)/1000.0 + 0.5; }
  57. int main( int argc, const char* argv[] ) {
  58. srand( time(NULL) );
  59. lattice2d< KAPPA , LAMBDA > lattice( beta );
  60. lattice.generate_pot( W , gap , MAX_N );
  61. state_type q( MAX_N , vector< double >( MAX_N , 0.0 ) );
  62. state_type p( q );
  63. state_type energy( q );
  64. p[MAX_N/2][MAX_N/2] = sqrt( 0.5*initial_e );
  65. p[MAX_N/2+1][MAX_N/2] = sqrt( 0.5*initial_e );
  66. p[MAX_N/2][MAX_N/2+1] = sqrt( 0.5*initial_e );
  67. p[MAX_N/2+1][MAX_N/2+1] = sqrt( 0.5*initial_e );
  68. cout.precision(10);
  69. lattice.local_energy( q , p , energy );
  70. double e=0.0;
  71. for( size_t i=0 ; i<energy.size() ; ++i )
  72. for( size_t j=0 ; j<energy[i].size() ; ++j )
  73. {
  74. e += energy[i][j];
  75. }
  76. cout << "initial energy: " << lattice.energy( q , p ) << endl;
  77. timeval elapsed_time_start , elapsed_time_end;
  78. gettimeofday(&elapsed_time_start , NULL);
  79. stepper_type stepper;
  80. for( size_t step=0 ; step<=steps ; ++step )
  81. {
  82. stepper.do_step( boost::ref( lattice ) ,
  83. make_pair( boost::ref( q ) , boost::ref( p ) ) ,
  84. 0.0 , 0.1 );
  85. }
  86. gettimeofday(&elapsed_time_end , NULL);
  87. double elapsed_time = time_diff_in_ms( elapsed_time_start , elapsed_time_end );
  88. cout << steps << " steps in " << elapsed_time/1000 << " s (energy: " << lattice.energy( q , p ) << ")" << endl;
  89. }