/* Steven Andrews, 1/00 */ /* See documentation called Quantum doc */ /* Copyright 2003 by Steven Andrews. Permission is granted for non-commercial use of and modifications to the code. */ #include #include #include "dynsys.h" #include "Plot.h" #include "Cn.h" #include "math2.h" #include "Rn.h" #include "Constants.h" #include "random.h" #include "Spectra.h" #include "Quantum.h" float psiHO(float x,int n,float k,float m) { float alph; alph=sqrt(k*m)/hbar_SSI; return sqrt(sqrt(4*PI/alph)/pow(2,n)/factorial(n))*hermite(x*sqrt(alph),n)*gauss(x,0,1/sqrt(alph)); } complex Bracket(float *psib,float *psik,float *xr,int n) { float *v1,*v2,*v3,*v1r; complex ans; v1=allocV(2*n); v2=allocV(2*n); v3=allocV(2*n); v1r=allocV(n); multCV(CompConj(psib,v1,n),psik,v2,n); integCV(v2,v1,n); deriv1V(xr,v1r,n); multCV(v1,makecmplx(v1r,NULL,v3,n),v2,n); ans.r=v2[2*n-2]; ans.i=v2[2*n-1]; freeV(v1); freeV(v2); freeV(v3); freeV(v1r); return ans; } float NormalKet(float *psi,float *xr,int n) { complex z; float s; z=Bracket(psi,psi,xr,n); multKV(s=pow(sqr(z.r)+sqr(z.i),-0.25),psi,psi,2*n); return s; } complex Hamiltonian(float *psib,float *ur,float *psik,float *xr,int n,float m) { float *v1,*v2,*v3,*v4; float *v1r,*v2r; complex ans; v1=allocV(2*n); v2=allocV(2*n); v3=allocV(2*n); v4=allocV(2*n); v1r=allocV(n); v2r=allocV(n); multCV(makecmplx(ur,NULL,v2,n),psik,v1,n); // v1=ur|psik> deriv2CV(psik,v2,n,1); // v2=¶^2 |psik> deriv1V(xr,v1r,n); // v1r=¶x multV(v1r,v1r,v2r,n); // v2r=¶x^2 divKV(1,v2r,v2r,n); // v2r=1/¶x^2 multCV(v2,makecmplx(v2r,NULL,v3,n),v4,n); // v4=¶^2/¶x^2 |psik> sumV(-sqr(hbar_SSI)/(2*m),v4,1,v1,v2,2*n); // v2=H|psik> CompConj(psib,v1,n); // v1=psib* multCV(v1,v2,v3,n); // v3=psib* H psik integCV(v3,v1,n); // v1=ºpsib* H psik multCV(v1,makecmplx(v1r,NULL,v3,n),v2,n); // v2=ºpsib* H psik dx ans.r=v2[2*n-2]; // ans= ans.i=v2[2*n-1]; // ans= freeV(v1); freeV(v2); freeV(v3); freeV(v4); freeV(v1r); freeV(v2r); return ans; } complex Dipole(float *psib,float *psik,float *xr,int n,float q) { float *v1,*v2,*v3,*v1r; complex ans; v1=allocV(2*n); v2=allocV(2*n); v3=allocV(2*n); v1r=allocV(n); multCV(makecmplx(xr,NULL,v2,n),psik,v1,n); // v1=x|psik> multCV(CompConj(psib,v2,n),v1,v3,n); // v3=psib* x psik integCV(v3,v1,n); // v1=º psib* x psik deriv1V(xr,v1r,n); // v1r=¶x multCV(v1,makecmplx(v1r,NULL,v3,n),v2,n); // v2=ºpsib* x psik dx ans.r=q*v2[2*n-2]; // ans= ans.i=q*v2[2*n-1]; freeV(v1); freeV(v2); freeV(v3); freeV(v1r); return ans; } void EQMFschrod(phptr u,void *k,phptr dudt) { float *psi,*v1,*v2,*v3; int n; struct param {float *pot;float dx2;float w;float *v1;float *v2;float *v3;} *eqmparam; eqmparam=(struct param *) k; n=u->fs/2; psi=u->fa; v1=eqmparam->v1; v2=eqmparam->v2; v3=eqmparam->v3; multCV(eqmparam->pot,psi,v1,n); // v1=ur/hbar |psik> deriv2CV(psi,v2,n,1); // v2=¶^2 |psik> multKV(eqmparam->dx2,v2,v3,2*n); // v3=-hbar/2m ¶^2/¶x^2 |psik> sumV(1,v3,1,v1,v2,2*n); // v2=1/hbar H|psik> rotateCV(v2,dudt->fa,n,1); // ¶|psi>/¶t =i/hbar H|psi> dudt->sa[0]=eqmparam->w; // overall phase factor return; } int TKFplotpsi(float t,phptr u,void *tkptr) { struct param2 {float dt;float *xr;float *v1r;float *v1;} *tkfparam; int n; n=u->fs/2; tkfparam=(struct param2 *) tkptr; if(t-floor(t)dt) { rotate2CV(u->fa,tkfparam->v1,n,u->sa[0]); PlotClear(); SetColor('B'); PlotData2(real(tkfparam->v1,tkfparam->v1r,n),tkfparam->xr,n,3); SetColor('R'); PlotData2(imag(tkfparam->v1,tkfparam->v1r,n),tkfparam->xr,n,3); } return 0; } float *TimeEvolve(float *psi,float *ur,float m,float *xr,int n,float Dt) { phptr ket; float intpar[MaxIntPar]; struct param {float *pot;float dx2;float w;float *v1;float *v2;float *v3;} *eqmparam; struct param2 {float dt;float *xr;float *v1r;float *v1;} *tkfparam; float *uc,*v1,*v2,*v3,*v1r,dx2,w; uc=allocV(2*n); v1=allocV(2*n); v2=allocV(2*n); v3=allocV(2*n); v1r=allocV(n); eqmparam=malloc(sizeof(struct param)); w=Hamiltonian(psi,ur,psi,xr,n,m).r/hbar_SSI; addKV(-w*hbar_SSI,ur,v1r,n); eqmparam->w=w; multKV(1/hbar_SSI,v1r,v1r,n); makecmplx(v1r,NULL,uc,n); eqmparam->pot=uc; // potential is [U(x)-]/hbar dx2=(xr[n-1]-xr[0])/(n-1); // assumes equally spaced points dx2=-hbar_SSI/(2*m*sqr(dx2)); // dx2=-hbar/(2m ¶x^2) eqmparam->dx2=dx2; eqmparam->v1=v1; eqmparam->v2=v2; eqmparam->v3=v3; tkfparam=malloc(sizeof(struct param2)); tkfparam->dt=intpar[0]=0.01; // time step in fs tkfparam->v1r=v1r; tkfparam->v1=v1; tkfparam->xr=xr; ket=phptalloc(1,1,2*n); copyV(psi,ket->fa,2*n); ket->sa[0]=0; ODEFrk4(EQMFschrod,(void *) eqmparam,ket,&Dt,intpar,TKFplotpsi,(void *) tkfparam); rotate2CV(ket->fa,psi,n,ket->sa[0]); phptfree(ket); free(eqmparam); free(tkfparam); freeV(uc); freeV(v1); freeV(v2); freeV(v3); freeV(v1r); return psi; } int TKFdipcorr(float t,phptr u,void *tkptr) { struct param3 {float dt;float *xr;float *bra;float wb;float prefact;float *dip;float *v1;} *tkfparam; int n; float *v1; complex ans; tkfparam=(struct param3 *) tkptr; if(t-floor(t)dt) { n=u->fs/2; v1=tkfparam->v1; rotate2CV(u->fa,v1,n,u->sa[0]-tkfparam->wb*t); ans=Dipole(tkfparam->bra,v1,tkfparam->xr,n,tkfparam->prefact); tkfparam->dip[((int) t)*2]=ans.r; tkfparam->dip[((int) t)*2+1]=ans.i; SetColor('B'); PlotPt(t,ans.r); SetColor('R'); PlotPt(t,ans.i); } return 0; } void DipCorr(float *psib,float *psik,float *ur,float m,float q,float *xr,int n,float Dt,float *dip) { phptr ket; float intpar[MaxIntPar]; struct param {float *pot;float dx2;float w;float *v1;float *v2;float *v3;} *eqmparam; struct param3 {float dt;float *xr;float *bra;float wb;float prefact;float *dip;float *v1;} *tkfparam; float *uc,*v1,*v2,*v3,*v1r,dx2,wk,wb; float *ketv,normk; int i; uc=allocV(2*n); v1=allocV(2*n); v2=allocV(2*n); v3=allocV(2*n); v1r=allocV(n); ketv=allocV(2*n); eqmparam=malloc(sizeof(struct param)); tkfparam=malloc(sizeof(struct param3)); for(i=0;iw=wk; multKV(1/hbar_SSI,v1r,v1r,n); makecmplx(v1r,NULL,uc,n); eqmparam->pot=uc; // potential is [U(x)-]/hbar dx2=(xr[n-1]-xr[0])/(n-1); // assumes equally spaced points dx2=-hbar_SSI/(2*m*sqr(dx2)); // dx2=-hbar/(2m ¶x^2) eqmparam->dx2=dx2; eqmparam->v1=v1; eqmparam->v2=v2; eqmparam->v3=v3; tkfparam->dt=intpar[0]=0.01; // time step in fs tkfparam->xr=xr; tkfparam->bra=psib; tkfparam->wb=wb; tkfparam->prefact=sqr(q)/normk; tkfparam->dip=dip; tkfparam->v1=v1; ket=phptalloc(1,1,2*n); copyV(ketv,ket->fa,2*n); ket->sa[0]=0; ODEFrk4(EQMFschrod,(void *) eqmparam,ket,&Dt,intpar,TKFdipcorr,(void *) tkfparam); phptfree(ket); free(eqmparam); free(tkfparam); freeV(uc); freeV(v1); freeV(v2); freeV(v3); freeV(v1r); freeV(ketv); return; } float EigenketAHO(float *xr,float *ur,float *psi,int n,float k,float m) { float *v1,*psitry; float *expans,*step; // expans is list of expansion parameters float *b; // matrix of complex basis kets float e,e2,oldex; int i,j,nb,it; nb=10; // number of basis kets v1=allocV(2*n); psitry=allocV(2*n); b=allocV(2*n*nb); // n complex rows, nb columns expans=allocV(nb); step=allocV(nb); setstdM(b,2*n,nb,0); for(j=0;jn=nv; vt=allocV(nv); ans->x=vw=allocV(nv); vdc=allocV(nv*2); vsc=allocV(nv*2); ans->y=vs=allocV(nv); for(i=0;i