Files
2026-04-19 19:42:30 +02:00

206 lines
5.5 KiB
C++

#pragma once
#include <filesystem>
#include <optional>
#include <string>
#include <vector>
#include "mocca/json.hpp"
namespace mocca {
struct DiracEnergy {
int n{};
int kappa{};
double vacuum_polarization_kev{};
double binding_kev{};
};
struct NlWeight {
int n{};
int l{};
double weight{};
};
enum class CaptureMode {
statistical_l,
quadratic_l,
explicit_l,
explicit_nl,
legacy_empty,
};
struct MetadataConfig {
std::string case_name;
};
struct AtomConfig {
double atomic_number{};
std::vector<double> effective_shell_charges;
std::vector<double> binding_energies_ev;
double atomic_mass{};
std::optional<double> exact_mass_number;
};
struct MassConfig {
double muon_electron_masses{206.7682827};
double electron_mass_ev{510998.95069};
double nucleon_mass_mev{938.272013};
};
struct TransitionConfig {
std::optional<double> two_p_to_one_s_energy_ev;
std::optional<double> two_s_to_two_p_split_ev;
std::vector<DiracEnergy> dirac_energies;
};
/**
* Initial capture distribution configuration.
*
* The modern interface names the supported distribution families explicitly
* instead of routing them through the historical `NOP`/`IP` control cards.
*/
struct CaptureConfig {
CaptureMode mode{CaptureMode::statistical_l};
int n_max{15};
double alpha{0.0};
std::vector<double> quadratic_coefficients;
std::vector<double> l_weights;
std::vector<NlWeight> nl_weights;
};
struct ChannelConfig {
std::vector<int> case_counts{3, 4, 4, 4};
std::vector<int> monopole_shells{1, 2, 3};
std::vector<int> dipole_shells{0, 1, 2, 3};
std::vector<int> quadrupole_shells{0, 1, 2, 3};
std::vector<int> octupole_shells{0, 1, 2, 3};
std::vector<int> dipole_subshell_channels{0, 0, 0, 0};
std::vector<int> quadrupole_subshell_channels{0, 0, 0, 0};
std::vector<int> octupole_subshell_channels{0, 0, 0, 0};
std::vector<int> dipole_penetration_codes{0, 1, 1, 1};
std::vector<int> quadrupole_penetration_codes{0, 1, 1, 1};
std::vector<int> octupole_penetration_codes{0, 1, 1, 1};
std::vector<int> dipole_penetration_avg_n_cutoffs{0, 0, 0, 0};
std::vector<int> quadrupole_penetration_avg_n_cutoffs{0, 0, 0, 0};
std::vector<int> octupole_penetration_avg_n_cutoffs{0, 0, 0, 0};
};
struct ShellModelConfig {
std::vector<double> subshell_populations{1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
std::vector<int> refill_codes{0, 0, 0};
std::vector<double> penetration_cutoffs{1.0, 1.0, 1.0, 1.0};
double width_k_ev{0.0};
bool track_polarization{true};
};
struct ReportingConfig {
double line_energy_min_mev{0.040};
double line_energy_max_mev{20.0};
double line_intensity_threshold{1.0e-06};
double energy_resolution_mev{0.000300};
};
struct ModelConfig {
double factorial_divider{15.0};
};
struct NumericsConfig {
int matrix_element_precision_digits{120};
};
/**
* Structured input schema for the new public-facing cascade interface.
*
* The schema is deliberately aligned with the validated cascade model while
* removing the legacy punch-card interface. It exposes the physics controls
* and precision settings needed by the modern kernel without leaking the
* historical deck/card vocabulary into the public API.
*/
struct SimulationConfig {
int schema_version{1};
MetadataConfig metadata;
AtomConfig atom;
MassConfig masses;
TransitionConfig transitions;
CaptureConfig capture;
ChannelConfig channels;
ShellModelConfig shell_model;
ReportingConfig reporting;
ModelConfig model;
NumericsConfig numerics;
};
struct TransitionLine {
int n1{};
int l1{};
int j1_twice{};
int n2{};
int l2{};
int j2_twice{};
std::string multipole;
double energy_kev{};
double intensity{};
};
struct StateSummary {
int n{};
int l{};
double population{};
std::optional<double> polar_up;
std::optional<double> polar_down;
std::optional<double> width_ev;
std::optional<double> rad_to_auger;
std::optional<double> spin_orbit_ev;
double k_electrons{};
double l_electrons{};
double m_electrons{};
};
struct SimulationResult {
double lyman_sum{};
int num_lines{};
std::vector<TransitionLine> lines;
std::vector<StateSummary> states;
std::vector<std::string> warnings;
};
/**
* JSON artifact emitted by the `mocca` CLI.
*
* It includes enough provenance to make regression outputs self-contained:
* the parsed input, the selected matrix-element precision, the coefficient-table
* source, and the resulting physics observables.
*/
struct SimulationArtifact {
int schema_version{1};
std::string implementation_name{"MOCCA"};
std::string numerical_backend{"modern_kernel"};
std::string coefficient_table_id{"aama_v1_0_block_data_v1"};
int matrix_element_precision_digits{120};
SimulationConfig input;
SimulationResult result;
};
/**
* Parse a modern JSON configuration document into a typed schema object.
*/
SimulationConfig parse_config_text(std::string_view text);
/**
* Load and parse a modern JSON configuration file.
*/
SimulationConfig load_config(const std::filesystem::path& path);
JsonValue to_json(const SimulationConfig& config);
JsonValue to_json(const SimulationResult& result);
JsonValue to_json(const SimulationArtifact& artifact);
/**
* Run the modern cascade kernel on a structured config and return a fully
* serialized-ready artifact.
*/
SimulationArtifact run_simulation(const SimulationConfig& config);
} // namespace mocca