/* * resizing_lattice.cpp * * Demonstrates the usage of resizing of the state type during integration. * Examplary system is a strongly nonlinear, disordered Hamiltonian lattice * where the spreading of energy is investigated * * Copyright 2011-2012 Mario Mulansky * Copyright 2012-2013 Karsten Ahnert * Distributed under the Boost Software License, Version 1.0. (See * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * */ #include #include #include #include #include using namespace std; using namespace boost::numeric::odeint; //[ resizing_lattice_system_class typedef vector< double > coord_type; typedef pair< coord_type , coord_type > state_type; struct compacton_lattice { const int m_max_N; const double m_beta; int m_pot_start_index; vector< double > m_pot; compacton_lattice( int max_N , double beta , int pot_start_index ) : m_max_N( max_N ) , m_beta( beta ) , m_pot_start_index( pot_start_index ) , m_pot( max_N ) { srand( time( NULL ) ); // fill random potential with iid values from [0,1] boost::mt19937 rng; boost::uniform_real<> unif( 0.0 , 1.0 ); boost::variate_generator< boost::mt19937&, boost::uniform_real<> > gen( rng , unif ); generate( m_pot.begin() , m_pot.end() , gen ); } void operator()( const coord_type &q , coord_type &dpdt ) { // calculate dpdt = -dH/dq of this hamiltonian system // dp_i/dt = - V_i * q_i^3 - beta*(q_i - q_{i-1})^3 + beta*(q_{i+1} - q_i)^3 const int N = q.size(); double diff = q[0] - q[N-1]; for( int i=0 ; i hamiltonian_stepper; hamiltonian_stepper stepper; hamiltonian_stepper::state_type state = make_pair( q , p ); //] //[ resizing_lattice_steps_loop double t = 0.0; const double dt = 0.1; const int steps = 10000; for( int step = 0 ; step < steps ; ++step ) { stepper.do_step( boost::ref(lattice) , state , t , dt ); lattice.energy_distribution( state.first , state.second , distr ); if( distr[10] > 1E-150 ) { do_resize( state.first , state.second , distr , state.first.size()+20 ); rotate( state.first.begin() , state.first.end()-20 , state.first.end() ); rotate( state.second.begin() , state.second.end()-20 , state.second.end() ); lattice.change_pot_start( -20 ); cout << t << ": resized left to " << distr.size() << ", energy = " << lattice.energy( state.first , state.second ) << endl; } if( distr[distr.size()-10] > 1E-150 ) { do_resize( state.first , state.second , distr , state.first.size()+20 ); cout << t << ": resized right to " << distr.size() << ", energy = " << lattice.energy( state.first , state.second ) << endl; } t += dt; } //] cout << "final lattice size: " << distr.size() << ", final energy: " << lattice.energy( state.first , state.second ) << endl; }