next up previous contents
Next: A..3 2005年12月の再挑戦 Up: A. 熱方程式プログラム (いつまでも工事中) Previous: A..1.2 Heat1d_e_5.java

A..2 2001年1月の作業

Heat1dyou.java は (実行は http://nalab.mind.meiji.ac.jp/~mk/labo/java/sample/Heat1dyou.html)、 大したことはしていない (イベント処理を JDK 1.1 以降のそれに置き換えた)。


   1 /*
   2  * Heat1dyou.java --- Heat1d_e_4.java を JDK 1.2 に合わせて変更したもの
   3  * 2001年1月18日
   4  *
   5  * コンパイル: javac Heat1dyou.java
   6  * 実行:       appletviewer Heat1dyou.java
   7  *
   8  * <applet code ="Heat1dyou" width=500 height=500></applet>
   9  */
  10 
  11 import java.applet.*;
  12 import java.awt.*;
  13 import java.awt.event.*;
  14 
  15 public class Heat1dyou extends Applet implements ActionListener {
  16 
  17     public int N = 20;
  18     public double lambda = 0.5;
  19     public double Tmax = 0.5;
  20     // ユーザーとのインターフェイス
  21     public Label labelLambda, labelN, labelTmax;
  22     public TextField inputLambda, inputN, inputTmax;
  23     public Button startB;
  24     // 差分法による熱方程式シミュレーション
  25     public HeatCanvas c1;
  26 
  27     public void init() {
  28         //画面のレイアウト、レイアウトマネージャーの設定
  29         setLayout(new BorderLayout());
  30 
  31         //Northパネルの設定
  32         Panel pn = new Panel();
  33         pn.setLayout(new GridLayout(3,2));
  34 
  35         //ボタン、テキストフィールドの準備
  36         String s = "lambda (should be <= 1/2)";
  37         labelLambda = new Label(s, Label.LEFT);
  38         pn.add(labelLambda);
  39 
  40         inputLambda = new TextField("" + lambda,10);
  41         pn.add(inputLambda);
  42 
  43         labelN = new Label("N", Label.LEFT);
  44         pn.add(labelN);
  45 
  46         inputN = new TextField("" + N,10);
  47         pn.add(inputN);
  48 
  49         labelTmax = new Label("Tmax", Label.LEFT);
  50         pn.add(labelTmax);
  51                 
  52         inputTmax = new TextField("" + Tmax,10);
  53         pn.add(inputTmax);
  54                 
  55         inputLambda.addActionListener(this);
  56         inputN.addActionListener(this);
  57         inputTmax.addActionListener(this);
  58                 
  59         add(pn, "North");
  60 
  61         //Centerパネルの設定
  62         Panel pc = new Panel();
  63         c1 = new HeatCanvas();
  64         c1.setSize(400,400);
  65         c1.compute(lambda, N, Tmax);
  66         pc.add(c1);
  67         add(pc,"Center");
  68         
  69         //Eastパネルの設定
  70         Panel pe = new Panel();
  71         startB = new Button("Restart");
  72         pe.add(startB);
  73         add(pe,"East");
  74         startB.addActionListener(this);
  75     }
  76 
  77     //イベント処理(ボタン)
  78     public void actionPerformed(ActionEvent e) {
  79         if (e.getSource() == startB) {
  80             String str1 = inputLambda.getText().trim();
  81             String str2 = inputN.getText().trim();
  82             String str3 = inputTmax.getText().trim();
  83             lambda = Double.valueOf(str1).doubleValue();
  84             N = Integer.parseInt(str2);
  85             Tmax = Double.valueOf(str3).doubleValue();
  86             c1.compute(lambda, N, Tmax);
  87         }
  88     }
  89 }
  90 
  91 // HeatCanvas.java
  92 
  93 class HeatCanvas extends Canvas {
  94 
  95     static final boolean DEBUG = false; // true;
  96     private static final String message = "1D Heat Equation";
  97     // 問題に取って基本的なパラメーター
  98     //   N:      区間の分割数
  99     //   Tmax:   最終時刻
 100     //   lambda: λ=τ/h^2
 101     private int N;
 102     private double Tmax, lambda;
 103     // 座標系の変換のためのパラメーター
 104     private int CanvasX = 400, CanvasY = 400;
 105     private double ratiox, ratioy, X0, Y0;
 106     //
 107     private HeatCanvas c1;
 108 
 109     // コンストラクター
 110     public HeatCanvas() {
 111         super();
 112         space(-0.1, -0.1, 1.1, 1.1);
 113     }
 114     public HeatCanvas(int cx, int cy) {
 115         super();
 116         CanvasX = cx; CanvasY = cy;
 117         space(-0.1, -0.1, 1.1, 1.1);
 118     }
 119 
 120     public void compute(double lambda, int N, double Tmax) {
 121         this.lambda = lambda;
 122         this.N = N;
 123         this.Tmax = Tmax;
 124         repaint();
 125     }
 126 
 127     // 初期条件
 128     private double f(double x) {
 129         if (x <= 0.5)
 130             return x;
 131         else
 132             return 1.0 - x;
 133     }
 134     // 座標変換の準備
 135     private void space(double x0, double y0, double x1, double y1) {
 136         X0 = x0; Y0 = y0;
 137         ratiox = CanvasX / (x1 - x0);
 138         ratioy = CanvasY / (y1 - y0);
 139     }
 140     // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系)
 141     private int wx(double x) {
 142         return (int)(ratiox * (x - X0));
 143     }
 144     // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系)
 145     private int wy(double y) {
 146         return CanvasY - (int)(ratioy * (y - Y0));
 147     }
 148     // x[], y[] の内容をグラフにする
 149     private void drawGaph(Graphics g, double x[], double u[]) {
 150         for (int i= 0; i < N; i++)
 151             g.drawLine(wx(x[i]), wy(u[i]), wx(x[i + 1]), wy(u[i + 1]));
 152     }
 153 
 154     public void paint(Graphics g) {
 155 
 156         double h = 1.0 / N;
 157         double tau = lambda * h * h;
 158         double dt = 0.01;
 159         int Jmax = (int) (Tmax / tau);
 160         int skip = (int) (dt / tau + 0.5);
 161         double [] u, unext, x;
 162         
 163         // ベクトルを確保する
 164         x = new double[N+1];
 165         u = new double[N+1];
 166         unext = new double[N+1];
 167         for (int i = 0; i <= N; i++)
 168             x[i] = i * h;
 169 
 170         // これはあんまり意味がない。
 171         g.setColor(Color.pink);
 172         g.fillOval(10, 10, 330, 60);
 173         g.setColor(Color.red);
 174         for (int i=0; i<4;i++) 
 175             g.drawOval(10-i, 10-i, 330+2*i, 60+2*i);
 176 
 177         // タイトルを表示する
 178         g.setColor(Color.black);
 179         g.setFont(new Font("Helvetica", Font.BOLD, 24));
 180         g.drawString(message, 40, 50);
 181 
 182         // 初期値を計算する
 183         for (int i = 0; i <= N; i++)
 184             u[i] = f(i * h);
 185 
 186         // 初期値のグラフを描く
 187         drawGaph(g, x, u);
 188 
 189         // 時間に関するループ
 190         for (int j = 1; j <= Jmax; j++) {
 191             int i;
 192             for (i = 1; i < N; i++)
 193                 unext[i] = (1 - 2 * lambda) * u[i]
 194                     + lambda * (u[i-1] + u[i+1]);
 195             for (i = 1; i < N; i++)
 196                 u[i] = unext[i];
 197             u[0] = 0; u[N] = 0;
 198 
 199             if (DEBUG)
 200                 for (i = 0; i <= N; i++)
 201                     System.out.println("u[" + i + "]=" + u[i]);
 202             // 適当な間隔 (dt=0.01) でグラフを描く
 203             if (j % skip == 0)
 204                 drawGaph(g, x, u);
 205         }
 206     }
 207 }


next up previous contents
Next: A..3 2005年12月の再挑戦 Up: A. 熱方程式プログラム (いつまでも工事中) Previous: A..1.2 Heat1d_e_5.java
Masashi Katsurada
平成20年2月28日