23 for (
int i = 0; i < N; ++i) {
24 for (
int j = 0; j < N; ++j) {
43 for (
int i = 0; i < N; ++i) {
44 int ip = (i + 1) % N, im = (i + N - 1) % N;
45 const T* row = x.
data() + i * N;
46 const T* row_p = x.
data() + ip * N;
47 const T* row_m = x.
data() + im * N;
48 T* d = y.
data() + i * N;
50 d[0] = row_p[0] + row_m[0] + row[1] + row[N - 1] - T(4) * row[0];
51 for (
int j = 1; j < N - 1; ++j)
52 d[j] = row_p[j] + row_m[j] + row[j + 1] + row[j - 1] - T(4) * row[j];
53 d[N - 1] = row_p[N - 1] + row_m[N - 1] + row[0] + row[N - 2] - T(4) * row[N - 1];
67 for (
int i = 0; i < N; ++i) {
68 for (
int j = 0; j < N; ++j) {
70 T val = T(-30) * x[k];
73 val += T(16) * x[(i - 1) * N + j];
75 val += T(16) * x[(i + 1) * N + j];
78 val -= x[(i - 2) * N + j];
80 val -= x[(i + 2) * N + j];
83 val += T(16) * x[k - 1];
85 val += T(16) * x[k + 1];
123 real fx = std::fmod((px - ox) / h,
static_cast<real>(N));
124 real fy = std::fmod((py - oy) / h,
static_cast<real>(N));
129 idx i0 =
static_cast<idx>(fx) % N;
130 idx i1 = (i0 + 1) % N;
131 real fi = fx - std::floor(fx);
132 idx j0 =
static_cast<idx>(fy) % N;
133 idx j1 = (j0 + 1) % N;
134 real fj = fy - std::floor(fy);
135 return (1 - fi) * (1 - fj) * field[i0 * N + j0] + fi * (1 - fj) * field[i1 * N + j0]
136 + (1 - fi) * fj * field[i0 * N + j1] + fi * fj * field[i1 * N + j1];
140template<
typename T,
typename F>
142 std::vector<T> fiber(N);
143 for (
int j = 0; j < N; ++j) {
144 for (
int i = 0; i < N; ++i)
145 fiber[i] = data[i * N + j];
147 for (
int i = 0; i < N; ++i)
148 data[i * N + j] = fiber[i];
153template<
typename T,
typename F>
155 std::vector<T> fiber(N);
156 for (
int i = 0; i < N; ++i) {
157 for (
int j = 0; j < N; ++j)
158 fiber[j] = data[i * N + j];
160 for (
int j = 0; j < N; ++j)
161 data[i * N + j] = fiber[j];
168 for (
int i = 0; i < N; ++i) {
169 double xi = (i + 1) * h;
170 for (
int j = 0; j < N; ++j) {
171 u[
static_cast<std::size_t
>(i) * N + j] = f(xi, (j + 1) * h);
179 s.reserve(
static_cast<std::size_t
>(N));
180 for (
int j = 0; j < N; ++j) {
181 s.
store((j + 1) * h, u[
static_cast<std::size_t
>(row) * N + j]);
189 s.reserve(
static_cast<std::size_t
>(N));
190 for (
int i = 0; i < N; ++i) {
191 s.
store((i + 1) * h, u[
static_cast<std::size_t
>(i) * N + col]);
227 heatmap<ScalarField2D>(g, g.
N(), g.
h(), vmin, vmax);
238 auto flat = [&](
int i,
int j,
int k) ->
idx {
239 return static_cast<idx>(k * ny * nx + j * nx + i);
241 for (
int k = 0; k < nz; ++k)
242 for (
int j = 0; j < ny; ++j)
243 for (
int i = 0; i < nx; ++i) {
244 idx id = flat(i, j, k);
245 if (i == 0 || i == nx - 1 || j == 0 || j == ny - 1 || k == 0
250 * (6.0 * x[id] - x[flat(i + 1, j, k)] - x[flat(i - 1, j, k)]
251 - x[flat(i, j + 1, k)] - x[flat(i, j - 1, k)]
252 - x[flat(i, j, k + 1)] - x[flat(i, j, k - 1)]);
259 int nx =
phi.nx(), ny =
phi.ny(), nz =
phi.nz();
260 double inv2dx = 1.0 / (2.0 *
phi.dx());
261 for (
int k = 0; k < nz; ++k)
262 for (
int j = 0; j < ny; ++j)
263 for (
int i = 0; i < nx; ++i) {
264 int ip = std::min(i + 1, nx - 1), im = std::max(i - 1, 0);
265 int jp = std::min(j + 1, ny - 1), jm = std::max(j - 1, 0);
266 int kp = std::min(k + 1, nz - 1), km = std::max(k - 1, 0);
267 gx(i, j, k) = (
phi(ip, j, k) -
phi(im, j, k)) * inv2dx;
268 gy(i, j, k) = (
phi(i, jp, k) -
phi(i, jm, k)) * inv2dx;
269 gz(i, j, k) = (
phi(i, j, kp) -
phi(i, j, km)) * inv2dx;
278 int nx = fx.
nx(), ny = fx.
ny(), nz = fx.
nz();
279 double inv2dx = 1.0 / (2.0 * fx.
dx());
280 for (
int k = 0; k < nz; ++k)
281 for (
int j = 0; j < ny; ++j)
282 for (
int i = 0; i < nx; ++i) {
283 int ip = std::min(i + 1, nx - 1), im = std::max(i - 1, 0);
284 int jp = std::min(j + 1, ny - 1), jm = std::max(j - 1, 0);
285 int kp = std::min(k + 1, nz - 1), km = std::max(k - 1, 0);
287 ((fx(ip, j, k) - fx(im, j, k)) + (fy(i, jp, k) - fy(i, jm, k))
288 + (fz(i, j, kp) - fz(i, j, km)))
300 int nx = ax.
nx(), ny = ax.
ny(), nz = ax.
nz();
301 double inv2dx = 1.0 / (2.0 * ax.
dx());
302 for (
int k = 0; k < nz; ++k)
303 for (
int j = 0; j < ny; ++j)
304 for (
int i = 0; i < nx; ++i) {
305 int ip = std::min(i + 1, nx - 1), im = std::max(i - 1, 0);
306 int jp = std::min(j + 1, ny - 1), jm = std::max(j - 1, 0);
307 int kp = std::min(k + 1, nz - 1), km = std::max(k - 1, 0);
309 (az(i, jp, k) - az(i, jm, k) - ay(i, j, kp) + ay(i, j, km)) * inv2dx;
311 (ax(i, j, kp) - ax(i, j, km) - az(ip, j, k) + az(im, j, k)) * inv2dx;
313 (ay(ip, j, k) - ay(im, j, k) - ax(i, jp, k) + ax(i, jm, k)) * inv2dx;
2D uniform interior grid: geometry only, no field data.
3D Cartesian scalar grid backed by num::Vector storage.
void heatmap(const ScalarField2D &g, double vmin=0.0, double vmax=1.0)
void laplacian_stencil_2d(const BasicVector< T > &x, BasicVector< T > &y, int N)
void row_fiber_sweep(BasicVector< T > &data, int N, F &&f)
Apply a mutable 1D operation to each row fiber.
constexpr real phi
Golden ratio.
void curl_3d(const Grid3D &ax, const Grid3D &ay, const Grid3D &az, Grid3D &bx, Grid3D &by, Grid3D &bz)
Compute with central differences.
void neg_laplacian_3d(const Vector &x, Vector &y, int nx, int ny, int nz, double inv_dx2)
Compute on a 3D grid.
real sample_2d_periodic(const Vector &field, idx N, real h, real px, real py, real ox, real oy)
void laplacian_stencil_2d_4th(const BasicVector< T > &x, BasicVector< T > &y, int N)
Fourth-order 2D Laplacian cross stencil.
Series col_slice(const Vector &u, int N, double h, int col)
Extract one column as plot data.
void laplacian_stencil_2d_periodic(const BasicVector< T > &x, BasicVector< T > &y, int N)
Periodic second-order 2D Laplacian stencil.
void divergence_3d(const Grid3D &fx, const Grid3D &fy, const Grid3D &fz, Grid3D &out)
Compute with central differences.
void gradient_3d(const Grid3D &phi, Grid3D &gx, Grid3D &gy, Grid3D &gz)
Compute with central differences.
void col_fiber_sweep(BasicVector< T > &data, int N, F &&f)
Apply a mutable 1D operation to each column fiber.
Series row_slice(const Vector &u, int N, double h, int row)
Extract one row as plot data.
void fill_grid(Vector &u, int N, double h, F &&f)
Fill grid values at .
Matplotlib-style plotting via a gnuplot pipe.
Scalar field on a 2D uniform interior grid.
void store(double x, double y)
Dense vector storage and operations.