Quantum Dissipation in a $x^2$ potential

$V = c x^2$

The dissipation model is

$A = $


In [1]:
import pickle
import h5py
import numpy as np
import scipy.fftpack as fftpack

from scipy.special import hyp1f1
import pylab as plt
import matplotlib.cm as cm

import scipy.linalg as linalg
from scipy import integrate
import time
#import ctypes
from string import Template
import sys
import os
import cv2

import pycuda.gpuarray as gpuarray
import pycuda.driver as cuda
from pycuda.compiler import SourceModule
import pycuda.autoinit

#import cublas

import scikits.cuda.linalg as cu_linalg
cu_linalg.init()

from pywignercuda_path import SetPyWignerCUDA_Path
SetPyWignerCUDA_Path()

from GPU_Rho2D_MUBasis import *

import matplotlib

%matplotlib inline

In [2]:
#Defining parameters

X_gridDIM = 256
X_amplitude =  20

dt= 0.005
timeSteps =      40000
skipFrames =       100


gammaRenormalization = 1. #15


print ' Evolution time ',timeSteps*dt


 Evolution time  200.0

In [3]:
# Defining the instance 

class Rho2D_Dissipation_X2(Rho2D_Dissipation):
    """
    Instance for dissipative dynamics     
    """
    def __init__(self):
        
        self.x_init =  0.
        self.p_init =  3.
        
        self.omega = 1
        self.mass = 1

        self.gammaDamping   = 0.07
        self.D_Theta = 0.02
        #self.kT = 0.1   
        #self.D_Theta = self.D_Function( self.kT )
    
        self.L_material = 2.
        
        self.epsilon = 0.5        
        epsilon = self.epsilon
    
        #
        
        constantX2 = 0.5*self.mass*self.omega**2
        self.potentialString = '{0}*pow(x,2)'.format( constantX2 )

        self.dPotentialString = '2.*{0}*x'.format( constantX2 )
        
        dampingType = 'Ohmic'  
        
        # Data output file
        self.fileName  ='/home/rcabrera/DATA/Rho2D/'+dampingType
        self.fileName +='/grid{2}_L{0}_epsilon{1}_amplitude{3}'.format( self.L_material,epsilon,X_gridDIM,X_amplitude)
        self.fileName +='/Rho2D_ODMDamping_XX_PInit{0}_Omega{1}_DTheta{2}.hdf5'.format(
                                                                            self.p_init, self.omega, self.D_Theta )
        
        # Lindbladian operator A
        self.A_fileName = '/home/rcabrera/Documents/source/python/PyWignerCUDA/instances/Rho2D/'+dampingType
        self.A_fileName += '/grid{2}_L{0}_epsilon{1}_amplitude{3}'.format(self.L_material,epsilon,X_gridDIM,X_amplitude)
        self.A_fileName += '/Lindblad_A.hdf5'
                
        Rho2D_Dissipation.__init__(
                self,X_gridDIM,X_amplitude,dt,timeSteps,skipFrames) 
        
        # Setting initial state   
        n = 0
        self.Rho_init = self.Rho_HarmonicOscillator(n,self.omega,self.x_init, self.p_init)
      
    def D_Function(self,kT,Omega=None):
            if Omega is None:
                Omega = 0.1*self.omega
            if Omega == 0:
                return 2*self.gammaDamping*self.mass*kT
            else:
                return self.gammaDamping*self.mass*Omega/2./np.tanh( Omega/(4* kT)  )         
            
    def f_Damping(self, P):
			return P*P/np.sqrt( P*P + self.epsilon**2  ) 
        
    def df_Damping(self, P):
            return (P*P*P + 2*P*self.epsilon**2 )/( P*P + self.epsilon**2  )**(1.5)       
        
    def  Ehrenfest_X2_QuantumCorrection(self,P):
            hBar = self.hBar
            L = self.L_material
            gamma = self.gammaDamping
            return  0.5*gamma*self.hBar*L*( P*P + 2*self.epsilon**2 )**2/( P*P + self.epsilon**2 )**(2.5)

In [4]:
instance = Rho2D_Dissipation_X2()


V(x)     =  0.5*pow(x,2)
            
dV(x)/dx =  2.*0.5*x

Gao's D = D(kT)


In [5]:
fig, ax = plt.subplots(figsize=(8, 8))

kT_Range = np.linspace( 1e-6, 0.2 ,100 )

ax.plot( kT_Range , instance.D_Function( kT_Range, Omega=0.1 )  ,label='$\\Omega=0.1$')
ax.plot( kT_Range , instance.D_Function( kT_Range, Omega=0.2 )  ,label='$\\Omega=0.2$')
ax.plot( kT_Range , instance.D_Function( kT_Range, Omega=0.3 )  ,label='$\\Omega=0.3$')
ax.plot( kT_Range , instance.D_Function( kT_Range, Omega=0.4 )  ,label='$\\Omega=0.4$')

ax.set_xlabel('kT')
ax.set_ylabel('D')
ax.grid('on')
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)


Out[5]:
<matplotlib.legend.Legend at 0x7fe09082b690>

In [6]:
energySpectrum = np.sort( linalg.eigvals( instance.Hamiltonian  ).real )

print '         dX = ',instance.dX , '           dP   =',instance.dP
print ' X_Amplitude = ',instance.X_amplitude , ' P_Amplitude = ',instance.P_amplitude 

print '  '
print ' Harm Osc  Potential with energy spectrum '
fig, ax = plt.subplots(figsize=(10, 10))
X_range = instance.X_Range() 
ax.plot( X_range  ,   instance.Potential(0,X_range  ) ,color = 'r')

map( lambda x: ax.plot( [-X_amplitude,X_amplitude], [x,x] , color='gray' )  ,energySpectrum)

ax.set_xlim(-10,10)
ax.set_ylim(0,30)
ax.set_xlabel('x')
ax.set_ylabel('V')
ax.set_aspect(1./2.)
#ax.grid('on')


         dX =  0.15625            dP   = 0.157079632679
 X_Amplitude =  20  P_Amplitude =  20.106192983
  
 Harm Osc  Potential with energy spectrum 

In [7]:
fig, ax = plt.subplots(figsize=(10, 10))
ax.plot( instance.P_Range()  ,  np.sign(instance.P_Range() )*instance.f_Damping( instance.P_Range()  )  ,
        '.', label=' sign(p) f(p) ' )

ax.plot( instance.P_Range()  ,  instance.f_Damping( instance.P_Range()  )  ,
        '-', label=' f(p) ' )
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
ax.set_xlabel('$p$')


Out[7]:
<matplotlib.text.Text at 0x7fe09061f350>

In [8]:
instance.fileName


Out[8]:
'/home/rcabrera/DATA/Rho2D/Ohmic/grid256_L2.0_epsilon0.5_amplitude20/Rho2D_ODMDamping_XX_PInit3.0_Omega1_DTheta0.02.hdf5'

In [9]:
if os.path.isfile( instance.A_fileName )==True:
    
    print 'Loading A file'
    A = instance.LoadLindbladianOperatorA( instance.A_fileName )
    
else:
    
    print 'Starting the computation of Ohmic Lindbladian operator A'
    
    initial_time = time.time()

    A = instance.A_Damping( )

    print "--- Calculation time ", time.time() - initial_time , ' s '
    
    instance.SaveLindbladianOperatorA( instance.A_fileName , A )


