Config-driven application pipeline (App → Simulator)¶
This page describes how a JSON or TOML file becomes a running simulation when you use pfc::ui::App<YourModel> (the pattern used by apps/tungsten, apps/aluminumNew, and several examples/). It ties together headers under include/openpfc/frontend/ui/ and simulation_wiring.hpp.
For install and MPI setup, see INSTALL.md. For shared config vocabulary, see configuration.md.
Big picture¶
flowchart LR
subgraph load [Load]
A[config.json / .toml]
end
subgraph stack [SpectralCpuStack]
W[Domain]
D[Decomposition]
F[CpuFft / HeFFTe]
T[Time]
end
subgraph session [SpectralSimulationSession]
M[ConcreteModel]
S[Simulator]
end
subgraph wire [Wiring from JSON]
RW[Results writers]
IC[Initial conditions]
BC[Boundary conditions]
SM[simulator section]
end
A --> W --> D --> F --> T
F --> M
T --> M
M --> S
A --> wire
wire --> S
SpectralCpuStackreads world, time, andplan_options(FFT) from the parsed document and constructs Domain → Decomposition → CpuFft → Time in a fixed order. CPU plan options andfft::createare factored throughspectral_cpu_stack_detail.hpp(cpu_spectral_plan_options_from_json,cpu_fft_from_json_and_decomposition) so a future GPU JSON stack can reuse the same parsing surface. Ifplan_optionsomitsbackendbut the document has a root-levelbackendstring (same key asfrom_json<fft::Backend>), that value is merged into the plan slice for parsing;backend: "cuda"is rejected on this CPU-only path.GPU drivers that still need a host
pfc::FFTforModelbut build HeFFTe with cuFFT / ROCm should usespectral_fft_stack_factory.hpp:merged_spectral_plan_options_json,cuda_spectral_plan_options_from_json, orhip_spectral_plan_options_from_jsonsoplan_optionsoverlays match the CPU JSON surface without silently re-basing onto FFTW defaults. Reuse this path’s singleSpectralCpuStackCpuFftfor theModelreference; avoid constructing a second throwaway CPU FFT in app code (see Doxygen onspectral_fft_stack_factory.hpp).SpectralSimulationSessionowns the stack, constructsConcreteModel(fft, world, comm)(sameMPI_Commas the stack and simulator), thenSimulator(model, time, comm). The FFT object and world are referenced by the model; do not reorder or move these after construction. Custom models should forward the optional thirdMPI_Commargument in their constructor (defaultMPI_COMM_WORLDkeeps two-argument construction valid).wire_simulator_from_settings(on the session) callswire_simulator_and_runtime_from_json, which attaches writers,ICs,BCs, and optionalsimulatorsubsection keys. The wiring APIs require explicitFieldModifierCatalogandResultsWriterCatalogreferences (no default parameters).Apppassesdefault_field_modifier_catalog()when no override is set, and always passesdefault_results_writer_catalog()for the stock binary writers unless you change the call path.
App<ConcreteModel>::main() order of operations¶
Implementation: include/openpfc/frontend/ui/app.hpp (settings load, MPI hints; configure_spectral_json_driver_hooks for from_json rank + NaN-check comm) and include/openpfc/frontend/ui/app_spectral_run.hpp (SpectralJsonAppRun — session through time loop).
Optional, outside the library: after loading the config file and before App::main(), application code may run ParameterValidator on settings["model"]["params"] (or your params subtree). OpenPFC does not call ParameterValidator automatically; ordering relative to from_json is described in parameter_validation.md.
Step |
What happens |
|---|---|
1 |
Load settings from |
2 |
|
3 |
If present, |
4 |
Profiling controller reads |
5 |
|
6 |
Memory report (model + FFT allocations). |
7 |
|
8 |
Time integration loop ( |
Custom drivers can replicate subsets: build a Simulator yourself, then call add_result_writers_from_json, add_initial_conditions_from_json, add_boundary_conditions_from_json, and apply_simulator_section_from_json from simulation_wiring.hpp directly. Each helper requires the relevant catalog at the call site (default_field_modifier_catalog(), default_results_writer_catalog(), or your injected registries). Pass JsonWiringContext{comm, mpi_rank, rank0} (or the legacy per-argument overloads) for MPI metadata. JsonWiringSession bundles context with both catalogs for wire_simulator_and_runtime_from_json(sim, time, settings, session).
JSON sections consumed by the default spectral path¶
Exact keys vary slightly by app and schema version; always treat apps/tungsten/inputs_json/ and examples/fft_backend_selection.toml as ground truth. Typical top-level usage:
Section / keys |
Handled by |
Role |
|---|---|---|
|
|
Grid and physical extent. |
|
|
Integration interval and output cadence. |
|
HeFFTe |
FFT backend ( |
|
Your |
Physics coefficients; optional |
|
|
If |
|
|
Each entry has |
|
|
Same pattern: |
|
|
Optional |
|
|
Export paths and regions; see |
TOML uses the same logical sections (e.g. [plan_options]).
SimulationContext and field modifiers¶
When Simulator applies initial or boundary modifiers, it passes a SimulationContext (MPI communicator, rank-0 flag) together with the Model. Modifier authors should read include/openpfc/kernel/simulation/simulation_context.hpp. This is separate from JSON but central to why IC/BC code can perform rank-aware I/O.
Registration of JSON type strings¶
Initial/boundary entries use "type": "<name>". Those names are resolved via FieldModifierCatalog (field_modifier_registry.hpp). Applications call register_field_modifier<MyModifier>("my_type") before constructing App. See examples/10_ui_register_ic.cpp and shipped apps’ main.
See also¶
Topic |
Where |
|---|---|
Spectral |
|
Layered architecture |
|
Main types and headers ( |
|
Minimal out-of-tree |
|
Validated |
|
FFT / |
|
Results formats (binary, VTK, PNG) |
|
CMake options |
|
Extending models |