Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F81104144
wavepacket.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Sep 4, 05:37
Size
7 KB
Mime Type
text/x-c++
Expires
Fri, Sep 6, 05:37 (1 d, 22 h)
Engine
blob
Format
Raw Data
Handle
20512932
Attached To
rLAMMPS lammps
wavepacket.h
View Options
# ifndef WAVEPACKET_H
# define WAVEPACKET_H
# ifndef _USE_MATH_DEFINES
# define _USE_MATH_DEFINES
# endif
# include <cmath>
# include <complex>
# include <functional>
# include "cvector_3.h"
using namespace std;
/** @file wpmd.h
@brief Classes to handle Gaussian Wave Packets. */
// Constants
const double MIN_EXP_ARG = -15.; // Minimum noticeable argument for exp function
class WavePacket;
///\en Template for v=der operation in \ref Wavepacket::int2phys_der()
template<class Type>
struct eq_second : public binary_function <Type, Type, Type> {
Type operator()(const Type& _Left, const Type& _Right) const{
return _Right;
}
};
///\en Template for v=-der operation in \ref Wavepacket::int2phys_der()
template<class Type>
struct eq_minus_second : public binary_function <Type, Type, Type> {
Type operator()(const Type& _Left, const Type& _Right) const{
return -_Right;
}
};
///\en Compares complex numbers on a per component basis.
/// \return \retval 0 if all component differences are 0 within tolerance \a tol (EQUAL),
/// \retval -1 for LESS
/// \retval 2 for GREATER
template< class CT >
int compare_compl(const CT &a, const CT& b, double tol=0.){
double dd=real(a)-real(b);
if(dd<-tol)
return -1;
if(dd>tol)
return 1;
dd=imag(a)-imag(b);
if(dd<-tol)
return -1;
if(dd>tol)
return 1;
return 0;
}
///\en Compares vectors on a per component basis.
/// \return \retval 0 if all component differences are 0 within tolerance \a tol (EQUAL),
/// \retval -1 for LESS
/// \retval 2 for GREATER
inline int compare_vec(const Vector_3 &a, const Vector_3& b, double tol=0.){
for(int i=0;i<3;i++){
double dd=a[i]-b[i];
if(dd<-tol)
return -1;
if(dd>tol)
return 1;
}
return 0;
}
/// wavepacket is w(x)=exp(-a*x^2+b*x+lz)
class WavePacket{
/// constructs a conjugate packet
friend WavePacket conj(const WavePacket &wp);
public:
cdouble a;
cVector_3 b;
cdouble lz;
WavePacket(const cdouble &sa=cdouble(1.,0.),const cVector_3 &sb=cVector_3(0.,0.), const cdouble &slz=0.): a(sa), b(sb), lz(slz){
}
WavePacket operator*(const WavePacket& other) const {
return WavePacket(a+other.a,b+other.b,lz+other.lz);
}
/// returns the integral of w(x) over 3D space
cdouble integral() const {
cdouble z = lz + b.norm2()/(4.*a);
if(real(z) < MIN_EXP_ARG) return 0.;
return pow(M_PI/a,3./2.)*exp(z);
}
/// init normalized packet with physical parameters: r0, p0, width, pw
/// w(x)=(3/2pi width^(3/4)exp[-(3/(4 width^2)-i pw/(2*width) )(x-r)^2+i p (x-r)]
void init(const double width=1., const Vector_3 &r=0., const Vector_3 &p=0., const double pw=0.){
a = (3./(2.*width) - cdouble(0.,1.)*pw)/(2.*width);
b = (2.*a)*r + cdouble(0.,1.)*p;
lz = log(3./(2.*M_PI*width*width))*(3./4.) + (-a*r.norm2() - cdouble(0.,1.)*(p*r));
}
/// init normalized packet with complex parameters a and b
/// w(x)=(3/2pi width^(3/4)exp[-(3/(4 width^2)-i pw/(2*width) )(x-r)^2+i p (x-r)]
void init(const cdouble &a_, const cVector_3 &b_){
a = a_;
b = b_;
Vector_3 r = get_r();
double r2 = r.norm2();
lz = cdouble( log( real(a)*(2./M_PI) )*(3./4.) - r2*real(a), r2*imag(a) - r*imag(b) );
}
cdouble operator()(const Vector_3 &x) const {
return exp(lz - a*x.norm2() + b*x);
}
/// ajusts lz so that Integral[w*(conj(w))] is 1 after this operation
WavePacket& normalize(){
//lz=0.;
//lz=overlap(conj(*this));
//lz=(-1./2)*log(lz);
Vector_3 r = get_r();
double r2 = r.norm2();
lz = cdouble( log( real(a)*(2./M_PI) )*(3./4.) - r2*real(a), r2*imag(a) - r*imag(b) );
return *this;
}
/// computes 3D overlap of wavepackets Inegral[w*other]
cdouble overlap(const WavePacket &other) const{
WavePacket wp=(*this)*other;
return wp.integral();
}
/// returns translated packet to the position of r'=r+dr
WavePacket translate(const Vector_3 &dr) const {
WavePacket wp(a,b,lz);
wp.b+=2*dr*a;
Vector_3 r=get_r();
double dr2=(r+dr).norm2()-r.norm2();
wp.lz+=-a*dr2-cdouble(0.,(get_p()*dr));
return wp;
}
/// width
double get_width() const{
return sqrt(3./4./real(a));
}
/// width momentum
double get_pwidth() const{
return -imag(a)*sqrt(3./real(a));
}
/// both width and width momentum
pair<double,double> get_width_pars() const{
double c=sqrt(3./2./real(a));
return make_pair(c/2,-imag(a)*c);
}
/// position
Vector_3 get_r() const {
return real(b)/(2*real(a));
}
/// momentum
Vector_3 get_p() const {
return imag(b) - real(b)*(imag(a)/real(a));
}
///\en Transforms derivatives of a function whith respect to WP parameters
/// from internal into physical representation, i. e.:\n
/// from df/d{are,aim,b0re,b0im,b1re,b1im,b2re,b2im} (8 values accessed by input iterator d_it in the given order)\n
/// to df/d{x0,x1,x2}, df/d{p0,p1,p2}, df/dw, df/dpw
/// The supplied inputs (val) are modified by op: val=op(val,phys_der).
/// Use operation=eq_second for the supplied inputs to be replaced by new physical derivative values.
/// The inpput and output locations may coinside, an internal buffer is used for transformation.
template<template<class A> class operation, class d_it, class dfdx_it, class dfdp_it, class dfdw_it, class dfdpw_it>
void int2phys_der(d_it dfdi_,dfdx_it dfdx, dfdp_it dfdp, dfdw_it dfdw, dfdpw_it dfdpw, double h_p=h_plank) const {
operation<double> op;
double dfdi[8], dfn[8];// internal buffer
for(int i=0;i<8;i++)
dfdi[i]=*dfdi_++;
double w=get_width();
Vector_3 r=get_r();
double t=3/(2*w*w*w);
dfn[6]= -t*dfdi[0]-imag(a)*dfdi[1]/w; //dw
dfn[7]=-dfdi[1]/(2*w*h_p); // dpw
for(int i=0;i<3;i++){
dfn[i]= 2*real(a)*dfdi[2+2*i]+2*imag(a)*dfdi[2+2*i+1];
dfn[3+i]= dfdi[2+2*i+1]*(/*m_electron*/1./h_p) ; //*(h_plank/m_electron);
dfn[7]+=-(r[i]*dfdi[2+2*i+1]/w)/h_p;
dfn[6]+=-2*r[i]*(t*dfdi[2+2*i]+imag(a)*dfdi[2+2*i+1]/w);
}
int i=0;
for(int k=0;k<3;k++)
*dfdx++=op(*dfdx,dfn[i++]);
for(int k=0;k<3;k++)
*dfdp++=op(*dfdp,dfn[i++]);
*dfdw=op(*dfdw,dfn[i++]);
*dfdpw=op(*dfdpw,dfn[i++]);
}
///\en Compares the wave packet to another on a per component basis.
/// \return \retval 0 if all component differences are 0 within tolerance \a tol (EQUAL),
/// \retval -1 for LESS
/// \retval 2 for GREATER
int compare(const WavePacket &other, double tol=0.) const {
int res=compare_compl(a,other.a, tol);
if(res)
return res;
for(int i=0;i<3;i++){
res=compare_compl(b[i],other.b[i]);
if(res)
return res;
}
return 0;
}
};
#if 0
double w=wk.get_width();
Vector_3 r=wk.get_r();
double t=3/(2*w*w*w);
fe_w[ic1+k1]+= t*E_der[s1][indw1+8*k1]+imag(wk.a)*E_der[s1][indw1+8*k1+1]/w;
fe_pw[ic1+k1]+=E_der[s1][indw1+8*k1+1]/(2*w*h_plank);
for(int i=0;i<3;i++){
fe_x[ic1+k1][i]+= -2*real(wk.a)*E_der[s1][indw1+8*k1+2+2*i]-2*imag(wk.a)*E_der[s1][indw1+8*k1+2+2*i+1];
fe_p[ic1+k1][i]+= (-E_der[s1][indw1+8*k1+2+2*i+1])*(m_electron/h_plank); //*(h_plank/m_electron);
fe_pw[ic1+k1]+=(r[i]*E_der[s1][indw1+8*k1+2+2*i+1]/w)/h_plank;
fe_w[ic1+k1]+=2*r[i]*(t*E_der[s1][indw1+8*k1+2+2*i]+imag(wk.a)*E_der[s1][indw1+8*k1+2+2*i+1]/w);
}
#endif
/// constructs a conjugate packet
inline WavePacket conj(const WavePacket &wp){
return WavePacket(conj(wp.a),conj(wp.b),conj(wp.lz));
}
# endif // WAVEPACKET_H
Event Timeline
Log In to Comment