Loading A file

RUN


In [10]:
initial_time = time.time()

instance.Run( A, gammaRenormalization )

print "--- Calculation time ", time.time() - initial_time , ' s '


progress  0 %
progress  0 %
progress  0 %
progress  0 %
progress  0 %
progress  1 %
progress  1 %
progress  1 %
progress  1 %
progress  2 %
progress  2 %
progress  2 %
progress  2 %
progress  3 %
progress  3 %
progress  3 %
progress  3 %
progress  4 %
progress  4 %
progress  4 %
progress  4 %
progress  5 %
progress  5 %
progress  5 %
progress  5 %
progress  6 %
progress  6 %
progress  6 %
progress  6 %
progress  7 %
progress  7 %
progress  7 %
progress  7 %
progress  8 %
progress  8 %
progress  8 %
progress  8 %
progress  9 %
progress  9 %
progress  9 %
progress  9 %
progress  10 %
progress  10 %
progress  10 %
progress  10 %
progress  11 %
progress  11 %
progress  11 %
progress  11 %
progress  12 %
progress  12 %
progress  12 %
progress  12 %
progress  13 %
progress  13 %
progress  13 %
progress  13 %
progress  14 %
progress  14 %
progress  14 %
progress  14 %
progress  15 %
progress  15 %
progress  15 %
progress  15 %
progress  16 %
progress  16 %
progress  16 %
progress  16 %
progress  17 %
progress  17 %
progress  17 %
progress  17 %
progress  18 %
progress  18 %
progress  18 %
progress  18 %
progress  19 %
progress  19 %
progress  19 %
progress  19 %
progress  20 %
progress  20 %
progress  20 %
progress  20 %
progress  21 %
progress  21 %
progress  21 %
progress  21 %
progress  22 %
progress  22 %
progress  22 %
progress  22 %
progress  23 %
progress  23 %
progress  23 %
progress  23 %
progress  24 %
progress  24 %
progress  24 %
progress  24 %
progress  25 %
progress  25 %
progress  25 %
progress  25 %
progress  26 %
progress  26 %
progress  26 %
progress  26 %
progress  27 %
progress  27 %
progress  27 %
progress  27 %
progress  28 %
progress  28 %
progress  28 %
progress  28 %
progress  29 %
progress  29 %
progress  29 %
progress  29 %
progress  30 %
progress  30 %
progress  30 %
progress  30 %
progress  31 %
progress  31 %
progress  31 %
progress  31 %
progress  32 %
progress  32 %
progress  32 %
progress  32 %
progress  33 %
progress  33 %
progress  33 %
progress  33 %
progress  34 %
progress  34 %
progress  34 %
progress  34 %
progress  35 %
progress  35 %
progress  35 %
progress  35 %
progress  36 %
progress  36 %
progress  36 %
progress  36 %
progress  37 %
progress  37 %
progress  37 %
progress  37 %
progress  38 %
progress  38 %
progress  38 %
progress  38 %
progress  39 %
progress  39 %
progress  39 %
progress  39 %
progress  40 %
progress  40 %
progress  40 %
progress  40 %
progress  41 %
progress  41 %
progress  41 %
progress  41 %
progress  42 %
progress  42 %
progress  42 %
progress  42 %
progress  43 %
progress  43 %
progress  43 %
progress  43 %
progress  44 %
progress  44 %
progress  44 %
progress  44 %
progress  45 %
progress  45 %
progress  45 %
progress  45 %
progress  46 %
progress  46 %
progress  46 %
progress  46 %
progress  47 %
progress  47 %
progress  47 %
progress  47 %
progress  48 %
progress  48 %
progress  48 %
progress  48 %
progress  49 %
progress  49 %
progress  49 %
progress  49 %
progress  50 %
progress  50 %
progress  50 %
progress  50 %
progress  51 %
progress  51 %
progress  51 %
progress  51 %
progress  52 %
progress  52 %
progress  52 %
progress  52 %
progress  53 %
progress  53 %
progress  53 %
progress  53 %
progress  54 %
progress  54 %
progress  54 %
progress  54 %
progress  55 %
progress  55 %
progress  55 %
progress  55 %
progress  56 %
progress  56 %
progress  56 %
progress  56 %
progress  57 %
progress  57 %
progress  57 %
progress  57 %
progress  58 %
progress  58 %
progress  58 %
progress  58 %
progress  59 %
progress  59 %
progress  59 %
progress  59 %
progress  60 %
progress  60 %
progress  60 %
progress  60 %
progress  61 %
progress  61 %
progress  61 %
progress  61 %
progress  62 %
progress  62 %
progress  62 %
progress  62 %
progress  63 %
progress  63 %
progress  63 %
progress  63 %
progress  64 %
progress  64 %
progress  64 %
progress  64 %
progress  65 %
progress  65 %
progress  65 %
progress  65 %
progress  66 %
progress  66 %
progress  66 %
progress  66 %
progress  67 %
progress  67 %
progress  67 %
progress  67 %
progress  68 %
progress  68 %
progress  68 %
progress  68 %
progress  69 %
progress  69 %
progress  69 %
progress  69 %
progress  70 %
progress  70 %
progress  70 %
progress  70 %
progress  71 %
progress  71 %
progress  71 %
progress  71 %
progress  72 %
progress  72 %
progress  72 %
progress  72 %
progress  73 %
progress  73 %
progress  73 %
progress  73 %
progress  74 %
progress  74 %
progress  74 %
progress  74 %
progress  75 %
progress  75 %
progress  75 %
progress  75 %
progress  76 %
progress  76 %
progress  76 %
progress  76 %
progress  77 %
progress  77 %
progress  77 %
progress  77 %
progress  78 %
progress  78 %
progress  78 %
progress  78 %
progress  79 %
progress  79 %
progress  79 %
progress  79 %
progress  80 %
progress  80 %
progress  80 %
progress  80 %
progress  81 %
progress  81 %
progress  81 %
progress  81 %
progress  82 %
progress  82 %
progress  82 %
progress  82 %
progress  83 %
progress  83 %
progress  83 %
progress  83 %
progress  84 %
progress  84 %
progress  84 %
progress  84 %
progress  85 %
progress  85 %
progress  85 %
progress  85 %
progress  86 %
progress  86 %
progress  86 %
progress  86 %
progress  87 %
progress  87 %
progress  87 %
progress  87 %
progress  88 %
progress  88 %
progress  88 %
progress  88 %
progress  89 %
progress  89 %
progress  89 %
progress  89 %
progress  90 %
progress  90 %
progress  90 %
progress  90 %
progress  91 %
progress  91 %
progress  91 %
progress  91 %
progress  92 %
progress  92 %
progress  92 %
progress  92 %
progress  93 %
progress  93 %
progress  93 %
progress  93 %
progress  94 %
progress  94 %
progress  94 %
progress  94 %
progress  95 %
progress  95 %
progress  95 %
progress  95 %
progress  96 %
progress  96 %
progress  96 %
progress  96 %
progress  97 %
progress  97 %
progress  97 %
progress  97 %
progress  98 %
progress  98 %
progress  98 %
progress  98 %
progress  99 %
progress  99 %
progress  99 %
progress  99 %
                     
