Appearance
The isolated Poisson solver
| ID | Group | Milestone | Backends | Figure | Regression |
|---|---|---|---|---|---|
| SV-6 | Self-gravity | M8 (#81), P4 | CPU, FNL | yes | selfgravity-star (through the star it solves for) |
Case and scope
On a periodic domain a self-gravitating object feels its own images, and the mean density must be removed. Isolated boundaries give the free-space potential,
The method (poisson_bc = isolated). Hockney and Eastwood's zero padding: the density sits in an array of
The kernel. scripts/lattice_green.py into adam_lattice_green_library (6545 values, the wedge
- near field,
: the Dirichlet problem on the cube , solved exactly by a type-I sine transform, with the far-field series on its faces; - far field: the series
, , , , , each term solving its order of the Taylor series of (checked symbolically). The series leaves one coefficient free in and one in (the cubic harmonics of degree 4 and 6); the lattice fixes them, and they are fitted to the table (least squares over ).
What the case catches:
- a kernel that is not the lattice Green's function of
(a sampled continuum kernel, a bad table/series seam): the residual of leaves the kernel's level; - a padding too small for the offsets the scatter reads: the error against the exact potential on the ghosts and the padded far field;
- a wrong mass normalisation or sign: the error against the exact potentials outside the source (
); - a solver that accepts a configuration it cannot solve: the scope is fatal otherwise (3-D, every direction non-periodic, cubic cells: the kernel is the unit lattice's).
Models and numerics
| Item | Choice | Code |
|---|---|---|
| Equation | models | |
| Solver, CPU | FFTW, zero padding to | initialize_blocks, make_kernel, transform, transform_kernel, adam_poisson_fft_object.F90 |
| Solver, FNL | cuFFT on rank 0's GPU | transform_kernel_fnl, spectral_convolve_dev, kernel_spectrum_dev, adam_fnl_poisson_fft_object.F90 |
| Kernel | the lattice Green's function: table for LGF_RADIUS), series | adam_lattice_green_library.F90, generated by scripts/lattice_green.py |
| Selection | [gravity] poisson_bc = isolated | load_from_file, adam_flume_gravity_object.F90 |
Initial and boundary conditions
| Item | Value |
|---|---|
| Domain | the cube |
| Grid | octree levels 1–3 ( |
| Ranks | CPU: 1, 2, 3; FNL: 1, 2 |
| Factor | |
| Source 1: the n = 1 polytrope | |
| Source 2: the uniform sphere | |
| Refusals | --refuse-isolated-periodic (a periodic grid), --refuse-isolated-anisotropic (cells --refuse-isolated-2d (null |
Generator checks (deterministic, scripts/lattice_green.py):
| Check | Bound | Measured |
|---|---|---|
| residual of | ||
| residual of | ||
Input files
| File | Role |
|---|---|
src/tests/poisson/test_poisson_fft.F90 | the unit test, --isolated (and the three --refuse-isolated-* flags) |
src/tests/flume/verification/selfgravity/poisson.sh | leg sv6: the test on every rank count of --np-list, and the refusals; --dump DIR covers SV-6 too |
src/tests/flume/verification/selfgravity/poisson_oracle.py | compare DIR_CPU DIR_FNL on the padded arrays |
scripts/lattice_green.py | generates adam_lattice_green_library.F90 and runs the generator checks |
src/tests/flume/verification/make_doc_runs.sh, group isolated | sv6-poisson: the test with its log and dumps |
src/tests/flume/verification/make_doc_figures.py, fig_selfgravity_isolated | draws the figure (--only selfgravity-isolated) |
bash
python3 scripts/lattice_green.py --check # generator checks; the committed module against a fresh emission
cd src/tests/flume/verification/selfgravity
./poisson.sh --legs sv6 # CPU (FFTW)
POISSON_EXE=$PWD/../../../../../exe/test_poisson_fft_fnl ./poisson.sh --legs sv6 --np-list "1 2" # FNL (cuFFT)Results

Left: the error against the exact potentials falls as
| Asserted | Bound | CPU (FFTW) | FNL (cuFFT, A30 and the WSL GPU) |
|---|---|---|---|
| residual of | |||
| least-squares order against the exact | 2.03 | 2.03 | |
| the same, uniform sphere | 1.35 | 1.35 | |
| ghost cells left unfilled | 0 | 0 | 0 |
| isolated on a periodic grid, with non-cubic cells, in 2-D | refused, exit 1 | refused | refused |
CPU against FNL (poisson_oracle.py compare, the padded arrays) |
Related cases: the periodic solver is SV-2; the stars it holds and collapses are SV-7 and SV-8; isolated boundaries on AMR are the multigrid's James step (#87, SV-13, SV-14).
Findings
- The kernel series needs
and . With alone the composite residual was , concentrated on the cube's faces, and summed over a source it showed as a residual of in ; with and they are and . - The residual is the kernel's, not round-off. It is
while every offset lies inside the table ( , ) and at , where the offsets reach the series: about per offset, summed over the source cells. At (measured once, 6 ranks) it is . - The polytrope converges at second order (2.14, 1.92, 2.02 per pair from
to ; the dip is the kink of its density at the surface). The uniform sphere converges irregularly (0.6, 2.1, 1.75): its surface cuts cells, and the bound only asserts better than first order. - Conservation needs symmetry, not a round-off residual. The convolution with an even kernel is a symmetric linear map, which is what the exact exchange of
and needs (models): SV-8 measures it. - The error is largest at the centre, where the potential is deepest.