/* * NewHeat1D.java * 2005/12/26 * * コンパイル: javac NewHeat1D.java * 実行: java NewHeat1D * * ダブルバッファリングを利用。一度しか計算しない。 * */ import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class NewHeat1D extends Frame { Image im = null; Graphics g2 = null; int i, n, nMax; int N = 40; double lambda = 0.5; double Tmax = 10.0; double dt = 0.01; double h, tau; int skip; double [] u, newu; double ratiox, ratioy, X0, Y0; public NewHeat1D() { this.setSize(500, 500); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent ev) { System.exit(0); } }); this.setVisible(true); } public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ new NewHeat1D(); } private void space(double x0, double y0, double x1, double y1) { X0 = x0; Y0 = y0; ratiox = 500 / (x1 - x0); ratioy = 500 / (y1 - y0); } private int wx(double x) { return (int)(ratiox * (x - X0)); } private int wy(double y) { return 500 - (int)(ratioy * (y - Y0)); } private double f(double x) { if (x <= 0.5) return x; else return 1.0 - x; } public void paint(Graphics g) { if (im == null) { im = this.createImage(this.getWidth(), this.getHeight()); g2 = im.getGraphics(); space(-0.1, -0.1, 1.1, 1.1); h = 1.0 / N; tau = lambda * h * h; skip = (int)Math.rint(dt / tau); nMax = (int)Math.rint(Tmax / tau); u = new double [N+1]; newu = new double [N+1]; // 初期値 for (i = 0; i <= N; i++) u[i] = f(i * h); // 初期値のグラフを描く for (i = 0; i < N; i++) g2.drawLine(wx(i * h), wy(u[i]), wx((i + 1) * h), wy(u[i+1])); // 時間発展 for (n = 1; n <= nMax; n++) { // 陽的差分法 for (i = 1; i < N; i++) newu[i] = (1 - 2 * lambda) * u[i] + lambda * (u[i + 1] + u[i - 1]); for (i = 1; i < N; i++) u[i] = newu[i]; // 同次Dirichlet境界条件 u[0] = 0.0; u[N] = 0.0; // 時刻が dt の整数倍のときにグラフを描く if (n % skip == 0) { for (i = 0; i < N; i++) g2.drawLine(wx(i * h), wy(u[i]), wx((i + 1) * h), wy(u[i+1])); } System.out.println(""+ n * tau); } } g.drawImage(im, 0, 0, this); } }