blockCUDA =  (256, 1, 1)
gridCUDA =  (256, 1)
--- Calculation time  1018.87623692  s 

Testing


In [11]:
print ' <X> = ', np.trace(instance.Rho_init.dot(instance.X)).real, ' -> ', np.trace(instance.Rho_end.dot(instance.X)).real

print ' <P> =  ', np.round(np.trace(instance.Rho_init.dot(instance.P)).real,14) , '  -> ', np.trace(instance.Rho_end.dot(instance.P)).real


 <X> =  7.5591861166e-17  ->  -0.00685122108224
 <P> =   3.0   ->  0.00218594416669

Plotting


In [12]:
if os.path.isfile( instance.fileName )==True:
    instance.Load_Ehrenfest()

In [13]:
print '  '
fig, ax = plt.subplots(figsize=(10, 4))

print ' normalization = ', np.trace( instance.Rho_end.real ), '    time = ', instance.timeRange[-1]

X_range = instance.X_Range()

maxProb = np.max( np.diagonal(instance.Rho_init).real/instance.dX )

ax.plot( X_range , np.log( np.diagonal(instance.Rho_init).real/instance.dX/maxProb ) , '--' ,label = 'init')
ax.plot( X_range , np.log( np.diagonal(instance.Rho_end).real/instance.dX/maxProb ) , '-'  ,label = 'final')

ax.grid()
ax.set_xlabel('x')
ax.set_ylabel('Log Probability')
ax.set_ylim(-12,1)
#ax.set_xlim(-10,10)
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)


  
 normalization =  1.00000000003     time =  200.0
Out[13]:
<matplotlib.legend.Legend at 0x7fe063019150>

In [14]:
print '  '
fig, ax = plt.subplots(figsize=(10, 4))

print ' normalization = ', np.trace( instance.Rho_end.real ), '    time = ', instance.timeRange[-1]

P_range = instance.P_Range()


Rho_init_PRepresent = instance.X_To_P_Basis( instance.Rho_init )
Rho_end_PRepresent = instance.X_To_P_Basis( instance.Rho_end )


ax.semilogy( P_range , np.diagonal(Rho_init_PRepresent).real/instance.dP , '--' ,label = 'init')
ax.semilogy( P_range , np.diagonal(Rho_end_PRepresent).real/instance.dP  , '-'  ,label = 'final')

ax.grid()
ax.set_xlabel('p')
ax.set_ylabel('Probability Log')
#ax.set_xlim(-10,10)
ax.set_ylim(1e-6,1)

ax.legend(bbox_to_anchor=(1.05, 1), loc=2)


  
 normalization =  1.00000000003     time =  200.0
Out[14]:
<matplotlib.legend.Legend at 0x7fe062f76ad0>

In [15]:
print '  '
fig, ax = plt.subplots(figsize=(10, 4))

print ' normalization = ', np.trace( instance.Rho_end.real ), '    time = ', instance.timeRange[-1]

P_range = instance.P_Range()

Rho_init_PRepresent = instance.X_To_P_Basis( instance.Rho_init )
Rho_end_PRepresent = instance.X_To_P_Basis( instance.Rho_end )


ax.plot( P_range , np.diagonal(Rho_init_PRepresent).real/instance.dP , '--' ,label = 'init')
ax.plot( P_range , np.diagonal(Rho_end_PRepresent).real/instance.dP  , '-'  ,label = 'final')

ax.grid()
ax.set_xlabel('p')
ax.set_ylabel('Probability')
ax.set_xlim(-10,10)
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)


  
 normalization =  1.00000000003     time =  200.0
Out[15]:
<matplotlib.legend.Legend at 0x7fe090418b10>

In [16]:
fig, ax = plt.subplots(figsize=(10, 4))

print ' normalization = ', np.trace( instance.Rho_end.real ),'     time = ',instance.timeRange[-1]

Rho_init_XBasis = instance.Rho_init
Rho_end_XBasis  = instance.Rho_end

ax.plot( instance.X_Range(), np.diagonal(Rho_init_XBasis).real/instance.dX  ,label = 'init')
ax.plot( instance.X_Range(),  np.diagonal(Rho_end_XBasis).real/instance.dX  ,label = 'final')

ax.grid()
ax.set_xlabel('x')
ax.set_ylabel('Probability')
#ax.set_xlim(-15,20)
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)


 normalization =  1.00000000003      time =  200.0
Out[16]:
<matplotlib.legend.Legend at 0x7fe090318650>

Testing Ehrenfest First Order


In [17]:
def plot_Ehrenfest_dxdt():
    time_index_max = 60000

    fig, ax = plt.subplots(figsize=(10, 5))

    ax.plot( instance.timeRange  ,  np.gradient( instance.X_average, instance.dt).real  , '-', 
        label = '$\\frac{d}{dt} \\langle x \\rangle $' ,color = 'red', linewidth=1.5)

    ax.plot( instance.timeRange ,  instance.P_average  , '--' , 
        label = '$\\frac{1}{m}\\langle p \\rangle$', linewidth=1.5 )

    axis_font = {'fontname':'Times', 'size':'24'}
    ax.set_xlabel(r'$t (a.u.)$',**axis_font)

    #ax.set_xlim(0,3.5)
    #ax.set_ylim(-1,1)
    ax.legend(bbox_to_anchor=(0.7, 0.99), loc=2, prop={'size':22})
    #ax.set_xlabel('t')
    ax.grid();
    return fig

In [18]:
plot_Ehrenfest_dxdt();


/usr/lib/pymodules/python2.7/matplotlib/font_manager.py:1236: UserWarning: findfont: Font family ['Times'] not found. Falling back to Bitstream Vera Sans
  (prop.get_family(), self.defaultFamily[fontext]))
/usr/lib/pymodules/python2.7/matplotlib/font_manager.py:1246: UserWarning: findfont: Could not match :family=Bitstream Vera Sans:style=normal:variant=normal:weight=normal:stretch=normal:size=24.0. Returning /usr/share/matplotlib/mpl-data/fonts/ttf/cmb10.ttf
  UserWarning)

In [19]:
fig, ax = plt.subplots(figsize=(10, 4))

ax.plot( instance.timeRange ,   np.gradient( instance.P_average, instance.dt).real ,'-' ,
        label = '$\\frac{d}{dt}p$' ,color = 'r' , linewidth=1.5)

ax.plot( instance.timeRange , -instance.dPotentialdX_average - 2*instance.gammaDamping*instance.P_average , '--' ,
        label = '$-\\frac{d}{dx}V - 2 \\gamma sign(p) |f(p)| $' ,linewidth=1.)


axis_font = {'fontname':'Times', 'size':'24'}
ax.set_xlabel(r'$t (a.u.)$',**axis_font)

ax.legend(bbox_to_anchor=(1.05, 1), loc=2, prop={'size':22})
ax.set_ylim(- 2.5 , 2.5)
#ax.set_xlabel('t')
ax.set_ylabel(' ')
ax.grid();


Ehrenfest Second Order


In [20]:
fig, ax = plt.subplots(figsize=(10, 4))

ax.plot( instance.timeRange,  np.gradient( instance.X2_average, instance.dt).real ,'-' ,
        label = '$\\frac{d}{dt}x^2$' ,color = 'r' , linewidth=1.)

