Skip to content

wolf75222/PoPS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,585 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PoPS - Plasma-Oriented PDE Solver

A model-free C++20 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes.

C++20 CMake Backends Python License

PoPS - Plasma-Oriented PDE Solver


PoPS is a compiled solver engine, not a Python numerical library and not a scenario repository. Python authors an inert, typed pops.Case: physics model, finite-volume descriptors, field problems, time program, outputs, and runtime parameters. The explicit typed pipeline is validate(case) → resolve(validated, layout=...) → compile(resolved) → bind(artifact, ...). Compilation lowers the resolved assembly to generated or native C++; binding creates the runtime; pops.run(sim, **run_controls) advances it with C++/Kokkos/MPI kernels. Python never runs a per-cell loop.

Named applications such as diocotron, Euler-Poisson, two-fluid, and validation setups live in adc_cases. This repository owns the reusable solver core, the Python DSL that builds compiled artifacts, and the C++ runtime that executes them.

At the mathematical level, a case usually couples conservative states U to one or more elliptic fields:

dU/dt + div F(U, fields, aux) = S(U, fields, aux)
D phi                         = f(U)

Field outputs are exposed through owner-qualified, typed field handles. Each field operator declares its own output schema (scalar, vector, tensor, components and frame); consumers bind those handles without relying on reserved names such as phi or grad_x. Names remain optional metadata for the generated C++ path, never Python callbacks or runtime lookup authority.

Table of contents

Prerequisites

  • C++20 compiler: AppleClang 16+, GCC 13+, Clang 17+ (nvcc_wrapper for the CUDA target).
  • CMake >= 3.21: the build is driven by presets (CMakePresets.json).
  • Kokkos 4.4.01: the exact promised release, with Serial and OpenMP execution spaces. It is the only on-node backend and is required. No need to pre-install it; if it is not found, CMake fetches and builds it (FetchContent).
  • MPI (optional, -DPOPS_USE_MPI=ON: halos and distributed FFT), with MPI_THREAD_MULTIPLE support for the native runtime.
  • HDF5 parallel (optional, -DPOPS_USE_HDF5=ON: DataWriter).
  • Python 3.12 + numpy (optional, the pops bindings; conda env via scripts/setup_env.sh).

Installation

Recommended path for the Python module:

git clone https://github.com/wolf75222/PoPS.git && cd PoPS
bash scripts/setup_env.sh      # conda env + toolchain
bash scripts/build_python.sh   # build + install, then pops.doctor()

scripts/setup_env.sh creates the conda environment and pins the platform toolchain. scripts/build_python.sh builds and installs pops, exports the discovery variables, and finishes with pops.doctor(). Use bash scripts/build_python.sh --mpi for the final distributed artifact; that strict route enables both MPI and its native parallel-HDF5 writer and fails if either backend is unavailable.

C++ core only

The C++ core is built through CMake presets:

cmake --preset serial
cmake --build --preset serial
ctest --preset serial --output-on-failure

The Ninja build already uses all available cores. Pin it to fewer jobs on a constrained machine with cmake --build --preset serial -j<N>. The serial test preset runs tests one at a time; parallelize with ctest --preset serial -j<N> when needed.

Parallel presets are available when the required backend dependencies are visible:

cmake --preset parallel && cmake --build --preset parallel && ctest --preset parallel  # threaded, Kokkos OpenMP
cmake --preset mpi      && cmake --build --preset mpi      && ctest --preset mpi        # distributed, MPI + parallel HDF5

Each preset writes into its own folder (build, build-kokkos, build-mpi). For an OpenMP build, set OMP_NUM_THREADS (and, where required by the Kokkos installation, KOKKOS_NUM_THREADS) before launching Python or use the scheduler's native CPU/thread controls.

Uninstall

bash scripts/uninstall_pops.sh # full teardown (env + caches); --keep-env drops only the module

Released versions and binaries: the Releases page.

Usage

Diocotron instability, 3-level AMR, on ROMEO

Validation scenario: diocotron instability (E x B drift) on a 3-level nested AMR hierarchy, ROMEO (96 cores). The scenario itself lives outside this core repository: adc_cases/diocotron_amr.

From a C++ project

The C++ core is header-only for consumers and is consumed via find_package(pops) or FetchContent:

include(FetchContent)
FetchContent_Declare(PoPS GIT_REPOSITORY https://github.com/wolf75222/PoPS.git)
FetchContent_MakeAvailable(PoPS)   # PoPS tests are not built for the consumer
target_link_libraries(my_app PRIVATE pops::pops)

Define a type that satisfies the PhysicalModel concept and compose it with the C++ coupling and time machinery. This is the low-level engine path. Most users should author a typed Python Case and let PoPS generate and bind the corresponding C++ artifact.

From Python

The public Python path is typed and compiled. Physics, numerics, boundaries, the explicit time Program, layout, consumers, and execution controls each have one authority. Final executable references are collected under examples/final; the complete scalar-advection case runs directly:

python examples/final/EXEMPLE_SPEC_FINALE_ADVECTION_SCALAIRE_COMPLET.py

Its final lifecycle is exactly Case -> validate -> resolve -> compile -> bind -> run. pops.bind receives concrete value families directly (params=, initial_state=, aux=, resources=, initial_values=); users never construct an install plan or runtime engine. See the complete source for explicit SSPRK2 construction, qualified handles, AMR policies, outputs, diagnostics, and checkpointing. The same acceptance corpus also executes the multiphysics, IMEX-AMR, and HyQMOM15 cases.

Documentation

The documentation corpus describes the final public lifecycle and its current implementation:

Core layers

Layer Role Entry point
python/pops/physics, python/pops/model, python/pops/time typed Python authoring: physics facade, operator-first model IR, and compiled time programs python/pops/physics
python/pops/mesh, python/pops/fields, python/pops/solvers, python/pops/numerics descriptors for layouts, AMR policies, field problems, solvers, Riemann fluxes, reconstruction, and finite-volume spatial choices python/pops/mesh
python/pops/codegen validation, inspection, generated C++ emission, cache keys, and .so loading python/pops/codegen
include/pops/core C++ concepts, state layout, model contracts, and equation blocks physical_model.hpp
include/pops/numerics C++ finite-volume, elliptic, time, Krylov, reconstruction, and Riemann kernels include/pops/numerics
include/pops/amr, include/pops/mesh, include/pops/parallel C++ mesh hierarchy, AMR clustering/regrid, MultiFab storage, halos, MPI seams, and reflux support include/pops/amr
include/pops/runtime, python/pops/runtime low-level runtime that pops.bind(...) uses internally to materialise uniform or AMR runs system.hpp

Versioning

PoPS follows Semantic Versioning. The public API under guarantee and the bump rules are declared in docs/VERSIONING.md. Available versions and their change logs: the Releases page and CHANGELOG.md. Version 1.0.0 establishes the stable public contract; subsequent compatibility and deprecation decisions follow those Semantic Versioning rules.

Contributing

Build, test and workflow conventions: CONTRIBUTING.md.

License

BSD-3-Clause. See LICENSE.

About

Model-free C++23 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes, with MPI and GPU (Kokkos) backends.

Topics

Resources

License

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors