定数でないディリクレ境界条件 クラスの継承

目次 解答例(ないかも)

締切は 2002/05/31. 重点問題は 05_01.

コメント のような部分は 実際には現れないここだけの説明. 1234 のような斜体の部分は, 人や場合によって変化したり, 自分で決めたりする部分. given のような太字の部分は, 最初からあるので新たに入力する必要のない部分.

課題05_01 定数でないディリクレ境界条件

差分解法を用いて, 区間 0.0 ≤ x ≤ 1.0, 0.0 ≤ t ≤ 6.0 で波動方程式 d2f/dt2(x,t)= v2 d2f/dx2(x,t) を解こう. ただし, v=0.5.

x=0側の境界条件は, ディリクレ境界条件(固定端) f(0,t)=0とする. x=1.0側の境界条件は, 次のディリクレ境界条件 f(0,t)=sin( 3 π(t-0.3)) (0.3<=t<=4.3), =0.0(それ以外) とする.

初期条件は, f(x,0)=0, df/dt(x,0)=0

差分の刻みは, x 方向が40, t 方向を200 とする.

これを解くのに, 課題 03_01 のクラス (を完成させたもの)を継承して, 次のようなクラス Sample05_01 をつくろう.

class Sample05_01 extends Sample03_01 {

    /** 初期条件 f(x,tmin) */
    double initial_f(double x){
	// 埋めてね *************************************************
    }

    /** 初期条件 df/dt(x,tmin) */
    double initial_dfdt(double x){ 
	 // 埋めてね *************************************************
     }
    
    /** ディリクレ境界条件 f(xmin,t) */
    double fmin(double t){ 
	// 埋めてね *************************************************
    }

    /** ディリクレ境界条件 f(xmax,t) */
    double fmax(double t){ 
	// 埋めてね *************************************************
    }	 

     public void initialize_parameters(){

	xmin=0.0; xmax=1.0; xinterval=40;
	tmin=0.0; tmax=6.0; tinterval=200; //ここ書き直したよ.
	v=0.5;			//ここ書き直したよ.

	dx=(xmax-xmin)/(double)xinterval;
	dt=(tmax-tmin)/(double)tinterval;
	v2=(v*dt/dx)*(v*dt/dx);
	return;//nothing
    }

    public static void main(String[] args){
	String myName = "香山リカ";

	Sample05_01 prog = new Sample05_01(); //ここ書き直したよ.
	RunInfo info= new RunInfo(myName, prog.getClass().getName());
	info.print();

	prog.initialize_parameters(); 
	prog.initialize_fields();
	prog.exec();
	return;//nothing
    }

}

次の looper.gp を利用して, gnuplot でアニメーションしよう.

plot [0:1][-4:4] "$0" every :::i::i using 2:3  
i=i+1
pause 0.7 
if(i< $1) reread
i=0

課題05_02 クラスの継承

差分解法を用いて, 区間 0.0 ≤ x ≤ 1.0, 0.0 ≤ t ≤ 5.3 で波動方程式 d2f/dt2(x,t)= v2 d2f/dx2(x,t) を解こう. ただし, v=0.2.

x=0側の境界条件は, ディリクレ境界条件 f(0,t)=-sin(4.0* π(t-0.3)) (0.3≤t), =0.0(それ以外) x=1.0側の境界条件は, ディリクレ境界条件 f(0,t)=sin( 3 π (t-0.3)) (0.3≤t), =0.0(それ以外) とする.

初期条件は, f(x,0)=0, df/dt(x,0)=0

差分の刻みは, x 方向が100, t 方向は, 計算が安定になるように定めよう. 100 と 200 の間くらいがいいはず.

これを解くのに, 課題 03_01 のクラス (を完成させたもの)を継承して, 次のようなクラス Sample05_02 をつくろう.

class Sample05_02 extends Sample03_01 {

    /** 初期条件 f(x,tmin) */
    double initial_f(double x){
	// 埋めてね *************************************************
    }

    /** 初期条件 df/dt(x,tmin) */
    double initial_dfdt(double x){ 
	// 埋めてね *************************************************
    }
    
    /** ディリクレ境界条件 f(xmin,t) */
    double fmin(double t){ 
	// 埋めてね *************************************************
    }

    /** ディリクレ境界条件 f(xmax,t) */
    double fmax(double t){ 
	// 埋めてね *************************************************
    }	 

    public void initialize_parameters(String[] args){ //引数をとるようにした
	//この中全面的に書き直したよ.
	xmin=0.0; xmax=1.0; xinterval=100;
	tmin=0.0; tmax=5.3; tinterval=100;
	v=0.2;

	//  加筆はじまり
	int i=0;
	while ( (i < args.length ) && ( (args[i]).startsWith("-"))){
	    switch( args[i].charAt(1) ){
	    case 'X':
		i++;
		xinterval=Integer.parseInt(args[i]);
		break;
	    case 'T':
		i++;
		tinterval=Integer.parseInt(args[i]);
		break;
	    case 't':
		i++;
		tmax=Double.parseDouble(args[i]);
		break;
	    case 'v':
		i++;
		v=Double.parseDouble(args[i]);
		break;
	    default:
		System.err.println("間違ったオプションです.");
		break;
	    }
	    i++;
	}    
	//  加筆おしまい
	 
	dx=(xmax-xmin)/(double)xinterval;
	dt=(tmax-tmin)/(double)tinterval;
	v2=(v*dt/dx)*(v*dt/dx);
	return;//nothing
    }

    public static void main(String[] args){
	String myName = "香山リカ";

	Sample05_02 prog = new Sample05_02(); //ここ書き直したよ.
	RunInfo info= new RunInfo(myName, prog.getClass().getName());
	info.print();

	prog.initialize_parameters(args);  //引数を与えるようにしたよ.
	prog.initialize_fields();
	prog.exec();
	return;//nothing
    }

}

このプログラムは,
s1609h111% java Sample05_02 -X 100 -T 200 -t 2.0 > datafile.1
のように実行することにより, 再コンパイルせずに, xinterval を 100, tinterval を 200, tmax を 2.0 に変更して実行できます. 上でいう, -X, -T, -t などを, コマンドラインオプションといいます.

コマンドラインオプションを指定して, 次の組合わせが安定かどうかを調べよう. なぜ安定か, 不安定か, 説明しよう.

上と同じ looper.gp を利用して, gnuplot でアニメーションしよう.

plot [0:1][-4:4] "$0" every :::i::i using 2:3  
i=i+1
pause 0.7 
if(i< $1) reread
i=0

Copyright © 2002 Saburo Higuchi. All rights reserved.
Saburo HIGUCHI, hig mail address
最後の更新 2002/05/12 Sun 13:18