ax.plot( instance.timeRange,  
        2*instance.XP_average/instance.mass  +  instance.delta_average + 0*instance.D_Theta,
        '--' ,
       label = '$\\frac{xp + px}{m} + \\frac{\\gamma\\hbar L}{2} \\frac{ \\left(\\frac{df(p)}{dp}\\right)^2 }{f(p)}  $',
        linewidth=1. )


axis_font = {'fontname':'Times', 'size':'24'}
ax.set_xlabel(r'$t (a.u.)$',**axis_font)

ax.legend(bbox_to_anchor=(1.05, 1), loc=2, prop={'size':20} )
#ax.set_ylim(- 1 ,  1)
ax.set_xlim( 0 , 100)

#ax.set_xlim( 0 , 10)
#ax.set_xlabel('t')
ax.set_ylabel(' ')
ax.grid();



In [21]:
fig, ax = plt.subplots(figsize=(10, 4))

ax.plot( instance.timeRange ,  np.gradient( instance.P2_average, instance.dt).real, 
        '-' , label = '$ \\frac{d}{dt} p^2 $',
        color = 'r' , linewidth=1.)


ax.plot( instance.timeRange , 
        -2.*instance.PdPotentialdX_average  + \
        instance.alpha_average + 2*instance.D_Theta
        , '--' ,
         label = '$-(p\\frac{dV}{dx} +\\frac{dV}{dx} p ) - 2\\gamma f( |p| )\\left( 2|p| - \\frac{\\hbar}{L} \\right) + 2D$',
        linewidth=1.)

axis_font = {'fontname':'Times', 'size':'24'}
ax.set_xlabel(r'$t (a.u.)$',**axis_font)

ax.legend(bbox_to_anchor=(1.05, 1), loc=2, prop={'size':20} )
#ax.set_ylim(- 1 , 1)
#ax.set_xlabel('t')
#ax.set_ylabel(' ')
ax.grid();



In [22]:
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot( instance.timeRange , + 2*instance.gammaDamping*instance.f_Damping_average/instance.L_material
        , '-' ,
        label = '$ 2\\gamma \\hbar f(|p|)/L $',
        linewidth=1.)

axis_font = {'fontname':'Times', 'size':'24'}
ax.set_xlabel(r'$t (a.u.)$',**axis_font)

ax.legend(bbox_to_anchor=(1.05, 1), loc=2, prop={'size':20} )
#ax.set_ylim(- 7 , 6)
#ax.set_xlabel('t')
#ax.set_ylabel(' ')
ax.grid();



In [23]:
fig, ax = plt.subplots(figsize=(10, 4))

ax.plot( instance.timeRange ,  2*np.gradient( instance.XP_average, instance.dt).real ,
        '-' ,label = '$\\frac{d}{dt}(xp+px)$' ,
        color = 'r' , linewidth=1.)

ax.plot( instance.timeRange , \
         2*instance.P2_average/instance.mass  \
         -2*instance.XdPotentialdX_average        
         +instance.beta_average \
        , '--' , label = '$\\frac{2}{m} p^2 - 2 x \\frac{d}{dx}V  -4 \\gamma\, sign(p) f(|p|) x $',
        linewidth=1.)



ax.legend(bbox_to_anchor=(1.05, 1), loc=2, prop={'size':22})
#ax.set_ylim(- 12 , 7)
ax.set_xlabel('t')
ax.set_ylabel(' ')
ax.grid();



In [24]:
fig, ax = plt.subplots(figsize=(10, 4))

ax.plot( instance.X2_average,
        '-' ,label = '$<x^2>$' ,linewidth=2.)


ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
#ax.set_ylim(- 6 , 5)
ax.set_xlabel('t')
ax.set_ylabel(' ')
ax.grid();



In [25]:
fig, ax = plt.subplots(figsize=(10, 4))

ax.plot( instance.P2_average,
        '-' ,label = '$<p^2>$' ,linewidth=2.)


ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
#ax.set_ylim(- 6 , 5)
ax.set_xlabel('t')
ax.set_ylabel(' ')
ax.grid();



In [26]:
fig, ax = plt.subplots(figsize=(10, 4))

ax.plot( instance.XP_average,
        '-' ,label = '$<xp>$' ,linewidth=2.)


ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
ax.set_ylim(- 1 , 1)
ax.set_xlabel('t')
ax.set_ylabel(' ')
ax.grid();



In [27]:
fig, ax = plt.subplots(figsize=(10, 4))
 
sx = instance.X2_average - instance.X_average**2
sp = instance.P2_average - instance.P_average**2

ax.plot( np.sqrt(sx*sp) , '-' ,label = '$\\sigma_x^2 \\sigma^2_p$' ,linewidth=2.)


ax.legend(bbox_to_anchor=(1.05, 1), loc=2)
#ax.set_ylim(0 , 2)
ax.set_xlabel('t')
ax.set_ylabel(' ')
ax.grid();


Energy


In [28]:
def EnergyWigner(n):
    
    gridDIM = instance.gridDIM*2
    
    Rho = instance.LoadRho(instance.fileName, n ) 
    W   = instance.DensityMatrix_To_Wigner(Rho)
    
    X_amplitude = instance.X_amplitude*np.sqrt(2)
    dX = instance.dX*np.sqrt(2)/2.
    x_min = -X_amplitude
    x_max =  X_amplitude - dX
    
    P_amplitude = instance.P_amplitude/np.sqrt(2)
    dP = instance.dP/np.sqrt(2)/2.
    p_min = -P_amplitude
    p_max =  P_amplitude - dP
    
    X_Range = np.linspace(  -X_amplitude,  X_amplitude-dX, gridDIM  )
    P_Range = np.linspace(  -P_amplitude,  P_amplitude-dP, gridDIM  )
    
    X = X_Range[np.newaxis,:]
    P = P_Range[:,np.newaxis]
    
    H = P**2/(2*instance.mass) + instance.Potential(0,X)
    
    return np.sum( W*H )*dX*dP

In [29]:
skipFactor =  10

energyW_list = []
for n in range( 0, instance.timeSteps, skipFactor*instance.skipFrames ):
    print ' n = ',n
    energyW_list.append( EnergyWigner(n)  )
    
energyW_list  = np.array( energyW_list )

energyW_timeLine  = instance.dt*np.array( range( 0, instance.timeSteps, skipFactor*instance.skipFrames ) )


 n =  0
 n =  1000
 n =  2000
 n =  3000
 n =  4000
 n =  5000
 n =  6000
 n =  7000
 n =  8000
 n =  9000
 n =  10000
 n =  11000
 n =  12000
 n =  13000
 n =  14000
 n =  15000
 n =  16000
 n =  17000
 n =  18000
 n =  19000
 n =  20000
 n =  21000
 n =  22000
 n =  23000
 n =  24000
 n =  25000
 n =  26000
 n =  27000
 n =  28000
 n =  29000
 n =  30000
 n =  31000
 n =  32000
 n =  33000
 n =  34000
 n =  35000
 n =  36000
 n =  37000
 n =  38000
 n =  39000

In [30]:
fig, ax = plt.subplots(figsize=(10, 5))


ax.plot(instance.timeRange, instance.P2_average/(2*instance.mass) + instance.Potential_average,
                 color='0.5', label = 'Total Energy (Rho)')

