1 // 菊地文雄, 山本昌宏「微分方程式と計算機演習」, 山海堂 (1991), p. 65
2 /* ** FINITE DIFFERENCE METHOD **
3 ** FOR -FNU D2U/Dx2+DU/DX=F **
4 FNU : DIFFUSIVITY
5 N : NO. OF DIVISIONS
6 METHOD : METHOD NUMBER
7 H : MESH SIZE
8 A,B,C : COEFFICIENT MATRIX
9 F : FREE TERM & SOLUTION VECTOR
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #define NDIM (100)
15 void trid(double a[], double b[], double c[], double f[], int n);
16
17 int main(void)
18 {
19 int n, i, method;
20 double fnu, h, h2; // fnu は nu でも良いかも。
21 double a[NDIM], b[NDIM], c[NDIM], f[NDIM], x[NDIM];
22 printf("INPUT : FNU=\n");
23 scanf("%lf", &fnu);
24 printf("INPUT : N=\n");
25 scanf("%d", &n);
26 if (n <= 1) exit(1);
27 printf("BACKWARD : METHOD=1, CENTRAL : =2, FORWARD : =3\n");
28 printf("INPUT : METHOD=\n");
29 scanf("%d", &method);
30 h = 1.0 / n; // (double) n とする必要もないでしょう。
31 h2 = h * h; // Cに冪乗演算子はないので、乗算で代用
32 for (i=0; i<n-1; i++) {
33 a[i] = - fnu / h2;
34 b[i] = 2.0 * fnu / h2;
35 c[i] = - fnu / h2;
36 if (method == 1) {
37 // BACKWARD
38 a[i] -= 1.0 / h;
39 b[i] += 1.0 / h;
40 }
41 else if (method == 2) {
42 // CENTRAL
43 a[i] -= 0.5 / h;
44 c[i] += 0.5 / h;
45 }
46 else {
47 // FORWARD
48 b[i] -= 1.0 / h;
49 c[i] += 1.0 / h;
50 }
51 f[i] = 1.0;
52 }
53 trid(a,b,c,f,n-1);
54 printf("DIFFUSIVITY=%12.4e MESH SIZE=%12.4e METHOD=%2d\n",
55 fnu, h, method);
56 printf("** NODAL VALUES OF SOLUTION **\n");
57 for (i = 0; i < 5; i++)
58 printf(" I U(I) ");
59 printf("\n");
60 for (i=0; i<n-1; i++) {
61 printf("%3d%12.4e ", i+1, f[i]);
62 if ((i+1) % 5 == 0 || (i+1) == n-1)
63 printf("\n");
64 }
65 }
66
67 void trid(double a[], double b[], double c[], double f[], int n)
68 {
69 int i;
70 double aa;
71 // FORWARD ELIMITNATION
72 for (i=0; i<n-1; i++) {
73 aa = a[i+1] / b[i];
74 b[i+1] -= aa * c[i];
75 f[i+1] -= aa * f[i];
76 }
77 // BACKWARD SUBSTITUTION
78 f[n-1] /= b[n-1];
79 for (i=n-2; i>= 0; i--)
80 f[i] = (f[i] - c[i]*f[i+1]) / b[i];
81 }
桂田 祐史
2018-06-08