Skip to content

Sources

Put a SimulationSourceDefinition in SimulationModel::source. The source defines one statistical history, not merely one particle track.

Point Beam

cpp
SimulationSourceDefinition source{
    .kind = SimulationSourceKind::independent,
    .independent = IndependentSourceDefinition{
        .spatial = SourceSpatialDefinition{
            .mode = SourceSpatialMode::point,
            .position = {1.0e-6, 0.0, 0.0},
        },
        .angular = SourceAngularDefinition{
            .mode = SourceAngularMode::fixed_direction,
            .direction = {1.0, 0.0, 0.0},
        },
        .energy = SourceEnergyDefinition{
            .distribution = SourceScalarDistribution{
                .mode = SourceScalarDistributionMode::delta,
                .value = 1.0e6,
            },
        },
        .particle_type = ParticleType::photon,
        .weight = 1.0,
        .master_seed = 47,
    },
};

This creates one 1 MeV photon per history at the stated point and direction. Positions use cm, kinetic energy uses eV and time uses seconds.

Distributed Source

Change only the source distributions; the simulation entry point remains the same:

cpp
IndependentSourceDefinition source{
    .spatial = SourceSpatialDefinition{
        .mode = SourceSpatialMode::uniform_sphere,
        .position = {0.0, 0.0, 0.0},
        .radius = 0.5,
    },
    .angular = SourceAngularDefinition{
        .mode = SourceAngularMode::isotropic,
    },
    .energy = SourceEnergyDefinition{
        .distribution = SourceScalarDistribution{
            .mode = SourceScalarDistributionMode::discrete,
            .abscissa = {1.1732e6, 1.3325e6},
            .probability = {0.5, 0.5},
        },
    },
    .particle_type = ParticleType::photon,
    .master_seed = 48,
};

Available scalar modes include delta, uniform, discrete, tabular, mixture, power-law, normal, Maxwell and Watt distributions. Use phase-space points or a correlated angle-energy distribution when separate scalar distributions would destroy a physical correlation.

Mixed Source Components

Use general when source components have different positions, particles or spectra:

cpp
SimulationSourceDefinition source{
    .kind = SimulationSourceKind::general,
    .general = GeneralSourceDefinition{
        .components = {
            GeneralSourceComponentDefinition{
                .source = make_left_beam(),
                .strength = 3.0,
            },
            GeneralSourceComponentDefinition{
                .source = make_right_beam(),
                .strength = 1.0,
                .spatial_domain_regions = {detector_region},
            },
        },
        .master_seed = 49,
    },
};

The strengths are relative component probabilities. A region restriction rejects sampled positions outside the listed physical regions.

Tabulated Phase Space

Use one phase-space distribution when position, direction, energy, time or particle identity must stay correlated:

cpp
IndependentSourceDefinition source{
    .phase_space = SourcePhaseSpaceDistribution{
        .points = {
            SourcePhaseSpacePoint{
                .position = {0.0, 0.0, 0.0},
                .direction = {1.0, 0.0, 0.0},
                .energy = 2.0e6,
                .particle_type = ParticleType::neutron,
                .probability = 0.8,
            },
            SourcePhaseSpacePoint{
                .position = {0.0, 0.0, 0.0},
                .direction = {0.0, 1.0, 0.0},
                .energy = 14.0e6,
                .particle_type = ParticleType::neutron,
                .probability = 0.2,
            },
        },
    },
    .master_seed = 50,
};

Decay Inventory

Resolve the decay chain, then place the runtime table in a static inventory source:

cpp
ResolvedDecayData resolved = resolve_decay_data(
    DecayDataLibraryDefinition{
        .data_root = decay_data_root,
        .data_version = "endf-b-viii.1",
    },
    {co60});

SimulationSourceDefinition source{
    .kind = SimulationSourceKind::static_decay_inventory,
    .static_decay_inventory = StaticDecayInventorySource{
        .decay_data = std::move(resolved.data),
        .inventory = {
            DecayInventoryItem{
                .nuclide = co60,
                .activity_bq = 1.0e6,
                .spatial = SourceSpatialDefinition{
                    .mode = SourceSpatialMode::point,
                    .position = {0.0, 0.0, 0.0},
                },
            },
        },
        .particle_filter =
            decay_source_particle_filter(ParticleType::photon),
        .radiation_sampling_method =
            DecayRadiationSamplingMethod::analog_two_gamma_cascade,
        .master_seed = 51,
        .unsupported_emission_policy =
            DecayUnsupportedEmissionPolicy::fail_unsupported,
    },
};

One decay history can emit several correlated particles. They and all secondaries remain in the same history when NeoMC calculates uncertainty.

Reusing A Runtime

For repeated runs, convert a source definition to a source batch:

cpp
SimulationSourceBatch batch =
    make_simulation_source_batch(std::move(source), geometry_handle);

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

Use the geometry-aware overload for region-restricted general or decay sources. Every emitted particle must have an enabled owning package unless the selected workflow gives it an explicit non-transport disposition.

NeoMC user documentation.