Add a new case¶
A case is a named scenario that builds a model, wires it into an pops.System, sets the
initial data, and runs the time loop. Cases are not part of adc_cpp: they live in the
companion adc_cases repository, one folder per case, each importing the installed pops
Python package. This guide assumes you can already build and import pops; if not, start
with the installation guide.
The convention is one folder per case under adc_cases. The folder holds a runnable
Python script that imports pops, composes a model, plugs it into a system, and steps it.
Steps¶
Build and install
popsso the case can import it. Use thepythonpreset, which builds the importablepopsmodule. Theserialpreset leavesPOPS_BUILD_PYTHON=OFF, soimport popswould later fail. Use thepython-parallelpreset instead for the multi-thread (Kokkos OpenMP) variant.cmake --preset python && cmake --build --preset python
In your clone of
adc_cases, create one folder for the case. ReplaceCASE_NAMEwith a short name for the scenario.mkdir adc_cases/CASE_NAMEWrite the case script in that folder. Author the physics with
pops.physics.Model, declare the typed elliptic field withpops.fields.PoissonProblem, assemble apops.Case, then compile and bind it. See the models overview for the model fronts.import pops import pops.time as T from pops.mesh.cartesian import CartesianMesh from pops.mesh.layouts import Uniform from pops.fields import PoissonProblem from pops.fields.bcs import Periodic from pops.fields.rhs import ChargeDensity from pops.solvers.elliptic import GeometricMG from pops.codegen import Production from pops.math import laplacian # m = pops.physics.Model(...): author the physics (see the models overview). poisson = PoissonProblem(name="phi", unknown="phi", equation=(-laplacian("phi") == ChargeDensity.from_blocks("ne")), bcs=(Periodic(),), solver=GeometricMG()) case = (pops.Case(layout=Uniform(CartesianMesh(n=96, L=1.0, periodic=True))) .block("ne", physics=m).field(poisson).time(T.Program("euler"))) compiled = pops.compile(case, backend=Production()) sim = pops.bind(compiled, state={"ne": ne0}) # ne0: 2D initial density sim.run(0.1, cfl=0.4)
Replace
ne0with a 2D array holding the initial density. For an adaptive run, swap the layout topops.mesh.layouts.AMR(mesh, max_levels=2, ratio=2)and author the refinement withcase.amr.refine(...).Run the case from its folder.
python adc_cases/CASE_NAME/run.py
Next steps¶
Follow the tutorial for the full reduced-diocotron walkthrough.
Read the models overview to choose between native bricks, the DSL, and a hybrid model.