/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | YLL 4/11/2004 | Now: WolffXY | | Basic framework for wolffxyulation. | Class inheritance hierarchy: | wolffxy extends Applet | wolffxyCanvas extends Canvas | wolffxyFrame extends Frame | Member hierarchy: | wolffxyFrame sf | |--- Applet applet | |--- wolffxyFrame sf (circular reference) | |--- GridBagConstraints gbc (data structure) | |--- wolffxyCanvas cv (placed LHS) | |--- Panel panelControl (placed RHS) | |--- ... | Coordinate systems: | xmax=xbor+xdisp+xbor (wolffxyulate xmax*ymax cells, display xdisp*ydisp) | &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ /* Sorry, you need a Java-enabled browser to see the wolffxyulation. */ import java.awt.*; import java.applet.Applet; import java.awt.event.*; import java.util.Random; public class wolffxy extends Applet { //----- Override Applet methods ----- wolffxyFrame sf; public void init() {sf = new wolffxyFrame(this); sf.init(); } public void destroy() {if (sf != null) sf.dispose(); sf = null; } }; class wolffxyCanvas extends Canvas { wolffxyFrame sf; wolffxyCanvas(wolffxyFrame sf0) {sf = sf0;} public Dimension getPreferredSize() {return new Dimension(300,400);} public void update(Graphics g) {sf.updatewolffxy(g);} public void paint(Graphics g) {sf.updatewolffxy(g);} }; class wolffxyFrame extends Frame implements ComponentListener, ActionListener, ItemListener, WindowListener { //----- Objects ----- static long timeNow,timeLast,timeElapsed; static int framesElapsed=0; double fps; boolean boolDetails=true; Random random; Dimension dimWin; int wxmax,wymax; Image imOffscreen; Panel panelControl; Checkbox cbStep; Checkbox cbRunning; Checkbox cbDetails; Label labelFPS; wolffxyCanvas cv; wolffxy applet; TextField tfSizeX; TextField tfSizeY; TextField tfSpeed; TextField tfCoupling; static final Color col0 = new Color (0xFFFFFF); static final Color col1 = new Color (0x0000FF); static final Color col10 = new Color (0xFFCCCC); static final Color col01 = new Color (0x66DDFF); final int delay1 = 1; final int delay2 = 1000; static final double pi = (double)Math.PI; static final double twopi = (double)(2*Math.PI); static final double ootwopi = (double)(1/(2*Math.PI)); int xmax; int ymax; int xdisp; int ydisp; int iSpeed; double fCoupling; int pause; byte cc[][]; //cluster flag int xqueue[]; int yqueue[]; double ff[][]; // phi double ux[][]; // cos phi double uy[][]; // sin phi List listPreset; //----- Constructor ----- wolffxyFrame(wolffxy applet0) {super("wolffxy"); applet = applet0; } //----- init(), reinit() are actually user-defined ---- public void init() { //----- GUI----- this.addWindowListener(this); cv = new wolffxyCanvas(this); cv.addComponentListener(this); panelControl = new Panel(); panelControl.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets (0, 8, 0, 8); // S,W,N,E this.add(cv, BorderLayout.CENTER); this.add(panelControl, BorderLayout.LINE_END); gbc.gridwidth = GridBagConstraints.RELATIVE; panelControl.add(new Label("System size LX"), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; panelControl.add(tfSizeX = new TextField("16"), gbc); tfSizeX.addActionListener(this); gbc.gridwidth = GridBagConstraints.RELATIVE; panelControl.add(new Label("System size LY"), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; panelControl.add(tfSizeY = new TextField("16"), gbc); tfSizeY.addActionListener(this); gbc.gridwidth = GridBagConstraints.RELATIVE; panelControl.add(new Label("Coupling J"), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; panelControl.add(tfCoupling = new TextField("1.0"), gbc); tfCoupling.addActionListener(this); gbc.gridwidth = GridBagConstraints.RELATIVE; panelControl.add(new Label("Speed"), gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; panelControl.add(tfSpeed = new TextField("1"), gbc); tfSpeed.addActionListener(this); gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.WEST; panelControl.add(cbStep = new Checkbox("Step", true), gbc); cbStep.addItemListener(this); panelControl.add(cbRunning = new Checkbox("Running", true), gbc); cbRunning.addItemListener(this); panelControl.add(cbDetails = new Checkbox("Details", false), gbc); cbDetails.addItemListener(this); labelFPS = new Label("FPS "); panelControl.add(labelFPS, gbc); listPreset = new List(4, false); listPreset.add("Phase (colour)"); listPreset.add("Energy density"); listPreset.add("Vorticity"); listPreset.add("Phase (graph)"); listPreset.select(0); panelControl.add(listPreset, gbc); //----- Params ----- int blah=123; try {blah = Integer.parseInt(applet.getParameter("RES"));} catch (Exception e) {} tfSizeX.setText(Integer.toString(blah)); tfSizeY.setText(Integer.toString(blah)); setParams(); pause = 10; //----- Various ----- random = new Random(); timeNow = System.currentTimeMillis(); timeLast = System.currentTimeMillis(); reinit(); cv.setBackground(Color.black); // setSize(600, 500); handleResize(); show(); } void reinit() { xdisp = xmax = Integer.parseInt(tfSizeX.getText()); ydisp = ymax = Integer.parseInt(tfSizeY.getText()); System.out.println("reinit " + xmax + " " + ymax + "\n"); ff = new double[xmax][ymax]; ux = new double[xmax][ymax]; uy = new double[xmax][ymax]; cc = new byte[xmax][ymax]; xqueue = new int[xmax*ymax+10]; //wouldn't need such a large array yqueue = new int[xmax*ymax+10]; // if we used circular queue. never mind int x,y; for (x=0; x= 1000) { fps = framesElapsed*1000.0f/timeElapsed; //labelFPS.setText (timeElapsed+"ms"); labelFPS.setText ("FPS: "+(int)fps + "; IPS: " +(int)(fps*iSpeed)); timeLast = timeNow; framesElapsed = 0; } //=============== PERFORM ONE STEP OF WOLFF ALGORITHM ============ // Floodfill algorithm for cluster detection (e.g., in site percolation): // Method 1: Depth-first fill (uses stack). // Method 2: Breadth-first fill (uses queue). // // Wolff algorithm: wolffxyilar to floodfill, // but with a probability p<1 of making each bond. // // Select x,y at random. Activate bond with prob p=1-e^(-2J) iIterations = boolDetails ? 1 : iSpeed; for (int iter=0; iter 1 || asq < 0.0001); // Second test is hardly necessary. //------ INIT CLUSTER-LABEL ARRAY ----- for (x=0; x 0) { // Cond 2 if (random.nextDouble() >= Math.exp(-fCoupling*auau2_asq)) { // Cond 3 itail++; xqueue[itail] = x2; yqueue[itail] = y2; cc[x2][y2] = 1; } } } x2=xm; if (cc[x2][y2]==0) { // Cond 1 au2 = ax*ux[x2][y2] + ay*uy[x2][y2]; auau2_asq = au_asq*au2; if (auau2_asq > 0) { // Cond 2 if (random.nextDouble() >= Math.exp(-fCoupling*auau2_asq)) { // Cond 3 itail++; xqueue[itail] = x2; yqueue[itail] = y2; cc[x2][y2] = 1; } } } x2=x; y2=yp; if (cc[x2][y2]==0) { // Cond 1 au2 = ax*ux[x2][y2] + ay*uy[x2][y2]; auau2_asq = au_asq*au2; if (auau2_asq > 0) { // Cond 2 if (random.nextDouble() >= Math.exp(-fCoupling*auau2_asq)) { // Cond 3 itail++; xqueue[itail] = x2; yqueue[itail] = y2; cc[x2][y2] = 1; } } } y2=ym; if (cc[x2][y2]==0) { // Cond 1 au2 = ax*ux[x2][y2] + ay*uy[x2][y2]; auau2_asq = au_asq*au2; if (auau2_asq > 0) { // Cond 2 if (random.nextDouble() >= Math.exp(-fCoupling*auau2_asq)) { // Cond 3 itail++; xqueue[itail] = x2; yqueue[itail] = y2; cc[x2][y2] = 1; } } } } } //System.out.println ("========="); if (boolDetails) { try {Thread.sleep(delay2);} catch(Exception e) {} } }//end if boolrunning //----- Update the offscreen image ----- if (boolRunning||boolStep) { g.setColor(cv.getBackground()); g.fillRect(0, 0, wxmax, wymax); // takes a long time switch (listPreset.getSelectedIndex()) { case 0: for (x=0; xpi) dum1-=twopi; dum2+=dum1; dum1 = ff[xp][y] - ff[xp][yp]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[xp][yp] - ff[x][yp]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[x][yp] - ff[x][y]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; //System.out.println(dum2+" "); if (dum2 >= 1d) g.setColor(Color.red); else if (dum2<=- 1d) g.setColor(Color.blue); else g.setColor(Color.black); g.fillRect (X, Y, xscal, yscal); } } break; case 3: double dum1,dum2; // PLOT PHASE VS X VALUE for (x=0; xpi) dum1-=twopi; dum2+=dum1; X2 = x*xscal; Y2 = (int) ( (y + 0.5 + dum2*0.01)*yscal); if (x>0) { g.setColor(Color.white); g.drawLine (X, Y, X2, Y2); } X = X2; Y = Y2; } } break; // PLOT VORTICITY 2 .. oops this wversion is bad /* if (boolRunning||boolStep) { for (x=0; xpi) dum1-=twopi; dum2+=dum1; dum1 = ff[xp][y] - ff[xp][ym]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[xp][ym] - ff[x][ym]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[x][ym] - ff[xm][ym]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[xm][ym] - ff[xm][y]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[xm][y] - ff[xm][yp]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[xm][yp] - ff[x][yp]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; dum1 = ff[x][yp] - ff[xp][yp]; if (dum1<-pi) dum1+=twopi; else if (dum1>pi) dum1-=twopi; dum2+=dum1; //System.out.println(dum2+" "); if (dum2 >= 1d) g.setColor(Color.red); else if (dum2<=- 1d) g.setColor(Color.blue); else g.setColor(Color.black); g.fillRect (X, Y, xscal, yscal); } } } */ } // end switch } //end if //----- Put offscreen image to screen even if sim is paused ----- realg.drawImage(imOffscreen, 0, 0, this); //----- Trigger the next update with millisec delay ----- if (boolRunning) { // Don't trigger! ======= HACK ====== cv.repaint(pause); //?? } if (!boolRunning) cbStep.setState(false); } }