まずはダブル・バッファリングを使うバージョン NewHeat1D.java (実行は http://nalab.mind.meiji.ac.jp/~mk/labo/java/sample/NewHeat1D.html) から。
1 /* 2 * NewHeat1D.java 3 * 2005/12/26 4 * 5 * コンパイル: javac NewHeat1D.java 6 * 実行: java NewHeat1D 7 * 8 * ダブルバッファリングを利用。一度しか計算しない。 9 * 10 */ 11 12 import java.awt.Frame; 13 import java.awt.Graphics; 14 import java.awt.Image; 15 import java.awt.event.WindowAdapter; 16 import java.awt.event.WindowEvent; 17 18 19 public class NewHeat1D extends Frame { 20 Image im = null; 21 Graphics g2 = null; 22 int i, n, nMax; 23 int N = 40; 24 double lambda = 0.5; 25 double Tmax = 10.0; 26 double dt = 0.01; 27 double h, tau; 28 int skip; 29 double [] u, newu; 30 double ratiox, ratioy, X0, Y0; 31 public NewHeat1D() { 32 this.setSize(500, 500); 33 this.addWindowListener(new WindowAdapter() { 34 public void windowClosing(WindowEvent ev) { 35 System.exit(0); 36 } 37 }); 38 this.setVisible(true); 39 } 40 public static void main(String[] args) { 41 // TODO 自動生成されたメソッド・スタブ 42 new NewHeat1D(); 43 } 44 private void space(double x0, double y0, double x1, double y1) { 45 X0 = x0; Y0 = y0; 46 ratiox = 500 / (x1 - x0); 47 ratioy = 500 / (y1 - y0); 48 } 49 private int wx(double x) { 50 return (int)(ratiox * (x - X0)); 51 } 52 private int wy(double y) { 53 return 500 - (int)(ratioy * (y - Y0)); 54 } 55 private double f(double x) { 56 if (x <= 0.5) 57 return x; 58 else 59 return 1.0 - x; 60 } 61 public void paint(Graphics g) { 62 if (im == null) { 63 im = this.createImage(this.getWidth(), this.getHeight()); 64 g2 = im.getGraphics(); 65 space(-0.1, -0.1, 1.1, 1.1); 66 h = 1.0 / N; 67 tau = lambda * h * h; 68 skip = (int)Math.rint(dt / tau); 69 nMax = (int)Math.rint(Tmax / tau); 70 u = new double [N+1]; 71 newu = new double [N+1]; 72 // 初期値 73 for (i = 0; i <= N; i++) 74 u[i] = f(i * h); 75 // 初期値のグラフを描く 76 for (i = 0; i < N; i++) 77 g2.drawLine(wx(i * h), wy(u[i]), wx((i + 1) * h), wy(u[i+1])); 78 // 時間発展 79 for (n = 1; n <= nMax; n++) { 80 // 陽的差分法 81 for (i = 1; i < N; i++) 82 newu[i] = (1 - 2 * lambda) * u[i] + lambda * (u[i + 1] + u[i - 1]); 83 for (i = 1; i < N; i++) 84 u[i] = newu[i]; 85 // 同次Dirichlet境界条件 86 u[0] = 0.0; 87 u[N] = 0.0; 88 // 時刻が dt の整数倍のときにグラフを描く 89 if (n % skip == 0) { 90 for (i = 0; i < N; i++) 91 g2.drawLine(wx(i * h), wy(u[i]), wx((i + 1) * h), wy(u[i+1])); 92 } 93 System.out.println(""+ n * tau); 94 } 95 } 96 g.drawImage(im, 0, 0, this); 97 } 98 }