/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
| 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)
|
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*
*/
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);
}
}