--- myst: html_meta: "description": "Design rationale for the Parameters decomposition: NSDMI defaults, INI extraction, JSON serialization, and narrow parameter passing." "keywords": "eOn parameters, configuration, JSON, INI, NSDMI, C++20" --- # Parameters system The `Parameters` class manages all runtime configuration for the eOn client. This page documents the design decisions behind its decomposition. ## Architecture The system has three layers: 1. **Option-group structs** (`Parameters.h`): 33 structs with C++20 NSDMI defaults. Each struct is independently constructable without parsing. 2. **INI parser** (`ParametersINI.cpp`): reads `config.ini` via [inih](https://github.com/benhoyt/inih) and populates option groups. 3. **JSON serializer** (`ParametersJSON.cpp`): provides `to_json()`/`from_json()` for library usage, RPC transport, and debugging. A `validate_and_link()` function resolves cross-group dependencies (time unit conversions, default inheritance) after loading from any source. ## NSDMI defaults All ~290 configuration fields have default values as Non-Static Data Member Initializers directly on the struct members: ```cpp struct main_options_t { JobType job{JobType::Process_Search}; long randomSeed{-1}; double temperature{300.0}; // ... } main_options; ``` The constructor calls only `validate_and_link()` to resolve computed fields (time unit conversions). This means a default-constructed `Parameters` object is immediately usable. ## Cross-group dependencies Some fields depend on values from other groups. These are resolved in `validate_and_link()` after all groups have their raw values: | Dependent field | Source | |---|---| | `optimizer_options.time_step` | `time_step_input / constants.timeUnit` | | `neb_options.force_tolerance` | `optimizer_options.converged_force` | | `process_search_options.minimization_offset` | `optimizer_options.max_move` | | `dynamics_options.steps` | `floor(time / time_step)` | | All `*_time` fields | `*_time_input / constants.timeUnit` | ## Narrow parameter passing Core classes receive only the option groups they need via config structs: | Class | Config struct | Fields | |---|---|---| | `Matter` | Direct members | `removeNetForce`, `structComp` | | `Optimizer` hierarchy | `OptimizerConfig` | `optimizer_options_t` + 2 extras | | `Dynamics` | `DynamicsConfig` | 12 fields from 5 groups | | `Potential` base | `PotType` only | No Parameters dependency | Deprecated backward-compatibility constructors are retained for callers that still pass the full `Parameters` object. ## JSON serialization `ParametersJSON.cpp` provides round-trip JSON serialization using [nlohmann/json](https://github.com/nlohmann/json). This enables: - **Library usage**: configure eOn programmatically without INI files - **RPC transport**: send config as JSON text via capnp serve mode - **Debugging**: dump current config to human-readable JSON ```cpp Parameters params; params.load_json(R"({"Main": {"job": "Nudged_Elastic_Band", "temperature": 500}})"); std::string json = params.to_json(); // pretty-printed JSON ``` ## History The v3c branch (2024) attempted to switch from INI to TOML and restructure all parameters simultaneously. It was abandoned because it changed too many axes at once. The current approach is incremental: extract defaults (Phase 1), narrow passing (Phase 2), add JSON (Phase 3). Each step is independently mergeable.