Skip to content

Transport And Models

User Entry Point

One-shot:

cpp
SimulationTransportSessionResult result =
    run_simulation_model(std::move(model));

For repeated runs only:

cpp
SimulationRuntimeBundle runtime =
    compile_simulation_model(std::move(model));

SimulationTransportSessionResult result =
    run_simulation_runtime_bundle(
        runtime, std::move(source_batch), settings);

run_simulation_model is the normal application entry. It compiles and runs the model in one call. SimulationRuntimeBundle is the reusable compiled form; SimulationTransportSession is a move-only wrapper over the same runtime.

Simulation Model

SimulationModel contains:

  • GeometryHandle geometry;
  • std::vector<MaterialDefinition> materials;
  • ObservableSetDefinition observables;
  • SimulationPackageSet packages;
  • optional SimulationSourceDefinition source;
  • SimulationRunSettings run.

compile_simulation_model binds package data to materials and observable responses, resolves reachable package ownership and prepares the runtime geometry.

cpp
SimulationModel model{
    .geometry = hold_geometry(geometry),
    .materials = materials,
    .observables = observables,
    .packages = std::move(packages),
    .source = std::move(source),
    .run = SimulationRunSettings{
        .histories = 100000,
        .worker_threads = 8,
    },
};

SimulationTransportSessionResult result =
    run_simulation_model(std::move(model));

Package Set

Add any of these package objects:

  • CoupledEmSimulationPackage;
  • ProtonSimulationPackage;
  • AlphaSimulationPackage;
  • LightIonSimulationPackage;
  • NeutronSimulationPackage.

The compiler infers enabled packages from present package objects and normalizes any explicit enabled_packages list. Use required_capabilities to state minimum registry status required by the application.

make_neutron_coupled_transport_package_set is a convenience for neutron models that also transport emitted photons or charged particles.

cpp
SimulationPackageSet packages =
    make_neutron_coupled_transport_package_set(
        NeutronCoupledTransportPackages{
            .neutron = std::move(neutron),
            .coupled_em = std::move(em),
            .proton = std::move(proton),
            .alpha = std::move(alpha),
            .light_ion = std::move(light_ions),
        });

packages.required_capabilities.push_back(
    SimulationRequiredTransportCapability{
        .package = TransportPackageId::neutron,
        .capability = "neutron_reaction_secondary_handoff",
        .minimum_status = TransportCapabilityStatus::experimental,
    });

Package Registry

transport_package_registry() is the authoritative public capability map. Applications can query descriptors and named capabilities with:

  • find_transport_package_descriptor;
  • find_transport_package_capability;
  • require_transport_package_capability;
  • owning_transport_package;
  • available_transport_packages.

Check a requirement before assembling a user-facing preset:

cpp
require_transport_package_capability(
    TransportPackageId::coupled_em,
    "em_photon_transport",
    TransportCapabilityStatus::implemented,
    "gamma shielding model");

for (const TransportPackageDescriptor &package :
     transport_package_registry()) {
  std::cout << package.name << ": "
            << transport_capability_status_name(package.status)
            << '\n';
}

Parallel Histories

cpp
SimulationRunSettings settings{
    .histories = 100000,
    .worker_threads = 8,
    .logical_history_shards = 64,
};

The runtime schedules complete source histories. Descendants and scores from one history remain in that history's statistical unit. Logical shards are reduced canonically and execution metadata is returned in SimulationExecutionSummary.

Multi-thread execution requires a concurrent-safe source and geometry. Sources created by the public source-batch helpers are marked appropriately. Compiled geometry adapters are concurrent-safe. A custom callback or borrowed geometry must declare concurrency only when its operations are actually safe.

cpp
SimulationRunSettings settings{
    .histories = 1'000'000,
    .worker_threads = 8,
    .logical_history_shards = 64,
};

SimulationTransportSessionResult result =
    run_simulation_model(SimulationModel{
        .geometry = hold_geometry(
            geometry, GeometryConcurrency::concurrent_safe),
        .materials = materials,
        .observables = observables,
        .packages = std::move(packages),
        .source = std::move(source),
        .run = settings,
    });

std::cout << result.execution.effective_worker_threads << '\n'
          << result.execution.logical_history_shards << '\n';

