/** applet No. t06 * * molecular dynamics 3D * Ar atom - Lennard-Jones 12-6 potential * - MD3D class, Display3D class * * Created by Ikeuchi Mitsuru on July 28 2007. * Copyright (c) 2007-2008 Ikeuchi Mitsuru. All rights reserved. * * ver 0.0.1 2007.07.28 created * ver 0.0.2 2008.06.22 added setGUIPannel() * */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class classMD3D extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener, AdjustmentListener, Runnable { // ------------------------------------ preset field ----------- Thread th = null; // for run()-paint() thread MD3D md = new MD3D(); Display3D dsp = new Display3D(md); // for event private Choice ch_tempCont, ch_view; private Button bt_reset, bt_startStop, bt_step; private Scrollbar sc_temp; private int dgX, dgY, dgXb, dgYb; // mouse control // for off-paint buffer private Image imgOff; private Graphics gOff; private int sleepTime = 30; private int thCount = 0; // ------------------------------ applet main thread ----------- public void init() { Dimension dim; resize(dsp.getDispWidth(),dsp.getDispHeight()); setBackground(Color.white); dim = getSize(); imgOff = createImage(dim.width,dim.height); gOff = imgOff.getGraphics(); dsp.setGraphics(gOff); setGUIPannel(); } public void start() { if (th == null) { th = new Thread(this); th.start(); } } public void stop() { if (th != null) th = null; } // ===================================== GUI control =========== private void setGUIPannel() { setChoice(); setButton(); setScrollbar(); setMouse(); 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(new Label(" ")); pnl.add(ch_tempCont); pnl.add(sc_temp); pnl.add(ch_view); add(pnl,"North"); } // choice private void setChoice() { 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("line"); ch_view.addItemListener(this); ch_view.select("ball"); } public void itemStateChanged(ItemEvent ev){ if (ev.getSource() == ch_tempCont) { md.setTempMode( ch_tempCont.getSelectedIndex() ); } else if (ev.getSource() == ch_view) { dsp.setDispMode( ch_view.getSelectedIndex() ); } } // button private void setButton() { bt_reset = new Button("reset"); bt_reset.addActionListener(this); bt_startStop = new Button("start/stop"); bt_startStop.addActionListener(this); bt_step = new Button("step"); bt_step.addActionListener(this); } 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); } } else if (ev.getSource() == bt_step){ if (md.getStartSW()==0) { md.setStepSW(); } } } // scrollbar private void setScrollbar() { sc_temp = new Scrollbar(Scrollbar.HORIZONTAL,300,10,10,610); sc_temp.addAdjustmentListener(this); } public void adjustmentValueChanged(AdjustmentEvent ev){ if (ev.getSource() == sc_temp) { md.setContTemp( 1.0*(double)(sc_temp.getValue()) ); } } // mouse private void setMouse() { addMouseListener(this); addMouseMotionListener(this); } public void mousePressed(MouseEvent ev){ } public void mouseReleased(MouseEvent ev){ dgXb = 0; dgYb = 0; dgX = 0; dgY = 0; } public void mouseClicked(MouseEvent ev){ } public void mouseEntered(MouseEvent ev){ } public void mouseExited (MouseEvent ev){ } public void mouseMoved (MouseEvent ev){ } public void mouseDragged(MouseEvent ev){ dgXb = dgX; dgYb = dgY; dgX=ev.getX(); dgY=ev.getY(); if (dgXb==0 && dgYb==0) { dgXb = dgX; dgYb = dgY; } dsp.setViewDelta( (dgX-dgXb), (dgY-dgYb) ); } // ========================= run() - paint() loop ============== public void run() { while (th != null) { md.timeEvolution(); dsp.offPaint(); repaint(); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(imgOff,0,0,this); } } // ==================================== display 3D class =========== class Display3D { private MD3D md; private Graphics gOff; private int dispWidth = 630; private int dispHeight = 460; private int dispMode = 0; private double theta = -20.0*3.14/180.0; // rotation angle theta private double fai = 10.0*3.14/180.0; // rotation angle fai private double dispScale = (250.0/(6.0e-9)); // 250dots/6nm private double viewScale = 1.0; private int NN = MD3D.getNmt(); private int srtz[][] = new int[2][NN]; private double px[] = new double[NN]; private double py[] = new double[NN]; private double pz[] = new double[NN]; private double wkx[] = new double[8]; private double wky[] = new double[8]; private double wkz[] = new double[8]; private double pwkx[] = new double[8]; private double pwky[] = new double[8]; private double pwkz[] = new double[8]; private int boxp[][] = { {0,1},{0,2},{0,4},{1,3},{1,5},{2,3},{2,6},{4,5},{4,6},{3,7},{5,7},{6,7} }; // ------------------------------- class constructor ----------- Display3D(MD3D amd) { md = amd; } // ----------------------------------- class methods ----------- public void offPaint() { int gbx,gby; double sc; gOff.setColor(Color.white); gOff.fillRect(0,0,630,460); gbx = 80; gby = 120; if (dispMode==0) { ball3dPlot(gbx,gby,1.0,0); } else if (dispMode==1) { ball3dPlot(gbx,gby,0.5,1); } else if (dispMode==2) { ; } gOff.setColor(Color.blue); gOff.drawString("t="+(int)(md.getTime()*1.0e13+0.5)/10.0+" ps",10,40); gOff.setColor(Color.black); if (md.getStartSW()==0) { gOff.drawString("stopped",630/6*1+10,40); } else { gOff.drawString("started",630/6*1+10,40); } gOff.drawString("T cont.",630/6*3+10,40); gOff.drawString("Tc="+md.getContTemp()+" K",630/6*4+10,40); gOff.setColor(Color.blue); gOff.drawString("T="+(int)(md.getTemperature()*10+0.5)/10.0+" K",630/6*4+10,60); gOff.setColor(Color.black); 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+ " x "+(int)(md.getZMax()*1.0e10+0.5)/10.0+" nm",10,60); } // ------------------------------------ plot methods ----------- private void ball3dPlot(int gbx, int gby, double size, int mode) { int i,j,jj,gx,gy,gz,g2x,g2y, Nmt; double sc,sz; setWaku(); rotate(theta,fai); zSort(); Nmt = md.getNmt(); drawWaku(gbx,gby,0); sc = dispScale*viewScale; for (i=0; imd.getContTemp()) { gOff.setColor(Color.black); } else { gOff.setColor(Color.red); } } gOff.drawLine(gx,gy, g2x, g2y); } } } } private int findMin() { int i,im; double m; im = 0; m = pwkz[im]; for (i=0; i<8; i++) { if (pwkz[i]=srtz[1][p]) p = i; k = qSortPartition(i,j,srtz[1][p]); qSort(i,k-1); qSort(k,j); } } private int qSortPartition(int i,int j, int x) { int l,r,w; l = i; r = j; while (l<=r) { while (l<=j && srtz[1][l]=i && srtz[1][r]>=x) r--; if (l>r) break; w = srtz[0][l]; srtz[0][l] = srtz[0][r]; srtz[0][r] = w; w = srtz[1][l]; srtz[1][l] = srtz[1][r]; srtz[1][r] = w; l++; r--; } return l; } // ------------------------------------- I/O methods ----------- public void setGraphics(Graphics gg) { gOff = gg; } public void setViewDelta(double xDisplacement, double yDisplacement) { theta += 0.5*3.14/180.0*xDisplacement; fai += 0.5*3.14/180.0*yDisplacement; } public void setDispMode(int m) { dispMode = m; } public int getDispWidth() { return dispWidth; } public int getDispHeight() { return dispHeight; } } // ========================= molecular dynamics 3D class =========== class MD3D { private double t = 0.0; // time (s) private double dt = 10.0*1.0e-15; // time division (s) private double xMax = 6.0e-9; // x-Box size (m) private double yMax = 6.0e-9; // y-Box size (m) private double zMax = 6.0e-9; // z-Box size (m) private double sgm = 3.40e-10; // sigma of L-J potential for Ar (m) private double eps = 0.0104*1.602e-19; // epsilon of L-J potential for Ar (J) private double mas = 39.948*1.661e-27; // mass of L-J potential for Ar (kg) private int tempMode = 2; // 0-adiabatic 1-scaling 2-wall cont private double contTemp = 300.0; // control temperature (K) private static int Nmt = 125; // number of molecules private int NN = Nmt; // dimension of array private double xx[] = new double[NN]; // i-th molecules x-position private double yy[] = new double[NN]; // i-th molecules y-position private double zz[] = new double[NN]; // i-th molecules z-position private double vx[] = new double[NN]; // i-th molecules x-velocity private double vy[] = new double[NN]; // i-th molecules y-velocity private double vz[] = new double[NN]; // i-th molecules z-velocity private double ffx[] = new double[NN]; // i-th molecules x-force private double ffy[] = new double[NN]; // i-th molecules y-force private double ffz[] = new double[NN]; // i-th molecules z-force private int resetSW = 0; // 1-reset : reset and set resetSW = 0 private int startSW = 1; // 0-stop 1-start private int stepSW = 0; // 0-stop 1-step private int count = 0; // ------------------------------- class constructor ----------- MD3D() { setInitialCondition(); } // private void setInitialCondition() { int i,ix,iy,iz; double s; t = 0.0; count = 0; s = xMax/5.0; i = 0; for (ix=0; ix<5; ix++) { for (iy=0; iy<5; iy++) { for (iz=0; iz<5; iz++) { xx[i] = s*(ix+0.5); yy[i] = s*(iy+0.5); zz[i] = s*(iz+0.5); vx[i] = 500.0*(Math.random()-0.5); vy[i] = 500.0*(Math.random()-0.5); vz[i] = 500.0*(Math.random()-0.5); ffx[i] = 0.0; ffy[i] = 0.0; ffz[i] = 0.0; i += 1; } } } vAjustment(contTemp); } // ---------------------------------- time evolution ----------- public void timeEvolution() { int i; if (resetSW==1) { setInitialCondition(); resetSW = 0; } if (startSW==1) { timeStep20(); } else { if (stepSW==1) { timeStep20(); stepSW = 0; } } } private void timeStep20() { int i; if (tempMode==1) { vAjustment(contTemp); } for (i=0; i<20; i++) { timeStep(); } } private void timeStep() { int i; double dtv2, a; dtv2 = dt/2.0; t = t + dt; for (i=0; i1.2){ rr=1.2; }; } for (i=0; i xMax) { xx[i] = xMax; vx[i] = -rr*vx[i]; vy[i] = rr*vy[i]; vz[i] = rr*vz[i]; } if (yy[i] < 0.0) { yy[i] = 0.0; vx[i] = rr*vx[i]; vy[i] = -rr*vy[i]; vz[i] = rr*vz[i]; } if (yy[i] > yMax) { yy[i] = yMax; vx[i] = rr*vx[i]; vy[i] = -rr*vy[i]; vz[i] = rr*vz[i]; } if (zz[i] < 0.0) { zz[i] = 0.0; vx[i] = rr*vx[i]; vy[i] = rr*vy[i]; vz[i] = -rr*vz[i]; } if (zz[i] > zMax) { zz[i] = zMax; vx[i] = rr*vx[i]; vy[i] = rr*vy[i]; vz[i] = -rr*vz[i]; } } } // --------------------------------------- utilities ----------- private double temperature() { int i; double s,ke; s = 0.0; for (i=0; i