#include #include #include #include #define CHUNKSIZE 5 #include #include #include #include #include #define CSET(x,a,b) (RE(x)=a, IM(x)=b) /*************************************System parameters**********************************************/ #define L 3.5 /*Length of the box for particle-in-a-box states*/ #define U0 -10.0 /* Pseudopotential interaction strength*/ #define V0 5.0 /*Double Well Depth*/ #define EPSILON0 4.0 /*STIRAP Pulse Amplitude, analytically kept small wrt V0 for truncability*/ /****************************************************************************************************/ #define STIRAPWIDTH 2700.00 /*STIRAP pulse width T*/ #define TSTOKE 9000.00 /*centroid of the stoke pulse */ #define TPUMP 18000.00 /*centroid of the pump pulse */ /*Adiabatic Time*/ #define TFIXMIN 5600.00 #define TFIXMAX 8317.9752 /*Up to ttot of 28009.465*/ #define TFIXINC 67.94938 /*Exact total of 20 oscillations b4 next increment (same as 1 osc) ideal */ /******Duffing Drive Parameters*********************/ #define OMEGASTOKE 3.6987449 #define OMEGAPUMP 9.2468622 /*omegastoke/omegapump is n1/n2 frequencies MUST BE COMMENSURATE CHECK THIS THOROUGHLY*/ #define N1 2 #define N2 5 /*******************************/ /***********************************Numerical Truncation Parameters********************************/ #define ALPHA 11 /*ALPHA+ ALPHA*(ALPHA-1)/2 is DIM. ALPHA is the # of 2-free-particles-in-a-box-states 8 works*/ #define DIM 66 /*Truncated Dimension of the Floquet Matrix generated from 2-free-particles-in-a-box states 36 works*/ /***********************************************ERROR TOLERANCES***********************************/ /* The step-size adjustment procedure for this method begins by computing the desired error level D_i for each component, D_i = ABSERROR + RELERROR * (YERROR |y_i| + YPRIMEERROR*DT |y'_i|) and comparing it with the observed error E_i = |yerr_i|. If the observed error E exceeds the desired error level D by more than 10% for any component then the method reduces the step-size by an appropriate factor */ #define DT 1e-6 #define ABSERROR 1e-6 #define RELERROR 1e-8 #define YERROR 0.5 #define YPRIMEERROR 0.2 /********The Parameter epsilon & the tower of 2-particle states are stored in this datatype********/ typedef struct { double v0; double u0; double epsilonstoke; double epsilonpump; double omegastoke; double omegapump; int tower[DIM][2]; }drive_and_tower; /*****************************Defines Kronecker Delta**********************************************/ double kdel(int i,int j) { int result; if(i==j) { result=1.0; } else result=0.0; return(result); } /*****************Calculates the Adiabatic Amplitude of the STIRAP Pulse**************************/ double amp(double tfix, double tmean) { double ampl; double beta=1.0/(2.0*STIRAPWIDTH*STIRAPWIDTH); ampl=EPSILON0*exp(-beta*(tfix-tmean)*(tfix-tmean)); return(ampl); } /*****************This is the lth single particle-in-a-box energy level*****************************/ double En(int l) { double energy; l=l+1; energy=M_PI/2.0; energy=energy*energy; energy=energy*l*l; energy=energy/(L*L); return(energy); } /**************************** This is a matrix element of x*****************************************/ double f1(int m, int n) { double value; m=m+1;/*Arrays are counted from n=0, but levels from n=1*/ n=n+1; if((m+n)%2==1) { value=16.0*m*n; value=value/(M_PI*M_PI); value=value/(m*m-n*n); value=value/(m*m-n*n); value=value*L; } else { value=0.0; } return(value); } /**************************** This is a matrix element of x^2**************************************/ double f2(int m, int n) { double value,temp; m=m+1; /*Arrays are counted from n=0, but levels from n=1*/ n=n+1; if((m+n)%2==0) { if(m==n) { value=((1/3.0)-(2.0/(n*n*M_PI*M_PI)))*L*L; } else { value=32.0*m*n*L*L/(M_PI*M_PI*(m*m-n*n)*(m*m-n*n)); } } else { value=0.0; } return(value); } /**************************** This is a matrix element of x^4***************************************/ double f4(int m, int n) { double value; m=m+1; /*Arrays are counted from n=0, but levels from n=1*/ n=n+1; if((m+n)%2==0) { if(m==n) { value=L*L*L*L*((1/5.0)-(4.0/(n*n*M_PI*M_PI))+(24.0/(n*n*n*n*M_PI*M_PI*M_PI*M_PI))); } else { value=(64.0*m*n/(M_PI*M_PI*M_PI*M_PI))*(pow(M_PI/(m*m-n*n),2)-(48.0*(m*m+n*n)/pow(m*m-n*n,4)))*L*L*L*L; } } else { value=0.0; } return(value); } /*Matrix elements of the Double Well Potential*/ double pot(int n, int m) { double f2(int,int),f4(int,int); double potelm; potelm=(-2.0*f2(n,m)+f4(n,m)); return(potelm); } /*Matrix Element of the Interaction*/ double in(int n1, int n2, int n3, int n4) { double interelm=0.0; n1++; n2++; n3++; n4++; if((n1==n2)&&(n2==n3)&&(n3==n4)) { interelm=3.0/(4.0*L); } if((n1==n2)&&(n3==n4)) { interelm=1.0/(2.0*L); } if((n1==n3)&&(n2==n4)) { interelm=1.0/(2.0*L); } if((n1==n4)&&(n2==n3)) { interelm=1.0/(2.0*L); } return(interelm); } /*This uses the above subroutines to evaluate the hamiltonian matrix elements*/ double hamilt(void *param, int nt, int mt, double t) { double kdel(int,int),En(int),in(int,int,int,int),pot(int,int); double matrixelm; int n1,n2,m1,m2,i,j; drive_and_tower *p=(drive_and_tower *)param; /*Get epsilon & towerofstates from structure param*/ double v0=p->v0; double u0=p->u0; double epsilonstoke=p->epsilonstoke; double epsilonpump=p->epsilonpump; double omegastoke=p->omegastoke; double omegapump=p->omegapump; double towerofstates[DIM][2]; for(i=0;itower[i][0]; towerofstates[i][1]=p->tower[i][1]; } n1=towerofstates[nt][0]; n2=towerofstates[nt][1]; m1=towerofstates[mt][0]; m2=towerofstates[mt][1]; matrixelm=En(n1)+En(n2); matrixelm=matrixelm*(kdel(m1,n1)*kdel(m2,n2)+kdel(m1,n2)*kdel(m2,n1)); matrixelm=matrixelm+v0*pot(n1,m1)*kdel(n2,m2); matrixelm=matrixelm+v0*pot(n1,m2)*kdel(n2,m1); matrixelm=matrixelm+v0*pot(n2,m1)*kdel(n1,m2); matrixelm=matrixelm+v0*pot(n2,m2)*kdel(n1,m1); matrixelm=matrixelm+2.0*u0*in(n1,n2,m1,m2); matrixelm=matrixelm+(epsilonstoke*sin(omegastoke*t)+epsilonpump*sin(omegapump*t))*f1(n1,m1)*kdel(n2,m2); matrixelm=matrixelm+(epsilonstoke*sin(omegastoke*t)+epsilonpump*sin(omegapump*t))*f1(n1,m2)*kdel(n2,m1); matrixelm=matrixelm+(epsilonstoke*sin(omegastoke*t)+epsilonpump*sin(omegapump*t))*f1(n2,m1)*kdel(n1,m2); matrixelm=matrixelm+(epsilonstoke*sin(omegastoke*t)+epsilonpump*sin(omegapump*t))*f1(n2,m2)*kdel(n1,m1); return(matrixelm); } /*********************This evaluates the Differential Equation System*****************************/ int func(double t, const double y[], double dydt[], void *param) { double y_re[DIM],y_im[DIM],dydt_re[DIM],dydt_im[DIM]; int nt,mt; /*Write out the (complicated) expression for RHS & assign to dydt[i]*/ for(nt=0;nt=ABSERROR) { printf("\n ERROR!!!\n"); printf("\nFrequencies are not commensurate, or N1, N2 entries are wrong, bailing..."); printf("\n========================================================================="); exit(1); } /*Build the 2-particle tower of states*/ count=0; for(i=0;i=ABSERROR) { errorcount=errorcount+1; printf("Eigenvalue %d = %lf +I %lf , quasienergy = %lf has non-unit modulus = %lf\n",i,RE(floqueteigenvalues[i]),IM(floqueteigenvalues[i]),quasi[i],shuldbeone); } } printf("\n========================================================================="); fprintf(floqueteigenval,"\n%lf",tfix); for(i=0;i