/** applet No. 1014 * * sectiom profile - molecular dynamics 3D * * Created by Ikeuchi Mitsuru on September 09 2006. * Copyright (c) 2006-2007 Ikeuchi Mitsuru. All rights reserved. * * ver 0.0.1 2006.09.09 created * ver 0.0.2 2006.09.10 view (added section thickness) improved * ver 0.0.3 2006.09.13 added NN selectiom (8^3 - 16^3) * ver 0.0.4 2006.09.15 bug fixed * ver 0.0.5 2006.09.16 added neighbor statistics * ver 0.0.6 2006.11.26 added N=343 selection * ver 0.0.7 2007.06.08 improved code * */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class sectionProfleMD3D extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener, AdjustmentListener, Runnable { // ------------------------------------ preset field ----------- Thread th = null; // for run()-paint() thread // for event Choice ch_mat,ch_nCube,ch_tempControl,ch_view; Button bt_reset, bt_startStop, bt_step; Scrollbar sc_temp,sc_scale,sc_zSection,sc_zThick; // for off-paint buffer Dimension dim; Image imgOff; Graphics gOff; int sleepTime = 30; double t = 0.0; // time (s) double dt = 10.0*1.0e-15; // time division (s) double xMax = 10.0*1.0e-9; // x-Box size in (m) double yMax = 10.0*1.0e-9; // y-Box size in (m) double zMax = 10.0*1.0e-9; // z-Box size in (m) double zDepth = 10.0*1.0e-9; int nCube = 8; int Nmt = nCube*nCube*nCube; int Nsx = 20; int Nsy = 20; int Nsz = 20; double dispWidth = 250.0; double dispScale = (dispWidth/xMax); double viewScale = 1.0; int resetSW = 0; int started = 1; int stepSW = 0; int dispMode = 3; int tempMode = 2; double contTemp = 300.0; double zSection = 1.0; double zThick = 1.0; int dgX, dgY, dgXb,dgYb; double cx = 0.5*xMax; double cy = 0.5*yMax; double cz = 0.5*zMax; double theta = -20.0*3.14/180.0; double fai = 10.0*3.14/180.0; double dtheta = 0.0*3.14/180.0; double pai = 3.1415926536; double rc = 1.0e-9; double rc2 = rc*rc; double AU = 1.661e-27; double EE = 1.602e-19; double AA = 1.0e-10; double Morse[][] = { /* 0:mass 1:charge 2:D(eV) 3:A(A^-1) 4:r0(A) 5:color */ /* 0 W */ {183.85 *AU, 0.0*EE, 0.9906*EE, 1.4116/AA, 3.032*AA, 0.30 }, /* 1 Mo*/ { 95.94 *AU, 0.0*EE, 0.8032*EE, 1.5079/AA, 2.976*AA, 0.33 }, /* 2 Cr*/ { 51.996*AU, 0.0*EE, 0.4414*EE, 1.5721/AA, 2.754*AA, 0.36 }, /* 3 Fe*/ { 55.847*AU, 0.0*EE, 0.4174*EE, 1.3885/AA, 2.845*AA, 0.39 }, /* 4 Ni*/ { 58.71 *AU, 0.0*EE, 0.4205*EE, 1.4199/AA, 2.780*AA, 0.42 }, /* 5 Al*/ { 26.98 *AU, 0.0*EE, 0.2703*EE, 1.1646/AA, 3.253*AA, 0.45 }, /* 6 Pb*/ {207.19 *AU, 0.0*EE, 0.2348*EE, 1.1836/AA, 3.733*AA, 0.48 }, /* 7 Cu*/ { 63.54 *AU, 0.0*EE, 0.3429*EE, 1.3588/AA, 2.866*AA, 0.20 }, /* 8 Ag*/ {107.87 *AU, 0.0*EE, 0.3323*EE, 1.3690/AA, 3.115*AA, 0.24 }, /* 9 Ca*/ { 40.08 *AU, 0.0*EE, 0.1623*EE, 0.8054/AA, 4.569*AA, 0.13 }, /*10 Sr*/ { 87.62 *AU, 0.0*EE, 0.1513*EE, 0.7878/AA, 4.988*AA, 0.16 }, /*11 Ba*/ {137.34 *AU, 0.0*EE, 0.1416*EE, 0.6570/AA, 5.373*AA, 0.19 }, /*12 Na*/ { 22.99 *AU, 0.0*EE, 0.0633*EE, 0.5900/AA, 5.336*AA, 0.01 }, /*13 K */ { 39.102*AU, 0.0*EE, 0.0542*EE, 0.4977/AA, 6.369*AA, 0.04 }, /*14 Rb*/ { 85.47 *AU, 0.0*EE, 0.0464*EE, 0.4298/AA, 7.207*AA, 0.07 }, /*15 Cs*/ {132.905*AU, 0.0*EE, 0.0449*EE, 0.4157/AA, 7.557*AA, 0.10 }, /*16 Ne*/ { 20.183*AU, 0.0*EE, 0.0031*EE, 1.6500/AA, 3.076*AA, 0.56 }, /*17 Ar*/ { 39.948*AU, 0.0*EE, 0.0104*EE, 1.3400/AA, 3.816*AA, 0.60 }, /*18 Kr*/ { 83.80 *AU, 0.0*EE, 0.0141*EE, 1.2500/AA, 4.097*AA, 0.64 }, /*19 Xe*/ {131.30 *AU, 0.0*EE, 0.0200*EE, 1.2400/AA, 4.467*AA, 0.68 }, /*20 Hg*/ {200.59 *AU, 0.0*EE, 0.0734*EE, 1.4900/AA, 3.255*AA, 0.72 } }; String material[] = { "W" ,"Mo","Cr","Fe","Ni","Al","Pb","Cu","Ag","Ca", "Sr","Ba","Na","K" ,"Rb","Cs","Ne","Ar","Kr","Xe","Hg" }; int NmatKind = 21; int MAT1 = 17; int NN = 5000; int kind[] = new int[NN]; // i-th molec kind double xx[] = new double[NN]; // i-th x-position double yy[] = new double[NN]; // i-th y-position double zz[] = new double[NN]; // i-th z-position double vx[] = new double[NN]; // i-th x-velocity double vy[] = new double[NN]; // i-th y-velocity double vz[] = new double[NN]; // i-th z-velocity double ffx[] = new double[NN]; // i-th x-force double ffy[] = new double[NN]; // i-th y-force double ffz[] = new double[NN]; // i-th z-force int reg[][] = new int[NN][750]; // registration int section[][][][] = new int[Nsx][Nsy][Nsz][300]; double hh = 1.0e-12; double forceTable[][][] = new double[NmatKind][NmatKind][1020]; int srtz[][] = new int[2][NN]; // z-sort work space double dispColor[] = new double[NmatKind]; int neighbor[] = new int[NN]; double neighborColor[] = { 0.65, 0.60, 0.55, 0.50, 0.45, 0.40, 0.35, 0.30, 0.25, 0.20, 0.15, 0.10, 0.05, 0.05, 0.05, 0.01, 0.01, 0.01, 0.01, 0.01 }; int neighborDistance[][] = new int[16][30]; double px[] = new double[NN]; double py[] = new double[NN]; double pz[] = new double[NN]; double wkx[] = new double[8]; double wky[] = new double[8]; double wkz[] = new double[8]; double pwkx[] = new double[8]; double pwky[] = new double[8]; double pwkz[] = new double[8]; 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} }; int rdf[] = new int[120]; int vdf[] = new int[220]; double virial[][] = new double[3][256]; double memTemp[] = new double[256]; int virialp = 0; // ------------------------------ applet main thread ----------- public void init() { resize(630,460); setBackground(Color.white); dim = getSize(); imgOff = createImage(dim.width,dim.height); gOff = imgOff.getGraphics(); ch_mat = new Choice(); /* ch_mat.add("W"); ch_mat.add("Mo"); ch_mat.add("Cr"); ch_mat.add("Fe"); ch_mat.add("Ni"); ch_mat.add("Al"); ch_mat.add("Pb"); ch_mat.add("Cu"); ch_mat.add("Ag"); ch_mat.add("Ca"); ch_mat.add("Sr"); ch_mat.add("Ba"); ch_mat.add("Na"); ch_mat.add("K"); ch_mat.add("Rb"); ch_mat.add("Cs"); */ ch_mat.add("Ne"); ch_mat.add("Ar"); ch_mat.add("Kr"); ch_mat.add("Xe"); ch_mat.add("Hg"); ch_mat.addItemListener(this); ch_mat.select("Ar"); ch_nCube = new Choice(); ch_nCube.add("N=343"); ch_nCube.add("N=512"); ch_nCube.add("N=729"); ch_nCube.add("N=1000"); ch_nCube.add("N=1331"); ch_nCube.add("N=1728"); ch_nCube.add("N=2197"); ch_nCube.add("N=2744"); ch_nCube.add("N=3375"); ch_nCube.add("N=4096"); ch_nCube.addItemListener(this); ch_nCube.select("N=512"); ch_tempControl = new Choice(); ch_tempControl.add("adiabatic"); ch_tempControl.add("t scaling"); ch_tempControl.add("wall cont."); ch_tempControl.addItemListener(this); ch_tempControl.select("wall cont."); ch_view = new Choice(); ch_view.add("ball"); ch_view.add("line"); ch_view.add("ball+line"); ch_view.add("real size"); ch_view.add("temperature"); ch_view.add("velocity"); ch_view.add("momentum"); ch_view.add("line+rdf"); ch_view.add("v+vdf"); ch_view.add("neighbor"); ch_view.addItemListener(this); ch_view.select("real size"); 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); sc_temp = new Scrollbar(Scrollbar.HORIZONTAL,300,10,10,610); sc_temp.addAdjustmentListener(this); sc_scale = new Scrollbar(Scrollbar.HORIZONTAL,100,10,50,510); sc_scale.addAdjustmentListener(this); sc_zSection = new Scrollbar(Scrollbar.HORIZONTAL,100,10,10,110); sc_zSection.addAdjustmentListener(this); sc_zThick = new Scrollbar(Scrollbar.HORIZONTAL,100,10,10,110); sc_zThick.addAdjustmentListener(this); addMouseListener(this); addMouseMotionListener(this); setLayout(new BorderLayout()); Panel pnl = new Panel(); pnl.setLayout(new GridLayout(2,6,5,0)); // pnl.add(new Label(" ")); pnl.add(ch_nCube); pnl.add(bt_reset); pnl.add(bt_startStop); pnl.add(bt_step); pnl.add(new Label(" section ")); pnl.add(ch_view); pnl.add(ch_mat); pnl.add(ch_tempControl); pnl.add(sc_temp); pnl.add(sc_scale); pnl.add(sc_zSection); pnl.add(sc_zThick); add(pnl,"North"); setForceTable(); setInitialCondition(); } public void start() { if (th == null) { th = new Thread(this); th.start(); } } public void stop() { if (th != null) th = null; } // ---------------------------------- event listener ----------- public void itemStateChanged(ItemEvent ev){ if (ev.getSource() == ch_mat){ MAT1 = 16 + ch_mat.getSelectedIndex(); setInitialCondition(); } else if (ev.getSource() == ch_nCube) { nCube = 7 + ch_nCube.getSelectedIndex(); Nmt = nCube*nCube*nCube; setInitialCondition(); } else if (ev.getSource() == ch_tempControl) { tempMode = ch_tempControl.getSelectedIndex(); } else if (ev.getSource() == ch_view){ dispMode = ch_view.getSelectedIndex(); } } public void actionPerformed(ActionEvent ev){ if(ev.getSource() == bt_reset){ resetSW = 1; } else if (ev.getSource() == bt_startStop){ if (started==0) { started = 1; } else { started = 0; } } else if (ev.getSource() == bt_step){ if (started==0) stepSW = 1; } } public void adjustmentValueChanged(AdjustmentEvent ev){ if (ev.getSource() == sc_temp) { contTemp = 1.0*(double)(sc_temp.getValue()); vAjustment(); } else if(ev.getSource() == sc_scale) { viewScale = 0.01*(double)(sc_scale.getValue()); } else if(ev.getSource() == sc_zSection) { zSection = 0.01*(double)(sc_zSection.getValue()); } else if(ev.getSource() == sc_zThick) { zThick = 0.01*(double)(sc_zThick.getValue()); } } 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; } theta += 0.5*3.14/180.0*(dgX-dgXb); fai += 0.5*3.14/180.0*(dgY-dgYb); } // ========================= run() - paint() loop ============== public void run() { while (th != null) { timeEvolution(); 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); } // --------------------------------------- off-paint ----------- void offPaint() { int gbx,gby; double tmp; gOff.setColor(Color.white); gOff.fillRect(0,0,dim.width,dim.height); rotate(theta,fai); zSort(); tmp = temperature(); gbx = 70; gby = 140; if (dispMode==0) { ballPlot(gbx,gby, 0.7, 0); } else if (dispMode==1) { ballPlot(gbx,gby, 0.5, 1); } else if (dispMode==2) { ballPlot(gbx,gby, 0.5, 2); } else if (dispMode==3) { ballPlot(gbx,gby, 1.0, 0); } else if (dispMode==4) { ballPlot(gbx,gby, 1.0, 3); } else if (dispMode==5) { velocity3DPlot(gbx,gby, 10.0,0); } else if (dispMode==6) { velocity3DPlot(gbx,gby, 10.0,1); } else if (dispMode==7) { ballPlot(gbx,gby, 0.5, 1); rdfPlot(400,140, 1.0*512.0/Nmt); } else if (dispMode==8) { velocity3DPlot(gbx,gby, 10.0,0); vdfPlot(400,140, 10.0*512.0/Nmt,MAT1); } else if (dispMode==9) { neighborPlot(gbx,gby, 0.7, 0); } gbx = dim.width/6; gOff.setColor(Color.black); gOff.drawString("t="+(int)(t*1.0e13+0.5)/10.0+" ps",gbx*0+10,70); gOff.drawString("temp control",gbx*1+10,70); gOff.setColor(Color.black); gOff.drawString("cont T="+contTemp+"K",gbx*2+10,70); gOff.drawString("scale="+(int)(viewScale*100.0+0.5)+"%",gbx*3+10,70); gOff.drawString("view(d="+(int)(zSection*100.0+0.5)/100.0+")",gbx*4+10,70); gOff.drawString("thick="+(int)(zThick*100.0+0.5)/100.0+" ",gbx*5+10,70); gOff.drawString("secton depth and thickness",gbx*4+0,90); gOff.setColor(Color.blue); gOff.drawString("T="+(int)(tmp*10+0.5)/10.0+" K",gbx*2+10,90); gOff.drawString("L="+(int)(xMax*1.0e10+0.5)/10.0+" nm",gbx*3+10,90); gOff.drawString("P="+(int)(pressure()/1.0e4+0.5)/100.0+"MPa",gbx*4+0,110); gOff.drawString("

="+(int)(meanPressure()/1.0e4+0.5)/100.0+"MPa",gbx*4+0,130); gOff.drawString("nkT="+(int)((Nmt/(xMax*yMax*zMax)*1.38e-23*tmp)/1.0e4+0.5)/100.0+"MPa",gbx*4+0,150); //gOff.setColor(Color.black); //gOff.drawString("regMax="+regMax()+"",gbx*5+10,100); //gOff.drawString("secMax="+secMax()+"",gbx*5+10,120); } // ------------------------------------ plot methods ----------- void ballPlot(int gbx, int gby, double size, int imode) { int i,j,k,jj,gx,gy,g2x,g2y,gr; double sz,scl,tm,rrr,col; drawWaku(gbx,gby,0); scl = dispScale*viewScale; sz = size*scl; for (i=0; izSection*zMax || zz[j]<(zSection-zThick)*zMax) continue; gx = (int)(scl*px[j])+gbx; gy = (int)(scl*py[j])+gby; gr = (int)(sz*Morse[kind[j]][4]*(0.2*(pz[j]/zDepth)+0.8)); if (gr<2) gr = 2; if (imode==1 || imode==2) { for (k=1; k0.99) tm = 0.99; gOff.setColor(Color.getHSBColor( 0.15f,0.8f,(float)(0.8*tm+0.2))); gOff.fillOval(gx-gr/2,gy-gr/2, gr, gr); } } drawWaku(gbx,gby,1); } double distance(int j, int jj) { double r2; r2 = (xx[j]-xx[jj])*(xx[j]-xx[jj])+(yy[j]-yy[jj])*(yy[j]-yy[jj])+(zz[j]-zz[jj])*(zz[j]-zz[jj]); return ( Math.sqrt(r2) ); } void setNeighbor() { int i,j,k,nb1,nb2; double rrr; for (i=0; izSection*zMax || zz[j]<(zSection-zThick)*zMax) continue; gx = (int)(scl*px[j])+gbx; gy = (int)(scl*py[j])+gby; gr = (int)(sz*Morse[kind[j]][4]*(0.2*(pz[j]/zDepth)+0.8)); if (gr<2) gr = 2; if (imode==1 || imode==2) { for (k=1; k0.99) tm = 0.99; gOff.setColor(Color.getHSBColor( 0.15f,0.8f,(float)(0.8*tm+0.2))); gOff.fillOval(gx-gr/2,gy-gr/2, gr, gr); } } drawWaku(gbx,gby,1); neighborTable(400, 200); } void neighborTable(int gbx, int gby) { int i,j,n; gOff.setColor(Color.black); for (j=16; j<24; j+=2) { gOff.drawString(""+(int)(j*100.0/20.0)/100.0+"-",gbx+(j-14)*20,gby); } for (i=1; i<=12; i++) { gOff.drawString("("+i+")",gbx,gby+20*i); for (j=16; j<24; j+=2) { n = neighborDistance[i][j] + neighborDistance[i][j+1]; gOff.drawString(""+n+"",gbx+(j-14)*20,gby+20*i); } } } void velocity3DPlot(int gbx, int gby, double mag, int imode) { int i,j,gx,gy,g2x,g2y; double sc,m,p2x,p2y,p2z,rotp2x,rotp2y,rotp2z; double cosTh,sinTh,cosFi,sinFi; drawWaku(gbx,gby,0); cosTh = Math.cos(theta); sinTh = Math.sin(theta); cosFi = Math.cos(fai); sinFi = Math.sin(fai); sc = dispScale*viewScale; for (i=0; icontTemp) { gOff.setColor(Color.black); } else { gOff.setColor(Color.red); } } gOff.drawLine(gx,gy, g2x, g2y); } } } } 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); } } 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 ); } // void rotate(double th,double fi) { int i; double cosTh,sinTh,cosFi,sinFi; cosTh = Math.cos(th); sinTh = Math.sin(th); cosFi = Math.cos(fi); sinFi = Math.sin(fi); for (i=0; i0) { gOff.fillRect(gx+i*2,gy+hoganHight-iy,2,iy); } } drawHogan(gx, gy, hoganWidth, hoganHight, xDiv, yDiv); gOff.setColor(Color.black); gOff.drawString("0",gx-5,gy+hoganHight+20); gOff.drawString("1 (nm)",gx+hoganWidth-20,gy+hoganHight+20); gOff.drawString("radial distribution",gx+40,gy+hoganHight+40); } void drawHogan(int gx, int gy, int hoganWidth, int hoganHight, int xDiv, int yDiv) { int i; gOff.setColor(Color.gray); for (i=0; i=0) { gOff.setColor(Color.getHSBColor((float)Morse[knd][5],0.8f,0.8f)); } for (i=0; i<200; i++) { iy = (int)(mag*vdf[i]); if (iy>0) { gOff.drawLine(gx+i,ghy-iy,gx+i,ghy); } } } void setVelocityDistribution(int knd) { int i,iv; double v2,vv; for (i=0; i<220; i++) { vdf[i]=0; } for (i=0; i=0.8*rc && r1.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]; } } } // registration void registration() { int i,j,k,ip,jp,kp,i0,i1,j0,j1,k0,k1,iq; double r2,rreg,rreg2; double x,y,z; preRegistration(); rreg = rc + 3000.0*20*dt; rreg2 = rreg*rreg; for(ip=0;ip=Nsx) i1 = Nsx-1; j0 = (int)(Nsy*(yy[ip]-rreg)/yMax); if (j0<0) j0 = 0; j1 = (int)(Nsy*(yy[ip]+rreg)/yMax); if (j1>=Nsy) j1 = Nsy-1; k0 = (int)(Nsz*(zz[ip]-rreg)/zMax); if (k0<0) k0 = 0; k1 = (int)(Nsz*(zz[ip]+rreg)/zMax); if (k1>=Nsz) k1 = Nsz-1; for(i=i0;i<=i1;i++) { for(j=j0;j<=j1;j++) { for(k=k0;k<=k1;k++) { for(iq=1;iq<=section[i][j][k][0];iq++) { jp = section[i][j][k][iq]; if (jp>ip) { r2=(xx[ip]-xx[jp])*(xx[ip]-xx[jp])+(yy[ip]-yy[jp])*(yy[ip]-yy[jp])+(zz[ip]-zz[jp])*(zz[ip]-zz[jp]); if (r2=Nsx) i = Nsx-1; j = (int)(Nsy*yy[ip]/yMax); if (j>=Nsy) j = Nsy-1; k = (int)(Nsz*zz[ip]/zMax); if (k>=Nsz) k = Nsz-1; iq = section[i][j][k][0]+1; section[i][j][k][0] = iq; section[i][j][k][iq] = ip; } } // --------------------------------------- utilities ----------- void vAjustment() { int i; double tmp, r; tmp = temperature(); r = Math.sqrt(contTemp/tmp); for (i=0; im) { m = reg[i][0]; } } return(m); } int secMax() { int i,j,k,m; m = 0; for(i=0;im) { m = section[i][j][k][0]; } } } } return(m); } // pressure void initVirial() { int i; for (i=0; i<256; i++) { virial[0][i] = 0.0; virial[1][i] = 0.0; virial[2][i] = 0.0; memTemp[i] = 0.0; } virialp = 0; } void setVirial() { int i; double xVir,yVir,zVir; xVir = 0.0; yVir = 0.0; zVir = 0.0; for (i=0; i