ax.plot(energyW_timeLine, energyW_list.real, '.',
                 color='red', label = 'Total Energy (Wigner)')

ax.set_ylim(0 , 5)

ax.set_xlabel('t')
ax.grid();

ax.legend(bbox_to_anchor=(0.8, 1), loc=2)


Out[30]:
<matplotlib.legend.Legend at 0x7fe0630dcb90>

Purity


In [31]:
def Purity(n):
    Rho = instance.LoadRho(instance.fileName, n ) 
    return np.trace( Rho.dot(Rho) ).real

In [32]:
purity_list = []
for n in range( 0, instance.timeSteps, instance.skipFrames ):
    purity_list.append( Purity(n)  )

purity_list      = np.array(purity_list )
purity_timeLine  = instance.dt*np.array( range( 0, instance.timeSteps, instance.skipFrames ) )

In [33]:
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot( purity_timeLine, purity_list  ,label='Purity' )
ax.set_xlabel('t')
ax.set_ylabel('Purity')
ax.grid();
ax.legend(bbox_to_anchor=(1.05, 1), loc=2)


Out[33]:
<matplotlib.legend.Legend at 0x7fe0906a7850>

Classical integration


In [34]:
def dVdx(x):
    return instance.dPotential(0,x)

In [35]:
# Approximate solution disregarding epsilon

trajectory = instance.SymplecticPropagator(
    instance.mass, instance.gammaDamping, instance.dt, instance.timeSteps, dVdx,
    np.array([ instance.x_init, instance.p_init  ]) ).T

In [36]:
# python ODE solution

def dxdt_dpdt( Y , t):
    return [ Y[1]/instance.mass ,  -dVdx(Y[0]) - instance.gammaDamping*Y[1]*np.abs(Y[1])/np.sqrt( Y[1]**2 + instance.epsilon ) ]


timeRange =  np.arange(0, instance.dt*instance.timeSteps , instance.dt)

trajectory2 = integrate.odeint( dxdt_dpdt , [instance.x_init, instance.p_init],  timeRange ).T

In [37]:
print 'final time = ' , instance.timeRange[-1]

p_min = -instance.dP *instance.gridDIM/2.
p_max =  instance.dP *instance.gridDIM/2.     
x_min = -instance.X_amplitude
x_max =  instance.X_amplitude 
x_range = instance.X_Range()
p_range = instance.P_Range()
X = x_range[np.newaxis,:]
P = p_range[:,np.newaxis]
H = P**2/(2*instance.mass) + instance.Potential(0,X)


fig, ax = plt.subplots(figsize=(10, 10))

ax.plot( instance.X_average ,  instance.P_average , '--' , label = 'quantum(<X>,<P>)', linewidth=2 )

#ax.plot( trajectory[0] ,  trajectory[1] , '.' , color='g', label = 'classical (X,P)', linewidth=1 )

ax.plot( trajectory[0] ,  trajectory[1] , '-' , color='r', 
        label = 'classical (X,P)', linewidth=1 )

ax.contour(H,  np.arange(0, 4, 0.5 ),origin='lower',extent=[x_min,x_max,p_min,p_max],
               linewidths=0.25,colors='k')

ax.set_xlabel('X')
ax.set_ylabel('P')
ax.set_aspect(1.)

ax.set_xlim(-3.,3.)
ax.set_ylim(-3.,3.)
ax.grid();

ax.legend(bbox_to_anchor=(1.05, 1), loc=2)


final time =  200.0
Out[37]:
<matplotlib.legend.Legend at 0x7fe082d65250>

Wigner function plots


In [38]:
def PlotWigner( W2 , messages=True,saveFigure=False):
    global_min = -0.08
    global_max =  0.08
    
    zero_position =  abs( global_min) / (abs( global_max) + abs(global_min)) 
    wigner_cdict = {'red' 	: 	((0., 0., 0.),
                                (zero_position, 1., 1.), 
                                (1., 1., 1.)),
                        'green' :	((0., 0., 0.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)),
                        'blue'	:	((0., 1., 1.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)) }
    
    wigner_cmap = matplotlib.colors.LinearSegmentedColormap('wigner_colormap', wigner_cdict, 512)
    #wigner_cmap = LinearSegmentedColormap('wigner_colormap', wigner_cdict, 512)
    
    plt.clf()
    fig, ax = plt.subplots(figsize=(10, 8))
    
    dp = instance.dP
    dx = instance.dX
    
    p_min = -instance.P_amplitude + dp/2.
    p_max =  instance.P_amplitude - dp/2.   
        
    x_min = -instance.X_amplitude + dx/2.
    x_max =  instance.X_amplitude - dx/2.
    
    
    norm = np.sum(W2)*dp*dx
    W2 /= norm
        
    cax = ax.imshow(  W2.real  ,
           extent = [ x_min , x_max , p_min , p_max ], 
           vmin= global_min, vmax=global_max,
           origin='lower',interpolation='none',cmap=wigner_cmap)
    
    X = instance.X_Range()[np.newaxis,:]
    P = instance.P_Range()[:,np.newaxis]
    
    H = P**2/(2*instance.mass) + instance.Potential(0,X)
       
    ax.contour( H ,  energySpectrum , origin='lower',extent=[x_min,x_max,p_min,p_max],
               linewidths=0.25,colors='k')
    
       
    ax.set_xlim( -5,5 )
    ax.set_ylim( -5,5 )
    ax.set_xlabel('x')
    ax.set_ylabel('p')
    
    ax.grid('on')
    
    ax.set_aspect(1)
    
    cbar = fig.colorbar( cax , ticks=[-0.3, -0.2,-0.1, 0, 0.1, 0.2 , 0.3])

    if saveFigure != False:
        fig.savefig( saveFigure  )
        
        
    if messages == True:
        print ' max W = ', np.max(W2.real)
        print ' min W = ', np.min(W2.real)
        print ' norm =  ', np.sum(W2).real*dp*dx
        print ' Energy =', np.sum( H*W2  ).real*dx*dp
        
        
    #return fig

