Public
Edited
Jan 14, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// The function u(x,t) that we actually plot.
// Cheat at time t=0 by using u0.
function u(x, t) {
if (t == 0) {
return u0_compiled.evaluate({ x: x });
} else {
return u_fourier(x, t);
}
}
Insert cell
// Compute the solution in terms of of the inputs.
u_fourier = uu(
a, // Temperature at left
b, // Temperature at right,
D, // Diffusitivity
x => f.evaluate({ x: x }), // Source
x => u0_compiled.evaluate({ x: x }) // Initial temperature distribution
)
Insert cell
// Use mathjs to parse u0 into computable code.
u0_compiled = math.compile(u0_text)
Insert cell
// Also use mathjs to parse f into computable code.
f = math.compile(f_text)
Insert cell
Insert cell
Insert cell
// This function takes the inputs and returns u(x,t) in terms of the appropriate Fourier series
function uu(a, b, D, f, u0) {
let N = 30;
let pi = Math.PI;
let exp = Math.exp;
let sin = Math.sin;
let cos = Math.cos;

let u;
if (!insulate_left && !insulate_right) {
let f_coeffs = d3
.range(1, N + 1)
.map(k => int(x => f(x) * sin(k * pi * x), 0, 1, 1e-10, 10, 5));
let u0_coeffs = d3
.range(1, N + 1)
.map(k => int(x => u0(x) * sin(k * pi * x), 0, 1, 1e-10, 10, 5));
u = (x, t) => {
return (
a +
(b - a) * x +
2 *
d3.sum(
d3.range(1, N + 1).map(function(k) {
let dkp2 = D * k ** 2 * pi ** 2;
let e = exp(-dkp2 * t);
return (
((f_coeffs[k - 1] * (1 - e)) / dkp2 +
e * (((-1) ** k * b - a) / (k * pi) + u0_coeffs[k - 1])) *
sin(k * pi * x)
);
})
)
);
};
} else if (!insulate_left && insulate_right) {
let f_coeffs = d3
.range(1, N + 1)
.map(k => int(x => f(x) * sin((k - 1 / 2) * pi * x), 0, 1, 1e-10, 10, 5));
let u0_coeffs = d3
.range(1, N + 1)
.map(k =>
int(x => (u0(x) - a) * sin((k - 1 / 2) * pi * x), 0, 1, 1e-10, 10, 5)
);
u = (x, t) => {
return (
a +
2 *
d3.sum(
d3.range(1, N + 1).map(function(k) {
let d2km1p2 = (D * (2 * k - 1) ** 2 * pi ** 2) / 4;
let e = exp(-d2km1p2 * t);
return (
((f_coeffs[k - 1] * 4 * (1 - e)) /
(D * (pi - 2 * k * pi) ** 2) +
e * u0_coeffs[k - 1]) *
sin((k - 1 / 2) * pi * x)
);
})
)
);
};
} else if (insulate_left && !insulate_right) {
let f_coeffs = d3
.range(1, N + 1)
.map(k => int(x => f(x) * cos((k - 1 / 2) * pi * x), 0, 1, 1e-10, 10, 5));
let u0_coeffs = d3
.range(1, N + 1)
.map(k =>
int(x => (u0(x) - b) * cos((k - 1 / 2) * pi * x), 0, 1, 1e-10, 10, 5)
);
u = (x, t) => {
return (
b +
2 *
d3.sum(
d3.range(1, N + 1).map(function(k) {
let d2km1p2 = (D * (2 * k - 1) ** 2 * pi ** 2) / 4;
let e = exp(-d2km1p2 * t);
return (
((f_coeffs[k - 1] * 4 * (1 - e)) /
(D * (pi - 2 * k * pi) ** 2) +
e * u0_coeffs[k - 1]) *
cos((k - 1 / 2) * pi * x)
);
})
)
);
};
} else if (insulate_left && insulate_right) {
let f_coeffs = d3
.range(1, N + 1)
.map(k => int(x => f(x) * cos(k * pi * x), 0, 1, 1e-10, 10, 5));
let u0_coeffs = d3
.range(1, N + 1)
.map(k => int(x => u0(x) * cos(k * pi * x), 0, 1, 1e-10, 10, 5));
let f_int = int(f, 0, 1, 1e-10, 10, 5);
let u0_int = int(u0, 0, 1, 1e-10, 10, 5);
u = (x, t) => {
return (
u0_int +
t * f_int +
2 *
d3.sum(
d3.range(1, N + 1).map(function(k) {
let dkp2 = D * k ** 2 * pi ** 2;
let e = exp(-dkp2 * t);
return (
((f_coeffs[k - 1] * (1 - e)) / dkp2 + e * u0_coeffs[k - 1]) *
cos(k * pi * x)
);
})
)
);
};
}
return u;
}
Insert cell
Insert cell
Insert cell
example_init = ({
"constant, inconsistent endpoints": "1",
lopsided: "5x*(1-x)^2",
"lopsided, with constant source": "5x*(1-x)^2",
"lopsided, inconsistent right": "5x*(1-x)^2",
"step, fixed ends": "x<1/2 ? -1 : 1",
"all zero with asymmetric heat source": "0",
"step, insulated ends": "x<1/2 ? -1 : 1"
})
Insert cell
example_source = ({
"constant, inconsistent endpoints": "0",
lopsided: "0",
"lopsided, with constant source": "1",
"lopsided, inconsistent right": "0",
"step, fixed ends": "0",
"all zero with asymmetric heat source": "10x",
"step, insulated ends": "0"
})
Insert cell
example_left = ({
"constant, inconsistent endpoints": "0",
lopsided: "0",
"lopsided, with constant source": "0",
"lopsided, inconsistent right": "0",
"step, fixed ends": "-1",
"all zero with asymmetric heat source": "0",
"step, insulated ends": "-1"
})
Insert cell
example_right = ({
"constant, inconsistent endpoints": "0",
lopsided: "0",
"lopsided, with constant source": "0",
"lopsided, inconsistent right": "1",
"step, fixed ends": "1",
"all zero with asymmetric heat source": "0",
"step, insulated ends": "1"
})
Insert cell
example_D = ({
"constant, inconsistent endpoints": 0.5,
lopsided: 0.5,
"lopsided, with constant source": 0.5,
"lopsided, inconsistent right": 0.2,
"step, fixed ends": 0.2,
"all zero with asymmetric heat source": 0.5,
"step, insulated ends": 0.2
})
Insert cell
example_insulate_left = ({
"constant, inconsistent endpoints": false,
lopsided: false,
"lopsided, with constant source": false,
"lopsided, inconsistent right": false,
"step, fixed ends": false,
"all zero with asymmetric heat source": false,
"step, insulated ends": "true"
})
Insert cell
example_insulate_right = ({
"constant, inconsistent endpoints": false,
lopsided: false,
"lopsided, with constant source": false,
"lopsided, inconsistent right": false,
"step, fixed ends": false,
"all zero with asymmetric heat source": false,
"step, insulated ends": "true"
})
Insert cell
Insert cell
d3 = require('d3-selection@2', 'd3-array@2', 'd3-format@2')
Insert cell
import { adaptiveSimpson as int } from '@rreusser/integration'
Insert cell
import { slider, text, checkbox, select } from "@jashkenas/inputs"
Insert cell
import { Scrubber } from "@mbostock/scrubber"
Insert cell
functionPlot = require("function-plot@1/dist/function-plot")
Insert cell
math = require('mathjs@7')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more