Repository organization¶
The project is split into two repositories with a clear boundary: the generic library on one side, the named scenarios on the other. Understanding this separation avoids looking for “the diocotron” in the wrong place.
adc_cpp: the library (the core)¶
https://github.com/wolf75222/adc_cpp
This is that repository. It contains:
the header-only C++ core (
include/pops/): physics bricks, numerical schemes, the AMR mesh stack, Poisson solvers, parallelism seams;the library’s Python bindings (
python/): thepopsmodule (pybind11), that is, the composition facadesSystem/AmrSystemand thepops.physics/pops.irDSL;the test suite (
tests/,python/tests/) and the design docs (docs/).
Structuring rule: the core is model-agnostic. It names no scenario. It only
knows generic bricks (Scalar / FluidState, ExB / CompressibleFlux,
NoSource / PotentialForce, BackgroundDensity / ChargeDensity…) that are composed into a
model via pops.Model(state, transport, source, elliptic), or written as formulas via
pops.physics.facade.Model. There is neither diocotron nor euler_poisson in adc_cpp. See
ARCHITECTURE.md (“The core is model-agnostic”).
This rule also holds for custom integrators: the asymptotic-preserving two-fluid scheme, which is not a block-by-block composable brick but a scenario, has left the core. It lives on the applications side, compiled on the fly against the generic headers.
adc_cases: the application layer (the named scenarios)¶
https://github.com/wolf75222/adc_cases
Sibling repository. It contains only Python code that imports the pops module and composes the
bricks into named scenarios: diocotron, euler_poisson, two species, magnetic isothermal,
two-fluid AP… Each case is a composition recipe (which bricks, which scheme, which
Poisson, which initial condition), not new core.
A few reference demonstrators (run in CI on the adc_cases side):
Scenario |
File |
|---|---|
ExB single-species (DSL) |
|
Two species (DSL) |
|
Magnetic isothermal (DSL) |
|
Who depends on whom¶
adc_cpp (coeur generique + bindings pops) <-- agnostique, ne nomme aucun scenario
^
| import pops / FetchContent pops::pops
|
adc_cases (scenarios Python nommes) --> diocotron, euler_poisson, ...
The dependency is strictly downward: adc_cases consumes adc_cpp (the Python module, or
the pops::pops headers via FetchContent for scenarios compiled on the fly). There is
no reverse dependency: the core does not know the cases.
In practice: a new “well-known” model (a diocotron, an Euler-Poisson) is coded in
adc_cases by composing bricks. A new generic brick (a new flux, a
new elliptic closure) is coded in adc_cpp. The A->Z tutorial, for its part, remains
deliberately self-contained: it imports only pops, numpy and matplotlib, and rebuilds the
diocotron model by hand (with no dependency on adc_cases) so that it stays reproducible from this single
repository.