まずはダブル・バッファリングを使うバージョン 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 }