Fission Eigenvalue

SimulationRunSettings::FissionEigenvalue adds inactive and active generations, generations per uncertainty batch, population-control seed and an optional source-convergence mesh.

The result includes generation records, batch means, k_effective, standard error, lag-one correlation and optional source-distribution diagnostics. These fields describe the implemented estimator; they do not by themselves establish a criticality validation claim.

cpp
SimulationRunSettings settings{
    .histories = 10000,
    .worker_threads = 8,
    .fission_eigenvalue = SimulationRunSettings::FissionEigenvalue{
        .inactive_generations = 50,
        .active_generations = 200,
        .generations_per_batch = 10,
        .population_control_seed = 71,
        .source_convergence_mesh =
            SimulationRunSettings::FissionSourceConvergenceMesh{
                .x_edges_cm = {-10.0, 0.0, 10.0},
                .y_edges_cm = {-10.0, 0.0, 10.0},
                .z_edges_cm = {-10.0, 0.0, 10.0},
            },
    },
};

model.run = settings;
SimulationTransportSessionResult result =
    run_simulation_model(std::move(model));

const SimulationFissionEigenvalueSummary &keff =
    result.fission_eigenvalue.value();
std::cout << keff.k_effective << " +/- "
          << keff.standard_error << '\n';

Result Structure

SimulationTransportSessionResult contains:

  • selected mode and execution summary;
  • enabled package ids and descriptors;
  • package result summaries;
  • observable rows;
  • activation source terms;
  • neutron support and processed-data provenance;
  • coupled-EM data provenance;
  • light-ion stopping-data provenance;
  • coupled-EM model summary;
  • optional fission eigenvalue result.

Use observable rows for requested scientific scores. Use package summaries, support manifests and provenance to audit how those scores were produced.

cpp
const SimulationPackageResultSummary &neutron =
    require_simulation_package_result(
        result, TransportPackageId::neutron);

std::cout << neutron.transport_model << '\n'
          << neutron.collision_sampling_method << '\n'
          << neutron.deposited_energy << '\n'
          << neutron.escaped_energy << '\n'
          << neutron.energy_balance_residual << '\n';

if (result.neutron_processed_data) {
  const NeutronProcessedDataProvenance &data =
      result.neutron_processed_data.value();
  std::cout << data.processor << ' '
            << data.processor_version << '\n';
  for (const NeutronEvaluatedSourceProvenance &source : data.sources) {
    std::cout << source.path << ' ' << source.sha256 << '\n';
  }
}
if (result.neutron_support) {
  const NeutronTransportSupportManifest &support =
      result.neutron_support.value();
  std::cout << support.transport_ready_reactions << " ready, "
            << support.unsupported_reactions << " unsupported\n";
}

Activation And Decay Chaining

Public helpers can:

  1. convert transport reaction products or reaction-rate observables into an inventory;
  2. evolve that inventory through irradiation and cooling;
  3. construct a correlated decay source;
  4. run a second SimulationModel for decay-particle transport.

The chained result keeps irradiation, source-rate and decay-transport outputs separate so an application can inspect each physical stage.

cpp
SimulationReactionRateActivationDecayTransportResult shutdown =
    run_reaction_rate_activation_decay_transport_from_simulation_result(
        irradiation_result,
        SimulationReactionRateActivationDecayTransportDefinition{
            .decay_data = std::move(decay_data),
            .activations = activations,
            .irradiation_schedule = schedule,
            .cooling_time_s = 7.0 * 24.0 * 3600.0,
            .decay_source_particle_filter =
                decay_source_particle_filter(ParticleType::photon),
            .decay_transport_model = std::move(decay_model),
        });

std::cout << shutdown.activation.final_inventory.total_activity_bq << '\n'
          << shutdown.decay_source.total_activity_bq << '\n';

const SimulationObservableRow &shutdown_dose =
    require_simulation_observable_row(
        shutdown.transport,
        TransportPackageId::coupled_em,
        "energy_deposit_dose",
        "total",
        ObservableId{1});
std::cout << shutdown_dose.value << " +/- "
          << shutdown_dose.standard_error << ' '
          << shutdown_dose.units << '\n';

NeoMC user documentation.