Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -1,15 +1,29 @@
using PyPlot;

asoln(x, y, t) = exp(0.75 * t) * sin(2 * x * y) * cosh(1.5 * (x + y));

const debug_flag = true;

macro if_debug(code)
if debug_flag
return code;
end
end

for h in [1/10; 1/20; 1/40]
const k = h;
w = open("h-$h.csv", "w");

const μ = 1.0;
const k = μ * h*h;
println("k = $k, h = $h");

const aax = -k / (2 * h*h);
const bbx = (k / (h*h) + 1);
const ccx = aax;

const aay = -k / (h*h);
const bby = (2 * k / (h*h) + 1);
const ccy = aax;
const ccy = aay;

xs = linspace(0.0, 1.0, Int(round(1.0 / h)));
ys = copy(xs);
@@ -20,8 +34,22 @@ for h in [1/10; 1/20; 1/40]
for (m, x) in zip(1:M, xs), (l, y) in zip(1:L, ys)
u[m, l, 1] = asoln(x, y, 0);
end

@time for n in 1:K-1
u_debug = (debug_flag) ? zeros(M, L, K) : zeros(1, 1, 1);
@if_debug(for (m, x) in zip(1:M, xs), (l, y) in zip(1:L, ys)
u_debug[m, l, 1] = asoln(x, y, 0);
end);

for n in 1:K-1
# calculate boundary terms
for l in 1:L
u[1, l, n+1] = asoln(0.0, ys[l], ts[n+1]);
u[M, l, n+1] = asoln(1.0, ys[l], ts[n+1]);
end
for m in 2:M-1
u[m, 1, n+1] = asoln(xs[m], 0.0, ts[n+1]);
u[m, L, n+1] = asoln(xs[m], 1.0, ts[n+1]);
end

for l in 2:L-1 # consider boundary terms
# calculate pi and qi for Thomas' algorithm
p = zeros(L);
@@ -32,15 +60,15 @@ for h in [1/10; 1/20; 1/40]
(u[m, l+1, n] - 2 * u[m, l, n] + u[m, l-1, n]));
denom = aax * p[m] + bbx;
p[m+1] = -ccx / denom;
q[m+1] = (ddx - aax * q[m]) / denom;
q[m+1] = (dd - aax * q[m]) / denom;
end
u[M, l, n+1] = asoln(1.0, ys[l], ts[n+1]);
for m=M-1:-1:1
for m=M-1:-1:2
u[m, l, n+1] = p[m+1] * u[m+1, l, n+1] + q[m+1];
end
end

for m in 1:M
for m in 2:M-1
# calculate pi and qi for Thomas' algorithm
p = zeros(M);
q = zeros(M);
@@ -51,18 +79,34 @@ for h in [1/10; 1/20; 1/40]
(u[m+1, l, n+1] - 2 * u[m, l, n+1] + u[m-1, l, n+1]));
denom = aay * p[m] + bby;
p[m+1] = -ccy / denom;
q[m+1] = (ddy - aay * q[m]) / denom;
q[m+1] = (dd - aay * q[m]) / denom;
end
u[m, L, n+1] = asoln(xs[m], 1.0, ts[n+1]);
for m=M-1:-1:1
for l=L-1:-1:2
u[m, l, n+1] = p[m+1] * u[m, l+1, n+1] + q[m+1];
end
end

err = zeros(M, L);
for (m, x) in zip(1:M, xs), (l, y) in zip(1:L, ys)
err[m, l] = u[m, l, n+1] - asoln(x, y, ts[n+1]);
@if_debug(begin
for l in 1:L
u_debug[1, l, n+1] = asoln(0.0, ys[l], ts[n+1]);
u_debug[M, l, n+1] = asoln(1.0, ys[l], ts[n+1]);
end
for m in 2:M-1
u_debug[m, 1, n+1] = asoln(xs[m], 0.0, ts[n+1]);
u_debug[m, L, n+1] = asoln(xs[m], 1.0, ts[n+1]);
end
for l in 2:L-1, m in 2:M-1
u_debug[m, l, n+1] = k / (h*h) * (u_debug[m+1, l, n] - 2 * u_debug[m, l, n]
+ u_debug[m-1, l, n] +
2 * (u_debug[m, l+1, n] - 2 * u_debug[m, l, n]
+ u_debug[m, l-1, n])) + u_debug[m, l, n];
end
end);

for m in 1:M, l in 1:L
write(w, "$(ts[n+1]), $(xs[m]), $(ys[l]), $(u[m, l, n+1]), $(asoln(xs[m], ys[l], ts[n+1])), $(u_debug[m, l, n+1])\n");
end
println("Error at t=$(ts[n+1]): ", norm(err, 2));
end
close(w);
end