File: gauss_packet.cpp

package info (click to toggle)
boost1.83 1.83.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 545,632 kB
  • sloc: cpp: 3,857,086; xml: 125,552; ansic: 34,414; python: 25,887; asm: 5,276; sh: 4,799; ada: 1,681; makefile: 1,629; perl: 1,212; pascal: 1,139; sql: 810; yacc: 478; ruby: 102; lisp: 24; csh: 6
file content (141 lines) | stat: -rw-r--r-- 3,762 bytes parent folder | download | duplicates (18)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * gauss_packet.cpp
 *
 * Schroedinger equation with potential barrier and periodic boundary conditions
 * Initial Gauss packet moving to the right
 *
 * pipe output into gnuplot to see animation
 *
 * Implementation of Hamilton operator via MTL library
 *
 * Copyright 2011-2013 Mario Mulansky
 * Copyright 2011-2012 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 <iostream>
#include <complex>

#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/mtl4/mtl4.hpp>

#include <boost/numeric/mtl/mtl.hpp>


using namespace std;
using namespace boost::numeric::odeint;

typedef mtl::dense_vector< complex< double > > state_type;

struct hamiltonian {

    typedef mtl::compressed2D< complex< double > > matrix_type;
    matrix_type m_H;

    hamiltonian( const int N ) : m_H( N , N )
    {
        // constructor with zero potential
        m_H = 0.0;
        initialize_kinetic_term();
    }

    //template< mtl::compressed2D< double > >
    hamiltonian( mtl::compressed2D< double > &V ) : m_H( num_rows( V ) , num_cols( V ) )
    {
        // use potential V in hamiltonian
        m_H = complex<double>( 0.0 , -1.0 ) * V;
        initialize_kinetic_term();
    }

    void initialize_kinetic_term( )
    {
        const int N = num_rows( m_H );
        mtl::matrix::inserter< matrix_type , mtl::update_plus< complex<double> > > ins( m_H );
        const double z = 1.0;
        // fill diagonal and upper and lower diagonal
        for( int i = 0 ; i<N ; ++i )
        {
            ins[ i ][ (i+1) % N ] << complex< double >( 0.0 , -z );
            ins[ i ][ i ] << complex< double >( 0.0 , z );
            ins[ (i+1) % N ][ i ] << complex< double >( 0.0 , -z );
        }
    }

    void operator()( const state_type &psi , state_type &dpsidt , const double t )
    {
        dpsidt = m_H * psi;
    }

};

struct write_for_gnuplot
{
    size_t m_every , m_count;

    write_for_gnuplot( size_t every = 10 )
    : m_every( every ) , m_count( 0 ) { }

    void operator()( const state_type &x , double t )
    {
        if( ( m_count % m_every ) == 0 )
        {
            //clog << t << endl;
            cout << "p [0:" << mtl::size(x) << "][0:0.02] '-'" << endl;
            for( size_t i=0 ; i<mtl::size(x) ; ++i )
            {
                cout << i << "\t" << norm(x[i]) << "\n";
            }
            cout << "e" << endl;
        }

        ++m_count;
    }
};

static const int N = 1024;
static const int N0 = 256;
static const double sigma0 = 20;
static const double k0 = -1.0;

int main( int argc , char** argv )
{
    state_type x( N , 0.0 );

    // initialize gauss packet with nonzero velocity
    for( int i=0 ; i<N ; ++i )
    {
        x[i] = exp( -(i-N0)*(i-N0) / ( 4.0*sigma0*sigma0 ) ) * exp( complex< double >( 0.0 , k0*i ) );
        //x[i] += 2.0*exp( -(i+N0-N)*(i+N0-N) / ( 4.0*sigma0*sigma0 ) ) * exp( complex< double >( 0.0 , -k0*i ) );
    }
    x /= mtl::two_norm( x );

    typedef runge_kutta4< state_type > stepper;

    // create potential barrier
    mtl::compressed2D< double > V( N , N );
    V = 0.0;
    {
        mtl::matrix::inserter< mtl::compressed2D< double > > ins( V );
        for( int i=0 ; i<N ; ++i )
        {
            //ins[i][i] << 1E-4*(i-N/2)*(i-N/2);

            if( i < N/2 )
                ins[ i ][ i ] << 0.0 ;
            else
                ins[ i ][ i ] << 1.0 ;

        }
    }

    // perform integration, output can be piped to gnuplot
    integrate_const( stepper() , hamiltonian( V ) , x , 0.0 , 1000.0 , 0.1 , write_for_gnuplot( 10 ) );

    clog << "Norm: " << mtl::two_norm( x ) << endl;

    return 0;
}