/* * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.awt.*; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.applet.*; import java.lang.Math; import java.awt.event.*; import java.awt.AWTEvent.*; import java.lang.Object; public class EnergyLevelDiagrams extends Applet implements ItemListener, AdjustmentListener { Graphics g ; // private Toolkit t = Toolkit.getDefaultToolkit(); // private String fonts[] = t.getFontList(); private Font myFont = new Font(Font.SERIF,Font.BOLD,12); private Scrollbar internuclearDistanceSlider = new Scrollbar(Scrollbar.HORIZONTAL,100,5,25,380); private int internuclearDistance = 100; private int separationLineStart, separationLine = 165; private Image orbitalImages, morseCurves, energyLevelDiagram; private Graphics orbitalImages_g, morseCurves_g, energyLevelDiagram_g; private Choice numberOfAtomsChoice = new Choice(); private Choice bandOccupancyChoice = new Choice(); private double[][] curve = new double[376][1001]; private int numberOfAtoms = 2; private int level[] = new int[1001]; private int bandOccupancyIndex = 0; private int[] densityOfStatesCount = new int[330]; @Override public void init() { orbitalImages = createImage(1000,100); orbitalImages_g = orbitalImages.getGraphics(); morseCurves = createImage(430,330); morseCurves_g = morseCurves.getGraphics(); energyLevelDiagram = createImage(430,330); energyLevelDiagram_g = energyLevelDiagram.getGraphics(); internuclearDistanceSlider.addAdjustmentListener(this); /* internuclearDistanceSlider.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseReleased(java.awt.event.MouseEvent evt) { internuclearDistanceSliderMouseReleased(evt); } }); */ GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout(gbl); gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.ipadx = 350; gbc.insets = new Insets(135,65,0,0); gbc.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; gbl.setConstraints(internuclearDistanceSlider,gbc); add(internuclearDistanceSlider); gbc.ipadx = 20; gbc.insets = new Insets(132,0,0,0); gbl.setConstraints(numberOfAtomsChoice,gbc); add(numberOfAtomsChoice); gbc.ipadx = 35; gbc.gridwidth = GridBagConstraints.REMAINDER; gbl.setConstraints(bandOccupancyChoice,gbc); add(bandOccupancyChoice); numberOfAtomsChoice.addItemListener(this); bandOccupancyChoice.addItemListener(this); numberOfAtomsChoice.addItem("2 atoms"); numberOfAtomsChoice.addItem("3 atoms"); numberOfAtomsChoice.addItem("4 atoms"); numberOfAtomsChoice.addItem("5 atoms"); numberOfAtomsChoice.addItem("10 atoms"); numberOfAtomsChoice.addItem("25 atoms"); numberOfAtomsChoice.addItem("50 atoms"); numberOfAtomsChoice.addItem("100 atoms"); numberOfAtomsChoice.addItem("1000 atoms"); bandOccupancyChoice.addItem("Empty band"); bandOccupancyChoice.addItem("Half-filled band"); bandOccupancyChoice.addItem("Filled band"); makeCurves(); drawOrbitals(); drawMorseCurves(); drawEnergyLevelDiagram(); repaint(); } void makeCurves(){ //calculate all the curves double internuclearDistance; double a, b; int j = numberOfAtoms - 1; for (int i = 0; i <= 375; i++){ //the boundary ones first internuclearDistance = ((float)(i))/100.0; curve[i][0] = (1.0 - Math.exp(-(internuclearDistance - 0.60)/0.60)); //most bonding curve[i][0] = curve[i][0]*curve[i][0]; curve[i][j] = (1.0 + Math.exp(-internuclearDistance)); //most antibonding curve[i][j] = curve[i][j]*curve[i][j]; } for (j = 1; j < numberOfAtoms-1; j++){//System.out.println("Averaging loop j = "+Integer.toString(j)); a = Math.pow((float)(numberOfAtoms - j-1),0.7); b = Math.pow((float)(j),0.7); for (int i = 0; i<= 375; i++){ curve[i][j] = (a*curve[i][0] + b*curve[i][numberOfAtoms-1])/(a + b); } } } void drawOrbitals(){ orbitalImages_g.setColor(Color.BLACK); orbitalImages_g.fillRect(0, 0, 999, 99); orbitalImages_g.setColor(Color.RED); orbitalImages_g.drawRect(0, 0, 998, 98); orbitalImages_g.drawRect(1, 1, 996, 96); } void drawMorseCurves(){ morseCurves_g.setColor(Color.WHITE); morseCurves_g.fillRect(0, 0, 429, 329); morseCurves_g.setColor(Color.RED); morseCurves_g.drawRect(0, 0, 428, 328); morseCurves_g.drawRect(1, 1, 426, 326); morseCurves_g.setColor(Color.BLUE); morseCurves_g.drawLine(25,25,25,305); // add axes morseCurves_g.drawLine(25,305,400,305); for (int i = 25; i <= 400; i = i + 25){ //add x-ticks morseCurves_g.drawLine(i,302,i,308); } morseCurves_g.drawLine(22,25,27,25); //Add y-axis ticks morseCurves_g.drawLine(22,165,27,165); morseCurves_g.drawLine(22,305,27,305); morseCurves_g.setColor(new Color(220,220,220)); //Add connecting lines for (int j = 0; j < numberOfAtoms; j++){ level[j] = (int)(90.0*curve[internuclearDistance][j]); morseCurves_g.drawLine(separationLine-37,290-level[j],426,290-level[j]); } morseCurves_g.setColor(new Color(132,22,0)); //draw curves for (int j = 0; j < numberOfAtoms; j++){ for (int i = 0; i <= 374; i++){ morseCurves_g.drawLine(i+26, 290-(int)(90.0*curve[i][j]), i+27, 290-(int)(90.0*curve[i+1][j])); } } } void drawEnergyLevelDiagram(){ energyLevelDiagram_g.setColor(Color.WHITE); energyLevelDiagram_g.fillRect(0, 0, 429, 329); energyLevelDiagram_g.setColor(Color.RED); energyLevelDiagram_g.drawRect(0, 0, 428, 328); energyLevelDiagram_g.drawRect(1, 1, 426, 326); } @Override public void paint(Graphics g) { g.drawImage(orbitalImages, 5, 5, null); g.drawImage(morseCurves, 40, 160, null); g.drawImage(energyLevelDiagram, 545, 160, null); g.setColor(Color.MAGENTA); g.drawLine(separationLine,162,separationLine,464); g.setColor(new Color(220,220,220)); for (int j = 0; j < numberOfAtoms; j++){ //extend connecting lines level[j] = (int)Math.round(90.0*curve[internuclearDistance][j]); g.drawLine(467,450-level[j],690,450-level[j]); g.drawLine(650,359,690,450-level[j]); } g.drawLine(440, 359, 575, 359); //"zero" line for (int j = 0; j < 330; j++){ densityOfStatesCount[j] = 0; } g.setColor(Color.GREEN.darker()); switch (bandOccupancyIndex) { //draw energy levels case 0: //all unoccupied for (int j = 0; j < numberOfAtoms; j++){ level[j] = (int)Math.round(90.0*curve[internuclearDistance][j]); g.drawLine(690,450-level[j],840,450-level[j]); } break; case 1: //half occupied if(numberOfAtoms - (numberOfAtoms/2)*2 == 1){ //odd number of atoms g.setColor(Color.BLUE.darker()); //filled ones for (int j = 0; j < numberOfAtoms/2; j++){ level[j] = (int)Math.round(90.0*curve[internuclearDistance][j]); g.drawLine(690,450-level[j],840,450-level[j]); } g.drawLine(690,450-level[numberOfAtoms/2],765,450-level[numberOfAtoms/2]); //middle one g.setColor(Color.GREEN.darker()); g.drawLine(765,450-level[numberOfAtoms/2],840,450-level[numberOfAtoms/2]); for (int j = (numberOfAtoms/2+1); j < numberOfAtoms; j++){ //empty ones level[j] = (int)Math.round(90.0*curve[internuclearDistance][j]); g.drawLine(690,450-level[j],840,450-level[j]); } } else{ //even number of atoms g.setColor(Color.BLUE.darker()); //filled ones for (int j = 0; j < numberOfAtoms/2; j++){ level[j] = (int)Math.round(90.0*curve[internuclearDistance][j]); g.drawLine(690,450-level[j],840,450-level[j]); } g.setColor(Color.GREEN.darker()); //empty ones for (int j = (numberOfAtoms/2); j < numberOfAtoms; j++){ level[j] = (int)Math.round(90.0*curve[internuclearDistance][j]); g.drawLine(690,450-level[j],840,450-level[j]); } } break; case 2: //all filled g.setColor(Color.BLUE.darker()); for (int j = 0; j < numberOfAtoms; j++){ level[j] = (int)Math.round(90.0*curve[internuclearDistance][j]); g.drawLine(690,450-level[j],840,450-level[j]); } } g.setColor(new Color(132,22,0)); g.drawLine(575, 359, 650, 359); if (numberOfAtoms == 2){ //H2 case - show separate 1s levels (left and right). g.drawLine(880, 359, 955, 359); g.setColor(new Color(220,220,220)); g.drawLine(840, 450-level[0], 880, 359); g.drawLine(840, 450-level[numberOfAtoms-1], 880, 359); } else { //construct density of states histogram for (int j = 0; j < 330; j++){ densityOfStatesCount[j] = 0; } for (int j = 0; j < numberOfAtoms; j++){ //count the levels int densityOfStatesIndex = level[j]; densityOfStatesCount[densityOfStatesIndex]++; } g.setColor(Color.ORANGE); for (int j = 0; j < 330; j++){ if (!(densityOfStatesCount[j] == 0)){ g.drawLine(870, 450-j, 870 + densityOfStatesCount[j], 450-j); } } } g.setColor(Color.BLACK); g.setFont(myFont); g.drawString("Adjust the internuclear distance with the slider",135,125); g.drawString("Choose number of atoms", 550, 125); g.drawString("Choose an occupancy", 785, 125); } @Override public void adjustmentValueChanged(AdjustmentEvent evt){ // private void internuclearDistanceSliderMouseReleased(java.awt.event.MouseEvent evt) { Object source = evt.getSource(); if (source == internuclearDistanceSlider) { // separationLine = internuclearDistanceSlider.getValue() + separationLineStart + 65; internuclearDistance = internuclearDistanceSlider.getValue(); separationLine = internuclearDistance + separationLineStart + 65; drawEnergyLevelDiagram(); drawMorseCurves(); repaint(40,150,1000,410); } } @Override public void itemStateChanged(ItemEvent evt){ // System.out.println("Item state changed"); Object source = evt.getSource(); int atomCountIndex; if (source == numberOfAtomsChoice) { atomCountIndex = numberOfAtomsChoice.getSelectedIndex(); switch (atomCountIndex) { case 0: numberOfAtoms = 2; break; case 1: numberOfAtoms = 3; break; case 2: numberOfAtoms = 4; break; case 3: numberOfAtoms = 5; break; case 4: numberOfAtoms = 10; break; case 5: numberOfAtoms = 25; break; case 6: numberOfAtoms = 50; break; case 7: numberOfAtoms = 100; break; case 8: numberOfAtoms = 1000; } } if (source == bandOccupancyChoice){ bandOccupancyIndex = bandOccupancyChoice.getSelectedIndex(); // System.out.println("bandOccupancyIndex = "+Integer.toString(bandOccupancyIndex)); } makeCurves(); drawMorseCurves(); drawEnergyLevelDiagram(); repaint(40,150,1000,410); } }