next up previous contents
Next: A..1.2 Heat1d_e_5.java Up: A..1 1998年秋の挑戦 Previous: A..1 1998年秋の挑戦

A..1.1 Heat1d_e_3.java

次の Heat1d_e_3.java (実行は http://nalab.mind.meiji.ac.jp/~mk/labo/java/sample/Heat1d_e_3.html) は最初に書いた叩き台プログラムである。


   1 /*
   2  * Heat1d_e_3.java
   3  * 1998年9月20日 (子供が産まれるちょっと前だったわけか)
   4  *
   5  * コンパイル: javac Heat1d_e_3.java
   6  * 実行:       appletviewer Heat1d_e_3.java
   7  *
   8  * <APPLET code="Heat1d_e_3.class" width=500 height=500></APPLET>
   9  *
  10  * 注意
  11  *   何と言っても古いので JDK1.1 以降では警告される。
  12  *  (1) reshape() よりも setBounds() を使えと言われる (置き換えれば OK)。
  13  *  (2) action() もよせ、と言われる。
  14  */
  15 
  16 import java.applet.*;
  17 import java.awt.*;
  18 
  19 public class Heat1d_e_3 extends Applet {
  20 
  21   static final boolean DEBUG = false; // true;
  22   private static final String message = "1D Heat Equation";
  23   private int N = 40;
  24   private double Tmax = 0.5, lambda = 0.5;
  25   // 座標系の変換のためのパラメーター
  26   private double ratiox, ratioy, X0, Y0;
  27   // ユーザーとのインターフェイス (パラメーターの入力)
  28   private Label labelLambda, labelN;
  29   private TextField inputLambda, inputN;
  30   private Button startB;
  31 
  32   // 準備 (変数の用意と座標系の初期化など)
  33   public void init() {
  34     //
  35     setLayout(null);
  36 
  37     labelLambda = new Label("lambda (should be <= 1/2)");
  38     add(labelLambda);
  39     labelLambda.setBounds(100, 100, 200, 30);
  40     inputLambda = new TextField("" + lambda);
  41     add(inputLambda);
  42     inputLambda.setBounds(300, 100, 100, 30);
  43 
  44     labelN = new Label("N");
  45     add(labelN);
  46     labelN.setBounds(100, 130, 200, 30);
  47     inputN = new TextField("" + N);
  48     add(inputN);
  49     inputN.setBounds(300, 130, 100, 30);
  50 
  51     startB = new Button("Restart");
  52     add(startB);
  53     startB.setBounds(250, 180, 50, 30);
  54     
  55     space(-0.1, -0.1, 1.1, 1.1);
  56   }
  57   // ボタンを押されたら、テキスト・フィールドの内容を読み取って、再描画
  58   public boolean action(Event evt, Object what) {
  59     if (evt.target == startB) {
  60       String str1 = inputLambda.getText();
  61       String str2 = inputN.getText();
  62       lambda = Double.valueOf(str1).doubleValue();
  63       N = Integer.parseInt(str2);
  64       repaint();
  65     }
  66     return true;
  67   }
  68 
  69   // 初期条件
  70   private double f(double x) {
  71     if (x <= 0.5)
  72       return x;
  73     else
  74       return 1-x;
  75   }
  76   // 座標変換の準備
  77   private void space(double x0, double y0, double x1, double y1) {
  78     X0 = x0; Y0 = y0;
  79     ratiox = 500 / (x1 - x0);
  80     ratioy = 500 / (y1 - y0);
  81   }
  82   // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系)
  83   private int wx(double x) {
  84     return (int)(ratiox * (x - X0));
  85   }
  86   // ユーザー座標 (ワールド座標系) をウィンドウ座標 (デバイス座標系)
  87   private int wy(double y) {
  88     return 500 - (int)(ratioy * (y - Y0));
  89   }
  90   // x[], y[] の内容をグラフにする
  91   private void drawGaph(Graphics g, double x[], double u[]) {
  92     for (int i= 0; i < N; i++)
  93       g.drawLine(wx(x[i]), wy(u[i]), wx(x[i + 1]), wy(u[i + 1]));
  94   }
  95 
  96   public void paint(Graphics g) {
  97 
  98     double h = 1.0 / N;
  99     double tau = lambda * h * h;
 100     double dt = 0.01;
 101     int Jmax = (int) (Tmax / tau);
 102     int skip = (int) (dt / tau + 0.5);
 103     double [] u, unext, x;
 104 
 105     // ベクトルを確保する
 106     x = new double[N+1];
 107     u = new double[N+1];
 108     unext = new double[N+1];
 109     for (int i = 0; i <= N; i++)
 110       x[i] = i * h;
 111 
 112     // これはあんまり意味がない。
 113     g.setColor(Color.pink);
 114     g.fillOval(10, 10, 330, 80);
 115     g.setColor(Color.red);
 116     for (int i=0; i<4;i++) 
 117       g.drawOval(10-i, 10-i, 330+2*i, 80+2*i);
 118 
 119     // タイトルを表示する
 120     g.setColor(Color.black);
 121     g.setFont(new Font("Helvetica", Font.BOLD, 24));
 122     g.drawString(message, 40, 75);
 123 
 124     // 初期値を計算する
 125     for (int i = 0; i <= N; i++)
 126       u[i] = f(i * h);
 127 
 128     // 初期値のグラフを描く
 129     drawGaph(g, x, u);
 130 
 131     // 時間に関するループ
 132     for (int j = 1; j <= Jmax; j++) {
 133       int i;
 134       for (i = 1; i < N; i++)
 135         unext[i] = (1 - 2 * lambda) * u[i]
 136                 + lambda * (u[i-1] + u[i+1]);
 137       for (i = 1; i < N; i++)
 138         u[i] = unext[i];
 139       u[0] = 0; u[N] = 0;
 140 
 141       if (DEBUG)
 142         for (i = 0; i <= N; i++)
 143           System.out.println("u[" + i + "]=" + u[i]);
 144       // 適当な間隔 (dt=0.01) でグラフを描く
 145       if (j % skip == 0)
 146         drawGaph(g, x, u);
 147     }
 148   }
 149 }


next up previous contents
Next: A..1.2 Heat1d_e_5.java Up: A..1 1998年秋の挑戦 Previous: A..1 1998年秋の挑戦
Masashi Katsurada
平成20年2月28日