CFFT Acceleration
Overview
Standard FFT-based SCFT solvers operate on the full $N^3$ grid, which contains redundant information when the crystal phase has high space group symmetry. Polyorder.jl integrates CrystallographicFFT.jl to exploit this redundancy through a Crystallographic FFT (CFFT) mode, operating on a symmetry-reduced subgrid $M^3$ where $M_i = N_i / L_i$.
Key benefits:
- Universal Symmetry Support: Works for all 230 space groups — including those with glide/screw symmetry (e.g., Gyroid SG 230 $Ia\bar{3}d$) that DCT cannot handle.
- Significant Speedup: MDE solving runs ~$L^3 \times$ faster. For Pm-3m ($L=2$): ~8×; for Ia-3d ($L=2$): ~8× with additional star compression. A further ~2× from real FFT (
rfft/irfft) vs complex FFT. - Memory Reduction: Solver buffers reduced by $L^3 \times$. Combined with SymmetricStorage: up to 99% total memory savings.
- Machine Precision: Mathematically equivalent to full FFT solver ($|\Delta F| < 10^{-14}$).
Mathematical Basis
Subgrid Decomposition
For a space group $G$ with point group $P$ acting on an $N^3$ grid, the symmetry-independent information lives on a subgrid of size $M^3 = (N/L)^3$, where $L$ is the stride factor determined by the space group and grid dimensions.
The CFFT algorithm (KRFFT) decomposes the full $N^3$ DFT into:
- An $M^3$ FFT on the subgrid
- A reconstruction step that maps $M^3$ spectral coefficients to the $n_\text{spec}$ points of the spectral ASU (Asymmetric Unit)
This is exact: the subgrid retains all symmetry-independent spatial information, and reconstruction recovers the full spectrum at uniquely determined ASU wave vectors.
Spectral ASU Operations
The spectral ASU is the minimal set of independent Fourier modes under the space group. All spectral operations (diffusion kernel $e^{-k^2 \Delta s}$, stress tensor) can be computed directly on the spectral ASU without ever touching the full $N^3$ grid:
- Diffusion kernel (
cfft_k2): $k^2$ values at spectral ASU points - Stress tensor (
cfft_kk_orbsum): Orbit-averaged $k_\alpha k_\beta$ for each Voigt component
MDE Solving on Subgrid
The Operator Splitting Formula (OSF) for the Modified Diffusion Equation:
\[q(\mathbf{r}, s + \Delta s) = e^{-w \Delta s / 2} \cdot \text{ICFFT}\left[ e^{-k^2 b^2 \Delta s / 6} \cdot \text{CFFT}\left[ e^{-w \Delta s / 2} \cdot q(\mathbf{r}, s) \right] \right]\]
All operations occur on the $M^3$ subgrid (real-space multiplication) and $n_\text{spec}$-point spectral ASU (spectral multiplication). The full $N^3$ grid is never allocated or accessed.
Architecture
CFFTAuxiliaryField
The core type representing a field on the subgrid:
struct CFFTAuxiliaryField{...} <: AbstractAuxiliaryField
data::A # Size: M³ = (Nx/L, Ny/L, Nz/L). CPU Array or CuArray.
lattice::BravaisLattice # Full lattice (with physical dimensions)
cfft_pair::PP # Bidirectional real CFFT plan (rcfft! / ircfft!)
sg_num::Int # Space group number (1–230)
N_full::NTuple{3, Int} # Full grid dimensions
star_map::SubgridStarMap # Weighted integration map
endAll internal buffers (stress tensor, spectral work arrays, propagator storage) are device-aware: they are allocated on the same device as data using KernelAbstractions.allocate or similar(data, ...), ensuring seamless CPU/GPU operation.
Pipeline: MDE Solve
q(M³) ──→ exp(-w·ds/2) (pointwise, M³)
──→ rcfft! (M³ → n_spec complex, via rfft)
──→ exp(-k²·ds) (pointwise, n_spec)
──→ ircfft! (n_spec → M³, via irfft)
──→ exp(-w·ds/2) (pointwise, M³)
──→ q(M³, s+ds)Pipeline: Stress Tensor (Spectral ASU)
Instead of FFT on $N^3$, stress is computed entirely in the spectral ASU:
\[S_{\alpha\beta}(s) = -\frac{1}{N^6} \sum_{i=1}^{n_\text{spec}} \overline{\hat{q}_i(s)} \cdot \hat{q}^\dagger_i(s) \cdot m_i \cdot \overline{k_\alpha k_\beta}_i\]
where $m_i$ is the orbit multiplicity and $\overline{k_\alpha k_\beta}_i$ is the orbit-averaged $k_\alpha k_\beta$ from cfft_kk_orbsum. The inner reduction uses GPU-compatible broadcasting (sum(real.(conj.(F̂_q) .* F̂_qc) .* mult .* kk_j)) to avoid scalar indexing. CFFTStressData stores kk_orbsum and multiplicity as device-adapted vectors via Adapt.adapt.
Weighted Statistics
Observables computed on the subgrid require a volume weight correction because the subgrid density of points is $L^3$ times lower than the full grid:
mean(w::CFFTAuxiliaryField) = mean(w.data) * (N_vol / M_vol)^(1/D)
# N_vol = prod(N_full), M_vol = prod(size(data))This ensures Hw, Hs, F, and residuals are exactly consistent with full-grid FFT values.
Spectral Updater Support (SIS/ETD/PO)
All SpectralSCFTAlgorithm updaters now support CFFT fields natively via trait-based dispatch:
| Updater | Type | CFFT Support |
|---|---|---|
| SIS | Diagonal κ | ✅ |
| ETD | Diagonal κ | ✅ |
| ETDPEC | Diagonal κ (predictor-corrector) | ✅ |
| PO | Diagonal κ (predictor-corrector) | ✅ |
| SISF | Full κ matrix | ✅ |
| ETDF | Full κ matrix | ✅ |
The mechanism uses a spectral_transform_type trait that returns Val(:fft) for standard fields and Val(:cfft) for CFFTAuxiliaryField. Each updater's step! dispatches to the appropriate implementation:
- FFT path (default): Uses
plan_fft/plan_iffton $N^3$ grid - CFFT path: Uses
rcfft!/ircfft!on $n_\text{spec}$-point spectral ASU
The κ response coefficients (from RPA) are computed on the spectral ASU using cfft_k2 — this is mathematically equivalent since κ depends only on $k^2$ and the spectral ASU orbits represent unique $k^2$ values.
Nested updaters (Anderson, NGMRES) that use spectral updaters as preconditioners work transparently — they operate in real space on the subgrid and delegate spectral operations to the preconditioner's CFFT path.
Integration with Performance Profiles
CFFT is compatible with all performance profiles that use symmetry:
| Profile | CFFT Compatible? | Storage | Compression |
|---|---|---|---|
:fast | ❌ No (default) | FullStorage | None |
:fast + symmetrize | ✅ Yes | FullStorage + CFFT | $L^3\times$ |
:balanced | ✅ Yes | SymmetricStorage + CFFT | $L^3 \times |P|/(2D)\times$ |
:compact | ✅ Yes | SymmetricStorage + CFFT (no precompute) | Same as balanced |
:minimal | ✅ Yes | Checkpoint + SymmetricStorage + CFFT | Maximum |
CFFT and DCT are mutually exclusive — the constructor automatically selects CFFT when a CFFTAuxiliaryField is provided, bypassing DCT detection.
Verification
- Free Energy: CFFT matches FFT to machine precision ($|\Delta F| < 10^{-14}$)
- Stress Tensor: CFFT stress matches FFT stress to $4.3 \times 10^{-19}$ (machine limit)
- Density: Pointwise difference $< 10^{-15}$
- GPU: Validated on NVIDIA RTX 2080 Ti ($|\Delta F_\text{GPU-CPU}| < 10^{-11}$)
- GPU VariableCell: Full GPU support including stress tensor, resize, and grid hysteresis
- Spectral Updaters: CFFT SIS/ETD/ETDPEC/PO/SISF/ETDF produce identical convergence to FFT counterparts
Supported Space Groups
CFFT supports all 230 space groups in 3D. The speedup depends on the stride factor $L$:
| Space Group | $L$ | Subgrid Ratio | Example Phase |
|---|---|---|---|
| Pmmm (47) | 2 | $1/8$ | Lamellar |
| P6/mmm (191) | varies | varies | Hexagonal Cylinder |
| Pm-3m (221) | 2 | $1/8$ | Simple Cubic |
| Fm-3m (225) | 2 | $1/8$ | FCC Sphere |
| Im-3m (229) | 2 | $1/8$ | BCC Sphere |
| Ia-3d (230) | 2 | $1/8$ | Gyroid |
Gyroid (SG 230 $Ia\bar{3}d$) involves glide planes and is not supported by DCT-I. CFFT is the only spectral acceleration available for Gyroid and other non-symmorphic groups.
Performance Benchmarks
Benchmarked on an AB diblock copolymer system with SG 230 (Ia-3d Gyroid), ds=0.01, profile=:balanced. The benchmark measures update_propagator! — one full MDE propagation step.
CPU (single-threaded)
| Method | Grid | Median Time | Speedup |
|---|---|---|---|
| Standard FFT | $80^3$ (512,000 pts) | 2310 ms | 1.0× |
| CFFT | $40^3$ subgrid (64,000 pts) | 385 ms | 6.0× |
GPU (NVIDIA RTX 2080 Ti)
| Method | Grid | Median Time | Speedup |
|---|---|---|---|
| Standard FFT | $256^3$ (16.8M pts) | 3879 ms | 1.0× |
| CFFT | $128^3$ subgrid (2.1M pts) | 684 ms | 5.7× |
The 8× grid reduction yields ~6× speedup. The gap is due to CFFT's reconstruction and fold/unfold overhead. GPU speedup is slightly lower because FFT kernel launch latency is a larger fraction of total time.
Initialization Overhead
CFFT initialization (planning, star map construction) is faster than standard FFT initialization after CrystallographicFFT.jl v0.2.1 optimization:
| CFFT | Standard FFT | |
|---|---|---|
| Init time ($64^3$, post-JIT) | 0.97 s | 1.37 s |
| Ratio | 0.71× (29% faster) | 1.0× |
Benchmark scripts: benchmark/cfft_performance.jl (CPU), benchmark/cfft_performance_gpu.jl (GPU), benchmark/cfft_init_profile.jl (init profiling).
Comparison with DCT Acceleration
| Feature | DCT | CFFT |
|---|---|---|
| Supported SGs | Pmmm supergroups only (~15 SGs) | All 230 SGs |
| Grid reduction | $N/8$ (octant) | $N/L^3$ (general subgrid) |
| Spectral domain | DCT-I (real, even) | CFFT spectral ASU (complex) |
| Glide/screw planes | ❌ Not supported | ✅ Supported |
| Gyroid (SG 230) | ❌ | ✅ |
| GPU support | ✅ VkDCT | ✅ KernelAbstractions |
| VariableCell GPU | ✅ | ✅ (with resize hysteresis) |
| External dependency | AcceleratedDCTs.jl | CrystallographicFFT.jl |