diff options
Diffstat (limited to 'figs/animation')
| -rw-r--r-- | figs/animation/FN_base.jl | 170 | ||||
| -rw-r--r-- | figs/animation/Makefile | 12 | ||||
| -rw-r--r-- | figs/animation/animate.py | 127 | ||||
| -rw-r--r-- | figs/animation/animate_compute.jl | 66 | 
4 files changed, 375 insertions, 0 deletions
| diff --git a/figs/animation/FN_base.jl b/figs/animation/FN_base.jl new file mode 100644 index 0000000..af2a1ee --- /dev/null +++ b/figs/animation/FN_base.jl @@ -0,0 +1,170 @@ +# fractional power with an arbitrary branch cut +function pow(x,a,cut) +  if(angle(x)/cut<=1) +    return(abs(x)^a*exp(1im*angle(x)*a)) +  else +    return(abs(x)^a*exp(1im*(angle(x)-sign(cut)*2*pi)*a)) +  end +end + +# asymptotic airy functions +# specify a branch cut for the fractional power +function airyai_asym(x,cut) +  if(abs(real(pow(x,3/2,cut)))<airy_threshold) +    return(exp(2/3*pow(x,3/2,cut))*airyai(x)) +  else +    ret=0 +    for n in 0:airy_order +      ret+=gamma(n+5/6)*gamma(n+1/6)*(-3/4)^n/(4*pi^(3/2)*factorial(n)*pow(x,3*n/2+1/4,cut)) +    end +    return ret +  end +end +function airyaiprime_asym(x,cut) +  if(abs(real(pow(x,3/2,cut)))<airy_threshold) +    return(exp(2/3*pow(x,3/2,cut))*airyaiprime(x)) +  else +    ret=0 +    for n in 0:airy_order +      ret+=gamma(n+5/6)*gamma(n+1/6)*(-3/4)^n/(4*pi^(3/2)*factorial(n))*(-1/pow(x,3*n/2-1/4,cut)-(3/2*n+1/4)/pow(x,3*n/2+5/4,cut)) +    end +    return ret +  end +end + +# solutions of (-\Delta+V-ip)phi=0 +# assume that p has an infinitesimal real part (and adjust the branch cuts appropriately) +function phi(p,x,E,V) +  return(airyai_asym(exp(-1im*pi/3)*(E^(1/3)*x-E^(-2/3)*(V-1im*p)),pi)) +end +function dphi(p,x,E,V) +  return(exp(-1im*pi/3)*E^(1/3)*airyaiprime_asym(exp(-1im*pi/3)*(E^(1/3)*x-E^(-2/3)*(V-1im*p)),pi)) +end +function eta(p,x,E,V) +  return(exp(-1im*pi/3)*airyai_asym(-(E^(1/3)*x-E^(-2/3)*(V-1im*p)),pi/2)) +end +function deta(p,x,E,V) +  return(-exp(-1im*pi/3)*E^(1/3)*airyaiprime_asym(-(E^(1/3)*x-E^(-2/3)*(V-1im*p)),pi/2)) +end + +# Laplace transform of psi +# assume that p has an infinitesimal real part (and adjust the branch cuts appropriately) +# for example, (1im*p-V)^(3/2) becomes pow(1im*p-V,3/2,-pi/2) because when 1im*p is real negative, its square root should be imaginary positive +function f(p,x,k0,E,V) +  T=2im*k0/(1im*k0-sqrt(V-k0*k0)) +  R=T-1 + +  if x>=0 +    C2=-1im*T/(pow(-1im*p,1/2,pi/2)*phi(p,0,E,V)-dphi(p,0,E,V))*((sqrt(V-k0*k0)+pow(-1im*p,1/2,pi/2))/(-1im*p+k0*k0)-2im*E^(-1/3)*pi*quadgk(y -> (pow(-1im*p,1/2,pi/2)*eta(p,0,E,V)-deta(p,0,E,V))*phi(p,y,E,V)*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2)-E^(-1)*pow(1im*p-V,3/2,-pi/2))),0,Inf)[1]) +    FT=2*E^(-1/3)*pi*(quadgk(y -> phi(p,x,E,V)*eta(p,y,E,V)*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*x+E^(-2/3)*(1im*p-V),3/2,-pi/2)-pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2))),0,x)[1]+quadgk(y -> eta(p,x,E,V)*phi(p,y,E,V)*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2)-pow(E^(1/3)*x+E^(-2/3)*(1im*p-V),3/2,-pi/2))),x,Inf)[1]) +    main=C2*phi(p,x,E,V)*exp(2im/3*(pow(E^(1/3)*x+E^(-2/3)*(1im*p-V),3/2,-pi/2)-E^(-1)*pow(1im*p-V,3/2,-pi/2)))+T*FT + +    # subtract the contribution of the pole, which will be added back in after the integration +    pole=psi_pole(x,k0,E,V)/(p+1im*k0*k0) +    return(main-pole) +  else +    C1=-1im*T*((sqrt(V-k0*k0)*phi(p,0,E,V)+dphi(p,0,E,V))/(-1im*p+k0*k0)/(pow(-1im*p,1/2,pi/2)*phi(p,0,E,V)-dphi(p,0,E,V))+E^(-1/3)*quadgk(y -> phi(p,y,E,V)/(pow(-1im*p,1/2,pi/2)*phi(p,0,E,V)-dphi(p,0,E,V))*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2)-E^(-1)*pow(1im*p-V,3/2,-pi/2))),0,Inf)[1]) +    FI=-1im*exp(1im*k0*x)/(-1im*p+k0*k0) +    FR=-1im*exp(-1im*k0*x)/(-1im*p+k0*k0) +    main=C1*exp(pow(-1im*p,1/2,pi/2)*x)+FI+R*FR + +    # subtract the contribution of the pole, which will be added back in after the integration +    pole=psi_pole(x,k0,E,V)/(p+1im*k0*k0) +    return(main-pole) +  end +end +# its derivative +function df(p,x,k0,E,V) +  T=2im*k0/(1im*k0-sqrt(V-k0*k0)) +  R=T-1 + +  if x>=0 +    C2=-1im*T/(pow(-1im*p,1/2,pi/2)*phi(p,0,E,V)-dphi(p,0,E,V))*((sqrt(V-k0*k0)+pow(-1im*p,1/2,pi/2))/(-1im*p+k0*k0)-2im*E^(-1/3)*pi*quadgk(y -> (pow(-1im*p,1/2,pi/2)*eta(p,0,E,V)-deta(p,0,E,V))*phi(p,y,E,V)*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2)-E^(-1)*pow(1im*p-V,3/2,-pi/2))),0,Inf)[1]) +    dFT=2*E^(-1/3)*pi*(quadgk(y -> dphi(p,x,E,V)*eta(p,y,E,V)*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*x+E^(-2/3)*(1im*p-V),3/2,-pi/2)-pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2))),0,x)[1]+quadgk(y -> deta(p,x,E,V)*phi(p,y,E,V)*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2)-pow(E^(1/3)*x+E^(-2/3)*(1im*p-V),3/2,-pi/2))),x,Inf)[1]) +    main=C2*dphi(p,x,E,V)*exp(2im/3*(pow(E^(1/3)*x+E^(-2/3)*(1im*p-V),3/2,-pi/2)-E^(-1)*pow(1im*p-V,3/2,-pi/2)))+T*dFT + +    # subtract the contribution of the pole, which will be added back in after the integration +    pole=dpsi_pole(x,k0,E,V)/(p+1im*k0*k0) +    return(main-pole) +  else +    C1=-1im*T*((sqrt(V-k0*k0)*phi(p,0,E,V)+dphi(p,0,E,V))/(-1im*p+k0*k0)/(pow(-1im*p,1/2,pi/2)*phi(p,0,E,V)-dphi(p,0,E,V))+E^(-1/3)*quadgk(y -> phi(p,y,E,V)/(pow(-1im*p,1/2,pi/2)*phi(p,0,E,V)-dphi(p,0,E,V))*exp(-sqrt(V-k0*k0)*y)*exp(2im/3*(pow(E^(1/3)*y+E^(-2/3)*(1im*p-V),3/2,-pi/2)-E^(-1)*pow(1im*p-V,3/2,-pi/2))),0,Inf)[1]) +    dFI=k0*exp(1im*k0*x)/(-1im*p+k0*k0) +    dFR=-k0*exp(-1im*k0*x)/(-1im*p+k0*k0) +    main=C1*pow(-1im*p,1/2,pi/2)*exp(pow(-1im*p,1/2,pi/2)*x)+dFI+R*dFR + +    # subtract the contribution of the pole, which will be added back in after the integration +    pole=dpsi_pole(x,k0,E,V)/(p+1im*k0*k0) +    return(main-pole) +  end +end + +# psi (returns t,psi(x,t)) +function psi(x,k0,E,V,p_npoints,p_cutoff) +  fft=fourier_fft(f,x,k0,E,V,p_npoints,p_cutoff) +  # add the contribution of the pole +  for i in 1:p_npoints +      fft[2][i]=fft[2][i]+psi_pole(x,k0,E,V)*exp(-1im*k0*k0*fft[1][i]) +  end +  return(fft) +end +# its derivative +function dpsi(x,k0,E,V,p_npoints,p_cutoff) +  fft=fourier_fft(df,x,k0,E,V,p_npoints,p_cutoff) +  # add the contribution of the pole +  for i in 1:p_npoints +    fft[2][i]=fft[2][i]+dpsi_pole(x,k0,E,V)*exp(-1im*k0*k0*fft[1][i]) +  end +  return(fft) +end + +# compute Fourier transform by sampling and fft +function fourier_fft(A,x,k0,E,V,p_npoints,p_cutoff) +  fun=zeros(Complex{Float64},p_npoints) +  times=zeros(p_npoints) + +  # prepare fft +  for i in 1:p_npoints +    fun[i]=p_cutoff/pi*A(1im*(-p_cutoff+2*p_cutoff*(i-1)/p_npoints),x,k0,E,V) +    times[i]=(i-1)*pi/p_cutoff +  end + +  ifft!(fun) +   +  # correct the phase +  for i in 2:2:p_npoints +    fun[i]=-fun[i] +  end +  return([times,fun]) +end + +# asymptotic value of psi +function psi_pole(x,k0,E,V) +  if x>=0 +    return(1im*phi(-1im*k0*k0,x,E,V)*2*k0/(1im*k0*phi(-1im*k0*k0,0,E,V)+dphi(-1im*k0*k0,0,E,V))*exp(2im/3*(pow(E^(1/3)*x+E^(-2/3)*(k0*k0-V),3/2,-pi/2)-E^(-1)*pow(k0*k0-V,3/2,-pi/2)))) +  else +    return((1im*k0*phi(-1im*k0*k0,0,E,V)-dphi(-1im*k0*k0,0,E,V))/(1im*k0*phi(-1im*k0*k0,0,E,V)+dphi(-1im*k0*k0,0,E,V))*exp(-1im*k0*x)+exp(1im*k0*x)) +  end +end +function dpsi_pole(x,k0,E,V) +  if x>=0 +    return(1im*dphi(-1im*k0*k0,x,E,V)*2*k0/(1im*k0*phi(-1im*k0*k0,0,E,V)+dphi(-1im*k0*k0,0,E,V))*exp(2im/3*(pow(E^(1/3)*x+E^(-2/3)*(k0*k0-V),3/2,-pi/2)-E^(-1)*pow(k0*k0-V,3/2,-pi/2)))) +  else +    return(-1im*k0*(1im*k0*phi(-1im*k0*k0,0,E,V)-dphi(-1im*k0*k0,0,E,V))/(1im*k0*phi(-1im*k0*k0,0,E,V)+dphi(-1im*k0*k0,0,E,V))*exp(-1im*k0*x)+1im*k0*exp(1im*k0*x)) +  end +end + +# current +function J(ps,dps) +  return(2*imag(conj(ps)*dps)) +end + +# complete computation of the current +function current(x,k0,E,V,p_npoints,p_cutoff) +  ps=psi(x,k0,E,V,p_npoints,p_cutoff) +  dps=dpsi(x,k0,E,V,p_npoints,p_cutoff) +  Js=zeros(Complex{Float64},p_npoints) +  for i in 1:p_npoints +    Js[i]=J(ps[2][i],dps[2][i]) +  end +  return(Js) +end diff --git a/figs/animation/Makefile b/figs/animation/Makefile new file mode 100644 index 0000000..d582a40 --- /dev/null +++ b/figs/animation/Makefile @@ -0,0 +1,12 @@ +PROJECTNAME=animate + +all: animate.dat + +run: animate.dat +	python3 animate.py animate.dat & + +animate.dat: +	julia animate_compute.jl > animate.dat + +clean: +	rm -f animate.dat diff --git a/figs/animation/animate.py b/figs/animation/animate.py new file mode 100644 index 0000000..aaa3a80 --- /dev/null +++ b/figs/animation/animate.py @@ -0,0 +1,127 @@ +from matplotlib import pyplot as pl +from matplotlib import animation +import sys + +# read data +# time dependent data +frames=[] +# asymptotic data (located in the first block) +asym=[] +infile=open(sys.argv[1],'r') +row=[] +for line in infile: +    # read first block +    if len(asym)==0: +        if line=='\n': +            asym=row +            row=[] +        else: +            dat=[] +            for n in line.split(): +                dat.append(float(n)) +            row.append(dat) +    # read other blocks +    else: +        if line=='\n': +            frames.append(row) +            row=[] +        else: +            dat=[] +            for n in line.split(): +                dat.append(float(n)) +            row.append(dat) +infile.close() + + +# set up plot +fig = pl.figure() +#pl.subplot(211) +axr=fig.gca() +asym_rho, = axr.plot([],[],linewidth=3.5,color='#00FF00') +rho, = axr.plot([],[],color='red') + +#pl.subplot(212) +#axJ=fig.gca() +#asym_J, = axJ.plot([],[],linewidth=3.5,color='#00FF00') +#J, = axJ.plot([],[],color='red') + +# plot ranges +xmax=0 +maxyr=0 +maxyJ=0 +for frame in frames: +    for i in range(len(frame)): +        if frame[i][1]>xmax: +            xmax=frame[i][1] +        if frame[i][2]>maxyr: +            maxyr=frame[i][2] +        if frame[i][3]>maxyJ: +            maxyJ=frame[i][3] +for i in range(len(asym)): +    if asym[i][0]>xmax: +        xmax=asym[i][0] +    if asym[i][1]>maxyr: +        maxyr=asym[i][1] +    if asym[i][2]>maxyJ: +        maxyJ=asym[i][2] +xmin=0 +minyr=0 +minyJ=0 +for frame in frames: +    for i in range(len(frame)): +        if frame[i][1]<xmin: +            xmin=frame[i][1] +        if frame[i][2]<minyr: +            minyr=frame[i][2] +        if frame[i][3]<minyJ: +            minyJ=frame[i][3] +for i in range(len(asym)): +    if asym[i][0]<xmin: +        xmin=asym[i][0] +    if asym[i][1]<minyr: +        minyr=asym[i][1] +    if asym[i][2]<minyJ: +        minyJ=asym[i][2] + + +# plot asymptotes +asym_rho_datax=[] +asym_rho_datay=[] +for i in range(len(asym)): +    asym_rho_datax.append(asym[i][0]) +    asym_rho_datay.append(asym[i][1]) +asym_rho.set_data(asym_rho_datax,asym_rho_datay) +#asym_J_datax=[] +#asym_J_datay=[] +#for i in range(len(asym)): +#    asym_J_datax.append(asym[i][0]) +#    asym_J_datay.append(asym[i][2]) +#asym_J.set_data(asym_J_datax,asym_J_datay) + +# animate +def init_plot(): +    axr.set_ylim(minyr,maxyr) +    axr.set_xlim(xmin,xmax) +    #axJ.set_ylim(minyJ,maxyJ) +    #axJ.set_xlim(xmin,xmax) + +    axr.vlines(0,minyr,maxyr,linestyles="dotted") +    #axJ.vlines(0,minyJ,maxyJ,linestyles="dotted") +def update(frame): +    axr.set_title("t=% .3f fs" % (frame[0][0])) +    xdata=[] +    ydata=[] +    for i in range(len(frame)): +        xdata.append(frame[i][1]) +        ydata.append(frame[i][2]) +    rho.set_data(xdata,ydata) + +    #xdata=[] +    #ydata=[] +    #for i in range(len(frame)): +    #    xdata.append(frame[i][1]) +    #    ydata.append(frame[i][3]) +    #J.set_data(xdata,ydata) +anim = animation.FuncAnimation(fig, update, frames=frames, blit=False, interval=100, repeat=True, init_func=init_plot) +#anim.save('schrodinger_barrier.mp4', fps=15, extra_args=['-vcodec', 'libx264']) +pl.show() diff --git a/figs/animation/animate_compute.jl b/figs/animation/animate_compute.jl new file mode 100644 index 0000000..452320e --- /dev/null +++ b/figs/animation/animate_compute.jl @@ -0,0 +1,66 @@ +using QuadGK +using SpecialFunctions +using FFTW + +# numerical values +hbar=6.58e-16 # eV.s +m=9.11e-31 # kg +Vn=9 # eV +#En=14e9 # V/m +En=10e9 # V/m +Kn=4.5 # eV + +V=1 +E=En*hbar/(2*Vn^1.5*m^0.5)*sqrt(1.60e-19) +k0=sqrt(Kn/Vn) + +# rescale x to nm +nm_scale=hbar*sqrt(1.6e-19)/sqrt(2*m*Vn)*1e9 + +# cutoffs +p_cutoff=20*k0 +p_npoints=256 + +# airy approximations +airy_threshold=30 +airy_order=5 + +# xbounds +xmax=10 +xmin=-10 +x_npoints=200 + +include("FN_base.jl") + +# compute wave function +ps=Array{Array{Array{Complex{Float64},1},1}}(undef,x_npoints) +dps=Array{Array{Array{Complex{Float64},1},1}}(undef,x_npoints) +for i in 1:x_npoints +  print(stderr,i,'/',x_npoints,'\n') +  x=xmin+(xmax-xmin)*i/x_npoints +  ps[i]=psi(x,k0,E,V,p_npoints,p_cutoff) +  dps[i]=dpsi(x,k0,E,V,p_npoints,p_cutoff) +end + +# compute asymptotic values +ps_asym=Array{Complex{Float64}}(undef,x_npoints) +dps_asym=Array{Complex{Float64}}(undef,x_npoints) +for i in 1:x_npoints +  x=xmin+(xmax-xmin)*i/x_npoints +  ps_asym[i]=psi_pole(x,k0,E,V) +  dps_asym[i]=dpsi_pole(x,k0,E,V) +end + +# print asymptotic values +for i in 1:x_npoints +  print((xmin+(xmax-xmin)*i/x_npoints)*nm_scale,' ',abs(ps_asym[i])^2,' ',J(ps_asym[i],dps_asym[i])/(2*k0),'\n') +end +print('\n') + +# print values at each time +for j in 1:p_npoints +  for i in 1:x_npoints +    print(real(ps[i][1][j])*hbar/Vn*1e15,' ',(xmin+(xmax-xmin)*i/x_npoints)*nm_scale,' ',abs(ps[i][2][j])^2,' ',J(ps[i][2][j],dps[i][2][j])/(2*k0),'\n') +  end +  print('\n') +end | 
