/* * icosa sand - dynamics 3D * * coded by Ikeuchi Mitsuru * ver 0.0.1 2005.12.11 created * ver 0.0.2 2006.02.04 change sort method (buble -> quick) * */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class icosaSandD3D extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener, AdjustmentListener, Runnable { /*-------------------------------------- define gloval -----*/ Choice ch_mat,ch_view; Button bt_reset, bt_startStop, bt_go; Scrollbar sc_gravity, sc_spin, sc_scale; Thread th = null; Dimension dim; Image imgOff; Graphics gOff; int sleepTime = 50; double t = 0.0; double dt = 2.5e-5; double xMax = 20.0*0.01; double yMax = 20.0*0.01; double zMax = 20.0*0.01; double zDepth = xMax; int Nmt = 10000; int NN = Nmt + 1; int Nsx = 20; int Nsy = 20; int Nsz = 20; double dispWidth = 250.0; double dispScale = (dispWidth/xMax); double viewScale = 1.0; int incRate = 20; int resetSW = 0; int started = 1; int dispMode = 0; double gravity = 9.8; double spin = 2.0; int MAT1 = 2; 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 = 0.01; double rc2 = rc*rc; double hh = rc/1000.0; double AU = 1.0e-3; double EE = 0.01; double AA = 0.001; double material[][] = { /* 0:mass(AU) 1:charge 2:D(EE) 3:A(/AA) 4:r0(AA) 5:color */ /*fixed*/ { 10.0 *AU, 0.0*EE, 0.1*EE, 2.0/AA, 8.0*AA, 0.85 }, /* 1 A */ { 5.0 *AU, 0.0*EE, 1.0*EE, 2.0/AA, 8.0*AA, 0.05 }, /* 2 B */ { 5.0 *AU, 0.0*EE, 5.0*EE, 2.0/AA, 8.0*AA, 0.15 }, /* 3 C */ { 10.0 *AU, 0.0*EE, 8.0*EE, 2.0/AA, 8.0*AA, 0.25 } }; String materialStr[] = { "A" ,"B","C" }; int NmatKind = 4; int kind[] = new int[NN]; double xx[] = new double[NN]; double yy[] = new double[NN]; double zz[] = new double[NN]; double vx[] = new double[NN]; double vy[] = new double[NN]; double vz[] = new double[NN]; double ffx[] = new double[NN]; double ffy[] = new double[NN]; double ffz[] = new double[NN]; int bond[][] = new int[NN][20]; int reg[][] = new int[NN][100]; int section[][][][] = new int[Nsx][Nsy][Nsz][30]; int srtz[][] = new int[2][NN]; double forceTable[][][] = new double[NmatKind][NmatKind][1020]; double dispColor[] = new double[NmatKind]; 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 control functions -----*/ public void init() { resize(630,400); setBackground(Color.white); dim = getSize(); imgOff = createImage(dim.width,dim.height); gOff = imgOff.getGraphics(); ch_mat = new Choice(); ch_mat.addItem("fixed"); ch_mat.addItem("A"); ch_mat.addItem("B"); ch_mat.addItem("C"); ch_mat.addItemListener(this); ch_mat.select("B"); ch_view = new Choice(); ch_view.addItem("ball"); ch_view.addItem("bond"); ch_view.addItem("ball+bond"); ch_view.addItem("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); bt_go= new Button("go"); bt_go.addActionListener(this); sc_gravity= new Scrollbar(Scrollbar.HORIZONTAL,98,10,0,510); sc_gravity.addAdjustmentListener(this); sc_spin= new Scrollbar(Scrollbar.HORIZONTAL,200,10,0,310); sc_spin.addAdjustmentListener(this); sc_scale= new Scrollbar(Scrollbar.HORIZONTAL,100,10,50,510); sc_scale.addAdjustmentListener(this); addMouseListener(this); addMouseMotionListener(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(bt_go); pnl.add(sc_gravity); pnl.add(sc_scale); pnl.add(ch_view); add(pnl,"North"); setInitialCondition(); } public void start() { if (th == null) { th = new Thread(this); th.start(); } } public void stop() { if (th != null) { th.stop(); th = null; } } public void itemStateChanged(ItemEvent ev){ if (ev.getSource() == ch_mat){ MAT1 = ch_mat.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_go){ gogogo(3); } } public void adjustmentValueChanged(AdjustmentEvent ev){ if (ev.getSource() == sc_gravity) { gravity = 0.1*(double)(sc_gravity.getValue()); } else if (ev.getSource() == sc_spin) { spin = 0.01*(double)(sc_spin.getValue()); } else if (ev.getSource() == sc_scale) { viewScale = 0.01*(double)(sc_scale.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); } public void run() { while (th != null) { try { timeEvolution(); offPaint(); repaint(); Thread.sleep(sleepTime); } catch (InterruptedException e) { } } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(imgOff,0,0,this); } /* ----------------------------- offPaint -------------------- */ void offPaint() { int gbx,gby,gx; gOff.setColor(Color.white); gOff.fillRect(0,0,dim.width,dim.height); rotate(theta,fai); zSort(); gbx = 70; gby = 90; if (dispMode==0) { ballPlot(gbx,gby, 1.2, 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) { velocity3DPlot(gbx,gby, 20.0,0); } else if (dispMode==4) { ; } else if (dispMode==5) { ; } /* potentialPlot(MAT1, MAT1); */ gbx = dim.width/6; gOff.setColor(Color.black); gOff.drawString("t="+(int)(t*10000.0+0.5)/10.0+" ms",gbx*0+10,40); if (started==1) { gOff.drawString("started",630/6*1+10,40); } else { gOff.drawString("stop",630/6*1+10,40); } gOff.setColor(Color.black); gOff.drawString("gravity="+(int)(gravity/9.8*100.0+0.5)/100.0+" g",gbx*3+10,40); gOff.drawString("scale="+(int)(viewScale*100.0+0.5)+"%",gbx*4+10,40); gOff.drawString("view",gbx*5+10,40); gx = 450; gOff.setColor(Color.black); gOff.drawString("Box="+(int)(xMax*1000.0+0.5)/10.0+" x "+(int)(yMax*1000.0+0.5)/10.0+" x "+(int)(zMax*1000.0+0.5)/10.0+" cm",gx,60); gOff.drawString("regMax="+regMax()+"",530,80); gOff.drawString("secMax="+secMax()+"",530,100); } /*------------------------------- 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,r,r0,col; drawWaku(gbx,gby,0); scl = dispScale*viewScale; sz = size*viewScale/AA; for (i=0; i0.66) col = 0.66; gOff.setColor(Color.getHSBColor((float)(col),0.5f,0.8f)); } else { gOff.setColor(Color.gray); } gOff.drawLine(gx,gy, g2x, g2y); } } } if (imode==0 || imode==2) { gOff.setColor(Color.getHSBColor( (float)material[kind[j]][5],0.8f,(float)(0.4*pz[j]/zDepth+0.3))); gOff.fillOval(gx-gr/2,gy-gr/2, gr, gr); } } drawWaku(gbx,gby,1); } void velocity3DPlot(int gbx, int gby, double mag, int imode) { int i,j,gx,gy,g2x,g2y,gr; double sc,sz,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; sz = 0.3*viewScale/AA; for (i=0; i0) { gOff.setColor(Color.blue); } else { gOff.setColor(Color.red); } gOff.drawLine(gx,gy, g2x,g2y); gOff.setColor(Color.getHSBColor( (float)material[kind[j]][5],0.8f,(float)(0.4*pz[j]/zDepth+0.3))); gOff.fillOval(gx-gr/2,gy-gr/2, gr, gr); } drawWaku(gbx,gby,1); } void drawWaku(int gbx, int gby, int imode) { int i,gx,gy,g2x,g2y,farPoint; double sc,tmp; sc = dispScale*viewScale; farPoint = findMin(); for (i=0; i<12; i++) { gx = (int)(sc*pwkx[boxp[i][0]])+gbx; gy = (int)(sc*pwky[boxp[i][0]])+gby; g2x = (int)(sc*pwkx[boxp[i][1]])+gbx; g2y = (int)(sc*pwky[boxp[i][1]])+gby; if (imode==0) { if (boxp[i][0]==farPoint || boxp[i][1]==farPoint) { gOff.setColor(Color.lightGray); gOff.drawLine(gx,gy, g2x, g2y); } } else if (imode==1) { if (boxp[i][0]!=farPoint && boxp[i][1]!=farPoint) { gOff.setColor(Color.black); 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 ); } /*------------------------------------- rotate ----------*/ 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; i=0.0) { if(v<200.0) { gOff.setColor(Color.green); gOff.drawLine(gx+i,gy-(int)(v),gx+i,gy); } } else { gOff.setColor(Color.pink); gOff.drawLine(gx+i,gy,gx+i,gy-(int)(v)); } } } /*------------------------------------- statictics ----------------*/ int regMax() { int i,m; m = 0; 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); } /*----------------------------- gogogo --------------*/ void gogogo(int mat) { int i; for(i=0;i0.045*0.045) i = setIcosahedron(i,x,y,z,mat); } } } return ( i ); } int setTetra(int ii, double xpos, double ypos, double zpos,int mat) { int i,ip; double a; i = ii; a = material[mat][4]; xx[i] = xpos; yy[i] = ypos; zz[i] = zpos; xx[i+1] = xpos-0.5774*a; yy[i+1] = ypos+0.8165*a; zz[i+1] = zpos; xx[i+2] = xpos+0.2887*a; yy[i+2] = ypos+0.8165*a; zz[i+2] = zpos+0.5*a; xx[i+3] = xpos+0.2887*a; yy[i+3] = ypos+0.8165*a; zz[i+3] = zpos-0.5*a; for (ip=0; ip<4; ip++) { kind[i+ip] = mat; vx[i+ip] = 0.01*(Math.random()-0.5); vy[i+ip] = 0.01*(Math.random()-0.5); vz[i+ip] = 0.01*(Math.random()-0.5); ffx[i+ip] = 0.0; ffy[i+ip] = 0.0; ffz[i+ip] = 0.0; } return ( i+4 ); } int setIcosahedron(int ii, double xpos, double ypos, double zpos,int mat) { int i,ip; double a,h,x; i = ii; a = material[mat][4]; x = 0.5*a/Math.sin(pai/5.0); h = Math.sqrt(a*a-x*x); xx[i] = xpos; yy[i] = ypos; zz[i] = zpos; for (ip=0; ip<5; ip++) { xx[i+1+ip] = xpos+h; yy[i+1+ip] = ypos+x*Math.cos(ip*2.0*pai/5.0); zz[i+1+ip] = zpos+x*Math.sin(ip*2.0*pai/5.0); } for (ip=0; ip<5; ip++) { xx[i+6+ip] = xpos+h+0.85*a; yy[i+6+ip] = ypos+x*Math.cos((ip+0.5)*2.0*pai/5.0); zz[i+6+ip] = zpos+x*Math.sin((ip+0.5)*2.0*pai/5.0); } xx[i+11] = xpos+2*h+0.85*a; yy[i+11] = ypos; zz[i+11] = zpos; for (ip=0; ip<12; ip++) { kind[i+ip] = mat; vx[i+ip] = 0.01*(Math.random()-0.5); vy[i+ip] = 0.01*(Math.random()-0.5); vz[i+ip] = 0.01*(Math.random()-0.5); ffx[i+ip] = 0.0; ffy[i+ip] = 0.0; ffz[i+ip] = 0.0; } return ( i+12 ); } int setBall(int ii, double xpos, double ypos, double zpos,int mat) { int i,ix,iy,iz,ir2; double a,r; i = ii; a = material[mat][4]*0.707; for (ix=-10; ix<=10; ix++) { for (iy=-10; iy<=10; iy++) { for (iz=-10; iz<=10; iz++) { if ((ix+iy+iz+100)%2==1) { ir2 = ix*ix+iy*iy+iz*iz; if (ir2<25) { r = Math.sqrt((double)ir2); kind[i] = mat; xx[i] = xpos+a*ix; yy[i] = ypos+a*iy; zz[i] = zpos+a*iz; vx[i] = 0.01*(Math.random()-0.5); vy[i] = 0.01*(Math.random()-0.5); vz[i] = 0.01*(Math.random()-0.5); ffx[i] = 0.0; ffy[i] = 0.0; ffz[i] = 0.0; i += 1; } } } } } return ( i ); } int setC60(int ii, double xpos, double ypos, double zpos,int mat) { int i,ip,iq; double a,h,x; double x0,y0,z0,x1,y1,z1; i = ii; a = 3.0*material[mat][4]; x0 = xpos; y0 = ypos; z0 = zpos; x = 0.5*a/Math.sin(pai/5.0); h = Math.sqrt(a*a-x*x); for (ip=0; ip<5; ip++) { x1 = xpos+h; y1 = ypos+x*Math.cos(ip*2.0*pai/5.0); z1 = zpos+x*Math.sin(ip*2.0*pai/5.0); i = interporate3(i, x0, y0, z0, x1, y1, z1, mat); } for (ip=0; ip<5; ip++) { x0 = xpos+h; y0 = ypos+x*Math.cos(ip*2.0*pai/5.0); z0 = zpos+x*Math.sin(ip*2.0*pai/5.0); x1 = xpos+h; y1 = ypos+x*Math.cos((ip+1)*2.0*pai/5.0); z1 = zpos+x*Math.sin((ip+1)*2.0*pai/5.0); i = interporate3(i, x0, y0, z0, x1, y1, z1, mat); } for (ip=0; ip<5; ip++) { x0 = xpos+h; y0 = ypos+x*Math.cos(ip*2.0*pai/5.0); z0 = zpos+x*Math.sin(ip*2.0*pai/5.0); x1 = xpos+h+0.85*a; y1 = ypos+x*Math.cos((ip+0.5)*2.0*pai/5.0); z1 = zpos+x*Math.sin((ip+0.5)*2.0*pai/5.0); i = interporate3(i, x0, y0, z0, x1, y1, z1, mat); x1 = xpos+h+0.85*a; y1 = ypos+x*Math.cos((ip-0.5)*2.0*pai/5.0); z1 = zpos+x*Math.sin((ip-0.5)*2.0*pai/5.0); i = interporate3(i, x0, y0, z0, x1, y1, z1, mat); } for (ip=0; ip<5; ip++) { x0 = xpos+h+0.85*a; y0 = ypos+x*Math.cos((ip+0.5)*2.0*pai/5.0); z0 = zpos+x*Math.sin((ip+0.5)*2.0*pai/5.0); x1 = xpos+h+0.85*a; y1 = ypos+x*Math.cos((ip+1.5)*2.0*pai/5.0); z1 = zpos+x*Math.sin((ip+1.5)*2.0*pai/5.0); i = interporate3(i, x0, y0, z0, x1, y1, z1, mat); } for (ip=0; ip<5; ip++) { x0 = xpos+h+0.85*a; y0 = ypos+x*Math.cos((ip+0.5)*2.0*pai/5.0); z0 = zpos+x*Math.sin((ip+0.5)*2.0*pai/5.0); x1 = xpos+2*h+0.85*a; y1 = ypos; z1 = zpos; i = interporate3(i, x0, y0, z0, x1, y1, z1, mat); } xx[i+11] = xpos+2*h+0.85*a; yy[i+11] = ypos; zz[i+11] = zpos; for (ip=0; ip<12; ip++) { kind[ii+ip] = mat; vx[ii+ip] = 0.01*(Math.random()-0.5); vy[ii+ip] = 0.01*(Math.random()-0.5); vz[ii+ip] = 0.01*(Math.random()-0.5); ffx[ii+ip] = 0.0; ffy[ii+ip] = 0.0; ffz[ii+ip] = 0.0; } return ( ii+60 ); } int interporate3(int ii, double x0, double y0, double z0,double x1, double y1, double z1,int mat) { int i, ip; i = ii; xx[i] = (2.0/3.0)*x0+(1.0/3.0)*x1; yy[i] = (2.0/3.0)*y0+(1.0/3.0)*y1; zz[i] = (2.0/3.0)*z0+(1.0/3.0)*z1; xx[i+1] = (1.0/3.0)*x0+(2.0/3.0)*x1; yy[i+1] = (1.0/3.0)*y0+(2.0/3.0)*y1; zz[i+1] = (1.0/3.0)*z0+(2.0/3.0)*z1; for (ip=0; ip<2; ip++) { kind[i+ip] = mat; vx[i+ip] = 0.01*(Math.random()-0.5); vy[i+ip] = 0.01*(Math.random()-0.5); vz[i+ip] = 0.01*(Math.random()-0.5); ffx[i+ip] = 0.0; ffy[i+ip] = 0.0; ffz[i+ip] = 0.0; } return ( i+2 ); } /*------- set forceTable[i][j][ir] -------*/ void setForceTable(){ int i,j,ir; double d,a,r0,y,r,sc; for (i=0; i=0.8*rc && r0) { a2 = dtv2/material[kind[i]][0]; vx[i] += a2*ffx[i]; vy[i] += a2*ffy[i]; vz[i] += a2*ffz[i]; xx[i] += vx[i]*dt; yy[i] += vy[i]*dt; zz[i] += vz[i]*dt; } } forceCalc(); for (i=0; i0) { a2 = dtv2/material[kind[i]][0]; vx[i] += a2*ffx[i]; vy[i] += a2*ffy[i]; vz[i] += a2*ffz[i]; } } rr = 0.9; 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]; } } } void forceCalc() { int i,j,k; double r2,rij,f,fxij,fyij,fzij; for(i=0;i=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; } } /*----- end of molecules motion -----*/ } /*----- end of applet -----*/