In [39]:
def PlotWignerScaled( W2 , messages=True,saveFigure=False):
    """
    This functions must be called when plotting Wigner functions are calculated from the density matrix
    """
    global_min = -0.08
    global_max =  0.08
        
    zero_position =  abs( global_min) / (abs( global_max) + abs(global_min)) 
    wigner_cdict = {'red' 	: 	((0., 0., 0.),
                                (zero_position, 1., 1.), 
                                (1., 1., 1.)),
                        'green' :	((0., 0., 0.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)),
                        'blue'	:	((0., 1., 1.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)) }
    
    wigner_cmap = matplotlib.colors.LinearSegmentedColormap('wigner_colormap', wigner_cdict, 512)
    
    plt.clf()
    fig, ax = plt.subplots( figsize=(10, 8) )
    
    gridDIM = W2.shape[0]
    
    X_amplitude = instance.X_amplitude*np.sqrt(2)
    dX = instance.dX*np.sqrt(2)/2.
    x_min = -X_amplitude + dX/2.
    x_max =  X_amplitude - dX/2.
    
    P_amplitude = instance.P_amplitude/np.sqrt(2)
    dP = instance.dP/np.sqrt(2)/2.
    p_min = -P_amplitude + dP/2.
    p_max =  P_amplitude - dP/2.
    
    X_Range = np.linspace(  -X_amplitude + dX/2.,  X_amplitude - dX/2., gridDIM  )
    P_Range = np.linspace(  -P_amplitude + dP/2.,  P_amplitude - dP/2., gridDIM  )
    
    X = X_Range[np.newaxis,:]
    P = P_Range[:,np.newaxis]
        
    cax = ax.imshow(  W2.real  ,
           extent = [ x_min , x_max , p_min , p_max ], 
           vmin= global_min, vmax=global_max,
           origin='lower',interpolation='none',cmap=wigner_cmap)
    
    H = P**2/(2*instance.mass) + instance.Potential(0,X)
     
    CS = ax.contour( H ,  energySpectrum[0:12] , origin='lower',extent=[x_min,x_max,p_min,p_max],
               linewidths=0.5,colors='green')
    
        
    ax.clabel( CS, inline=1,fontsize=12, fmt='%1.2f')
    
    ax.set_xlim( -5,5 )
    ax.set_ylim( -5,5 )
    ax.set_xlabel('x')
    ax.set_ylabel('p')
    
    ax.grid('on')
    
    ax.set_aspect(1)
    
    cbar = fig.colorbar( cax , ticks=[-0.3, -0.2,-0.1, 0, 0.1, 0.2 , 0.3])

    if saveFigure != False:
        fig.savefig( saveFigure  )
        
        
    if messages == True:
        print ' max W = ', np.max(W2.real)
        print ' min W = ', np.min(W2.real)
        print ' norm =  ', np.sum(W2).real*dP*dX
        print ' Energy (Wigner) =', np.sum( H*W2  ).real*dX*dP
        print ' <xp> (Wigner) =', np.sum( W2*X*P).real*dX*dP

In [40]:
def PlotWignerScaled( W2 , messages=True,saveFigure=False):
    """
    This functions must be called when plotting Wigner functions are calculated from the density matrix
    """
    global_min = -0.08
    global_max =  0.08
        
    zero_position =  abs( global_min) / (abs( global_max) + abs(global_min)) 
    wigner_cdict = {'red' 	: 	((0., 0., 0.),
                                (zero_position, 1., 1.), 
                                (1., 1., 1.)),
                        'green' :	((0., 0., 0.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)),
                        'blue'	:	((0., 1., 1.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)) }
    
    wigner_cmap = matplotlib.colors.LinearSegmentedColormap('wigner_colormap', wigner_cdict, 512)
    
    plt.clf()
    fig, ax = plt.subplots( figsize=(10, 8) )
    
    gridDIM = W2.shape[0]
    
    X_amplitude = instance.X_amplitude*np.sqrt(2)
    dX = instance.dX*np.sqrt(2)/2.
    x_min = -X_amplitude + dX/2.
    x_max =  X_amplitude - dX/2.
    
    P_amplitude = instance.P_amplitude/np.sqrt(2)
    dP = instance.dP/np.sqrt(2)/2.
    p_min = -P_amplitude + dP/2.
    p_max =  P_amplitude - dP/2.
    
    X_Range = np.linspace(  -X_amplitude + dX/2.,  X_amplitude - dX/2., gridDIM  )
    P_Range = np.linspace(  -P_amplitude + dP/2.,  P_amplitude - dP/2., gridDIM  )
    
    X = X_Range[np.newaxis,:]
    P = P_Range[:,np.newaxis]
        
    cax = ax.imshow(  W2.real  ,
           extent = [ x_min , x_max , p_min , p_max ], 
           vmin= global_min, vmax=global_max,
           origin='lower',interpolation='none',cmap=wigner_cmap)
    
    H = P**2/(2*instance.mass) + instance.Potential(0,X)
     
    CS = ax.contour( H ,  energySpectrum[0:12] , origin='lower',extent=[x_min,x_max,p_min,p_max],
               linewidths=0.5,colors='green')
    
        
    ax.clabel( CS, inline=1,fontsize=12, fmt='%1.2f')
    
    ax.set_xlim( -5,5 )
    ax.set_ylim( -5,5 )
    ax.set_xlabel('x')
    ax.set_ylabel('p')
    
    ax.grid('on')
    
    ax.set_aspect(1)
    
    cbar = fig.colorbar( cax , ticks=[-0.3, -0.2,-0.1, 0, 0.1, 0.2 , 0.3])

    if saveFigure != False:
        fig.savefig( saveFigure  )
        
        
    if messages == True:
        print ' max W = ', np.max(W2.real)
        print ' min W = ', np.min(W2.real)
        print ' norm =  ', np.sum(W2).real*dP*dX
        print ' Energy (Wigner) =', np.sum( H*W2  ).real*dX*dP
        print ' <xp> (Wigner) =', np.sum( W2*X*P).real*dX*dP

In [41]:
def PlotWignerScaled_Hot( W2 , messages=True,saveFigure=False):
    """
    This functions must be called when plotting Wigner functions are calculated from the density matrix
    """
    global_min =  -1e-6
    global_max =  0.13
        
    zero_position =  abs( global_min) / (abs( global_max) + abs(global_min)) 
    wigner_cdict = {'red' 	: 	((0., 0., 0.),
                                (zero_position, 1., 1.), 
                                (1., 1., 1.)),
                        'green' :	((0., 0., 0.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)),
                        'blue'	:	((0., 1., 1.),
                                (zero_position, 1., 1.),
                                (1., 0., 0.)) }
    
    wigner_cmap = matplotlib.colors.LinearSegmentedColormap('wigner_colormap', wigner_cdict, 512)
    
    plt.clf()
    fig, ax = plt.subplots(  figsize=(10, 8) )
    
    gridDIM = W2.shape[0]
    
    X_amplitude = instance.X_amplitude*np.sqrt(2)
    dX = instance.dX*np.sqrt(2)/2.
    x_min = -X_amplitude + dX/2.
    x_max =  X_amplitude - dX/2.
    
    P_amplitude = instance.P_amplitude/np.sqrt(2)
    dP = instance.dP/np.sqrt(2)/2.
    p_min = -P_amplitude + dP/2.
    p_max =  P_amplitude - dP/2.
    
    X_Range = np.linspace(  -X_amplitude + dX/2.,  X_amplitude - dX/2., gridDIM  )
    P_Range = np.linspace(  -P_amplitude + dP/2.,  P_amplitude - dP/2., gridDIM  )
    
    X = X_Range[np.newaxis,:]
    P = P_Range[:,np.newaxis]
        
    #cax = ax.imshow(  W2.real  ,
    #       extent = [ x_min , x_max , p_min , p_max ], 
    #       vmin= global_min, vmax=global_max,
    #       origin='lower',interpolation='none',cmap=wigner_cmap)
    
    cax = ax.imshow(  W2.real  ,
           extent = [ x_min , x_max , p_min , p_max ], 
           vmin= global_min, vmax=global_max,
           origin='lower',interpolation='none',cmap=cm.hot_r) 
    
    H = P**2/(2*instance.mass) + instance.Potential(0,X)
     
    CS = ax.contour( H ,  energySpectrum[0:12] , origin='lower',extent=[x_min,x_max,p_min,p_max],
               linewidths=0.5,colors='green')
    
    axis_font = {'size':'34'}    
    #ax.clabel( CS, inline=1,fontsize=12, fmt='%1.2f')
    
    ax.set_xlim( -5,5 )
    ax.set_ylim( -5,5 )
    ax.set_xlabel('x (a.u.)',**axis_font)
    ax.set_ylabel('p (a.u.)',**axis_font)
    plt.xticks(fontsize = 28)
    plt.yticks(fontsize = 28)
    
    #ax.grid('on')
    
    ax.set_aspect(1)
    
    cbar = fig.colorbar( cax , ticks=[-0.3, -0.2,-0.1, 0, 0.1, 0.2 , 0.3])

    if saveFigure != False:
        fig.savefig( saveFigure  )
        
        
    if messages == True:
        print ' max W = ', np.max(W2.real)
        print ' min W = ', np.min(W2.real)
        print ' norm =  ', np.sum(W2).real*dP*dX
        print ' Energy (Wigner) =', np.sum( H*W2  ).real*dX*dP
        print ' <xp> (Wigner) =', np.sum( W2*X*P).real*dX*dP
        
    return fig

