/** applet No. 1248 * * n-type semiconductor - Monte-Carlo simulation 2D * - multi thread MCS2D :: display - asynchronous * * Created by Ikeuchi Mitsuru on January 12 2008. * Copyright (c) 2008 Ikeuchi Mitsuru. All rights reserved. * * ver 0.0.1 2008.01.12 created * */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class nTypeMCS2D extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener, AdjustmentListener, Runnable { // ------------------------------------ preset field ----------- Thread th = null; // for run()-paint() thread Thread thmcs = null; // for MCS2D() thread MCS2D mcs = new MCS2D(); // create MCS2D instance // for event Choice ch_view; Button bt_reset, bt_startStop, bt_step; Scrollbar sc_scale; // for off-paint buffer Dimension dim; Image imgOff; Graphics gOff; // display private int sleepTime = 30; // sleep time (ms) private int dispWidth = 630; private int dispHeight = 460; private int dispMode = 0; private double boxDispWidth = 320.0; private double dispScale = 1.0; private double viewScale = 1.0; private double xShift = 0.0; private double yShift = 0.0; private int gx0 = 60; private int gy0 = 90; private int xImageLoc = gx0; private int yImageLoc = gy0; private double viewTheta = -15.0*3.14/180.0; private double viewFai = -60.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 xpts[] = new int[400]; private int ypts[] = new int[400]; private double fpts[] = new double[400]; int dgX, dgY, dgXb,dgYb; // mouse private int thCount = 0; // ------------------------------ applet main thread ----------- public void init() { resize(dispWidth,dispHeight); setBackground(Color.white); dim = getSize(); imgOff = createImage(dim.width,dim.height); gOff = imgOff.getGraphics(); ch_view = new Choice(); ch_view.add("e+h"); ch_view.add("e+h+pot"); ch_view.add("grid pot"); ch_view.addItemListener(this); ch_view.select("e+h"); 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_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_step); pnl.add(new Label(" ")); pnl.add(sc_scale); pnl.add(ch_view); add(pnl,"North"); } public void start() { if (th == null) { th = new Thread(this); th.start(); } if (thmcs == null) { thmcs = new Thread(mcs); thmcs.start(); } } public void stop() { if (th != null) th = null; if (thmcs != null) thmcs = null; } // ---------------------------------- event listener ----------- public void itemStateChanged(ItemEvent ev){ if (ev.getSource() == ch_view) { dispMode = ch_view.getSelectedIndex(); } } public void actionPerformed(ActionEvent ev){ if (ev.getSource() == bt_reset){ mcs.reset(); thCount = 0; } else if (ev.getSource() == bt_startStop){ if (mcs.getStartSW()==0) { mcs.setStartSW(1); } else { mcs.setStartSW(0); } } else if (ev.getSource() == bt_step){ if (mcs.getStartSW()==0) { mcs.setStepSW(); } } } public void adjustmentValueChanged(AdjustmentEvent ev){ double vs; if (ev.getSource() == sc_scale) { vs = viewScale; viewScale = 0.01*(double)(sc_scale.getValue()); xImageLoc = xImageLoc - (int)(0.5*mcs.getNNx()*(viewScale - vs)); yImageLoc = yImageLoc - (int)(0.5*mcs.getNNy()*(viewScale - vs)); xShift = (xImageLoc-gx0)/(dispScale*viewScale); yShift = (yImageLoc-gy0)/(dispScale*viewScale); } } 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; } if (dispMode==2) { viewTheta += 0.5*3.14159/180.0*(dgX-dgXb); viewFai += 0.5*3.14159/180.0*(dgY-dgYb); cosTh = Math.cos(viewTheta); sinTh = Math.sin(viewTheta); cosFi = Math.cos(viewFai); sinFi = Math.sin(viewFai); } else { xShift += (1.0/viewScale/dispScale)*(dgX-dgXb); yShift += (1.0/viewScale/dispScale)*(dgY-dgYb); xImageLoc = gx0+(int)(dispScale*viewScale*xShift); yImageLoc = gy0+(int)(dispScale*viewScale*yShift); } } // ========================= run() - paint() loop ============== public void run() { while (th != null) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } thCount += 1; offPaint(); repaint(); } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(imgOff,0,0,this); } // --------------------------------------- off-paint ----------- private void offPaint() { gOff.setColor(Color.white); gOff.fillRect(0,0,dim.width,dim.height); if (dispMode==0) { walkerPlot(1); linePotentialPlot(); } else if (dispMode==1) { potentialPlot(2.0); walkerPlot(0); } else if (dispMode==2) { gridPlot(20.0); } else if (dispMode==3) { ; } gOff.setColor(Color.blue); gOff.drawString("t="+mcs.getTime()+" ",10,40); gOff.setColor(Color.black); if (mcs.getStartSW()==0) { gOff.drawString("stopped",dispWidth/6*1+10,40); } else { gOff.drawString("started",dispWidth/6*1+10,40); } gOff.drawString("scale="+(int)(viewScale*100.0)+"%",dispWidth/6*4+10,40); gOff.drawString("view",dispWidth/6*5+10,40); gOff.setColor(Color.cyan); gOff.drawString("Nelec="+mcs.getNparticles(-1)+" ",dispWidth/6*0+10,60); gOff.setColor(Color.black); gOff.drawString("N type",200,80); gOff.drawString("I type",360,80); gOff.setColor(Color.black); gOff.drawString("count MD="+mcs.getCount()+" ",400,440); gOff.drawString("disp="+thCount+" ",530,440); } // ------------------------------------ plot methods ----------- private void walkerPlot(int sw) { int i, j, k, ix, iy, ir, NNx, NNy; float col; double sc; NNx = mcs.getNNx(); NNy = mcs.getNNy(); sc = 1.0*viewScale; ir = (int)sc+1; if (ir<1) ir = 1; for (i=0; i0.0) { col = 0.61; } else { col = 0.01; p = -p; } p = 0.5*p; if (p>1.0) p=1.0; gOff.setColor(Color.getHSBColor((float)col,0.5f,(float)p)); ix = (int)(i*4*viewScale)+xImageLoc; iy = (int)(j*4*viewScale)+yImageLoc; gOff.fillRect(ix,iy, (int)(4*viewScale+1), (int)(4*viewScale+1)); } } } private void gridPlot(double mag) { int cx,cy,cz,Nsx,Nsy; int i,j,gbx,gby,ic; double sc,z,px,py,pz,f; Nsx = mcs.getNNx()/4; Nsy = mcs.getNNy()/4; cx = Nsx/2; cy = Nsy/2; cz = 0; sc = (480.0/Nsx); ic = 2; gbx = 60; gby = 90; for(j=0; j0.0) { d = (float)(0.5*f+0.1); if (d>=0.99f) d=0.99f; } else { f = -f; d = (float)(0.5*f+0.1); if (d>=0.99f) d=0.99f; } gOff.setColor(Color.getHSBColor(col,s,d)); } } // =================== Monte-Carlo simulation 2D class =========== class MCS2D implements Runnable { private int t = 0; // system time private int dt = 1; // time division // private int hh = 1; // space division v0=hh/dt private int NBlock = 4; private int Nsx = 120; private int Nsy = 80; private int NNx = Nsx*NBlock; private int NNy = Nsy*NBlock; private double alpha = 1.0; // vd/v0 = a = alpha E ; drift velocity // point difinition private int p_x1 = 60; private int p_x2 = p_x1 + 180; private int p_x3 = p_x2 + 180; private int p_y1 = 60; private int p_y2 = p_y1 + 200; // area difinition .... xPos, yPos, xSize, ySize private int area_world[] = { 0, 0, NNx, NNy }; private int area_n[] = { p_x1, p_y1, p_x2-p_x1, p_y2-p_y1 }; // n-type private int area_i[] = { p_x2, p_y1, p_x3-p_x2, p_y2-p_y1 }; // i-type private int NNp = 20000; // number of particles private int NN = 20000; private byte kind[] = new byte[NN]; // particle kind -1-electron, 0-dead, 1-hole private int px[] = new int[NN]; // particle x-pos private int py[] = new int[NN]; // particle y-pos private byte field[][] = new byte[NNx][NNy]; // -2-acceptor,-1-electron, 0-space, 1-hole, 2-donor, 3-wall private float potential[][] = new float[Nsx][Nsy]; // potential private float charge[][] = new float[Nsx][Nsy]; // charge private int sleepTime = 1; private int stopSleepTime = 100; private int resetSW = 0; private int startSW = 1; private int stepSW = 0; private int statMode = 2; private int count = 0; // ------------------------------- class constructor ----------- MCS2D() { setInitialCondition(); } // -------------------------------------- thread run ----------- public void run() { while (true) { count += 1; timeEvolution(); if (sleepTime>0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } } } // --------------------------- set initial condition ----------- private void setInitialCondition() { int i, ix, iy; t = 0; count = 0; fillField(3, area_world); //clear (outer space = 3) i = 0; i = setNtype(i, area_n); i = setItype(i, area_i); NNp = i; initPotential(); } private int setNtype(int ip, int area[]) { // n-type semiconductor int ii; fillField(0, area); // inner space = 0 ii = ip; ii = setBlock(ii,-1, 1, 1, area); // electron ii = setBlock(ii, 2, 2, 2, area); // donor return ii; } private int setPtype(int ip, int area[]) { // p-type semiconductor int ii; fillField(0, area); // inner space = 0 ii = ip; ii = setBlock(ii, 1, 1, 2, area); // hole ii = setBlock(ii,-2, 2, 1, area); // acceptor return ii; } private int setItype(int ip, int area[]) { // intrinsic semiconductor fillField(0, area); // inner space = 0 return ip; } private void fillField(int f, int area[]) { int ix,iy, xPos,yPos,xSize,ySize; xPos = area[0]; yPos = area[1]; xSize = area[2]; ySize = area[3]; for (ix=xPos; ix=1+a) { ix = px[i]+1; } else { ix = px[i]-1; } iy = py[i]; } else { // y-direction r = r - 2.0; ix = px[i]; a = alpha*k*eyField(px[i],py[i]); if (r>=1+a) { iy = py[i]+1; } else { iy = py[i]-1; } } move(i,ix,iy); } } private int move(int i, int ix, int iy) { int ib,jb,irem; if (ix<0 || ix>=NNx || iy<0 || iy>=NNy) return 0; if (field[ix][iy]!=0) return 0; ib = px[i]; jb = py[i]; field[ib][jb] = 0; field[ix][iy] = kind[i]; px[i] = ix; py[i] = iy; return -1; } // set charge private void setCharge() { int i,j, ii,jj,k,cg; for (i=1; i