Skip to content

Releases: wolf75222/PoPS

Release list

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 16 Jun 18:56
1b17b02

Added

  • AMR checkpoint/restart (ADC-65): AmrSystem.checkpoint(path) / restart(path) write and read
    a bit-identical npz (per-level conservative state with fine patches, per-level phi as the multigrid
    warm-start, the fine hierarchy and the clock), replacing the old NotImplementedError. Restart
    imposes the saved fine layout via the new set_hierarchy (no re-clustering, no re-prolongation).
    Mono-block mono-rank for now: MPI np>1, multi-block and regrid_every>0 are rejected explicitly.
    Adds the append-only level accessors n_levels / n_vars / level_state / level_potential /
    set_hierarchy.

  • Model-declared named aux fields (ADC-70, phase 1, Cartesian System): a model declares
    persistent auxiliary fields with m.aux_field("name") (read in a formula via aux.extra_field(k));
    sim.set_aux_field(block, name, array) and sim.aux_field(block, name) set and read them (up to
    four). The Aux POD stays trivially copyable and device-clean, named components are static (never
    rewritten by solve_fields), and a model with no named field is cache/hash-identical to before;
    B_z / T_e stay on their dedicated setters.

  • Generic 2D moment-hierarchy generator (ADC-164): the new adc.moments module derives the full
    M->C->S->closure->C'->M' algebra (binomial transform plus standardization) over the DSL AST, so a
    user supplies only the closure (S -> standardized moments of order N+1). Ships build_moment_model,
    gaussian_closure (Levermore), lorentz_sources (Vlasov-Lorentz) and moment_indices /
    moment_names; robust=True adds differentiable smooth floors and exact_speeds=True wires HLL
    speeds via autodiff plus numeric eig.

  • SSPRK3 time integration on AMR (ADC-64): AmrSystem.add_block(..., time="ssprk3") (or
    adc.Explicit(ssprk3=True)) runs a 3-stage Shu-Osher SSPRK3 per subcycled level, staying exactly
    conservative across coarse-fine boundaries by refluxing the effective flux
    Feff = 1/6 F0 + 1/6 F1 + 2/3 F2. The default stays forward Euler (bit-identical); rejected
    explicitly on the compiled .so paths and with imex.

  • First-order forward Euler explicit method (ADC-174): adc.Explicit(method="euler") selects the
    ForwardEuler stepper on System.add_block (native and backend="production"), for
    first-order-reference fidelity; ssprk2 stays the default. The frozen-ABI AOT path rejects euler
    (pointing to the production/native backends) rather than silently ignoring it.

  • Explicit signed wave speeds in the DSL (ADC-83): m.wave_speeds(x=(smin,smax), y=(smin,smax))
    declares signed face speeds directly, unlocking riemann="hll" for models with no pressure
    primitive (moment systems, isothermal). Without set_eigenvalues the Rusanov/CFL bound derives
    from max(|smin|,|smax|); an add_equation guard rejects riemann="hll" with no emitted speeds.

  • HLL wave speeds from the flux Jacobian (ADC-86/87): m.wave_speeds_from_jacobian(x=, y=, eig="numeric"|"fd", blocks=) emits exact HLL speeds as the spectrum extremes of the flux Jacobian
    (new device-clean header adc::real_eig_minmax: closed form for N<=2, Hessenberg plus Francis QR
    otherwise, Gershgorin outer-bound fallback). x/y=None autodiffs the declared flux; the Abs
    autodiff node is now differentiable, so smooth max(x,eps) floors are Jacobian-able.

  • Positivity floor limiter (ADC-76): adc.FiniteVolume(positivity_floor=...) imposes a density
    floor on reconstructed face states, falling back locally to the source-cell average (conservative,
    first-order) on a violating face. floor<=0 is bit-identical to before; it is threaded through the
    Cartesian, polar and cut-cell kernels and the compiled-block ABI, and rejected explicitly on the
    paths that do not support it (prototype JIT, AOT/production, AMR).

  • Opt-in HLL wave-speed cache (ADC-199): adc.FiniteVolume(wave_speed_cache=True) evaluates
    model.wave_speeds once per cell and direction and reuses it as the face bound instead of
    recomputing on every face and RK stage (measured speedup on moment hierarchies). Off by default,
    bit-identical to OFF in the no-slope path, and rejected outside riemann="hll" plus explicit time.

  • Spectral Poisson FFT variant (ADC-175): a new elliptic kind solver="fft_spectral" (from
    System.set_poisson, adc.EllipticSolver, listed in adc.capabilities()) reuses the periodic
    single-rank FFT plumbing of "fft" but with the continuous Laplacian symbol -(kx^2+ky^2), exact
    on sinusoids. The discrete "fft" and "geometric_mg" solvers are unchanged.

  • Native Windows (MSVC) support (ADC-99/100/136/144): adc_cpp compiles and imports natively on
    Windows without WSL2. A portable dynamic-loading layer adc::dynlib (LoadLibraryW /
    GetProcAddress), an ADC_EXPORT macro (__declspec), an MSVC-aware ABI key, and
    std::numbers::pi for M_PI cover the runtime; the DSL production backend compiles a model to a
    .dll with cl and runs bit-identical to the brick path (shared Kokkos, _adc.lib). All _WIN32
    branches are dead off Windows.

  • System.dt_hotspot(name) CFL diagnostic (ADC-182): returns {w, i, j} for the global cell
    that dominates a block's transport CFL bound, to locate a collapsing dt without an external scan.
    On-demand and off the hot path (step / step_cfl stay bit-identical), a two-pass device-clean
    reduction with an MPI all-reduce.

  • Find-or-fetch Kokkos (ADC-263): if no Kokkos install is found, CMake downloads and builds a
    release tarball verified by SHA256, so a plain cmake -B build works without a pre-installed
    Kokkos. Overridable via ADC_KOKKOS_FETCH_VERSION (default 4.4.01) and ADC_KOKKOS_FETCH_SHA256.

  • Eigenvalue witness in the projection DSL (ADC-289): dsl.eig_max_im(rows), dsl.eig_lmin(rows)
    and dsl.eig_lmax(rows) build a small dense matrix from moment expressions and return a scalar
    Expr from its spectrum via adc::real_eig_minmax (max imaginary part as a complex-eigenvalue
    witness, or the real-part bounds). The codegen emits a named device-clean functor (no extended
    lambda), so m.projection can express a branchless "if a moment matrix has a complex eigenvalue,
    correct it" rule (unblocks the native relaxation15 projector, ADC-275). Additive: the existing
    expression set and m.projection (ADC-177) are unchanged.

  • Documentation rebuilt around a Diataxis navigation (ADC-248): Getting started, Tutorials,
    Concepts (11 pages, ADC-249), How-to (12 task pages), Simulation, AMR, Running, Advanced topics,
    Reference and Development sections, plus a Quickstart page and an internal documentation style
    guide (ADC-250). Pages are kebab-case.

  • Embedded C++ reference in the Sphinx site via doxysphinx (ADC-149), with a modern Doxygen
    theme and full dot diagrams (ADC-239).

  • Documentation-as-code tooling: per-page docmap.toml with owner and freshness plus an
    example harness (ADC-147), a doc taxonomy and a stack ADR (ADC-146), and CI doc lanes (a light PR
    lane and a weekly heavy lane with lld and ccache, ADC-151/225).

  • Quality tooling / static analysis (ADC-105): dedicated CI workflow .github/workflows/quality.yml,
    off the PR critical path (weekly Sunday cron + workflow_dispatch + quality label). Five
    informative (non-blocking) jobs: clang-format (.clang-format), strict warnings
    (ADC_ENABLE_WARNINGS), clang-tidy (.clang-tidy), ASan+UBSan sanitizers (ADC_ENABLE_SANITIZERS,
    ci-warnings/ci-asan presets) and CodeQL. CMake options OFF by default (empty adc_dev_options
    target), so ci.yml, local builds and adc_cases are unchanged. See docs/QUALITY_TOOLING.md.

  • Fuzzing, coverage and developer automation (ADC-113): invariant-checked libFuzzer harnesses in
    fuzz/ (Box2D, Berger-Rigoutsos clustering, real_eig_minmax; option ADC_BUILD_FUZZING +
    ci-fuzz preset, clang), gcov/gcovr coverage (ADC_ENABLE_COVERAGE + ci-coverage preset),
    Python ruff lint ([tool.ruff]), opt-in pre-commit hooks (.pre-commit-config.yaml: clang-format
    and ruff at commit), and two more quality.yml jobs (fuzz, coverage) on the same weekly
    informative cadence; the default build stays bit-unchanged.

  • Repository health and GitHub hygiene: BSD-3 LICENSE and license declaration, CONTRIBUTING,
    SECURITY, .gitattributes, PR and issue templates (ADC-223/224/244/246), a root-hygiene guard
    (ADC-169), Dependabot weekly Actions bumps (ADC-117), a release workflow that turns a v* tag
    into a GitHub Release from this changelog (ADC-234), and docs/VERSIONING.md with the bump rules
    (ADC-232/237).

  • Shared C++ test harness (test_harness.hpp, bench/common.hpp, ADC-215); a Schur-split test
    with an AMR guard on add_block and auto-skip without Kokkos (ADC-207).

  • CI: ci.yml split into parallel gate-cpp / gate-python lanes with mold and path
    routing (ADC-171).

  • Moment-model documentation: a step-by-step HyQMOM tutorial, a moments-and-closures concept
    page, a moment-models reference, and adc.moments (build_moment_model, gaussian_closure,
    lorentz_sources) added to the Python API reference (autodoc).

  • Generic pointwise post-step PROJECTION hook (ADC-177): m.projection([...]) on the DSL side
    (C++ trait HasPointwiseProjection, compiled like the flux/source), applied by System at the
    end of every whole macro-step (never per RK stage) on the valid cells of each block -- replaces
    the per-cell Python callback (aot and production backends; prototype and
    target="amr_system" reject it explicitly). Adds dsl.sign(x) (branch-free mask selections,
    differentiable). See docs/DSL_API.md section 5.

Changed

  • Kokkos is the only on-node backend (ADC-263): the standalone OpenMP path is removed (the
    ADC_USE_OPENMP option, find_package(OpenMP), the mutual-exclusion check and every #pragma omp
    or manual h...
Read more