In [42]:
W0 = instance.DensityMatrix_To_Wigner( instance.LoadRho(instance.fileName,0) )

In [43]:
fig0 = PlotWignerScaled_Hot(W0);


 max W =  0.318807261349
 min W =  -0.00238469150917
 norm =   1.0
 Energy (Wigner) = 4.96734785563
 <xp> (Wigner) = -0.0686739781865
<matplotlib.figure.Figure at 0x7fe09020a9d0>

In [44]:
W10000 = instance.DensityMatrix_To_Wigner( instance.LoadRho(instance.fileName, instance.timeSteps ) )

In [45]:
fig1 = PlotWignerScaled_Hot(W10000);


 max W =  0.104286424706
 min W =  -9.00972712361e-05
 norm =   1.0
 Energy (Wigner) = 1.70408055917
 <xp> (Wigner) = -0.164641900973
<matplotlib.figure.Figure at 0x7fe09053e390>

In [46]:
instance.D_Theta


Out[46]:
0.02

In [47]:
fig1.savefig('finalState_L3_D0.01429_P3.pdf')

Boltzmann Equation

$D = 2 m k T \gamma$


In [48]:
effective_kT = 1.2908 #1.166

print '************* Effective kT = ',effective_kT,' *******************' 

BoltzmannRho = linalg.expm(  -instance.Hamiltonian/effective_kT   )
norm = np.trace( BoltzmannRho )
BoltzmannRho /= norm


************* Effective kT =  1.2908  *******************

In [49]:
W_Boltzmann = instance.DensityMatrix_To_Wigner( BoltzmannRho )

In [50]:
fig2 = PlotWignerScaled_Hot(W_Boltzmann);


 max W =  0.118959480125
 min W =  -0.000114040059546
 norm =   1.0
 Energy (Wigner) = 1.34004245502
 <xp> (Wigner) = 6.06339130365e-15
<matplotlib.figure.Figure at 0x7fe0637dee50>

In [51]:
#fig2.savefig('BoltzmannState_kT1.166.pdf')

In [52]:
BoltzmannProb_x = np.diagonal(BoltzmannRho).real
print ' Boltzmann Norm = ', np.trace( BoltzmannRho ).real
print ' Purity Boltzmann = ', np.trace( BoltzmannRho.dot(BoltzmannRho)  ).real

Rho_End = instance.LoadRho(instance.fileName, instance.timeSteps )

RhoEnd_Prob_x = np.diagonal( Rho_End ).real
print '             '
print ' Rho Norm = ', np.trace( Rho_End ).real
print ' Purity Rho_End = ', np.trace( Rho_End.dot(Rho_End)  ).real
print '              '


fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(  instance.X_Range() , BoltzmannProb_x   ,label='Boltzmann Prob x' )
ax.plot(  instance.X_Range() , RhoEnd_Prob_x    ,label='Rho End Prob x' )

ax.set_xlim( -5,5 )
ax.legend(bbox_to_anchor=(0.8, 1), loc=2)
ax.grid()
ax.set_xlabel('x')
ax.set_ylabel('Prob')


 Boltzmann Norm =  1.0
 Purity Boltzmann =  0.369079208467
             
 Rho Norm =  1.00000000003
 Purity Rho_End =  0.372659954036
              
Out[52]:
<matplotlib.text.Text at 0x7fe06358f290>

In [53]:
BoltzmannProb_p = np.diagonal( instance.X_To_P_Basis( BoltzmannRho ) ).real
print ' Boltzmann Norm = ', np.trace( BoltzmannRho ).real

Rho_End = instance.X_To_P_Basis( instance.LoadRho(instance.fileName, instance.timeSteps ) )

RhoEnd_Prob_p = np.diagonal( Rho_End ).real
print ' Rho Norm = ', np.trace( Rho_End ).real


fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(  instance.X_Range() , BoltzmannProb_p   ,label='Boltzmann Prob p' )
ax.plot(  instance.X_Range() , RhoEnd_Prob_p    ,label='Rho End Prob p' )

ax.set_xlim( -5,5 )
ax.legend(bbox_to_anchor=(0.8, 1), loc=2)
ax.grid()
ax.set_xlabel('p')
ax.set_ylabel('Prob')


 Boltzmann Norm =  1.0
 Rho Norm =  1.00000000003
Out[53]:
<matplotlib.text.Text at 0x7fe0634caa50>

In [54]:
BoltzmannProb_x = np.diagonal(BoltzmannRho).real
print ' Boltzmann Norm = ', np.trace( BoltzmannRho ).real
print ' Purity Boltzmann = ', np.trace( BoltzmannRho.dot(BoltzmannRho)  ).real

Rho_End = instance.LoadRho(instance.fileName, instance.timeSteps )

RhoEnd_Prob_x = np.diagonal( Rho_End ).real
print '             '
print ' Rho Norm = ', np.trace( Rho_End ).real
print ' Purity Rho_End = ', np.trace( Rho_End.dot(Rho_End)  ).real
print '              '


fig, ax = plt.subplots(figsize=(10, 5))
ax.semilogy(  instance.X_Range() , BoltzmannProb_x   ,label='Boltzmann Prob x' )
ax.semilogy(  instance.X_Range() , RhoEnd_Prob_x    ,label='Rho End Prob x' )

ax.set_xlim( -15,15 )
ax.set_ylim( 1e-6,2 )

ax.legend(bbox_to_anchor=(0.8, 1), loc=2)
ax.grid()
ax.set_xlabel('x')
ax.set_ylabel('Prob')


 Boltzmann Norm =  1.0
 Purity Boltzmann =  0.369079208467
             
 Rho Norm =  1.00000000003
 Purity Rho_End =  0.372659954036
              
Out[54]:
<matplotlib.text.Text at 0x7fe063539710>

In [55]:
def WignerStationary( x,p , kT):
    return np.exp( -( p**2/instance.mass + instance.mass*instance.omega**2*x**2 )/( instance.omega/np.tanh( instance.omega/2./kT )  )  )

In [56]:
from scipy.optimize import curve_fit 

def FindkT(Prob_p, P_Range, omega, mass):
    """
    Function to find kT by maximazing the overlap with the Boltzmann state
    """
    def BoltzmannPMarginal(P, kT):
        
        if kT == 0:
            C = 1/(omega*mass)
        else:
            C = np.tanh(0.5*omega/kT) / (omega*mass)
            
        B = np.exp(-C*P**2)
        B /= B.sum()
        return B
    
    return curve_fit(BoltzmannPMarginal, P_Range, Prob_p)[0][0]

