/** applet No. 1021 * * template - molecular dynamics 2D * - multi thread MD :: display - synchronized / notify * * Created by Ikeuchi Mitsuru on September 18 2006. * Copyright (c) 2006-2007 Ikeuchi Mitsuru. All rights reserved. * * ver 0.0.1 2006.09.18 created * ver 0.0.2 2007.06.08 improved code * */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class noticeMTmd2d extends Applet implements ItemListener, ActionListener, AdjustmentListener, Runnable { // ------------------------------------ preset field ----------- Thread th = null; // for run()-paint() thread MolecularDynamics md = null; Notice ntc = new Notice(); // for event Choice ch_tempCont, ch_view; Button bt_reset, bt_startStop; Scrollbar sc_mdSleep, sc_temp; // for off-paint buffer Dimension dim; Image imgOff; Graphics gOff; int sleepTime = 50; int mdSleepTime = 10; int dispMode = 0; int tempMode = 2; double contTemp = 300.0; int thCount = 0; // ------------------------------ applet main thread ----------- public void init() { resize(630,320); setBackground(Color.white); dim = getSize(); imgOff = createImage(dim.width,dim.height); gOff = imgOff.getGraphics(); ch_tempCont = new Choice(); ch_tempCont.add("adiabatic"); ch_tempCont.add("T scaling"); ch_tempCont.add("wall cont."); ch_tempCont.addItemListener(this); ch_tempCont.select("wall cont."); ch_view = new Choice(); ch_view.add("ball"); ch_view.add("velocity"); ch_view.addItemListener(this); ch_view.select("ball"); bt_reset= new Button("reset"); bt_reset.addActionListener(this); bt_startStop= new Button("start/stop"); bt_startStop.addActionListener(this); sc_mdSleep = new Scrollbar(Scrollbar.HORIZONTAL,10,10,5,110); sc_mdSleep.addAdjustmentListener(this); sc_temp = new Scrollbar(Scrollbar.HORIZONTAL,300,10,10,610); sc_temp.addAdjustmentListener(this); setLayout(new BorderLayout()); Panel pnl = new Panel(); pnl.setLayout(new GridLayout(1,6,5,0)); //pnl.add(new Label(" ")); pnl.add(bt_reset); pnl.add(bt_startStop); pnl.add(sc_mdSleep); pnl.add(ch_tempCont); pnl.add(sc_temp); pnl.add(ch_view); add(pnl,"North"); } public void start() { if (md == null) { md = new MolecularDynamics(64,ntc); md.start(); } if (th == null) { th = new Thread(this); th.start(); } } public void stop() { if (md == null) md = null; if (th == null) th = null; } // ---------------------------------- event listener ----------- public void itemStateChanged(ItemEvent ev){ if (ev.getSource() == ch_tempCont) { tempMode = ch_tempCont.getSelectedIndex(); md.setTempMode(tempMode); } else if (ev.getSource() == ch_view) { dispMode = ch_view.getSelectedIndex(); } } public void actionPerformed(ActionEvent ev){ if(ev.getSource() == bt_reset){ md.reset(); thCount = 0; } else if (ev.getSource() == bt_startStop){ if (md.getStartSW()==0) { md.setStartSW(1); } else { md.setStartSW(0); } } } public void adjustmentValueChanged(AdjustmentEvent ev){ if (ev.getSource() == sc_mdSleep) { mdSleepTime = sc_mdSleep.getValue(); md.setSleepTime(mdSleepTime); } else if (ev.getSource() == sc_temp) { contTemp = 1.0*(double)(sc_temp.getValue()); md.setTemperature(contTemp); } } // ========================= run() - paint() loop ============== public void run() { while (th != null) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } ntc.getup(); thCount += 1; offPaint(); repaint(); } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(imgOff,0,0,this); } // --------------------------------------- off-paint ----------- void offPaint() { int gbx,gby; double sc,dispScale,viewScale; gOff.setColor(Color.white); gOff.fillRect(0,0,dim.width,dim.height); gbx = 30; gby = 60; dispScale = (250.0/(10.0e-9)); viewScale = 1.0; sc = viewScale*dispScale; if (dispMode==0) { particlePlot(gbx,gby,sc); } else if (dispMode==1) { velocityPlot(gbx,gby,sc, 0.05); } else if (dispMode==2) { ; } gOff.setColor(Color.black); gOff.drawString("t="+(int)(md.getTime()*1.0e13+0.5)/10.0+" ps",10,40); if (md.getStartSW()==0) { gOff.drawString("stopped",630/6*1+10,40); } else { gOff.drawString("started",630/6*1+10,40); } gOff.drawString("md sleep="+mdSleepTime+" ",630/6*2+10,40); gOff.drawString("T cont.",630/6*3+10,40); gOff.drawString("Tc="+contTemp+" K",630/6*4+10,40); gOff.drawString("T="+(int)(md.temperature()*10+0.5)/10.0+" K",630/6*4+10,60); gOff.drawString("view",630/6*5+10,40); gOff.drawString("Box="+(int)(md.getxMax()*1.0e10+0.5)/10.0+" x " + (int)(md.getyMax()*1.0e10+0.5)/10.0+" nm",400,80); gOff.drawString("loop count",400,120); gOff.drawString("thread md ="+md.getcount()+"",400,140); gOff.drawString("thread disp ="+thCount+"",400,160); gOff.drawString("disp sleep = 50 ms",400,180); } // ------------------------------------ plot methods ----------- void particlePlot(int gbx, int gby, double sc) { int nn, i, ix, iy, ballSize; double sgm; nn = md.getnMax(); sgm = 3.40e-10; ballSize = (int)(sgm*sc); drawBox(gbx, gby, sc, ballSize); gOff.setColor(Color.blue); for (i=0; i display - synchronized =========== class Notice { private int flag = 1; public synchronized void attention() { notifyAll(); flag = 0; } public synchronized void getup() { while (flag==1) { try { wait(); } catch (InterruptedException e) { } } flag = 1; } } // ==================================== Particle class =========== class Particle { double xx; double yy; double vx; double vy; double ffx; double ffy; double mass; int kind; Particle() { } } // ======================= molecular dynamics 2D class =========== class MolecularDynamics extends Thread { double t = 0.0; double dt = 10.0e-15; double xMax = 10.0e-9; double yMax = 10.0e-9; Particle p[] = new Particle[2000]; int sleepTime = 10; // in ms int waitSleepTime = 100; int nMax; int resetSW = 0; // 1-reset int startSW = 1; // 0-stop 1-start int tempMode = 2; // 0-adiabatic 1-scaling 2-wall cont double contTemp = 300.0; // in K int mdCount = 0; Notice note; // ------------------------------- class constructor ----------- MolecularDynamics(int numberOfParticles, Notice ntc) { nMax = numberOfParticles; note = ntc; setInitialCondition(); } // ----------------------------------- class methods ----------- public void run() { while (true) { mdCount += 1; timeEvolution(); try { this.sleep(sleepTime); } catch (InterruptedException e) { } note.attention(); } } // --------------------------- set initial condition ----------- void setInitialCondition() { int i; double s; t = 0.0; mdCount = 0; s = xMax/8.0; for (i=0; i1.2){ rr=1.2; }; } for (i=0; i xMax) { p[i].xx = xMax; p[i].vx = -rr*p[i].vx; p[i].vy = rr*p[i].vy; } if (p[i].yy < 0.0) { p[i].yy = 0.0; p[i].vx = rr*p[i].vx; p[i].vy = -rr*p[i].vy; } if (p[i].yy > yMax) { p[i].yy = yMax; p[i].vx = rr*p[i].vx; p[i].vy = -rr*p[i].vy; } } } // ----------------------------------------- utility ----------- void vAjustment() { int i; double tmp, r; tmp = temperature(); r = Math.sqrt(contTemp/tmp); for (i=0; i