/** applet No. 1237 * * grain growth in poly-crystal tungsten (NTP) * - periodic molecular dynamics 2D * - selected Morse potential * - multi thread SMD :: display - asynchronous * * Created by Ikeuchi Mitsuru on November 18 2007. * Copyright (c) 2007 Ikeuchi Mitsuru. All rights reserved. * * ver 0.0.1 2007.11.18 created * */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class grainGrowthSMD2D extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener, AdjustmentListener, Runnable { // ------------------------------------ preset field ----------- Thread th = null; // for run()-paint() thread Thread thmd = null; // PeriodicMD2D thread Particles ma = new Particles(0); // W PeriodicMD2D md = new PeriodicMD2D(ma); DrawGraph2D dg2d = new DrawGraph2D(); // for event Choice ch_mat1, ch_mat2, ch_tempControl, ch_view; Button bt_reset, bt_startStop, bt_step, bt_restart; Scrollbar sc_content, sc_temp, sc_press, sc_xLen, sc_scale; TextArea ta; String CRLF = System.getProperty("line.separator"); // for off-paint buffer private Dimension dim; private Image imgOff; private Graphics gOff; private int dgX, dgY, dgXb, dgYb; // mouse private int printCount = 0; private int sleepTime = 50; private double viewScale = 1.0; private int dispMode = 3; private int thCount = 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_mat1 = new Choice(); for (int i=0; i=printCount+1.0) { ta.append(""+(printCount+1)+", "+md.getNumberOfDefect()+", "+ (int)(md.getMeanGrainSize()*1.0e9*10.0+0.5)/10.0+CRLF); printCount = printCount+1; } } } // =============================== draw graph 2D class =========== class DrawGraph2D { private Graphics gOff; private PeriodicMD2D md; private int Nmt; private double xMax; private double yMax; private double plotSize = 300.0; private double dispScale = plotSize/md.getxMax(); private double viewScale = 1.0; private int gx0 = 30; private int gy0 = 110; private int xImageLoc = gx0; private int yImageLoc = gy0; private int dragSW = 1; private double xShift = 0.0; private double yShift = 0.0; private double viewTheta = -15.0*3.14/180.0; private double viewFai = -72.0*3.14/180.0; private double cosTh = Math.cos(viewTheta); private double sinTh = Math.sin(viewTheta); private double cosFi = Math.cos(viewFai); private double sinFi = Math.sin(viewFai); private int rdf[][] = new int[120][3]; private double meanRDF[][] = new double [120][3]; private int vdf[][] = new int [200][3]; private double meanVDF[][] = new double [200][3]; private int adf[] = new int [220]; private int drawnCount = 0; // ------------------------------- class constructor ----------- DrawGraph2D() { } // ----------------------------------- class methods ----------- public void plotGraph2D(Graphics gg, PeriodicMD2D md2d, int dispMode, int thCount) { int gbh,mdCount; gOff = gg; md = md2d; if (md2d==null) return; mdCount = md.getCount(); if (mdCount==drawnCount) return; drawnCount = mdCount; Nmt = md.getNmt(); xMax = md.getxMax(); yMax = md.getyMax(); gOff.setColor(Color.white); gOff.fillRect(0,0,630,460); if (dispMode==0) { // ball ballPlot(0.6, 0.0); drawBox(); rdfPlot(400, 220, 0.4); } else if (dispMode==1) { // line linePlot(); drawBox(); rdfPlot(400, 220, 0.4); } else if (dispMode==2) { // ball + line ballPlot(0.6, 0.0); linePlot(); drawBox(); rdfPlot(400, 220, 0.4); } else if (dispMode==3) { // grain drawBox(); grainPlot(); adfPlot(400, 220, 0.4); } else if (dispMode==4) { // ball + grain drawBox(); ballPlot(0.6, 0.0); grainPlot(); adfPlot(400, 220, 0.4); } else if (dispMode==5) { // defect drawBox(); nearPlot(); } else if (dispMode==6) { // temp ballPlot(0.6, 2000.0); drawBox(); rdfPlot(400, 220, 0.4); } else if (dispMode==7) { // velocity velocityPlot(500.0); drawBox(); vdfPlot(400, 220, 0.01); } else if (dispMode==8) { // v-space vSpacePlot(320, 3000.0); vdfPlot(400, 220, 0.01); } else if (dispMode==9) { ; } gbh = 630/6; gOff.setColor(Color.black); gOff.drawString("poly-crystal W",gbh*0+10,70); gOff.drawString("Tcont="+md.getContTemp()+"K",gbh*3+10,70); gOff.drawString("Pcont="+(int)(md.getContPress()*100.0+0.5)/100.0+"",gbh*4+10,70); gOff.drawString("scale="+(int)(viewScale*100.0+0.499)+"%",gbh*5+10,70); gOff.setColor(Color.blue); gOff.drawString("box="+(int)(md.getxMax()*1.0e12+0.5)/1000.0+"x" +(int)(md.getyMax()*1.0e12+0.5)/1000.0+"nm",140,70); gOff.setColor(Color.blue); gOff.drawString("t="+(int)(md.getTime()*1.0e14+0.5)/100.0+" ps",gbh*0+10,90); gOff.drawString("N="+md.getNmt()+" ",gbh*2+10,90); gOff.drawString("T="+(int)(md.getTemperature()*10+0.5)/10.0+" K",gbh*3+10,90); gOff.drawString("P="+(int)(md.getPressure()*1000.0)/1000.0+"N/m",gbh*4+10,90); //gOff.drawString("Pxx="+(int)(md.getxxPress()*1000.0)/1000.0+"N/m",400,110); //gOff.drawString("Pyy="+(int)(md.getyyPress()*1000.0)/1000.0+"N/m",400,125); //gOff.drawString("Pxy="+(int)(md.getxyPress()*1000.0)/1000.0+"N/m",400,140); //gOff.setColor(Color.black); //gOff.drawString("thread MD = "+md.getCount()+" ",20,440); //gOff.drawString("thread disp = "+thCount+" ",220,440); gOff.setColor(Color.black); gOff.drawString("time(ps), defect, grain size(nm)",400,115); } // ------------------------------------ plot methods ----------- private void ballPlot(double dia, double tempSpan) { int i,ix,iy,ir; double sc,tm; sc = viewScale*dispScale; for (i=0; i0.0) { tm = md.getTemp(i); tm = 0.8*tm/tempSpan+0.199; if (tm>0.99) tm = 0.99; } gOff.setColor(Color.getHSBColor((float)(md.getColor(i)),0.95f,(float)tm)); gOff.fillOval(ix-ir/2,iy-ir/2, ir, ir); } } private void grainPlot() { int i,j,k,ix,iy,ix2,iy2; double sc,x,y,r2,dij,gcol; for (i=0; i<200; i++) { adf[i] = 0; } sc = viewScale*dispScale; for (i=0; ii) { ix2 = xImageLoc + (int)(sc*md.getxx(j)); iy2 = yImageLoc + (int)(sc*md.getyy(j)); gcol = grainColor(x,y); adf[(int)(gcol*200.0)] += 1; gOff.setColor(Color.getHSBColor((float)gcol,0.9f,0.9f)); gOff.drawLine(ix,iy, ix2,iy2); } } } } private double grainColor(double x, double y) { double th,col; th = 3.0*(Math.atan2(y,x)/Math.PI + 1.0); return (th-(int)th); } private void linePlot() { int i,j,k,ix,iy,ix2,iy2; double sc,r2,dij; sc = viewScale*dispScale; for (i=0; ii) { ix2 = xImageLoc + (int)(sc*md.getxx(j)); iy2 = yImageLoc + (int)(sc*md.getyy(j)); gOff.setColor(Color.gray); gOff.drawLine(ix,iy, ix2,iy2); } } } } private void nearPlot() { int i,j,k,ix,iy,ix2,iy2, ir, n; double sc,x,y,r2,dij,gcol; sc = viewScale*dispScale; for (i=0; i0) gOff.fillOval(ix-ir/2,iy-ir/2, ir, ir); } gOff.setColor(Color.red); n = md.getNumberOfDefect(); gOff.drawString("no. of defect="+n+" ",400,400); gOff.drawString("mean grain size="+(int)(md.getMeanGrainSize()*1.0e9*10.0+0.5)/10.0+" nm",400,420); //if (1.0*n>0.4*Nmt) initMeanNear(); } // private void velocityPlot(double vSpan) { int i,ix,iy,ix2,iy2; double sc; sc = viewScale*dispScale; for (i=0; i0) { gOff.fillRect(gx+i*2,gy+hoganHight-n1,2,n1); } } gOff.setColor(Color.getHSBColor(md.getColorOf(md.getMAT1()),0.9f,0.6f)); for (i=10; i<100-1; i++) { n1 = (int)(a*meanRDF[i][1]/i); n2 = (int)(a*meanRDF[i+1][1]/i); gOff.drawLine(gx+i*2,gy+hoganHight-n1,gx+i*2+2,gy+hoganHight-n2); } gOff.setColor(Color.getHSBColor(md.getColorOf(md.getMAT2()),0.9f,0.6f)); for (i=10; i<100-1; i++) { n1 = (int)(a*meanRDF[i][2]/i); n2 = (int)(a*meanRDF[i+1][2]/i); gOff.drawLine(gx+i*2,gy+hoganHight-n1,gx+i*2+2,gy+hoganHight-n2); } 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 (n/r)",gx+20,gy+hoganHight+40); } private void setRadialDistribution() { int i,j,k,ir,m1,m2,ki,kj; double xij,yij,rij; for (i=0; i<120; i++) { rdf[i][0]=0; rdf[i][1]=0; rdf[i][2]=0; } m1 = md.getMAT1(); m2 = md.getMAT2(); for (i=0; i119) ir=119; rdf[ir][0] +=1; if (ki==m1 && kj==m1) { rdf[ir][1] += 1; } else if (ki==m2 && kj==m2) { rdf[ir][2] += 1; } } } } for (i=0; i<120; i++) { meanRDF[i][0] = 0.9*meanRDF[i][0]+0.1*rdf[i][0]; meanRDF[i][1] = 0.9*meanRDF[i][1]+0.1*rdf[i][1]; meanRDF[i][2] = 0.9*meanRDF[i][2]+0.1*rdf[i][2]; } } // velocity distribution private void vdfPlot(int gx, int gy, double mag) { int i,n1,n2; double yMag; setVelocityDistribution(); yMag = mag*0.005*Nmt; gOff.setColor(Color.lightGray); for (i=0; i<200-1; i++) { n1 = (int)(yMag*meanVDF[i][0]); gOff.drawLine(gx+i,gy+200-n1,gx+i,gy+200); } gOff.setColor(Color.getHSBColor(md.getColorOf(md.getMAT1()),0.9f,0.6f)); for (i=0; i<200-2; i++) { n1 = (int)(yMag*meanVDF[i][1]); n2 = (int)(yMag*meanVDF[i+1][1]); gOff.drawLine(gx+i,gy+200-n1,gx+i+1,gy+200-n2); } gOff.setColor(Color.getHSBColor(md.getColorOf(md.getMAT2()),0.9f,0.6f)); for (i=0; i<200-2; i++) { n1 = (int)(yMag*meanVDF[i][2]); n2 = (int)(yMag*meanVDF[i+1][2]); gOff.drawLine(gx+i,gy+200-n1,gx+i+1,gy+200-n2); } drawHogan(gx, gy, 200, 200, 50, 100); gOff.setColor(Color.black); gOff.drawString("0",gx-5,gy+220); gOff.drawString("1000",gx+100-15,gy+220); gOff.drawString("(m/s)",gx+200-30,gy+220); gOff.drawString("velocity distribution",gx+20,gy+235); } private void setVelocityDistribution() { int i,iv,m1,m2,knd; double vx,vy,v; for(i=0;i<200;i++) { vdf[i][0] = 0; vdf[i][1] = 0; vdf[i][2] = 0; } m1 = md.getMAT1(); m2 = md.getMAT2(); for(i=0;i199) iv = 199; vdf[iv][0] += 1; if (knd==m1) { vdf[iv][1] += 1; } else if (knd==m2) { vdf[iv][2] += 1; } } for(i=0;i<200;i++) { meanVDF[i][0] = 0.98*meanVDF[i][0]+0.02*vdf[i][0]; meanVDF[i][1] = 0.98*meanVDF[i][1]+0.02*vdf[i][1]; meanVDF[i][2] = 0.98*meanVDF[i][2]+0.02*vdf[i][2]; } } // azimuth distribution private void adfPlot(int gx, int gy, double mag) { int i,n1,n2; double yMag; yMag = 10000.0/Nmt*mag; gOff.setColor(Color.lightGray); for (i=0; i<200; i++) { n1 = (int)(yMag*adf[i]); gOff.setColor(Color.getHSBColor((float)(i/200.0),0.9f,0.8f)); gOff.drawLine(gx+i,gy+200-n1,gx+i,gy+200); } drawHogan(gx, gy, 200, 200, 50, 100); gOff.setColor(Color.black); gOff.drawString("0",gx-5,gy+220); gOff.drawString("PI/3",gx+200-15,gy+220); gOff.drawString("azimuth distribution",gx+20,gy+235); } // private 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.8*rCutoff && r0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } } } // --------------------------- set initial condition ----------- private void setInitialCondition() { int i,ix,iy; double nm; count = 0; t = 0.0; nm = 1.0e-9; xMax = 90.0*nm; yMax = 90.0*nm; i = 0; for (ix=0; ix=x0 && xp<=x0+xLen && yp>=y0 && yp<=y0+yLen) { kind[ip] = knd; xx[ip] = xp; yy[ip] = yp; vx[ip] = 500.0*(Math.random()-0.5); vy[ip] = 500.0*(Math.random()-0.5); ffy[ip] = 0.0; ffy[ip] = 0.0; ip += 1; } } } return ip; } // private void initMeanNear() { int i; for (i=0; i0.5*xMax) xij -= xMax; if (xij<-0.5*xMax) xij += xMax; if (yij>0.5*yMax) yij -= yMax; if (yij<-0.5*yMax) yij += yMax; r2=xij*xij+yij*yij; if (r21.2) { rr=1.2; }; } for (i=0; i xMax) { xx[i] -= xMax; } if (yy[i] < 0.0) { yy[i] += yMax; } if (yy[i] > yMax) { yy[i] -= yMax; } } } //registration and set meanNear private void registration() { int i,j,ii,jj,ip,jp,kp,i0,i1,j0,j1,iq; double xij,yij,r2,rreg,rreg2,dij; preRegistration(); rreg = particle.getrCutoff() + 3000.0*10*dt; rreg2 = rreg*rreg; for (i=0; iip) { xij = xx[ip] - xx[jp]; yij = yy[ip] - yy[jp]; if (xij>0.5*xMax) xij -= xMax; if (xij<-0.5*xMax) xij += xMax; if (yij>0.5*yMax) yij -= yMax; if (yij<-0.5*yMax) yij += yMax; r2=xij*xij+yij*yij; if (r2=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; } } // ----------------------------------------- utility ----------- private void vAjustment() { int i; double tmp, r; tmp = temperature(); r = Math.sqrt(contTemp/tmp); for (i=0; ixMax+d) { x = xMax + d; } else if (xyMax+d) { y = yMax + d; } else if (ym) m = reg[i][0]; } return(m); } // ------------------------------------- I/O methods ----------- // control public void reset() { resetSW = 1; } public void setStartSW(int sw) { startSW = sw; } public int getStartSW() { return startSW; } public void setStepSW() { stepSW = 1; } public void restart() { restartSW = 1; } public int getCount() { return count; } public static double getxMax() { return xMax; } public static double getyMax() { return yMax; } public void setTempMode(int tmode) { tempMode = tmode; } public int getTempMode() { return tempMode; } public void setContTemp(double tmp) { contTemp = tmp; vAjustment(); } public double getContTemp() { return contTemp; } public void setContPress(double p) { contPress = p; } public double getContPress() { return contPress; } public void setxLength(double len) { xLength = len; scaleSW = 1; } public double getxLength() { return xLength; } public void setMAT1(int m) { MAT1 = m; resetSW = 1; } public int getMAT1() { return MAT1; } public void setMAT2(int m) { MAT2 = m; resetSW = 1; } public int getMAT2() { return MAT2; } public void setMat1content(int m2c) { mat2content = m2c; resetSW = 1; } public int getMat2content() { return mat2content; } // get data public double getTime() { return t; } public double getdt() { return dt; } public int getNmt() { return Nmt; } public float getColorOf(int knd) { return (float)particle.getColorOf(knd); } public double getDia(int i) { return particle.getDiaOf(kind[i]); } public double getMass(int i) { return particle.getMassOf(kind[i]); } public float getColor(int i) { return (float) particle.getColorOf(kind[i]); } public int getKind(int i) { return kind[i]; } public double getxx(int i) { return xx[i]; } public double getyy(int i) { return yy[i]; } public double getvx(int i) { return vx[i]; } public double getvy(int i) { return vy[i]; } public double getTemp(int i) { return temp(i); } public double getTemperature() { return temperature(); } public double getPressure() { return pressure(); } public double getxxPress() { return xxPress(); } public double getyyPress() { return yyPress(); } public double getxyPress() { return xyPress(); } public int getnnReg(int i) { return reg[i][0]; } public int getReg(int i, int k) { return reg[i][k]; } public int getRegMax() { return regMax(); } public double getMeanNear(int i) { return meanNear[i]; } public int getNumberOfDefect() { return numberOfDefect(); } public double getMeanGrainSize() { return xMax/(numberOfDefect()/Math.sqrt(Nmt*1.0)/4.0); } }