/* Schrodinger equation explorer */ /* Michael Creutz */ /* creutz@bnl.gov */ /* to compile: */ /* cc -O -L/usr/X11R6/lib schrodinger.c -lX11 -lm */ /* this solves the Schrodinger equation in a potential */ /* displays amplitude squared and the potential superposed */ /* the left mouse button perturbs the wave function */ /* the right mouse button perturbs the potential */ /* the damp button evolves system towards the ground state */ /* version of July 1997, adds hbar button */ # include # include # include # include # include # include # include # include # include # include /* NSITES=number of lattice sites fft (as implemented here) REQUIRES a power of two */ # define NSITES 64 # define NPOINTS 128 double repsi[NSITES],impsi[NSITES]; /* real and imaginary parts of psi */ double rekpsi[NSITES],imkpsi[NSITES]; /* field in momentum space */ double potential[NSITES]; /* potential in Schrodinger equation */ double repfactor[NSITES],impfactor[NSITES]; /* for updating potential term */ double rekfactor[NSITES],imkfactor[NSITES]; /* for updating kinetic term */ double cn[NSITES],sn[NSITES]; /* for cosine and sin of angles */ double pi; /* 3.14... */ int iamp[NPOINTS+1],ipot[NPOINTS+1]; XPoint xpoints[2*NPOINTS]; /* for drawing waves */ struct timeval timeout; /* timer for speed control */ /* dimensions for buttons */ # define BUTTONWIDTH 84 # define BUTTONHEIGHT 18 int paused=0; /* is the system paused? */ int damped=0; /* is the system damped? */ int speed=1; /* updating delay proportional to speed; between 0 and 10 */ int hbar=5; /* between 1 and 10 */ int delay=0; /* counter for implementing speed control */ struct timeval timeout; /* timer for speed control */ void drawbutton(),openwindow(),makebuttons(),update(),repaint(), cleanup(),drawit(),renorm(),oldupdate(),newupdate(), makefactor(),fastfourier(); # define line(x1,y1,x2,y2) XDrawLine(display,window,gc,x1,y1,x2,y2) # define color(i) XSetForeground(display,gc,translate[i]) /* various window stuff */ Display *display; int screen; static char *progname; Window window,quitbutton,pausebutton,vconstbutton, dampbutton,speedbutton,hbarbutton,makebutton(); XColor xcolor,colorcell; Colormap cmap; GC gc; int windowwidth,windowheight,playwidth,playheight; XFontStruct *font=NULL; int font_height,font_width; XSizeHints size_hints; int darkcolor,lightcolor,black,white; long translate[256]; /* for converting colors */ int main(argc,argv) int argc; char **argv; {int i,j,k,p; double psipeg,w; unsigned int width, height; XEvent report; progname=argv[0]; openwindow(argc,argv); makebuttons(); /* set up trig stuff */ pi=4*atan(1.0); for (i=0;i10) speed=10; delay=speed; drawbutton(speedbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"speed",-2); drawbutton(speedbutton,1+((10-speed)*(BUTTONWIDTH-2))/11,1, (BUTTONWIDTH-2)/11,BUTTONHEIGHT-2,"",2); } else if (report.xbutton.window==hbarbutton) { /* reset hbar */ hbar=1+(10*report.xbutton.x)/BUTTONWIDTH; if (hbar<1) hbar=1; if (hbar>10) hbar=10; makefactor(); drawbutton(hbarbutton,0,0,BUTTONWIDTH,BUTTONHEIGHT,"hbar",-2); drawbutton(hbarbutton,1+((hbar-1)*(BUTTONWIDTH-2))/10,1, (BUTTONWIDTH-2)/11,BUTTONHEIGHT-2,"",2); } else /* button one changes wave function, two updates, and three modifies potential */ {i=report.xbutton.x; j=report.xbutton.y; if (j=NSITES/2) j-=NSITES; temp=kfactor*dt*j*j; rekfactor[i]=nsitesinv*cos(temp); imkfactor[i]=nsitesinv*sin(temp); if (damped) {temp=exp(-dampfactor*temp); rekfactor[i]*=temp; imkfactor[i]*=temp; } } return; } void renorm() /* normalizes the wave function */ {int i; double norm; norm=0.0; for(i=0;ib)? b : a) #define max(a,b) ((a>b)? a : b) void drawit() /* draws the wave function */ {int i,k1,k2,j,jmax; double mag; /* calculate potential and amplitude to display as integers */ j=0; for (i=0;iascent+font->descent; font_width=font->max_bounds.width; /* make graphics context: */ gc=XCreateGC(display,window,0,NULL); XSetFont(display,gc,font->fid); XSetForeground(display,gc,black); XSetBackground(display,gc,lightcolor); /* show the window */ XMapWindow(display,window); return; } void makebuttons() { /* first destroy any old buttons */ XDestroySubwindows(display,window); /* now make the new buttons */ quitbutton =makebutton(0,windowheight-3*BUTTONHEIGHT,BUTTONWIDTH,BUTTONHEIGHT); vconstbutton=makebutton(BUTTONWIDTH,windowheight-3*BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); pausebutton=makebutton(2*BUTTONWIDTH,windowheight-3*BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); dampbutton=makebutton(3*BUTTONWIDTH,windowheight-3*BUTTONHEIGHT, BUTTONWIDTH,BUTTONHEIGHT); speedbutton=makebutton(windowwidth-BUTTONWIDTH, windowheight-3*BUTTONHEIGHT,BUTTONWIDTH,BUTTONHEIGHT); hbarbutton=makebutton(windowwidth-2*BUTTONWIDTH, windowheight-3*BUTTONHEIGHT,BUTTONWIDTH,BUTTONHEIGHT); return; } void cleanup() {XUnloadFont(display,font->fid); XFreeGC(display,gc); XCloseDisplay(display); exit(0); } Window makebutton(xoffset,yoffset,xsize,ysize) int xoffset,yoffset,xsize,ysize; /* Puts button of specified dimensions on window. Nothing is drawn. */ {Window buttonwindow; long event_mask; buttonwindow=XCreateSimpleWindow(display,window,xoffset,yoffset, xsize,ysize,0,black,lightcolor); event_mask=ButtonPressMask|ExposureMask; /* look for mouse-button presses */ XSelectInput(display,buttonwindow,event_mask); XMapWindow(display,buttonwindow); return buttonwindow; } void drawbutton(buttonwindow,xoffset,yoffset,xsize,ysize,text,state) Window buttonwindow; int xoffset,yoffset,xsize,ysize,state; char * text; /* Draw a button in buttonwindow of specified dimensions with text centered. Color of button determined by sign of "state", size of border determined by magnitude. I don't need no stinking tookit. */ {int textlength,i,j; int cdark,clight,cup,cdown; int cleft,cright,cbutton,ctext; cup=lightcolor; cdown=darkcolor; cdark=black; clight=white; if (state<0) {cbutton=cdown; ctext=clight; cleft=cdark; cright=clight; } else {cbutton=cup; ctext=cdark; cleft=clight; cright=cdark; } j=abs(state); /* width for button borders */ XSetForeground(display,gc,cbutton); XFillRectangle(display,buttonwindow,gc,xoffset+j,yoffset+j, xsize-2*j,ysize-2*j); XSetForeground(display,gc,cleft); XFillRectangle(display,buttonwindow,gc,xoffset,yoffset,xsize,j); XFillRectangle(display,buttonwindow,gc,xoffset,yoffset,j,ysize); XSetForeground(display,gc,cright); for (i=0;i>1; /* half the vector length */ /* recursively call fastfourier */ fastfourier(rex ,imx ,ref ,imf ,nd2,2*d1,d2,direction); fastfourier(rex+d1,imx+d1,ref+nd2*d2,imf+nd2*d2,nd2,2*d1,d2,direction); /* combine the results */ Ndn=NSITES/n; for (j=0;j