//setDefaultLookAndFeelDecorated (true); // doens't work properly /*

Potts model with disorder

Definitions of the model, Hamiltonian, parameters, etc.

This applet simulates a disordered Potts model. It generates samples from the distribution Prob[s] ~ exp (-Ham/T) where

Ham[s] = -sum_{} K_{ij} 2 delta_{s_i s_j} - sum_i (H + H_i) 2 delta_{s_i 0},    and:
To do: Make LAYERED Ising model where Kx and Kz can be different.

Suggestions for use

You can try the following:

Comments (on programming issues)

Credits and references

(...)

*/ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; // for changelistener import javax.swing.JSpinner.NumberEditor; import java.text.DecimalFormat; import java.util.Random; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Frame class with image that updates automatically // "Picture Displayer" // This simple functionality requires hierarchy of 5 objects! // This is the only reason why I am making this a separate class. //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class MyFrame extends JFrame { Container pane; JLabel label; ImageIcon icon; Image image; //=========================================================================== // Constructor public MyFrame () { //Component listener) { super(); // call JFrame constructor pane = this.getContentPane(); icon = new ImageIcon(); label = new JLabel(icon); label.setDoubleBuffered(true); //This helps to eliminate flicker label.setOpaque(true); //No need for JFrameInFrame to redraw itself pane.add(label); //this.setIgnoreRepaint(false);//Controls need to draw themselves. Actually this statement doesn't seem to be necessary. } //=========================================================================== // Make sure that "image" is valid void woohoo () { int widthLabel,heightLabel,widthImage,heightImage; widthLabel = label.getSize().width; heightLabel = label.getSize().height; if (image==null) { image = createImage(widthLabel, heightLabel); icon.setImage(image); } else { widthImage = image.getWidth(null); heightImage = image.getHeight(null); if (widthImage != widthLabel || heightImage != heightLabel) { image = createImage(widthLabel, heightLabel); // memleak? icon.setImage(image); } } } } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // JApplet class //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ public class dirtypotts extends JApplet implements Runnable,ComponentListener,ChangeListener,ActionListener { final String namesOfLattices[] = {"Cubic"}; final String namesOfAlgorithms[] = {"Metropolis", "Glauber", "Wolff"}; final String namesOfVisualizations[] = {"Colored cells", "Cells w/borders", "Stripes"}; //---------- Eyecandy stuff // Usage of the following flags is not well thought-out boolean makeLattice,makeDirt,drawLattice,drawDirt,getRuntime,drawSpins; // These are WIDTH AND HEIGHT OF THE OFFSCREEN IMAGE THAT IS CURRENTLY BEING WORKED ON int width,height; Container appletPane; JFrame frCtrls; MyFrame mfSpinConfig,mfDirtConfig,mfNoise,mfHysteresis,mfMvsT; JSpinner spnrsmax,spnrxmax,spnrymax,spnrzmax, spnrK0,spnrPK,spnrSK,spnrH0,spnrPH,spnrSH,spnrseed, spnrH,spnrT, spnrdelay,spnrrefresh, spnrz; JButton buttonPolarize,buttonRandomize; JComboBox comboAlgorithm,comboLattice,comboVisual; JCheckBox chkboxRunning; Color colorTable[]; Thread thread1; int zslice; int delay,refresh; double mctime; // This is a joke. Don't take it seriously. //---------- Core stuff int smax,xmax,ymax,zmax,imax,bmax; double kk[][]; // Random bonds double hh[]; // Random fields byte ss[]; // Potts spins int cc[]; // Cluster flags for Wolff int nn[][] ; // Neighbour list double zz[]; // Probability list for Glauber int iqueue[]; // Queue for Wolff int counter=1; // Counter for Wolff int seed; boolean haveNumber=false; // For drand_gauss double boxMullerNumber=1e100; // For drand_gauss double disorderK0,disorderH0,disorderPK,disorderSK,disorderPH,disorderSH, tempT,beta,pstop,fieldH; int ncluster; Random rng; int nsub[]; // total "0-particles" on each sublattice int ntot; double mag; // magnetization //==================================================================== // Set up Potts model //==================================================================== public int IXYZ (int x, int y, int z) {return x+xmax*(y+ymax*z);} int irand (int i) { //return (int)(Math.random()*i); return rng.nextInt(i); } double drand_gauss () { /* double x,y,u,t,xx; if (haveNumber) {haveNumber=false; return boxMullerNumber;} haveNumber=true; do {x=rng.nextDouble()*2-1; y=rng.nextDouble()*2-1; u=x*x + y*y;} while (u>1); t = Math.sqrt(-2*Math.log(u)/u); xx=t*x; boxMullerNumber=t*y; return xx; */ return rng.nextGaussian(); } public void initPotts() { int x,y,z,i; getSetupPars(); rng = new Random(); //---------- Set up the neighborlist switch (comboLattice.getSelectedIndex()) { case 0: // LATTICE_CUBIC: bmax = 6; imax = xmax*ymax*zmax; nn = new int[imax][bmax]; for (z=0; z pstop) { ss[j] = sprimej; // Flip j cc[j] = counter; // Mark j as part of cluster iqueue[++ltail] = j;// Push j on queue } } } } ncluster = lhead+1; // Return the cluster size! mctime += ncluster/(double)imax; // Time not well-defined for Wolff... } //&&&&&&&&&&&& Get parameterse from spinners public void getSetupPars() { // Essential parameters such as system size // get lattice type ... but no need really smax = Integer.parseInt(spnrsmax.getValue().toString()); xmax = Integer.parseInt(spnrxmax.getValue().toString()); ymax = Integer.parseInt(spnrymax.getValue().toString()); zmax = Integer.parseInt(spnrzmax.getValue().toString()); } public void getDisorderPars() { disorderK0 = Double.parseDouble(spnrK0.getValue().toString()); disorderPK = Double.parseDouble(spnrPK.getValue().toString()); disorderSK = Double.parseDouble(spnrSK.getValue().toString()); disorderH0 = Double.parseDouble(spnrH0.getValue().toString()); disorderPH = Double.parseDouble(spnrPH.getValue().toString()); disorderSH = Double.parseDouble(spnrSH.getValue().toString()); seed = Integer.parseInt(spnrseed.getValue().toString()); } public void getRuntimePars() { tempT = Double.parseDouble(spnrT.getValue().toString()); fieldH = Double.parseDouble(spnrH.getValue().toString()); refresh = Integer.parseInt(spnrrefresh.getValue().toString()); //delay = Integer.parseInt(spnrdelay.getValue().toString()); beta = 1d/tempT; zslice = Integer.parseInt(spnrz.getValue().toString()); if (zslice >= zmax || zslice < 0) { zslice = (zslice+zmax*10) % zmax; spnrz.setValue(new Integer(zslice)); } } //&&&&&&&&&&&&&&&& Override JApplet.init() etc //public void stop() {frame1.dispose();} // I think I gotit right //public void destroy() {frame1.dispose();} //========== Make a spinner and add it to frCtrls public JSpinner addSpnr (String labeltext, char mnemonic, int initval, int minval, int maxval, int step) { GridBagConstraints gbc = new GridBagConstraints(); JLabel lbl = new JLabel(labeltext); JSpinner spnr = new JSpinner(new SpinnerNumberModel(initval, minval, maxval, step)); if (mnemonic != ' ') lbl.setDisplayedMnemonic(mnemonic); lbl.setLabelFor(spnr); spnr.setEditor(new NumberEditor(spnr, "###0")); //No commas! gbc.anchor = GridBagConstraints.EAST; gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; frCtrls.add(lbl, gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; frCtrls.add(spnr, gbc); spnr.addChangeListener(this); return spnr; } public JSpinner addSpnr (String labeltext, char mnemonic, double initval, double minval, double maxval, double step) { GridBagConstraints gbc = new GridBagConstraints(); JLabel lbl = new JLabel(labeltext); JSpinner spnr = new JSpinner(new SpinnerNumberModel(initval, minval, maxval, step)); if (mnemonic != ' ') lbl.setDisplayedMnemonic(mnemonic); lbl.setLabelFor(spnr); spnr.setEditor(new NumberEditor(spnr, "###0.#####")); //Float gbc.anchor = GridBagConstraints.EAST; gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; frCtrls.add(lbl, gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; frCtrls.add(spnr, gbc); spnr.addChangeListener(this); return spnr; } public void init() { makeLattice=drawLattice=makeDirt=drawDirt=getRuntime=drawSpins=true; smax=2; xmax=ymax=32; zmax=32; disorderK0=1d; disorderPK=0d; disorderSK=0d; disorderH0=0d; disorderPH=0d; disorderSH=2.0d; seed = 123456789; tempT=1d; fieldH=0.0d; zslice=0; refresh=500; //---------- Set up applet, frame, and panels appletPane = getContentPane(); setSize(256,32); appletPane.add(new JLabel("See popup window")); //============================================================= // Set up frCtrls (CONTROL PANEL) GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.CENTER; gbc.weightx = 0.0; GridBagConstraints gbcL = new GridBagConstraints(); gbcL.anchor = GridBagConstraints.EAST; gbcL.gridwidth = GridBagConstraints.RELATIVE; gbcL.fill = GridBagConstraints.NONE; gbcL.weightx = 0.0; GridBagConstraints gbcR = new GridBagConstraints(); gbcR.gridwidth = GridBagConstraints.REMAINDER; gbcR.fill = GridBagConstraints.HORIZONTAL; gbcR.weightx = 1.0; frCtrls = new JFrame("Controls"); //frCtrls.setFont (new Font("TimesRoman", Font.PLAIN, 12)); frCtrls.setSize(256, 768); frCtrls.setLayout(new GridBagLayout()); //---------- Add lattice combo box JLabel lbl; comboLattice = new JComboBox(namesOfLattices); lbl = new JLabel (" Lattice "); lbl.setDisplayedMnemonic('L'); lbl.setLabelFor(comboLattice); frCtrls.add(lbl, gbcL); frCtrls.add(comboLattice, gbcR); // comboLattice.addActionListener(this);// nonneed? //---------- Add spinners spnrsmax = addSpnr(" Spin-type smax " ,'s', smax, 1, 10, 1); spnrxmax = addSpnr(" Size xmax " ,'x', xmax, 1, 8192, 1); spnrymax = addSpnr(" Size ymax " ,'y', ymax, 1, 8192, 1); spnrzmax = addSpnr(" Size zmax " ,'z', zmax, 1, 8192, 1); frCtrls.add(new JLabel(" "), gbc); // spacer //frCtrls.add(new JLabel(" RBIM parameters ", SwingConstants.CENTER), gbc); spnrK0 = addSpnr(" Ising coupling K0 " ,' ', disorderK0, -1000d, 1000d, 0.01d); spnrPK = addSpnr(" RBIM p " ,' ', disorderPK, 0d, 1d, 0.01d); spnrSK = addSpnr(" RBIM R " ,' ', disorderSK, 0d, 1000d, 0.01d); frCtrls.add(new JLabel(" "), gbc); // spacer spnrH0 = addSpnr(" RFIM H0 " ,' ', disorderH0, -1000d, 1000d, 0.01d); spnrPH = addSpnr(" RFIM p " ,' ', disorderPH, 0d, 1d, 0.01d); spnrSH = addSpnr(" RFIM R " ,' ', disorderSH, 0d, 1000d, 0.01d); spnrseed = addSpnr(" Disorder seed " ,' ', seed,-0x7fffffff,0x7fffffff,1); frCtrls.add(new JLabel(" "), gbc); // spacer spnrH = addSpnr(" Field H " ,'H', fieldH, -1000d, 1000d, 0.01d); spnrT = addSpnr(" Temperature T " ,'T', tempT, 0.000001d, 1000d, 0.01d); spnrrefresh = addSpnr(" Refresh intvl ",' ', refresh, 1, 5000, 1); comboLattice.setEnabled(false); spnrPK.setEnabled(false); spnrSK.setEnabled(false); spnrH0.setEnabled(false); spnrPH.setEnabled(false); //---------- Add algorithm combo box comboAlgorithm = new JComboBox(namesOfAlgorithms); lbl = new JLabel (" Algorithm "); lbl.setDisplayedMnemonic('A'); lbl.setLabelFor(comboAlgorithm); frCtrls.add(lbl, gbcL); frCtrls.add(comboAlgorithm, gbcR); frCtrls.add(new JLabel(" "), gbc); // spacer //---------- Add visualization-mode combo box comboVisual = new JComboBox(namesOfVisualizations); lbl = new JLabel (" Visualization "); lbl.setDisplayedMnemonic('V'); lbl.setLabelFor(comboVisual); frCtrls.add(lbl, gbcL); frCtrls.add(comboVisual, gbcR); comboVisual.addActionListener(this); // balhblah spnrz = addSpnr(" zslice " ,'z', zslice, -8192, 8192, 1); //---------- Add checkboxes chkboxRunning = new JCheckBox ("Running", true); frCtrls.add(chkboxRunning, gbc); frCtrls.setVisible(true); //============================================================= // Set up other display frames mfSpinConfig = new MyFrame(); //this); mfSpinConfig.setTitle("Spin Configuration"); mfSpinConfig.setLocation(256, 0); mfSpinConfig.setSize(512, 512); mfSpinConfig.setVisible(true); mfDirtConfig = new MyFrame(); mfDirtConfig.setTitle("Dirt Configuration"); mfDirtConfig.setLocation(768, 0); mfDirtConfig.setSize(512, 512); mfDirtConfig.setVisible(true); mfNoise = new MyFrame(); //this); mfNoise.setTitle("Noise m(t)"); mfNoise.setLocation(256, 512+28); mfNoise.setSize(256,256); mfNoise.setVisible(true); mfHysteresis = new MyFrame(); //this); mfHysteresis.setTitle("Hysteresis m(h)"); mfHysteresis.setLocation(512, 512+28); mfHysteresis.setSize(256,256); mfHysteresis.setVisible(true); mfMvsT = new MyFrame(); //this); mfMvsT.setTitle("m(T)"); mfMvsT.setLocation(768, 512+28); mfMvsT.setSize(256,256); mfMvsT.setVisible(true); mfSpinConfig.addComponentListener(this); // maybe not necessary mfDirtConfig.addComponentListener(this); // this is necessary mfNoise.addComponentListener(this); // this is necessary mfHysteresis.addComponentListener(this); // this is necessary mfMvsT.addComponentListener(this); // this is necessary //---------- Init system and start simulation thread1=new Thread(this); thread1.start(); } //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& // Implement Runnable. // This method runs in the thread that calls glauber() and also // renderSpinConfig(), etc. public void run() { try { while (true) { if (makeLattice) { initPotts(); makeLattice=false; drawLattice=true; makeDirt=true; } if (makeDirt) { makeDirt(); makeDirt=false; drawDirt=true; } if (drawDirt) { renderDirtConfig(); mfDirtConfig.label.repaint(); drawDirt = false; } if (getRuntime) { getRuntimePars(); getRuntime=false; drawSpins=true; } if (drawSpins) { renderSpinConfig(); mfSpinConfig.label.repaint(); computeMag(); // Important! renderNoise(); // Every time we draw ss[i], draw m(t) too mfNoise.label.repaint(); renderHysteresis(); // Every time we draw ss[i], draw m(t) too mfHysteresis.label.repaint(); renderMvsT(); // Every time we draw ss[i], draw m(t) too mfMvsT.label.repaint(); drawSpins=false; } drawLattice=false; // don't know what im doing if (chkboxRunning.isSelected()) { //----- Metropolis or Wolff ---- switch (comboAlgorithm.getSelectedIndex()) { case 0: // Metropolis: n=number of iterations for (int n=1+(int)((500d*refresh)/imax); n>0; n--) metropolis(); break; case 1: // Glauber for (int n=1+(int)((500d*refresh)/imax); n>0; n--) glauber(); break; case 2: // Wolff // Assume that flipping 1 spin takes 1 unit of time. // In order for the Wolff simulation to have a steady refresh rate // regardless of temperature, we need to aim for roughly the same number // of spin flips between refreshes, n. for (int n=1000*refresh; n>0; n-=ncluster) wolff(); break; } drawSpins=true; } else { Thread.sleep (250); } } } catch (Exception e) { System.out.println("run() exception, exiting"); } } //&&&&&&&&&&&&&&&& Implement ChangeListener public void stateChanged(ChangeEvent e) { Object esrc = e.getSource(); if (esrc==spnrsmax || esrc==spnrxmax || esrc==spnrymax || esrc==spnrsmax) makeLattice=true; // demand full restart else if (esrc==spnrK0 || esrc==spnrPK || esrc==spnrSK || esrc==spnrH0 || esrc==spnrPH || esrc==spnrSH || esrc==spnrseed) makeDirt=true; else { getRuntime=true; // if tempT is changed, must read new tempT drawSpins=true; // if zslice is changed then we need to redraw } } //&&&&&&&&&&&&&&&& Implement ActionListener public void actionPerformed(ActionEvent e) { Object esrc = e.getSource(); if (esrc==comboLattice || esrc==comboVisual) { drawLattice=true; } } //&&&&&&&&&&&&&&&& Implement ComponentListener // These events are only triggered by MyFrame objects! ...? public void componentHidden(ComponentEvent e){} public void componentMoved(ComponentEvent e){} public void componentShown(ComponentEvent e) {} public void componentResized(ComponentEvent e) { Object esrc = e.getSource(); if (esrc==mfDirtConfig.pane) drawDirt=true; // leave it to run() to do the drawing else drawLattice=true; //?????? } //&&&&&&&&&&&&&&&& Implement MouseListener (NOT!) public void mouseEntered (MouseEvent e) {} public void mouseExited (MouseEvent e) {} public void mousePressed (MouseEvent e) {} public void mouseReleased (MouseEvent e) {} public void mouseClicked (MouseEvent e) {} //&&&&&&&&&&&&&&&& This code is the RENDERING CODE! // It prepares the offscreen images..... //=========================================================================== // Render the current spin configuration, ss[i] //=========================================================================== void renderSpinConfig() { int X,Y,x,y; Graphics g; if (!mfSpinConfig.isShowing()) return; mfSpinConfig.woohoo(); g = mfSpinConfig.image.getGraphics(); width = mfSpinConfig.image.getWidth(null); height = mfSpinConfig.image.getHeight(null); if (drawLattice) { g.setColor(Color.white); g.fillRect(0,0,width,height); //drawLattice = false; humph } int xscal=width/xmax; int yscal=height/ymax; xscal = yscal = Math.max(1, Math.min(xscal,yscal)); int Yorg = height - yscal; if (comboVisual.getSelectedIndex()==0) { for (y=0; y= 0) { ih = (int)(h*255); if (ih > 255) ih = 255; g.setColor(new Color( (ih << 16) )); } else { ih = (int)(-h*255); if (ih > 255) ih = 255; g.setColor(new Color( (ih<<8) | (ih) )); } g.fillRect (X, Y, xscal-cellborder, yscal-cellborder); } } } //=========================================================================== // Add points to the "noise" plot //=========================================================================== void computeMag() { int sublatt,x,y,z; ntot=0; for (sublatt=0; sublatt<2; sublatt++) { nsub[sublatt] = 0; for (z=0; z