/**
* Schroedinger equation for the hydrogen atom:
* bisection algorithm for finding eigenvalues
* Feynman algorithm for the radial wavefunction
* optional radial probability density plot.
* The distance is given in units of a_0, the Bohr radius. Energy is
* given in units of E_0 = 13,6 eV. Writing the radial wavefunction
* as R(r) = r^l u(r), we get the equation:
* d^2u/dr^2 = -Eu - 2*u/r - 2*(l+1)/r*du/dr
* This equation is solved using Feynman method (Euler method +
* du/dr calculated at midpoints in the mesh).
*
* The HTML file should be:
*
*
* C.A. Bertulani, 09/01/2000
**/
import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Hatom extends Applet
implements ActionListener {
double ymax, zmax; //
int n, l; // atomic quantum numbers
int kk=0; // k=1 ---> action
// define buttons
String b1s="1s"; Button b1=new Button(b1s);
String b2s="2s"; Button b2=new Button(b2s);
String b3s="2p"; Button b3=new Button(b3s);
String b4s="3s"; Button b4=new Button(b4s);
String b5s="3p"; Button b5=new Button(b5s);
String b6s="3d"; Button b6=new Button(b6s);
String b7s="4s"; Button b7=new Button(b7s);
String b8s="4p"; Button b8=new Button(b8s);
String b9s="4d"; Button b9=new Button(b9s);
String b10s="4f"; Button b10=new Button(b10s);
// check boxes
TextField tx1=new TextField(20);
CheckboxGroup chg=new CheckboxGroup();
Checkbox[] ch=new Checkbox[2];
// text
String Caption1, Caption2, Caption3;
public void init() {
// ad buttons
add(tx1);
add(b1); add(b2); add(b3); add(b4); add(b5);
add(b6); add(b7); add(b8); add(b9); add(b10);
// add check boxes
add(ch[0]=new Checkbox("Eigen", chg, true));
add(ch[1]=new Checkbox("Pdens", chg, false));
// define captions
Caption1="Numerical solution of the hydrogen atom";
Caption2="Energy, eigenfunction and probability density."
+ " Abcissa = distance/Bohr radius";
// keep aware of actions
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);
b5.addActionListener(this);
b6.addActionListener(this);
b7.addActionListener(this);
b8.addActionListener(this);
b9.addActionListener(this);
b10.addActionListener(this);
// background
setBackground(Color.white);
}
public void pin(Graphics g) {
if (kk==0) { // Screen layout
// Set the size and location relative to the parent's upper left corner,
// in pixels. The four int arguments specify x, y, width, and height, in
// that order. Use these methods to position and size a component when you
// aren't using layout manager
tx1.setBounds(425, 2, 129, 20);
ch[0].setBounds(425, 25, 65, 20);
ch[1].setBounds(490, 25, 65, 20);
b1.setBounds(425, 117, 30, 20);
b2.setBounds(425, 94, 30, 20);
b3.setBounds(458, 94, 30, 20);
b4.setBounds(425, 71, 30, 20);
b5.setBounds(458, 71, 30, 20);
b6.setBounds(491, 71, 30, 20);
b7.setBounds(425, 48, 30, 20);
b8.setBounds(458, 48, 30, 20);
b9.setBounds(491, 48, 30, 20);
b10.setBounds(524, 48, 30, 20);
g.setFont(new Font("TimesRoman", Font.PLAIN, 14));
}
g.setColor(Color.black);
// draw grid lines
for (int i=0; i<=4; i=i+1) {
g.drawLine(140*i, 0, 140*i, 280);
}
for (int i=0; i<=2;i=i+1) {
g.drawLine(0, 140*i, 560, 140*i);
}
}
public void paint(Graphics g) { // Main program
double a, b, e, de;
int sa, sb, se;
pin(g);
g.setColor(Color.red);
// draw caption
g.drawString(Caption1,5,255);
g.drawString(Caption2,5,270);
if (kk==1) {
g.setColor(Color.blue);
e=-1./n/n; zmax=1.05*zmax; // e= analytical value of energy
if (ch[0].getState()==true) {
de=.00001; a=e*1.1; b=e/1.1; // Bisection Algorithm
sa=fey(a, g); sb=fey(b, g); // check nodes
if (sa!=sb) {
while ((b-a)>de) {
e=(a+b)/2; se=fey(e, g); // bisect and recalculate
if (sa==se) {
a=e;
}
else {
b=e;
}
}
g.setColor(Color.red); // plot best wavefunction
e=(a+b)/2; se=fey(e, g);
}
}
else {
se=fey(e, g);
}
// Success. Got numerical energy.
g.setColor(Color.black); tx1.setText("E = "+(float)e);
}
kk=0;
}
int fey(double e, Graphics g) {
double r, u, v, dv, dr, z;
int test=0;
int x1, y1, x2, y2;
r=0; u=1; v=-u/(l+1); dr=n*n*.002; // Feynman Algorithm
dv=-e*u*dr; v=v+dv/2;
if (ch[0].getState()==true) {
if (l==0) {
x1=0; y1=(int)(140*(1-1/ymax));
}
else {
x1=0; y1=0;
}
do { // Plot function R
r=r+dr; u=u+v*dr;
z=u*Math.pow(r, l);
x2=(int)(140*r/n/n); y2=(int)(140*(1-z/ymax));
g.drawLine(x1, y1, x2, y2); x1=x2; y1=y2;
dv=-(e*u+2/r*(u+(l+1)*(v+dv/2)))*dr; // Schroedinger step
v=v+dv;
} while ((z>-ymax)&&(z0) {
test=1;
}
else {
test=0;
}
return test;
}
public void actionPerformed(ActionEvent e) { // Buttons
String tst;
tst=e.getActionCommand();
// get actions and initialize values
if (b1s.equals(tst)) { n=1; l=0; kk=1; ymax=1.1; zmax=.368; }
if (b2s.equals(tst)) { n=2; l=0; kk=1; ymax=1.1; zmax=.618; }
if (b3s.equals(tst)) { n=2; l=1; kk=1; ymax=1; zmax=2.165; }
if (b4s.equals(tst)) { n=3; l=0; kk=1; ymax=1.1; zmax=.828; }
if (b5s.equals(tst)) { n=3; l=1; kk=1; ymax=1; zmax=2.64; }
if (b6s.equals(tst)) { n=3; l=2; kk=1; ymax=5; zmax=36.3; }
if (b7s.equals(tst)) { n=4; l=0; kk=1; ymax=1.1; zmax=1.1; }
if (b8s.equals(tst)) { n=4; l=1; kk=1; ymax=1; zmax=3.15; }
if (b9s.equals(tst)) { n=4; l=2; kk=1; ymax=5; zmax=36.5; }
if (b10s.equals(tst)) { n=4; l=3; kk=1; ymax=100; zmax=1200; }
repaint();
}
}