Quick Start
This page shows the current user path: build a model, run it once, then read the requested score.
Add NeoMC To Your Build
NeoMC currently builds from source:
add_subdirectory(path/to/neomc)
add_executable(my_transport main.cc)
target_link_libraries(
my_transport
PRIVATE
neomc_simulation
neomc_physics_data_importers
)Enable importers when configuring the parent build:
cmake -S . -B build -DNEOMC_BUILD_IMPORTERS=ON
cmake --build build --parallelBuild The Problem
Start with material definitions. This example uses an aluminum slab:
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),
},
},
});
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));Ask for energy deposited in the target:
ObservableSetDefinition observables = make_observable_set_definition(
ObservableSetInputDefinition{
.observables = {
ObservableInputDefinition{
.observable_id = ObservableId{0},
.quantity = ObservableQuantity::edep,
.target = ObservableTargetKind::volume,
.region = "target",
},
},
},
*geometry);Define a 1 MeV photon beam:
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,
},
};Resolve the coupled electromagnetic package from a named data installation:
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 loads only the elements used by the model and records the source files and hashes in the runtime data. It does not add photonuclear data or invent missing material-specific tables.
Run
Put the pieces into SimulationModel and call the one-shot entry point:
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,
},
});Package objects present in SimulationPackageSet are enabled automatically. required_capabilities states what the application expects and makes model compilation fail if that boundary is not available.
Read The Result
Retrieve the score by package, observable type, response and id:
const SimulationObservableRow &edep =
require_simulation_observable_row(
result,
TransportPackageId::coupled_em,
"energy_deposit_edep",
"total",
ObservableId{0});
std::cout << edep.value << " +/- " << edep.standard_error
<< " " << edep.units << '\n';Read value, standard_error, units and histories together. Then inspect the package summary and data provenance:
const SimulationPackageResultSummary &transport =
require_simulation_package_result(
result, TransportPackageId::coupled_em);
std::cout << "tracks = " << transport.tracks << '\n'
<< "deposited = " << transport.deposited_energy << " eV\n"
<< "escaped = " << transport.escaped_energy << " eV\n";
if (result.coupled_em_data) {
std::cout << result.coupled_em_data->library_version << '\n';
}Continue with your first simulation for the meaning of each model component, or physics data for resolver and provenance details.