Skip to content

Your First Simulation ​

A NeoMC calculation has six parts:

text
materials -> geometry -> observables -> physics package -> source -> run

This tutorial uses a photon slab because the supported coupled-EM resolver shows the complete path from an external data installation to the result.

1. Materials ​

cpp
std::vector<MaterialDefinition> materials =
    material_definitions_from_inputs({
        MaterialInputDefinition{
            .name = "aluminum",
            .density_g_cm3 = 2.70,
            .temperature_kelvin = 293.6,
            .components = {
                element_atom_fraction("Al", 1.0),
            },
        },
    });

Use element components for element-based EM data. Use explicit nuclides when a nuclear evaluation depends on isotope identity.

2. Geometry ​

cpp
auto geometry = std::make_shared<RectilinearGrid>(
    make_rectilinear_grid(
        RectilinearGridInputDefinition{
            .x_edges = {0.0, 1.0},
            .y_edges = {-2.0, 2.0},
            .z_edges = {-2.0, 2.0},
            .material_names = {"aluminum"},
            .observable_regions = {ObservableId{0}},
            .region_names = {"target"},
        },
        materials));

Named regions make source restrictions and observable targets readable.

3. Observable ​

cpp
ObservableSetDefinition observables = make_observable_set_definition(
    ObservableSetInputDefinition{
        .observables = {
            ObservableInputDefinition{
                .observable_id = ObservableId{0},
                .quantity = ObservableQuantity::edep,
                .target = ObservableTargetKind::volume,
                .region = "target",
            },
        },
    },
    *geometry);

The observable id identifies this request in the result. response_id distinguishes totals, bins and additional statistics generated for it.

4. Physics Package ​

Choose the reference profile, then resolve the data required by the material list:

cpp
const CoupledEmPhysicsProfile profile =
    CoupledEmPhysicsProfile::neomc_reference_epdl_eedl;

CoupledEmSimulationPackage em =
    resolve_coupled_em_simulation_package(
        CoupledEmDataLibraryDefinition{
            .root = physics_data_root,
        },
        materials,
        make_coupled_em_transport_config(profile),
        make_coupled_em_material_process_config(profile));

The resolver returns the package consumed by SimulationModel. The selected data-library version and consumed source hashes are retained in the result.

5. Source ​

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,
        .master_seed = 47,
    },
};

NeoMC uses eV, cm and seconds for these fields.

6. Run ​

cpp
SimulationTransportSessionResult result = run_simulation_model(
    SimulationModel{
        .geometry = hold_geometry(geometry),
        .materials = materials,
        .observables = observables,
        .packages = SimulationPackageSet{
            .coupled_em = std::move(em),
            .required_capabilities = {
                SimulationRequiredTransportCapability{
                    .package = TransportPackageId::coupled_em,
                    .capability = "em_photon_transport",
                    .minimum_status =
                        TransportCapabilityStatus::implemented,
                },
            },
        },
        .source = std::move(source),
        .run = SimulationRunSettings{
            .histories = 10000,
            .worker_threads = 4,
        },
    });

Compilation checks that the source particle and reachable secondaries have an enabled owner, that the requested capability is available, and that material, geometry, package data and observables are compatible.

7. Inspect The Result ​

cpp
const SimulationObservableRow &row =
    require_simulation_observable_row(
        result,
        TransportPackageId::coupled_em,
        "energy_deposit_edep",
        "total",
        ObservableId{0});

Read row.value, row.standard_error, row.units and row.histories together. Also inspect require_simulation_package_result(...) and result.coupled_em_data before preserving or comparing the score.

NeoMC user documentation.