/* diffusion - direct simulation Monte Carlo method 2D */ /* coded by Ikeuchi Mitsuru */ /* ver 0.0.1 2005.09.18 */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class diffusionDSMC2D extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener, AdjustmentListener, Runnable { /* -------------------------------------- set global ------ */ Button bt_reset, bt_startStop, bt_dye; Choice ch_col,ch_view; Scrollbar sc_adsorption, sc_scale; Thread th = null; Dimension dim; Image imgOff; Graphics gOff; int sleepTime = 50; double t = 0.0; double dt = 1.0e-7;/* s */ double dx = 1.0e-3;/* m */ double dy = 1.0e-3;/* m */ double vvc = dx*dy; int Nsx = 100; int Nsy = 20; double xMax = Nsx*dx; double yMax = Nsy*dy; double ffn = 2.0e4; double sgm = 4.0*3.0e-10; int dispMode = 3; int resetSW = 0; int started = 1; int incRate = 1; double dispScale = (400.0/xMax); double scale = 1.0; double adsorptionEnergy = 0.1; /* eV */ int collisionMode = 1; int dispWidth = 630; int dispHeight = 320; int dgX, dgY, dgXb, dgYb; double xShift = 0.0; double yShift = 0.0; int NNp = Nsx*Nsy*30; int kind[] = new int [NNp]; double mass[] = new double [NNp]; double xx[] = new double [NNp]; double yy[] = new double [NNp]; double vx[] = new double [NNp]; double vy[] = new double [NNp]; int mark[] = new int [NNp]; int section[][][] = new int [Nsx][Nsy][200]; int cellAttribute[][] = new int [Nsx][Nsy]; double density[][] = new double [Nsx][Nsy]; double temperature[][] = new double [Nsx][Nsy]; double pressure[][] = new double [Nsx][Nsy]; int vDistribution[] = new int [200]; int vSpace[][] = new int [250][250]; /* ----------------------------- applet control ------ */ public void init() { resize(dispWidth,dispHeight); setBackground(Color.white); dim = getSize(); imgOff = createImage(dim.width,dim.height); gOff = imgOff.getGraphics(); bt_reset= new Button("reset"); bt_reset.addActionListener(this); bt_startStop= new Button("start/stop"); bt_startStop.addActionListener(this); bt_dye= new Button("dyeing"); bt_dye.addActionListener(this); ch_col = new Choice(); ch_col.addItem("null"); ch_col.addItem("rigid sphere"); ch_col.addItemListener(this); ch_col.select("rigid sphere"); ch_view = new Choice(); ch_view.addItem("particle"); ch_view.addItem("collision"); ch_view.addItem("velocity"); ch_view.addItem("sample 1000"); ch_view.addItem("veloc. 1000"); ch_view.addItem("density"); ch_view.addItem("mean flow"); ch_view.addItem("v space"); ch_view.addItem("temperature"); ch_view.addItem("pressure"); ch_view.addItemListener(this); ch_view.select("sample 1000"); sc_adsorption= new Scrollbar(Scrollbar.HORIZONTAL,100,10,0,160); sc_adsorption.addAdjustmentListener(this); sc_scale= new Scrollbar(Scrollbar.HORIZONTAL,100,10,50,1010); 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(ch_col); pnl.add(bt_dye); 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_view) { dispMode = ch_view.getSelectedIndex(); } else if (ev.getSource() == ch_col) { collisionMode = ch_col.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_dye){ dyeing(); t = 0.0; } } public void adjustmentValueChanged(AdjustmentEvent ev){ if (ev.getSource() == sc_adsorption) { adsorptionEnergy = 0.001*sc_adsorption.getValue(); } else if (ev.getSource() == sc_scale) { scale = 0.01*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; } xShift += (1.0/scale/dispScale)*(dgX-dgXb); yShift += (1.0/scale/dispScale)*(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 gx, gbx, gby; double sc; gOff.setColor(Color.white); gOff.fillRect(0,0,dim.width,dim.height); sc = scale*dispScale; gbx = 15+(int)(sc*xShift); gby = 60+(int)(sc*yShift); gOff.setColor(Color.getHSBColor(0.33f,0.9f,0.8f)); kindDistributionPlot(gbx, gby+80, 1, 0.1); gOff.setColor(Color.getHSBColor(0.15f,0.9f,0.8f)); kindDistributionPlot(gbx, gby+150, 2, 0.1); gOff.setColor(Color.black); gOff.drawRect(gbx,gby,(int)(sc*xMax+0.5),(int)(sc*yMax+0.5)); if (dispMode==0) { drawBlock(gbx,gby,sc); ovalPlot(gbx,gby,sc,NNp); } else if (dispMode==1) { drawBlock(gbx,gby,sc); markPlot(gbx,gby,sc); } else if (dispMode==2) { drawBlock(gbx,gby,sc); velosityPlot(gbx,gby,sc,NNp,20.0); } else if (dispMode==3) { drawBlock(gbx,gby,sc); ovalPlot(gbx,gby,sc,1000); } else if (dispMode==4) { drawBlock(gbx,gby,sc); velosityPlot(gbx,gby,sc,1000,20.0); } else if (dispMode==5) { densityPlot(gbx,gby,sc); drawBlock(gbx,gby,sc); } else if (dispMode==6) { drawBlock(gbx,gby,sc); meanflowPlot(gbx,gby,sc,5.0); } else if (dispMode==7) { vSpacePlot(gbx,gby,0.1); } else if (dispMode==8) { setField(); fieldPlot(temperature,gbx,gby,sc,0.001); drawBlock(gbx,gby,sc); } else if (dispMode==9) { setField(); fieldPlot(pressure,gbx,gby,sc,2.0e8); drawBlock(gbx,gby,sc); } else if (dispMode==10) { ; } /* gOff.setColor(Color.blue); vDistributionPlot(410,110,0.05); */ gOff.setColor(Color.black); gOff.drawString("t="+(int)(t*1.0e6*1000.0+0.5)/1000.0+" us",630/6*0+10,40); if (started==1) { gOff.drawString("started",630/6*1+10,40); } else { gOff.drawString("stopped",630/6*1+10,40); } gOff.drawString("collision",630/6*2+10,40); gOff.drawString("scale="+(int)(scale*100.0)/100.0+" ",630/6*4+10,40); gOff.drawString("view",630/6*5+10,40); gx = 430; gOff.drawString("Lx="+(float)(xMax*1000.0)+"(mm), Ly="+(float)(yMax*1000.0)+"(mm)",gx,60); gOff.drawString("max Nc="+maxSection()+"",gx,80); gOff.drawString("N="+NNp+", FN="+(float)ffn+"",gx,100); gOff.drawString("cross section = "+(float)(sgm)+"(1/m^2)",gx,120); gOff.drawString("vmax="+(float)maxSpeed()+"(m/s)",gx,140); gOff.drawString("Etot="+(float)totalKineticEnergy()+"(J)",gx,160); } /*------------------------- plot methods -------------------*/ void ovalPlot(int gx, int gy, double sc,int Nsample) { int i,ir; ir = 2; for (i=0; i0) { ix = gx+(int)(xx[i]*sc+0.5); iy = gy+(int)(yy[i]*sc+0.5); if (vx[i]>0.0) { gOff.setColor(Color.getHSBColor(0.66f,0.8f,0.8f)); } else { gOff.setColor(Color.getHSBColor(0.01f,0.8f,0.8f)); } ix2 = ix+(int)(vx[i]*dt*sc*mag+0.5); iy2 = iy+(int)(vy[i]*dt*sc*mag+0.5); gOff.drawLine(ix,iy,ix2,iy2); } } } void densityPlot(int gx, int gy, double sc) { int ix,iy,iss; double ss; ss = sc*xMax/(double)Nsx; iss = (int)(ss+0.999); for (ix=0; ix0.0) { gOff.setColor(Color.getHSBColor(0.66f,0.8f,0.8f)); } else { gOff.setColor(Color.getHSBColor(0.01f,0.8f,0.8f)); } igx2 = igx+(int)(mvx*dt*sc*mag+0.5); igy2 = igy+(int)(mvy*dt*sc*mag+0.5); gOff.drawLine(igx,igy,igx2,igy2); } } } void fieldPlot(double fld[][], int gx, int gy, double sc, double mag) { int ix,iy,iss; double ss,f; ss = sc*xMax/(double)Nsx; iss = (int)(ss+0.999); for (ix=0; ix0.999) f = 0.999; gOff.setColor(Color.getHSBColor((float)(0.66-0.66*f),0.9f,0.9f)); gOff.fillRect(gx+(int)(ss*ix+0.5),gy+(int)(ss*iy+0.5), iss, iss); } } } void vSpacePlot(int gx, int gy, double mag) { int i,j; double f; setVSpace(); gOff.setColor(Color.getHSBColor(0.66f,0.9f,0.9f)); gOff.fillRect(gx,gy,250,250); for (i=0; i<250; i++) { for (j=0; j<250; j++) { f = vSpace[i][j]*mag; if (f>0.999) f = 0.999; if (f>0.0) { gOff.setColor(Color.getHSBColor((float)(0.66-0.66*f),0.9f,0.9f)); gOff.fillRect(gx+i,gy+j,1,1); } } } gOff.setColor(Color.yellow); gOff.drawLine(gx,gy+125,gx+250,gy+125); gOff.drawLine(gx+125,gy,gx+125,gy+250); } void vDistributionPlot(int gx, int gy, double yMag) { int i; setVelocityDistribution(); for (i=0; i<200; i++) { gOff.drawLine(gx+i,gy+200,gx+i,gy+200-(int)(yMag*vDistribution[i])); } } void drawBlock(int gx, int gy, double sc) { int ix,iy,iss,ca; double ss; ss = sc*xMax/(double)Nsx; iss = (int)(ss+0.999); for (ix=0; ix0) { if (ca==1) { gOff.setColor(Color.getHSBColor(0.85f,0.9f,0.9f)); } else if (ca==2) { gOff.setColor(Color.getHSBColor(0.85f,0.9f,0.2f)); } else if (ca==3) { gOff.setColor(Color.getHSBColor(0.85f,0.9f,0.5f)); } gOff.fillRect(gx+(int)(ss*ix+0.5),gy+(int)(ss*iy+0.5), iss, iss); } } } } void kindDistributionPlot(int gx, int gy, int knd, double yMag) { int n,nnc,ix,iy,ip,j; for (ix=0; ix0) { v2 = vx[i]*vx[i]+vy[i]*vy[i]; if (v2>vm2) vm2 = v2; } } return( Math.sqrt(vm2) ); } double totalKineticEnergy() { int i; double tke; tke = 0.0; for(i=0;i0) { tke += 0.5*mass[i]*(vx[i]*vx[i]+vy[i]*vy[i]); } } return( ffn*tke ); } int numberOfPartickes(int knd) { int i,n; n = 0; for(i=0;i0) { v = Math.sqrt(vx[i]*vx[i]+vy[i]*vy[i]); if (v>1999.0) v = 1999.0; vDistribution[(int)(v/10.0)] += 1; } } } void setVSpace() { int i,j,ip; double v; for(i=0;i<250;i++) { for(j=0;j<250;j++) { vSpace[i][j] = 0; } } for(ip=0;ip0) { i = (int)((vx[ip]+1250.0)/10.0+0.5); if (i<0) { i = 0; } else if (i>249) { i = 249; } j = (int)((vy[ip]+1250.0)/10.0+0.5); if (j<0) { j = 0; } else if (j>249) { j = 249; } vSpace[i][j] += 1; } } } void setField() { int i,j,k,ip,n; double ke,vmx,vmy; for(i=0;i10) { vmx = 0.0; vmy = 0.0; for(ip=1;ip<=section[i][j][0];ip++) { k = section[i][j][ip]; vmx += vx[k]; vmy += vy[k]; } vmx = vmx/n; vmy = vmy/n; ke = 0.0; for(ip=1;ip<=section[i][j][0];ip++) { k = section[i][j][ip]; ke += 0.5*mass[k]*((vx[k]-vmx)*(vx[k]-vmx)+(vy[k]-vmy)*(vy[k]-vmy)); } temperature[i][j] = ke/n/(1.0*1.38e-23); } pressure[i][j] = density[i][j]*1.38e-23*temperature[i][j]; } } } /* ------------------------- dyeing particle -------- */ void dyeing() { int i; for (i=0; i0) { interaction(); } } /*------------------------------- movement -------------*/ void movement() { int i,ca; double rr; rr = 1.0; for (i=0; i0) { xx[i] += vx[i]*dt; yy[i] += vy[i]*dt; ca = cellAttributeAt(xx[i],yy[i]); if (ca>0) { if (ca==1) { wallCell(i); } else if (ca==2) { absorbCell(i); } else if (ca==3) { adsorbCell(i); } } } else if (kind[i]<0) { if (Math.random()<1.0*Math.exp(-adsorptionEnergy/0.025)) { kind[i] = -kind[i]; vx[i] = -vx[i]; vy[i] = -vy[i]; } } } rr = 1.0; for (i=0; i0) { if (xx[i] < 0.0) { xx[i] = 0.0; vx[i] = -rr*vx[i]; vy[i] = rr*vy[i]; } if (xx[i] > xMax) { xx[i] = xMax; vx[i] = -rr*vx[i]; vy[i] = rr*vy[i]; } if (yy[i] < 0.0) { yy[i] = 0.0; vx[i] = rr*vx[i]; vy[i] = -rr*vy[i]; } if (yy[i] > yMax) { yy[i] = yMax; vx[i] = rr*vx[i]; vy[i] = -rr*vy[i]; } } } } int cellAttributeAt(double x, double y) { int ix,iy; ix = (int)(Nsx*x/xMax); if (ix>=Nsx) ix = Nsx-1; iy = (int)(Nsy*y/yMax); if (iy>=Nsy) iy = Nsy-1; return( cellAttribute[ix][iy] ); } void wallCell(int i) { int at10, at01; xx[i] -= vx[i]*dt; yy[i] -= vy[i]*dt; at10 = cellAttributeAt(xx[i]+vx[i]*dt, yy[i]); at01 = cellAttributeAt(xx[i], yy[i]+vy[i]*dt); if (at10==1) vx[i] = -vx[i]; if (at01==1) vy[i] = -vy[i]; if (at10==0 && at01==0) { vx[i] = -vx[i]; vy[i] = -vy[i]; } } void absorbCell(int i) { kind[i] = 0; } void adsorbCell(int i) { kind[i] = -kind[i]; xx[i] -= vx[i]*dt; yy[i] -= vy[i]*dt; } /*------------------------------- dividing section -------------*/ void dividingSection() { int i,j,ip,iq; for(i=0;i0) { i = (int)(Nsx*xx[ip]/xMax); if (i>=Nsx) i = Nsx-1; j = (int)(Nsy*yy[ip]/yMax); if (j>=Nsy) j = Nsy-1; iq = section[i][j][0]+1; section[i][j][0] = iq; section[i][j][iq] = ip; } } } int maxSection() { int i,j,m; m = 0; for(i=0;im) m = section[i][j][0]; } } return ( m ); } /*------------------------------- interaction -------------*/ void interaction() { int ic,jc,ii,ir,i,j,nn,immc,pi,pj; double vmax,mmc; for(i=0;i1) { mmc = 0.5*nn*nn*ffn*sgm*vmax*dt/vvc; immc = (int)mmc; for(ii=0;ii=nnc) i = nnc-1; j = (int)(nnc*Math.random()); if (j>=nnc) j = nnc-1; } while (i==j); pi = section[ic][jc][i+1]; pj = section[ic][jc][j+1]; collision(pi,pj,vmax); mark[pi] = 1; mark[pj] = 1; } void collision(int i, int j, double vmax) { double vrel,a,b,vcmx,vcmy,th,costh,sinth; vrel = Math.sqrt((vx[i]-vx[j])*(vx[i]-vx[j])+(vy[i]-vy[j])*(vy[i]-vy[j])); if ( vrel/vmax > Math.random() ) { a = mass[i]/(mass[i]+mass[j]); b = 1.0 - a; vcmx = a*vx[i] + b*vx[j]; vcmy = a*vy[i] + b*vy[j]; th = 2.0*3.14159265*Math.random(); costh = Math.cos(th); sinth = Math.sin(th); vx[i] = vcmx + vrel*costh*b; vx[j] = vcmx - vrel*costh*a; vy[i] = vcmy + vrel*sinth*b; vy[j] = vcmy - vrel*sinth*a; } } /* ----------------------------- end of applet -------------- */ }