偏微分方程式の解法 熱拡散問題 図のような金属の棒がある。金属の両端の温度は T=0 に設定されている x=L/2 x=0 時刻 t=0 で 温度分布が右図で表されている ような分布であったとすると T T ( x 0, t 0) 0 x=L T=T0 T ( x L, t 0) 0 時刻 t=t での温度分布はどうなっているか? これを数値計算で求める。 偏微分方程式の解法(熱拡散問題) 偏微分方程式の解法(熱拡散方程 式) 熱の熱拡散は次の方程式で求めることが出来る。 T T 2 t x 2 初期条件 x T (x,0) 2T0 L x T (x,0) 2T0 1 L (x L / 2) (x L / 2) 偏微分方程式の解法 (差分メッシュ) T[0] T[1] T[2] x0 x1 x=0 x軸を N 等分 x2 T[i] T[N] xi x xN x=L x L / N 位置 xi ix における温度を T[i] に記憶。 配列要素は N+1 個必要 double 棒の両端の温度は 0 に固定 T[N+1]; T[0]=0 T[N]=0 差分化 T T 2 t x 2 T 1 T ( x, t t ) T ( x, t ) t t T 1 T ( x x, t ) 2T ( x, t ) T ( x x, t ) 2 2 x ( x ) 2 T (x,t t) T (x,t) t T (x x,t) 2T (x,t) T (x x,t) 2 (x) T[0], T[1], …, T[N] だけでは足りない。 各 i 毎に2個の温度を記憶する必要がある 配列の宣言は double T[N+1][2]; となる。 T[0][0], T[1][0], T[2][0], …, T[N][0] T[0][1], T[1][1], T[2][1], …, T[N][1] t T (xi ,t t) T (xi ,t) T (xi 1,t) 2T (xi ,t) T (xi 1,t) 2 (x) x0 0 xi 1 xi x xi xi 1 xi x t T[0][now] … T[i-1][now] T[i][now] T[i+1][now] … t t T[0][new] … T[i-1][new] T[i][new] T[i+1][new] … 偏微分方程式の解法 (差分メッシュ) 計算の進め方 step=0 (初期状態) step=0 now=0 new=1 T[i][0] から T[i][1] を計算 step=1 step=2 t 0 t t step=3 step=1 now=1 new=0 T[i][1] から T[i][0] を計算 step=5 step=2 now=0 new=1 step=4 t t t 2t T[i][0] から T[i][1] を計算 step=6 t 2t now=0 now=1 new=1 new=0 t 3t 偏微分方程式の解法 (差分メッシュ) step=0 T(i,0) step=2 T(i,0) step=4 T(i,0) step=1 T(i,1) step=3 T(i,1) now= step % 2 new= (step+1) % 2 とすると step=0 now=0 step=1 now=1 step=2 now=0 ….. が実現出来る。 new=1 new=0 new=1 T (x,t t) T (x,t) t T (x x,t) 2T (x,t) T (x x,t) 2 (x) a = kappa*dt/(dx*dx); T[i][new] = T[i][now] + a*(T[i+1][now]-2*T[i][now]+T[i-1][now]); #include <stdio.h> #define N 10 /* x 軸の分割数。定数でなければならない */ int main() { double T0, L, dx; double kappa, dt, tmax, a; double T[N+1][2]; int i, now, new; int step, nstep; int nout, m; /* 計算条件 */ T0 = 100.0; /* L = 1.0; /* kappa = 1.0; /* dt = 0.002; tmax = 0.5; /* nout = 10; /* dx = L/N; a = kappa*dt/(dx*dx); nstep = tmax/dt; m = nstep/nout; (続く) 中心の温度 */ 棒の長さ */ 熱拡散係数 */ 時間刻み幅と最終時刻 */ 出力回数 */ /* x軸の刻み幅 */ /* 計算回数 */ /* 出力間隔 */ /* 初期温度を設定 */ now = 0; new = 1; for(i=0; i<N/2; ++i) { T[i][now] = i*2.0*T0/N; } for(i=N/2; i<=N; ++i) { T[i][now] = (N-i)*2.0*T0/N; } T[0][new] = 0.0; T[N][new] = 0.0; /* 境界条件: 両端は常に T=0 */ /* 各時刻の温度を計算 */ for(step=0; step<nstep; ++step) { /* m ステップ毎に温度を出力 */ if(step % m == 0) { for(i=0; i<=N; ++i) { printf("%f\t%f\n", i*dx, T[i][now]); } printf("\n\n"); /* 空行を2行出力 */ } /* now と new の設定 */ now = step % 2; new = (step+1) % 2; /* 各点の新しい温度を計算 */ for(i=1; i<N; ++i) { /* 両端 i=0,N は計算しない */ T[i][new] = T[i][now] + a*(T[i+1][now] - 2.0*T[i][now] + T[i-1][now]); } } return 0; } gnuplot に複数のグラフを一度に描かせる 1.0 2.0 3.0 1.0 2.0 2.5 3.0 1.2 1.8 2.2 1.7 1.9 2.3 2.8 1つめのグラフのデータ 空行2行以上 2つめのグラフのデータ
© Copyright 2025 ExpyDoc