1次元区間
における熱伝導方程式の初期値境界値問題
(
|
||
ここで
は時刻
での初期温度分布である。
時間発展する系なので、
各時刻
での差分解
のグラフを描くことにする。
差分法の説明は、例えば 「発展系の数値解析」 に載っている。
/*
* heat1d-gnuplot.c --- 1次元領域の熱伝導方程式
* u_t=u_{xx}, 同次Dirichlet境界条件
*/
#include <stdio.h>
#include <math.h> // floor()
#include <stdlib.h> // malloc()
#include <unistd.h> // sleep()
// 初期条件
double u0(double x)
{
if (x < 0.5)
return x;
else
return 1.0 - x;
}
int main(void)
{
int N, i, n, nMax, nskip;
double Tmax, tau, h, t, lambda, c, dt;
double *x, *u, *newu;
FILE *gp;
Tmax = 0.5; // 最終時刻
dt = 0.01; // 描画間隔
// 分割
N = 50;
h = 1.0 / N;
lambda = 0.5; // λ=τ/h^2
tau = lambda * h * h;
nskip = rint(dt / tau); if (nskip == 0) nskip = 1;
nMax = Tmax / tau;
printf("N=%d, h=%g, tau=%g, nskip=%d\n", N, h, tau, nskip);
// メモリー確保
x = malloc(sizeof(double) * (N+1));
u = malloc(sizeof(double) * (N+1));
newu = malloc(sizeof(double) * (N+1));
if (x == NULL || u == NULL || newu == NULL) {
fprintf(stderr, "メモリー確保に失敗しました。\n");
exit(1);
}
// gnuplot を呼び出す
if ((gp = popen("gnuplot -persist", "w")) == NULL) {
fprintf(stderr, "gnuplot 呼び出しに失敗しました。\n");
exit(1);
}
// fprintf(gp, "set term gif animate\n");
// fprintf(gp, "set output \"heat1d.gif\"\n");
fprintf(gp, "set yrange [-0.01:0.5]\n");
fprintf(gp, "set xlabel \"x\"\n");
fprintf(gp, "set ylabel \"u\"\n");
fprintf(gp, "set label \"1D heat equation\" at screen 0.4,0.95\n");
// 初期値
t = 0;
for (i = 0; i <= N; i++) {
x[i] = i * h;
u[i] = u0(x[i]);
}
// 初期値を描く
fprintf(gp, "plot '-' with lines title \"t=0\"\n");
for (i = 0; i <= N; i++) {
fprintf(gp, "%f %f\n", x[i], u[i]);
}
fprintf(gp, "e\n"); fflush(gp);
sleep(3);
// 時間を進める
c = 1 - 2.0 * lambda;
for (n = 1; n <= nMax; n++) {
t = n * tau;
for (i = 1; i < N; i++)
newu[i] = c * u[i] + lambda * (u[i+1]+u[i-1]);
newu[0] = newu[N] = 0.0;
for (i = 0; i <= N; i++)
u[i] = newu[i];
if (n % nskip == 0) {
fprintf(gp, "plot '-' with lines title \"t=%g\"\n", t);
for (i = 0; i <= N; i++)
fprintf(gp, "%f %f\n", x[i], u[i]);
fprintf(gp, "e\n"); fflush(gp);
}
}
pclose(gp);
return 0;
}
| Mac のターミナルの場合: プログラムの入手、コンパイル、実行 |
curl -O http://nalab.mind.meiji.ac.jp/~mk/misc/20191229/heat1d-gnuplot.c cc heat1vi d-gnuplot.c ./a.out(Xcode の cc, GNU の gcc で動作確認済み) |