mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 12:30:23 -04:00 
			
		
		
		
	
		
			
	
	
		
			166 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			166 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | /*
 | ||
|  |  Copyright 2011 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)
 | ||
|  |  */ | ||
|  | 
 | ||
|  | 
 | ||
|  | /* strongly nonlinear hamiltonian lattice in 2d */ | ||
|  | 
 | ||
|  | #ifndef LATTICE2D_HPP
 | ||
|  | #define LATTICE2D_HPP
 | ||
|  | 
 | ||
|  | #include <vector>
 | ||
|  | 
 | ||
|  | #include <boost/math/special_functions/pow.hpp>
 | ||
|  | 
 | ||
|  | using boost::math::pow; | ||
|  | 
 | ||
|  | template< int Kappa , int Lambda > | ||
|  | struct lattice2d { | ||
|  | 
 | ||
|  |     const double m_beta; | ||
|  |     std::vector< std::vector< double > > m_omega; | ||
|  | 
 | ||
|  |     lattice2d( const double beta ) | ||
|  |         : m_beta( beta ) | ||
|  |     { } | ||
|  | 
 | ||
|  |     template< class StateIn , class StateOut > | ||
|  |     void operator()( const StateIn &q , StateOut &dpdt ) | ||
|  |     { | ||
|  |         // q and dpdt are 2d
 | ||
|  |         const int N = q.size(); | ||
|  | 
 | ||
|  |         int i; | ||
|  |         for( i = 0 ; i < N ; ++i ) | ||
|  |         { | ||
|  |             const int i_l = (i-1+N) % N; | ||
|  |             const int i_r = (i+1) % N; | ||
|  |             for( int j = 0 ; j < N ; ++j ) | ||
|  |             { | ||
|  |             const int j_l = (j-1+N) % N; | ||
|  |             const int j_r = (j+1) % N; | ||
|  |             dpdt[i][j] = - m_omega[i][j] * pow<Kappa-1>( q[i][j] ) | ||
|  |                 - m_beta * pow<Lambda-1>( q[i][j] - q[i][j_l] ) | ||
|  |                 - m_beta * pow<Lambda-1>( q[i][j] - q[i][j_r] ) | ||
|  |                 - m_beta * pow<Lambda-1>( q[i][j] - q[i_l][j] ) | ||
|  |                 - m_beta * pow<Lambda-1>( q[i][j] - q[i_r][j] ); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     template< class StateIn > | ||
|  |     double energy( const StateIn &q , const StateIn &p ) | ||
|  |     { | ||
|  |         // q and dpdt are 2d
 | ||
|  |         const int N = q.size(); | ||
|  |         double energy = 0.0; | ||
|  |         int i; | ||
|  |         for( i = 0 ; i < N ; ++i ) | ||
|  |         { | ||
|  |             const int i_l = (i-1+N) % N; | ||
|  |             const int i_r = (i+1) % N; | ||
|  |             for( int j = 0 ; j < N ; ++j ) | ||
|  |             { | ||
|  |             const int j_l = (j-1+N) % N; | ||
|  |             const int j_r = (j+1) % N; | ||
|  |             energy += p[i][j]*p[i][j] / 2.0 | ||
|  |                         + m_omega[i][j] * pow<Kappa>( q[i][j] ) / Kappa | ||
|  |                 + m_beta * pow<Lambda>( q[i][j] - q[i][j_l] ) / Lambda / 2 | ||
|  |                 + m_beta * pow<Lambda>( q[i][j] - q[i][j_r] ) / Lambda / 2 | ||
|  |                 + m_beta * pow<Lambda>( q[i][j] - q[i_l][j] ) / Lambda / 2 | ||
|  |                 + m_beta * pow<Lambda>( q[i][j] - q[i_r][j] ) / Lambda / 2; | ||
|  |             } | ||
|  |         } | ||
|  |         return energy; | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< class StateIn , class StateOut > | ||
|  |     double local_energy( const StateIn &q , const StateIn &p , StateOut &energy ) | ||
|  |     { | ||
|  |         // q and dpdt are 2d
 | ||
|  |         const int N = q.size(); | ||
|  |         double e = 0.0; | ||
|  |         int i; | ||
|  |         for( i = 0 ; i < N ; ++i ) | ||
|  |         { | ||
|  |             const int i_l = (i-1+N) % N; | ||
|  |             const int i_r = (i+1) % N; | ||
|  |             for( int j = 0 ; j < N ; ++j ) | ||
|  |             { | ||
|  |                 const int j_l = (j-1+N) % N; | ||
|  |                 const int j_r = (j+1) % N; | ||
|  |                 energy[i][j] = p[i][j]*p[i][j] / 2.0 | ||
|  |                     + m_omega[i][j] * pow<Kappa>( q[i][j] ) / Kappa | ||
|  |                     + m_beta * pow<Lambda>( q[i][j] - q[i][j_l] ) / Lambda / 2 | ||
|  |                     + m_beta * pow<Lambda>( q[i][j] - q[i][j_r] ) / Lambda / 2 | ||
|  |                     + m_beta * pow<Lambda>( q[i][j] - q[i_l][j] ) / Lambda / 2 | ||
|  |                     + m_beta * pow<Lambda>( q[i][j] - q[i_r][j] ) / Lambda / 2; | ||
|  |                 e += energy[i][j]; | ||
|  |             } | ||
|  |         } | ||
|  |         //rescale
 | ||
|  |         e = 1.0/e; | ||
|  |         for( i = 0 ; i < N ; ++i ) | ||
|  |             for( int j = 0 ; j < N ; ++j ) | ||
|  |                 energy[i][j] *= e; | ||
|  |         return 1.0/e; | ||
|  |     } | ||
|  | 
 | ||
|  |     void load_pot( const char* filename , const double W , const double gap ,  | ||
|  |                    const size_t dim ) | ||
|  |     { | ||
|  |         std::ifstream in( filename , std::ios::in | std::ios::binary ); | ||
|  |         if( !in.is_open() ) { | ||
|  |             std::cerr << "pot file not found: " << filename << std::endl; | ||
|  |             exit(0); | ||
|  |         } else { | ||
|  |             std::cout << "using pot file: " << filename << std::endl; | ||
|  |         } | ||
|  | 
 | ||
|  |         m_omega.resize( dim ); | ||
|  |         for( int i = 0 ; i < dim ; ++i ) | ||
|  |         { | ||
|  |             m_omega[i].resize( dim ); | ||
|  |             for( size_t j = 0 ; j < dim ; ++j ) | ||
|  |             { | ||
|  |                 if( !in.good() ) | ||
|  |                 { | ||
|  |                     std::cerr << "I/O Error: " << filename << std::endl; | ||
|  |                     exit(0); | ||
|  |                 } | ||
|  |                 double d; | ||
|  |                 in.read( (char*) &d , sizeof(d) ); | ||
|  |                 if( (d < 0) || (d > 1.0) ) | ||
|  |                 { | ||
|  |                     std::cerr << "ERROR: " << d << std::endl; | ||
|  |                     exit(0); | ||
|  |                 } | ||
|  |                 m_omega[i][j] = W*d + gap; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |     } | ||
|  | 
 | ||
|  |     void generate_pot( const double W , const double gap , const size_t dim ) | ||
|  |     { | ||
|  |         m_omega.resize( dim ); | ||
|  |         for( size_t i = 0 ; i < dim ; ++i ) | ||
|  |         { | ||
|  |             m_omega[i].resize( dim ); | ||
|  |             for( size_t j = 0 ; j < dim ; ++j ) | ||
|  |             { | ||
|  |                 m_omega[i][j] = W*static_cast<double>(rand())/RAND_MAX + gap; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | #endif
 |