This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
SHOCCS (Stable High-Order Cut-Cell Solver) is a C++ Cartesian cut-cell solver for time-dependent PDEs (heat equation, scalar wave, Euler equations). It uses high-order finite difference operators on structured grids with embedded boundaries. The codebase uses Kokkos for parallel execution.
docs/ONBOARDING.md— start here if you are new to the codebase.docs/CAPABILITY_AUDIT.md— per-subsystem maturity status (what actually works vs. scaffolding).docs/reference/— per-subsystem reference docs.docs/CLEANUP_PLAN.md— known issues and remediation plan (see §0/§0a for the Kokkos 5.1 build fix and the one remaining test failure).docs/handoff/MASTER.md— Python framework (stencil derivation / sweeps) handoff.
✅ Build status (2026-06-04): Green. A Kokkos 5.0→5.1.1
create_graphAPI break was fixed by migrating the call sites tocreate_graph<execution_space>(...);ctestpasses 47/48, with one remaining failure (t-laplacian);t-csrandt-E2_1are fixed. Tracked indocs/CLEANUP_PLAN.md§0a. Also: ifbuild.ninjaerrors with a missing cmake path (stale tree), re-runcmake -S . -B build -G Ninja ...(see "Reconfigure from scratch" below) to regenerate it.
# Build (from repo root; build/ is pre-configured with Ninja)
cmake --build build
# Build a single target
cmake --build build --target t-heat
# Run all tests
ctest --test-dir build
# Run tests by label (fields, matrices, operators, stencils, mesh, systems, temporal, simulation)
ctest --test-dir build -L fields
# Run a single test by name
ctest --test-dir build -R t-dense
# Reconfigure from scratch
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=ON -DBUILD_BENCHMARKS=ON# Run all benchmarks and compare against stored baseline
./scripts/bench_compare.sh
# Save a new baseline
./scripts/bench_compare.sh --saveBenchmark executables are in build/benchmarks/ (bench_stencil, bench_block, bench_derivative, bench_expr, bench_selection, bench_rhs).
GitHub Actions workflows in .github/workflows/:
ci.yml— runs on PRs and pushes to main. Thecppjob builds and tests inside the prebuilt dependency imageghcr.io/lanl/shoccs-ci(visibly skipped if the image hasn't been published yet); the gating ctest run excludest-laplacian(known failure,docs/CLEANUP_PLAN.md§0a), which runs separately as a non-gating step. Thepythonjob runs the stencil_gen suite (slow tests deselected) via uv. Benchmarks are compile-checked, never executed in CI.devcontainer-image.yml— builds the leancistage of.devcontainer/Dockerfileand pushes it to GHCR. Triggers on pushes to main touching.devcontainer/orspack_repo/, weekly cron, or manual dispatch. Dispatch it manually after changing the dependency stack; a cold build takes hours (full Spack source build).python-extended.yml— weekly/manual run of the stencil_gen suite including--run-slowtests. Full-resolution sweeps stay out of CI.
- C++20 with concepts,
std::ranges, andstd::span. No C++23 features; missing C++23 utilities (stride, zip_transform, cartesian_product, bind_back) have project-local implementations insrc/fields/lazy_views.hpp. - Namespace: Everything lives under
ccs. Core type aliases insrc/shoccs_config.hpp:real = double,integer = long,int3 = std::array<int,3>,real3 = std::array<real,3>. - Kokkos types in
src/kokkos_types.hpp:execution_space,memory_space,device_view<T>. Currently host-only (DefaultHostExecutionSpace). - Test files: Named
*.t.cpp, use Catch2 v3. Tests needing Kokkos provide a custommain()withKokkos::ScopeGuardand linkCatch2::Catch2(notWithMain). Simple tests use theadd_unit_test()CMake helper which linksCatch2::Catch2WithMain. - CMake targets follow the pattern
shoccs-<subsystem>(e.g.,shoccs-matrices,shoccs-operators). Test executables aret-<name>.
Lua config → simulation_cycle::from_lua → mesh + operators + system + integrator → simulation_cycle::run() (time-stepping loop)
-
Indexing (
src/indexing.hpp,index_extents.hpp,index_view.hpp) — Multi-dimensional index mapping for structured grids. All subsystems depend on this. -
Fields (
src/fields/) — Field storage and algebra.field_registryowns all buffers asKokkos::View<real*>.field_refis a lightweight handle (slot index). Expression templates (expr.hpp) enabledst = a + alpha * bsyntax that dispatches toKokkos::parallel_for. Selection descriptors (selection_desc.hpp) describe contiguous/strided/gather subsets of a field for BC application. -
Mesh (
src/mesh/) — Cartesian grid with cut-cell geometry.cartesianholds 1D coordinate arrays and grid spacings.object_geometryperforms ray-casting intersection with embedded shapes (spheres, rectangles) to computepsiparameters for cut-cell stencils. -
Matrices (
src/matrices/) — Small per-line operators, not global sparse systems. Composite structure:inner_block = [dense_left | circulant_interior | dense_right], wrapped inblockfor multi-line application. CSR for sparse boundary coupling. Matrix-vector products use explicit loops (no KokkosKernels). -
Stencils (
src/stencils/) — Finite difference coefficients. Named by scheme (E2, E4, E6, E8) and order. Each provides interior circulant + boundary dense + optional CSR cut-cell coefficients. -
Operators (
src/operators/) — Discrete differential operators (derivative, gradient, laplacian) built from stencils + matrices. Applied per-direction usingoperator_visitorpattern acrossblock/inner_block. -
Systems (
src/systems/) — PDE implementations. Each system providesrhs()(spatial discretization),update_boundary(),timestep_size(), and initialization. Concrete:heat,scalar_wave,hyperbolic_eigenvalues. Usessystemvariant wrapper for type erasure; the variant also includesempty(placeholder) andinviscid_vortex(partial Euler scaffolding, not a working PDE). Note: onlyheatis fully wired throughsimulation_cycle;scalar_waveandhyperbolic_eigenvaluesare not yet wired through. The real entry point issimulation_cycle::from_lua— thesimulation_builderclass is a dead stub. -
Temporal (
src/temporal/) — Time integrators (euler,rk4) operating onfield_refslots in the registry.step_controllermanages adaptive time stepping. Slot arithmetic helpers inslot_ops.hpp. -
Simulation (
src/simulation/) —simulation_cycle::from_luaassembles the full simulation from Lua config (system + integrator + step_controller + field_io).simulation_cycleowns the time-stepping loop. (The oldersimulation_builderclass is a dead stub — seedocs/reference/simulation.md.) -
I/O (
src/io/) — XDMF/binary field output, spdlog-based logging.
The codebase was migrated from range-v3 to Kokkos. The plans/ directory contains the migration plans and architectural decisions from that effort. Key decisions are documented in plans/meta.md.
The scripts/stencil_gen/ directory contains a SymPy-based pipeline for deriving finite difference stencil coefficients symbolically. Managed by uv.
# Run stencil_gen tests (from repo root); add -n auto to parallelize (pytest-xdist)
cd scripts/stencil_gen && SYMPY_CACHE_SIZE=50000 uv run pytest tests/ -x -q
# Run a specific sweep (epsilon, tension, tension-penalty, footprint, comparison, alpha, mixed-epsilon)
cd scripts/stencil_gen && uv run python -m sweeps epsilon --scheme E2
# Run all sweeps with reduced resolution for quick verification
cd scripts/stencil_gen && uv run python -m sweeps all --quick
# Run all sweeps at full resolution and update known values
cd scripts/stencil_gen && uv run python -m sweeps all- SYMPY_CACHE_SIZE=50000 is essential for performance — default 1000 causes severe slowdowns with large symbolic expressions.
- For linear systems with symbolic parameters, use
linear_eq_to_matrix+linsolve(notsympy.solve). Linearize bilinear terms first with the theta-substitution trick (theta = w*phi). - Reference Mathematica code in
mathematica-files/finitedifferences/(taylor.wlfor functions,explicitr-E4d1.nb.pdffor workflow). - Key entry points:
derive_cut_cell_mathematica()(singularity-free),derive_cut_cell_scheme()(legacy with psi-clamping). - Generated C++ goes to
scripts/stencil_gen/output/and replaces files insrc/stencils/. - Sweep workflow: Parameter-space explorations live in
scripts/stencil_gen/sweeps/as standalone scripts. Sweeps discover optimal parameters and write results tosweeps/known_values.json. Regression tests intest_phs.pyload fromknown_values.jsonto verify stability at those values. To update known values after a sweep:uv run python -m sweeps epsilon --scheme E2 --update-known-values.