# test 
FindkT(np.diagonal( Rho_End ).real, instance.P_Range(), instance.omega ,  instance.mass)


Out[56]:
1.290827094674095

Alternative Propagator Limiting the Boltzmann state


In [57]:
#dBoltzmannRho = BoltzmannRho

#for i in range(50):
#        dBoltzmannRho = linalg.sqrtm( dBoltzmannRho )

In [58]:
# Testing Boltzmann decomposition 
# np.abs( BoltzmannRho - BoltzmannRho_Cho.dot(BoltzmannRho_Cho.conj().T) ).max()  

#V = dBoltzmannRho.dot( linalg.expm( -1j*instance.Hamiltonian*instance.dt )  )

In [59]:
#RhoInit2     = instance.LoadRho(instance.fileName, 10*instance.skipFrames )
#Rho_Cho = linalg.cholesky( RhoInit2 ).conj().T

In [60]:
# Testing Initial state decomposition
#np.abs( RhoInit2 - B_init.dot( B_init.conj().T )  ).max()

In [61]:
"""x_average = []
p_average = []

for t_index in range(1000):
    
    norm       =  np.trace(  RhoInit2  )
    RhoInit2  /= norm
    
    x_average.append( np.sum( RhoInit2*instance.X )  )
    p_average.append( np.sum( RhoInit2*instance.P )  )
    
    RhoInit2   = V.dot( RhoInit2.dot( V.conj().T )  )
    
x_average = np.array(x_average).real    
p_average = np.array(p_average).real    """;

In [72]:
RhoInit = instance.Rho_init + (1e-2)*BoltzmannRho

In [98]:
instance.Run_To_Boltzmann( RhoInit , effective_kT )


 tIndex= 0
 tIndex= 1000
 tIndex= 2000
 tIndex= 3000
 tIndex= 4000
 tIndex= 5000
 tIndex= 6000
 tIndex= 7000
 tIndex= 8000
 tIndex= 9000
 tIndex= 10000
 tIndex= 11000
 tIndex= 12000
 tIndex= 13000
 tIndex= 14000
 tIndex= 15000
 tIndex= 16000
 tIndex= 17000
 tIndex= 18000
 tIndex= 19000
 tIndex= 20000
 tIndex= 21000
 tIndex= 22000
 tIndex= 23000
 tIndex= 24000
 tIndex= 25000
 tIndex= 26000
 tIndex= 27000
 tIndex= 28000
 tIndex= 29000
 tIndex= 30000
 tIndex= 31000
 tIndex= 32000
 tIndex= 33000
 tIndex= 34000
 tIndex= 35000
 tIndex= 36000
 tIndex= 37000
 tIndex= 38000
 tIndex= 39000
 tIndex= 40000
Out[98]:
0

In [99]:
WTerminal =  instance.DensityMatrix_To_Wigner( instance.RhoTerminal_end  )

In [100]:
PlotWignerScaled_Hot( WTerminal );


 max W =  0.318747334316
 min W =  -0.00020021792825
 norm =   1.0
 Energy (Wigner) = 0.498922206689
 <xp> (Wigner) = -1.03143861865e-05
<matplotlib.figure.Figure at 0x7fe0612c6190>

In [101]:
fig, ax = plt.subplots(figsize=(10, 5))

ax.plot(  instance.X_Range() , BoltzmannProb_p   ,label='Boltzmann Prob p' )

ax.plot(  instance.X_Range() , np.diagonal( instance.RhoTerminal_end ).real  ,label='Terminal' )

ax.set_xlim( -5,5 )
ax.legend(bbox_to_anchor=(0.8, 1), loc=2)


Out[101]:
<matplotlib.legend.Legend at 0x7fe041dec350>

In [102]:
fig, ax = plt.subplots(figsize=(10, 5))

ax.plot(   instance.X_average_  , 'r-' , 
        label = ' Terminal $\\langle x \\rangle$', linewidth=1.5 )

ax.plot(   instance.X_average  , '--' , 
        label = 'ODM $\\langle x \\rangle$', linewidth=1.5 )

#ax.set_xlim(0, 10000)
ax.legend(bbox_to_anchor=(0.8, 1), loc=2)


Out[102]:
<matplotlib.legend.Legend at 0x7fe041dfae50>

In [103]:
fig, ax = plt.subplots(figsize=(10, 5))

ax.plot(   instance.P_average_  , 'r-' , 
        label = ' Terminal $\\langle x \\rangle$', linewidth=1.5 )

ax.plot(   instance.P_average  , '--' , 
        label = 'ODM $\\langle x \\rangle$', linewidth=1.5 )

#ax.set_xlim(0, 100)
ax.legend(bbox_to_anchor=(0.8, 1), loc=2)


Out[103]:
<matplotlib.legend.Legend at 0x7fe04143aa10>

In [104]:
fig, ax = plt.subplots(figsize=(10, 5))

ax.plot(   instance.X2_average_  , 'r-' , 
        label = ' Terminal $\\langle x \\rangle$', linewidth=1.5 )

ax.plot(   instance.X2_average  , '--' , 
        label = 'ODM $\\langle x \\rangle$', linewidth=1.5 )

#ax.set_xlim(0, 100)
ax.legend(bbox_to_anchor=(0.8, 1), loc=2)


Out[104]:
<matplotlib.legend.Legend at 0x7fe060663d10>

In [105]:
fig, ax = plt.subplots(figsize=(10, 5))

ax.plot(   instance.P2_average_  , 'r-' , 
        label = ' Terminal $\\langle x \\rangle$', linewidth=1.5 )

ax.plot(   instance.P2_average  , '--' , 
        label = 'ODM $\\langle x \\rangle$', linewidth=1.5 )

#ax.set_xlim(0, 100)
ax.legend(bbox_to_anchor=(0.8, 1), loc=2)


Out[105]:
<matplotlib.legend.Legend at 0x7fe06074b890>

eigenstates


In [66]:
WW = instance.DensityMatrix_To_Wigner( 
instance.Rho_HarmonicOscillator( 2, instance.omega, 0, 0)
).real

In [67]:
PlotWignerScaled(WW)


 max W =  0.320304404085
 min W =  -0.134088586592
 norm =   1.0
 Energy (Wigner) = 2.50158363708
 <xp> (Wigner) = 1.11142319563e-14
<matplotlib.figure.Figure at 0x7fe06333c110>

In [68]:
PlotWigner(
instance.Wigner_HarmonicOscillator( 2 ,instance.omega,0,0)
);


 max W =  0.29908752195
 min W =  -0.131674093621
 norm =   1.0
 Energy = 2.5
<matplotlib.figure.Figure at 0x7fe063111190>

Movie


In [69]:
# avconv -r 10  -i fig%05d.png -b:v 1000k test.mp4
"""
m=0
for n in range(0,instance.timeSteps,instance.skipFrames):
    print ' n = ',n
    m+=1
    W = instance.DensityMatrix_To_Wigner( instance.LoadRho(instance.fileName,n) )
    PlotWigner( W , messages=False, saveFigure='/home/rcabrera/DATA/Rho2D/Ohmic/movie1/fig%05d'%m );
""";