diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index ec3b587dfa..f403da8e30 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -56,7 +56,7 @@ jobs: . /etc/profile echo "/opt/view/bin" >> $GITHUB_PATH echo "CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" >> $GITHUB_ENV - # NOTE: checkout must occur *after* setting up environment to use the right Git version + # NOTE: checkout must occur *after* setting up environment for git tags to work # NOTE: depth must be enough to include the previous tag - name: Check out Celeritas uses: actions/checkout@v4 @@ -66,7 +66,6 @@ jobs: - name: Configure Celeritas run: | git config --global --add safe.directory ${PWD} - git fetch --tags ln -fs scripts/cmake-presets/ci-${{matrix.image}}.json CMakeUserPresets.json cmake --preset=${CMAKE_PRESET} - name: Build Celeritas diff --git a/app/celer-g4/RunInput.cc b/app/celer-g4/RunInput.cc index 4a3225a8bd..45b9ffb00d 100644 --- a/app/celer-g4/RunInput.cc +++ b/app/celer-g4/RunInput.cc @@ -6,13 +6,172 @@ //---------------------------------------------------------------------------// #include "RunInput.hh" +#include + +#include "corecel/Config.hh" + #include "corecel/io/EnumStringMapper.hh" +#include "corecel/io/Logger.hh" +#include "corecel/math/ArrayUtils.hh" +#include "celeritas/inp/StandaloneInput.hh" +#include "celeritas/phys/PrimaryGeneratorOptions.hh" #include "accel/SharedParams.hh" namespace celeritas { namespace app { +namespace +{ +//---------------------------------------------------------------------------// +inp::System load_system(RunInput const& ri) +{ + inp::System s; + + if (celeritas::Device::num_devices()) + { + inp::Device d; + d.stack_size = ri.cuda_stack_size; + d.heap_size = ri.cuda_heap_size; + s.device = std::move(d); + } + + s.environment = {ri.environ.begin(), ri.environ.end()}; + + return s; +} + +//---------------------------------------------------------------------------// +inp::Problem load_problem(RunInput const& ri) +{ + inp::Problem p; + + // Model definition + p.model.geometry = ri.geometry_file; + + // Control + p.control.capacity = [&ri] { + inp::StateCapacity capacity; + capacity.tracks = ri.num_track_slots; + capacity.initializers = ri.initializer_capacity; + capacity.secondaries = static_cast(ri.secondary_stack_factor + * ri.num_track_slots); + capacity.primaries = ri.auto_flush; + return capacity; + }(); + + if (celeritas::Device::num_devices()) + { + inp::DeviceDebug dd; + dd.default_stream = ri.default_stream; + dd.sync_stream = ri.action_times; + p.control.device_debug = std::move(dd); + } + + if (ri.track_order != TrackOrder::size_) + { + p.control.track_order = ri.track_order; + } + + { + inp::TrackingLimits& limits = p.tracking.limits; + limits.steps = ri.max_steps; + } + + // Field setup + if (ri.field_type == "rzmap") + { + CELER_LOG_LOCAL(info) << "Loading RZMapField from " << ri.field_file; + std::ifstream inp(ri.field_file); + CELER_VALIDATE(inp, + << "failed to open field map file at '" << ri.field_file + << "'"); + + // Read RZ map from file + RZMapFieldInput rzmap; + inp >> rzmap; + + // Replace driver options with user options + rzmap.driver_options = ri.field_options; + + p.field = std::move(rzmap); + } + else if (ri.field_type == "uniform") + { + inp::UniformField field; + field.strength = ri.field; + + auto field_val = norm(field.strength); + if (field_val > 0) + { + CELER_LOG_LOCAL(info) + << "Using a uniform field " << field_val << " [T]"; + field.driver_options = ri.field_options; + p.field = std::move(field); + } + } + else + { + CELER_VALIDATE(false, + << "invalid field type '" << ri.field_type << "'"); + } + + if (ri.sd_type != SensitiveDetectorType::none) + { + // Activate Geant4 SD callbacks + p.scoring.sd.emplace(); + } + + { + // Diagnostics + auto& d = p.diagnostics; + d.output_file = ri.output_file; + d.export_files.physics = ri.physics_output_file; + d.export_files.offload = ri.offload_output_file; + d.timers.action = ri.action_times; + + if (!ri.slot_diagnostic_prefix.empty()) + { + inp::SlotDiagnostic slot_diag; + slot_diag.basename = ri.slot_diagnostic_prefix; + d.slot = std::move(slot_diag); + } + + if (ri.step_diagnostic) + { + inp::StepDiagnostic step; + step.bins = ri.step_diagnostic_bins; + d.step = std::move(step); + } + } + + CELER_VALIDATE(ri.macro_file.empty(), + << "macro file is no longer supported"); + + return p; +} + +//---------------------------------------------------------------------------// +inp::Events load_events(RunInput const& ri) +{ + CELER_VALIDATE(ri.event_file.empty() != !ri.primary_options, + << "either a event filename or options to generate " + "primaries must be provided (but not both)"); + + if (!ri.event_file.empty()) + { + inp::ReadFileEvents rfe; + rfe.event_file = ri.event_file; + return rfe; + } + + CELER_ASSERT(ri.primary_options); + return to_input(ri.primary_options); +} + +//---------------------------------------------------------------------------// +} // namespace + //---------------------------------------------------------------------------// /*! * Get a string corresponding to the physics list selection. @@ -57,6 +216,49 @@ RunInput::operator bool() const && (step_diagnostic_bins > 0 || !step_diagnostic); } +//---------------------------------------------------------------------------// +/*! + * Convert to standalone input format. + */ +inp::StandaloneInput to_input(RunInput const& ri) +{ + inp::StandaloneInput si; + + si.system = load_system(ri); + si.problem = load_problem(ri); + + // Set up Geant4 + if (ri.physics_list == PhysicsListSelection::celer_ftfp_bert) + { + // Build hadronic physics + std::get(si.problem).physics.hadronic.emplace(); + } + else + { + CELER_VALIDATE(ri.physics_list == PhysicsListSelection::celer_em, + << "invalid physics list selection '" + << to_cstring(ri.physics_list) << "' (must be 'celer')"); + } + + si.geant_setup = ri.physics_options; + + inp::GeantImport geant_import; + geant_import.ignore_processes.push_back("CoulombScat"); + if (CELERITAS_GEANT4_VERSION >= 0x0b0100) + { + CELER_LOG(warning) << "Default Rayleigh scattering 'MinKinEnergyPrim' " + "is not compatible between Celeritas and " + "Geant4@11.1: disabling Rayleigh scattering"; + geant_import.ignore_processes.push_back("Rayl"); + } + si.physics_import = std::move(geant_import); + + si.geant_data = inp::GeantDataImport{}; + si.events = load_events(ri); + + return si; +} + //---------------------------------------------------------------------------// } // namespace app } // namespace celeritas diff --git a/app/celer-g4/RunInput.hh b/app/celer-g4/RunInput.hh index b69d80c6f8..71c7307493 100644 --- a/app/celer-g4/RunInput.hh +++ b/app/celer-g4/RunInput.hh @@ -25,18 +25,14 @@ namespace celeritas { -namespace app -{ //---------------------------------------------------------------------------// -//! Physics list selection -enum class PhysicsListSelection +namespace inp { - ftfp_bert, - celer_ftfp_bert, //!< FTFP BERT with Celeritas EM standard physics - celer_em, //!< Celeritas EM standard physics only - size_, -}; +struct StandaloneInput; +} +namespace app +{ //---------------------------------------------------------------------------// //! Sensitive detector capability enum class SensitiveDetectorType @@ -47,6 +43,16 @@ enum class SensitiveDetectorType size_, }; +//---------------------------------------------------------------------------// +//! Physics list selection (TODO: remove) +enum class PhysicsListSelection +{ + ftfp_bert, + celer_ftfp_bert, //!< FTFP BERT with Celeritas EM standard physics + celer_em, //!< Celeritas EM standard physics only + size_, +}; + //---------------------------------------------------------------------------// /*! * Input for a single run. @@ -121,6 +127,8 @@ struct RunInput char const* to_cstring(PhysicsListSelection value); char const* to_cstring(SensitiveDetectorType value); +inp::StandaloneInput to_input(RunInput const& run_input); + //---------------------------------------------------------------------------// } // namespace app } // namespace celeritas diff --git a/app/celer-sim/CMakeLists.txt b/app/celer-sim/CMakeLists.txt index 2d3ebf77c5..932680b3ac 100644 --- a/app/celer-sim/CMakeLists.txt +++ b/app/celer-sim/CMakeLists.txt @@ -7,6 +7,7 @@ set(SOURCES celer-sim.cc Runner.cc RunnerOutput.cc + RunnerInput.cc RunnerInputIO.json.cc Transporter.cc ) diff --git a/app/celer-sim/RunnerInput.cc b/app/celer-sim/RunnerInput.cc new file mode 100644 index 0000000000..5fdb4abb76 --- /dev/null +++ b/app/celer-sim/RunnerInput.cc @@ -0,0 +1,227 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celer-sim/RunnerInput.cc +//---------------------------------------------------------------------------// +#include "RunnerInput.hh" + +#include + +#include "celeritas/field/FieldDriverOptions.hh" +#include "celeritas/inp/Import.hh" +#include "celeritas/inp/Problem.hh" +#include "celeritas/inp/StandaloneInput.hh" +#include "celeritas/phys/PrimaryGeneratorOptions.hh" + +namespace celeritas +{ +namespace app +{ +namespace +{ +//---------------------------------------------------------------------------// +inp::System load_system(RunnerInput const& ri) +{ + inp::System s; + + s.environment = {ri.environ.begin(), ri.environ.end()}; + + if (ri.use_device) + { + s.device = [&ri] { + inp::Device d; + d.stack_size = ri.cuda_stack_size; + d.heap_size = ri.cuda_heap_size; + return d; + }(); + } + return s; +} + +//---------------------------------------------------------------------------// +inp::Problem load_problem(RunnerInput const& ri) +{ + inp::Problem p; + + // Geometry and event configurations + p.model.geometry = ri.geometry_file; + + // Magnetic field + if (ri.field == RunnerInput::no_field()) + { + p.field = inp::NoField{}; + } + else + { + inp::UniformField field; + field.strength = ri.field; + field.driver_options = ri.field_options; + p.field = field; + } + + // Diagnostics + { + auto& d = p.diagnostics; + if (!ri.mctruth_file.empty()) + { + d.mctruth = [&ri] { + inp::McTruth mct; + mct.output_file = ri.mctruth_file; + mct.filter = ri.mctruth_filter; + return mct; + }(); + } + d.perfetto_file = ri.tracing_file; + d.timers.action = ri.action_times; + d.timers.step = ri.write_step_times; + d.action = ri.action_diagnostic; + if (!ri.slot_diagnostic_prefix.empty()) + { + d.slot = inp::SlotDiagnostic{ri.slot_diagnostic_prefix}; + } + if (ri.step_diagnostic) + { + d.step = [&ri] { + inp::StepDiagnostic step_diag; + step_diag.bins = ri.step_diagnostic_bins; + return step_diag; + }(); + } + d.counters.step = ri.write_track_counts; + d.counters.event = ri.transporter_result; + } + + // Control + { + inp::StateCapacity capacity; + capacity.tracks = ri.num_track_slots; + capacity.initializers = ri.initializer_capacity; + capacity.secondaries = static_cast(ri.secondary_stack_factor + * ri.num_track_slots); + + // TODO: replace "max" with # events during construction? + using LimitsT = std::numeric_limits; + capacity.events = ri.merge_events ? LimitsT::max() : 0; + + p.control.capacity = capacity; + + p.control.warm_up = ri.warm_up; + p.control.seed = ri.seed; + + // TODO: set number of streams + p.control.num_streams = 1; + + if (ri.use_device) + { + p.control.device_debug = [&ri] { + inp::DeviceDebug dd; + dd.default_stream = ri.default_stream; + dd.sync_stream = ri.action_times; + return dd; + }(); + } + p.control.track_order = ri.track_order; + } + + // Physics + { + CELER_ASSERT(p.physics.em); + auto& em = *p.physics.em; + + CELER_ASSERT(em.brems); + em.brems->combined_model = ri.brem_combined; + + // Spline energy loss order + CELER_VALIDATE(ri.spline_eloss_order == 1 || ri.spline_eloss_order == 3, + << "unsupported energy loss spline order " + << ri.spline_eloss_order); + em.eloss_spline = (ri.spline_eloss_order == 3); + } + + // Tracking + p.tracking.limits.steps = ri.max_steps; + p.tracking.force_step_limit = ri.step_limiter; + + // Optical options + if (ri.optical) + { + p.control.optical_capacity = [&ri] { + inp::StateCapacity sc; + sc.tracks = ri.optical.num_track_slots; + sc.initializers = ri.optical.initializer_capacity; + sc.primaries = ri.optical.auto_flush; + return sc; + }(); + } + + // Simple calorimeter scoring + if (!ri.simple_calo.empty()) + { + p.scoring.simple_calo = inp::SimpleCalo{ri.simple_calo}; + } + + return p; +} + +//---------------------------------------------------------------------------// +inp::Events load_events(RunnerInput const& ri) +{ + CELER_VALIDATE(ri.event_file.empty() != !ri.primary_options, + << "either a event filename or options to generate " + "primaries must be provided (but not both)"); + + if (!ri.event_file.empty()) + { + if (ri.file_sampling_options) + { + inp::SampleFileEvents sfe; + sfe.num_events = ri.file_sampling_options.num_events; + sfe.num_merged = ri.file_sampling_options.num_merged; + sfe.event_file = ri.event_file; + sfe.seed = ri.seed; + return sfe; + } + + inp::ReadFileEvents rfe; + rfe.event_file = ri.event_file; + return rfe; + } + + CELER_ASSERT(ri.primary_options); + return to_input(ri.primary_options); +} + +//---------------------------------------------------------------------------// +} // namespace + +//---------------------------------------------------------------------------// +/*! + * Convert to standalone input format. + */ +inp::StandaloneInput to_input(RunnerInput const& ri) +{ + inp::StandaloneInput si; + + si.system = load_system(ri); + si.problem = load_problem(ri); + if (!ri.physics_file.empty()) + { + // Read ROOT input + si.physics_import = inp::FileImport{ri.physics_file}; + } + else + { + // Set up Geant4 + si.geant_setup = ri.physics_options; + si.physics_import = inp::GeantImport{}; + } + si.geant_data = inp::GeantDataImport{}; + si.events = load_events(ri); + + return si; +} + +//---------------------------------------------------------------------------// +} // namespace app +} // namespace celeritas diff --git a/app/celer-sim/RunnerInput.hh b/app/celer-sim/RunnerInput.hh index b25c2631c9..3a30bde2a5 100644 --- a/app/celer-sim/RunnerInput.hh +++ b/app/celer-sim/RunnerInput.hh @@ -14,7 +14,6 @@ #include "corecel/sys/Environment.hh" #include "celeritas/Types.hh" #include "celeritas/ext/GeantPhysicsOptions.hh" -#include "celeritas/ext/GeantSetup.hh" #include "celeritas/ext/RootFileManager.hh" #include "celeritas/field/FieldDriverOptions.hh" #include "celeritas/phys/PrimaryGeneratorOptions.hh" @@ -29,15 +28,16 @@ namespace celeritas { +namespace inp +{ +struct StandaloneInput; +} + namespace app { //---------------------------------------------------------------------------// /*! * Input for a single run. - * - * TODO for v1.0: unify these names, combine with celer-g4, separate into - * schemas for individual classes, ... ? and decide whether max_steps should be - * per track or total step iterations. */ struct RunnerInput { @@ -49,7 +49,7 @@ struct RunnerInput explicit operator bool() const { return num_events > 0 && num_merged > 0; - }; + } }; struct OpticalOptions @@ -65,7 +65,7 @@ struct RunnerInput { return num_track_slots > 0 && buffer_capacity > 0 && initializer_capacity > 0 && auto_flush > 0; - }; + } }; static constexpr Real3 no_field() { return Real3{0, 0, 0}; } static constexpr size_type unspecified{0}; @@ -146,6 +146,10 @@ struct RunnerInput } }; +//---------------------------------------------------------------------------// +// Convert to standalone input format +inp::StandaloneInput to_input(RunnerInput const&); + //---------------------------------------------------------------------------// } // namespace app } // namespace celeritas diff --git a/doc/implementation/core-physics/import.rst b/doc/implementation/core-physics/import.rst index ed624c5def..1b0f1d5b47 100644 --- a/doc/implementation/core-physics/import.rst +++ b/doc/implementation/core-physics/import.rst @@ -6,6 +6,9 @@ Imported data ============= +.. note:: These classes will be merged into the problem input definition + :ref:`input`. + Celeritas reads physics data from Geant4 (or from a ROOT file exported from data previously loaded into Geant4). Different versions of Geant4 (and Geant4 data) can be used seamlessly with any version of Celeritas, allowing diff --git a/doc/implementation/core-physics/problem-def.rst b/doc/implementation/core-physics/problem-def.rst index d9e8ebc574..c8d18fdb23 100644 --- a/doc/implementation/core-physics/problem-def.rst +++ b/doc/implementation/core-physics/problem-def.rst @@ -23,3 +23,86 @@ classes (see the `developer documentation`_ for details). .. doxygenclass:: celeritas::CutoffParams + +.. _api_problem_setup: + +Setting up problems +------------------- + +Problem data is specified from applications and the Geant4 user interface using +the :ref:`input` API and loaded through "importers". Different front ends to +Celeritas use different sets of importers. + +.. _api_problem_setup_standalone: + +Standalone execution +^^^^^^^^^^^^^^^^^^^^ + +Standalone execution describes how to set up physics data (either through +Geant4 or loaded through an external file) and other problem properties. + +.. doxygenstruct:: celeritas::inp::StandaloneInput + +Standalone inputs must also specify the mechanism for loading primary +particles. The ``events`` field is a variant that can be one of these +structures: + +.. doxygenstruct:: celeritas::inp::PrimaryGenerator +.. doxygenstruct:: celeritas::inp::SampleFileEvents +.. doxygenstruct:: celeritas::inp::ReadFileEvents + +The primary generator, similar to Geant4's "particle gun", has different +configuration options: + +.. doxygentypedef:: celeritas::inp::Events +.. doxygentypedef:: celeritas::inp::ShapeDistribution +.. doxygentypedef:: celeritas::inp::AngleDistribution +.. doxygentypedef:: celeritas::inp::EnergyDistribution + +.. doxygenstruct:: celeritas::inp::PointShape +.. doxygenstruct:: celeritas::inp::UniformBoxShape +.. doxygenstruct:: celeritas::inp::IsotropicAngle +.. doxygenstruct:: celeritas::inp::MonodirectionalAngle +.. doxygenstruct:: celeritas::inp::Monoenergetic + +.. _api_problem_setup_framework: + +User application/framework +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +User applications define the system configuration, as well as what Celeritas +physics to enable (via :cpp:struct:`GeantImport`). Additional custom physics +can be added via the ``adjuster`` parameter to set or change any loaded data. + +.. doxygenstruct:: celeritas::inp::FrameworkInput + :members: + :no-link: + + +Importers +^^^^^^^^^ + +Import options are read in to load problem input from various sources. + +.. doxygenstruct:: celeritas::inp::FileImport + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::GeantImport + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::GeantDataImport + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::UpdateImport + :members: + :no-link: + + +Setup +^^^^^ + +.. doxygennamespace:: celeritas::setup + diff --git a/doc/index.rst b/doc/index.rst index ea8137efb8..edd757d4fc 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -216,6 +216,7 @@ well as several helper applications and front ends. usage/installation.rst usage/integration.rst usage/execution.rst + usage/input.rst .. *************************************************************************** diff --git a/doc/usage/execution/applications.rst b/doc/usage/execution/applications.rst index 1f663c41d6..ca1f03d5ef 100644 --- a/doc/usage/execution/applications.rst +++ b/doc/usage/execution/applications.rst @@ -38,7 +38,8 @@ Input ^^^^^ .. todo:: - The input parameters will be documented for version 1. Until then, refer to the + The input parameters will be documented for version 1 in the :ref:`input` + section and :ref:`api_problem_setup_standalone`. Until then, refer to the source code at :file:`app/celer-sim/RunnerInput.hh` . In addition to these input parameters, :ref:`environment` can be specified to @@ -86,7 +87,8 @@ with ``field_options`` corresponding to the ``FieldOptions`` class in :ref:`api_ The macro file usage is in the process of being replaced by JSON input for improved automation. The input parameters will be documented for - version 1. Until then, refer to the source code + version 1 in the :ref:`input` section and + :ref:`api_problem_setup_standalone`. Until then, refer to the source code at :file:`app/celer-g4/RunInput.hh` . The input is a Geant4 macro file for executing the program. Celeritas defines diff --git a/doc/usage/execution/environment.rst b/doc/usage/execution/environment.rst index cd3d7d7275..6b14555b5b 100644 --- a/doc/usage/execution/environment.rst +++ b/doc/usage/execution/environment.rst @@ -6,6 +6,9 @@ Environment variables ===================== +.. note:: Many of these environment variables will eventually be replaced by + :ref:`inp_control` and :ref:`inp_system` options in Celeritas v1.0 and beyond. + Some pieces of core Celeritas code interrogate the environment for variables to change system- or output-level behavior. These variables are checked once per execution, and checking them inserts the key and user-defined value (or empty) diff --git a/doc/usage/execution/profiling.rst b/doc/usage/execution/profiling.rst index ac41e7d560..4e866db7ce 100644 --- a/doc/usage/execution/profiling.rst +++ b/doc/usage/execution/profiling.rst @@ -64,6 +64,7 @@ tool. On CPU, timelines are generated using Perfetto, which is only supported when CUDA and HIP are disabled. Perfetto supports application-level and system-level profiling. +To use the application-level profiling, see :ref:`inp_diagnostics`. .. sourcecode:: :linenos: diff --git a/doc/usage/input.rst b/doc/usage/input.rst new file mode 100644 index 0000000000..3c88dde25b --- /dev/null +++ b/doc/usage/input.rst @@ -0,0 +1,56 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _input: + +***** +Input +***** + +.. note:: This section is a sneak preview of Celeritas 1.0 input. It is *not* + currently exposed to users. + +.. only:: nobreathe + + .. warning:: The breathe_ extension was not used when building this version + of the documentation. The input definitions will not be displayed. + + .. _breathe: https://github.com/michaeljones/breathe#readme + +All front ends to Celeritas, and the library interface for external +integration, use a single interface to define properties about the simulation +to be run. This interface is a nested set of simple struct objects that are +used both to enable options and to set up low-level C++ data structures. Many +of the struct names in the ``inp`` namespace correspond to runtime Celeritas +classes and objects. + +The highest-level problem definition input is: + +.. doxygenstruct:: celeritas::inp::Problem + :members: + :no-link: + +The following sections describe the members and their configuration options. +Note that most input classes (namespace ``inp``) match up with the runtime +classes that they help construct. Many of these definitions allow selection +between hard-coded C++ types via std::`variant`_ and optional types using +std::`optional`_. + +.. _variant: https://en.cppreference.com/w/cpp/utility/variant +.. _optional: https://en.cppreference.com/w/cpp/utility/optional + +Problems are loaded into the framework or application front end via :ref:`api_problem_setup`. + +.. toctree:: + :maxdepth: 2 + :caption: Input definition + + input/model.rst + input/physics.rst + input/field.rst + input/scoring.rst + input/tracking.rst + input/control.rst + input/diagnostics.rst + input/system.rst + diff --git a/doc/usage/input/control.rst b/doc/usage/input/control.rst new file mode 100644 index 0000000000..64b3da9a9f --- /dev/null +++ b/doc/usage/input/control.rst @@ -0,0 +1,23 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _inp_control: + +Control +======= + +These options manage trade-offs between performance and memory usage, and other +parameters that affect the simulation results without changing the physics. + +.. doxygenstruct:: celeritas::inp::Control + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::DeviceDebug + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::StateCapacity + :members: + :no-link: + diff --git a/doc/usage/input/diagnostics.rst b/doc/usage/input/diagnostics.rst new file mode 100644 index 0000000000..0e2f6c1b6f --- /dev/null +++ b/doc/usage/input/diagnostics.rst @@ -0,0 +1,41 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _inp_diagnostics: + +Diagnostics +=========== + +Diagnostics are information about the behavior of the computational simulation, +primarily used to diagnose performance and accuracy. These are used to set up +:ref:`api_diagnostics` as well as additional output gleaned from the Monte +Carlo particle transport states. + +.. doxygenstruct:: celeritas::inp::Diagnostics + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::ExportFiles + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::SlotDiagnostic + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::Timers + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::Counters + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::McTruth + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::StepDiagnostic + :members: + :no-link: + diff --git a/doc/usage/input/field.rst b/doc/usage/input/field.rst new file mode 100644 index 0000000000..55913b0834 --- /dev/null +++ b/doc/usage/input/field.rst @@ -0,0 +1,25 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _inp_field: + +Field +===== + +The field currently allows a few hard-coded options. It will be extended to +additional field types and may allow completely custom field implementations. + +.. doxygenstruct:: celeritas::inp::NoField + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::UniformField + :members: + :no-link: + +.. doxygentypedef:: celeritas::inp::RZMapField + +The field type is selected with a variant: + +.. doxygentypedef:: celeritas::inp::Field + diff --git a/doc/usage/input/model.rst b/doc/usage/input/model.rst new file mode 100644 index 0000000000..4721dc2738 --- /dev/null +++ b/doc/usage/input/model.rst @@ -0,0 +1,14 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _model: + +Model +===== + +This specifies the problem geometry and material properties. + +.. doxygenstruct:: celeritas::inp::Model + :members: + :no-link: + diff --git a/doc/usage/input/physics.rst b/doc/usage/input/physics.rst new file mode 100644 index 0000000000..00b316a864 --- /dev/null +++ b/doc/usage/input/physics.rst @@ -0,0 +1,48 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _inp_physics: + +Physics +======= + +.. doxygenstruct:: celeritas::inp::Physics + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::EmPhysics + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::OpticalPhysics + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::HadronicPhysics + :members: + :no-link: + + +Processes +--------- + +.. doxygenstruct:: celeritas::inp::BremsProcess + :members: + :no-link: + + +Models +------ + +.. doxygenstruct:: celeritas::inp::SeltzerBergerModel + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::RelBremsModel + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::MuBremsModel + :members: + :no-link: + diff --git a/doc/usage/input/scoring.rst b/doc/usage/input/scoring.rst new file mode 100644 index 0000000000..a08fff81bf --- /dev/null +++ b/doc/usage/input/scoring.rst @@ -0,0 +1,39 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _inp_scoring: + +Scoring +======= + +Scoring setup is for measuring and recording physical simulation results. + +.. doxygenstruct:: celeritas::inp::Scoring + :members: + :no-link: + + +Geant4 sensitive detectors +-------------------------- + +These options are used to integrate Celeritas with Geant4 sensitive detectors +by reconstructing Geant4 hits and calling back to user code. + +.. doxygenstruct:: celeritas::inp::GeantSensitiveDetector + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::GeantSDStepPointAttributes + :members: + :no-link: + + +Independent scoring +------------------- + +This is used to set up :cpp:class:`celeritas::SimpleCalo`. + +.. doxygenstruct:: celeritas::inp::SimpleCalo + :members: + :no-link: + diff --git a/doc/usage/input/system.rst b/doc/usage/input/system.rst new file mode 100644 index 0000000000..fb0c267d2e --- /dev/null +++ b/doc/usage/input/system.rst @@ -0,0 +1,20 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _inp_system: + +System +====== + +These are low-level system options set up once per program execution, such as +enabling GPU. They are not loaded by the :cpp:struct:`Problem` definition but +are used when :ref:`api_problem_setup`. + +.. doxygenstruct:: celeritas::inp::System + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::Device + :members: + :no-link: + diff --git a/doc/usage/input/tracking.rst b/doc/usage/input/tracking.rst new file mode 100644 index 0000000000..0d841ab0b5 --- /dev/null +++ b/doc/usage/input/tracking.rst @@ -0,0 +1,18 @@ +.. Copyright Celeritas contributors: see top-level COPYRIGHT file for details +.. SPDX-License-Identifier: CC-BY-4.0 + +.. _inp_tracking: + +Tracking +======== + +Tracking options control trade-offs between performance and accuracy. + +.. doxygenstruct:: celeritas::inp::Tracking + :members: + :no-link: + +.. doxygenstruct:: celeritas::inp::TrackingLimits + :members: + :no-link: + diff --git a/doc/usage/integration.rst b/doc/usage/integration.rst index 02090ac0f9..6fec17d2bc 100644 --- a/doc/usage/integration.rst +++ b/doc/usage/integration.rst @@ -79,7 +79,8 @@ Integrating with Geant4 user applications and experiment frameworks requires setting up: - Initialization options that depend on the problem being run and the system - architecture (see :cpp:class:`celeritas::SetupOptions`) + architecture (see :cpp:class:`celeritas::SetupOptions` until version 1.0, or + :ref:`input` after) - "Global" data structures for shared problem data such as geometry (see :cpp:class:`celeritas::SharedParams`) - Per-worker (i.e., ``G4ThreadLocal`` using Geant4 manager/worker semantics) diff --git a/scripts/dev/celeritas-gen.py b/scripts/dev/celeritas-gen.py index 5b7a3d993d..72000be5a0 100755 --- a/scripts/dev/celeritas-gen.py +++ b/scripts/dev/celeritas-gen.py @@ -15,7 +15,11 @@ ############################################################################### -def _make_top(comment_prefix, preamble=None, postamble=None): +CODE_LICENSE = "(Apache-2.0 OR MIT)" +DOC_LICENSE = "CC-BY-4.0" + +def _make_top(comment_prefix, + preamble=None, postamble=None, license=CODE_LICENSE): lines = [] def _append_lines(s): if s: @@ -26,7 +30,7 @@ def _append_lines(s): _append_lines(preamble) lines.extend(comment_prefix + " " + line for line in [ "Copyright Celeritas contributors: see top-level COPYRIGHT file for details", - "SPDX-License-Identifier: (Apache-2.0 OR MIT)", + "SPDX-License-Identifier: " + license, ]) _append_lines(postamble) lines.append("") @@ -404,10 +408,11 @@ class {name}Test : public ::celeritas::test::Test shapes world_box ~mycyl ''' -RST_TOP = _make_top("..") +RST_TOP = _make_top("..", license=DOC_LICENSE) RST_FILE = ''' .. _{name}: + **************** {name} **************** diff --git a/src/accel/AlongStepFactory.cc b/src/accel/AlongStepFactory.cc index 9267cf3a96..dbdc35ed88 100644 --- a/src/accel/AlongStepFactory.cc +++ b/src/accel/AlongStepFactory.cc @@ -47,7 +47,7 @@ auto UniformAlongStepFactory::operator()( AlongStepFactoryInput const& input) const -> result_type { // Get the field strength in tesla (or zero if accessor is undefined) - auto field_params = get_field_ ? get_field_() : UniformFieldParams{}; + auto field_params = this->get_field(); auto magnitude = native_value_to(norm(field_params.field)); @@ -78,6 +78,15 @@ auto UniformAlongStepFactory::operator()( } } +//---------------------------------------------------------------------------// +/*! + * Get the field params (used for converting to celeritas::inp). + */ +UniformFieldParams UniformAlongStepFactory::get_field() const +{ + return get_field_ ? get_field_() : UniformFieldParams{}; +} + //---------------------------------------------------------------------------// /*! * Emit an along-step action with a non-uniform magnetic field. @@ -90,6 +99,10 @@ RZMapFieldAlongStepFactory::RZMapFieldAlongStepFactory(RZMapFieldFunction f) CELER_EXPECT(get_fieldmap_); } +//---------------------------------------------------------------------------// +/*! + * Emit an along-step action. + */ auto RZMapFieldAlongStepFactory::operator()( AlongStepFactoryInput const& input) const -> result_type { @@ -105,5 +118,14 @@ auto RZMapFieldAlongStepFactory::operator()( input.imported->em_params.energy_loss_fluct); } +//---------------------------------------------------------------------------// +/*! + * Get the field params (used for converting to celeritas::inp). + */ +RZMapFieldInput RZMapFieldAlongStepFactory::get_field() const +{ + return this->get_fieldmap_(); +} + //---------------------------------------------------------------------------// } // namespace celeritas diff --git a/src/accel/AlongStepFactory.hh b/src/accel/AlongStepFactory.hh index b61294f40d..addcd9820b 100644 --- a/src/accel/AlongStepFactory.hh +++ b/src/accel/AlongStepFactory.hh @@ -118,6 +118,9 @@ class UniformAlongStepFactory final : public AlongStepFactoryInterface // Emit an along-step action result_type operator()(argument_type input) const final; + // Get the field params (used for converting to celeritas::inp) + UniformFieldParams get_field() const; + private: FieldFunction get_field_; }; @@ -142,6 +145,9 @@ class RZMapFieldAlongStepFactory final : public AlongStepFactoryInterface // Emit an along-step action result_type operator()(argument_type input) const final; + // Get the field params (used for converting to celeritas::inp) + RZMapFieldInput get_field() const; + private: RZMapFieldFunction get_fieldmap_; }; diff --git a/src/accel/SetupOptions.cc b/src/accel/SetupOptions.cc index 4337eed284..0601f7f47b 100644 --- a/src/accel/SetupOptions.cc +++ b/src/accel/SetupOptions.cc @@ -6,12 +6,178 @@ //---------------------------------------------------------------------------// #include "SetupOptions.hh" +#include "corecel/io/Logger.hh" +#include "corecel/math/ArrayUtils.hh" #include "geocel/GeantGeoUtils.hh" +#include "celeritas/field/RZMapFieldInput.hh" +#include "celeritas/field/UniformFieldData.hh" +#include "celeritas/inp/FrameworkInput.hh" +#include "celeritas/inp/Problem.hh" +#include "AlongStepFactory.hh" #include "ExceptionConverter.hh" namespace celeritas { +namespace +{ +//---------------------------------------------------------------------------// + +auto to_input(SDSetupOptions::StepPoint const& sp) +{ + inp::GeantSDStepPointAttributes result; + result.global_time = sp.global_time; + result.position = sp.position; + result.direction = sp.direction; + result.kinetic_energy = sp.kinetic_energy; + return result; +} + +auto to_input(SDSetupOptions const& sd) +{ + inp::GeantSensitiveDetector result; + + result.ignore_zero_deposition = sd.ignore_zero_deposition; + result.energy_deposition = sd.energy_deposition; + result.locate_touchable = sd.locate_touchable; + result.track = sd.track; + result.pre = to_input(sd.pre); + result.post = to_input(sd.post); + result.force_volumes = std::set( + sd.force_volumes.begin(), sd.force_volumes.end()); + result.skip_volumes = std::set( + sd.skip_volumes.begin(), sd.skip_volumes.end()); + + return result; +} + +//---------------------------------------------------------------------------// +/*! + * Construct system attributes from setup options. + */ +inp::System load_system(SetupOptions const& so) +{ + inp::System s; + if (celeritas::Device::num_devices()) + { + inp::Device d; + d.stack_size = so.cuda_stack_size; + d.heap_size = so.cuda_heap_size; + + s.device = d; + } + return s; +} + +//---------------------------------------------------------------------------// +/*! + * FrameworkInput adapter function. + */ +struct ProblemSetup +{ + SetupOptions const& so; + + void operator()(inp::Problem&) const; +}; + +//---------------------------------------------------------------------------// +/*! + * Set a Celeritas problem input definition. + */ +void ProblemSetup::operator()(inp::Problem& p) const +{ + if (!so.geometry_file.empty()) + { + p.model.geometry = so.geometry_file; + } + p.diagnostics.output_file = so.output_file; + + p.control.num_streams = so.get_num_streams(); + + p.control.capacity = [this, num_streams = p.control.num_streams] { + inp::StateCapacity c; + c.tracks = so.max_num_tracks * num_streams; + c.initializers = so.initializer_capacity * num_streams; + c.secondaries + = static_cast(so.secondary_stack_factor * c.tracks); + c.primaries = so.auto_flush; + return c; + }(); + + p.tracking.limits = [this] { + inp::TrackingLimits tl; + tl.steps = so.max_steps; + tl.step_iters = so.max_step_iters; + tl.field_substeps = so.max_field_substeps; + return tl; + }(); + + if (so.track_order != TrackOrder::size_) + { + p.control.track_order = so.track_order; + } + + if (celeritas::Device::num_devices()) + { + inp::DeviceDebug dd; + dd.default_stream = so.default_stream; + dd.sync_stream = so.action_times; + + p.control.device_debug = std::move(dd); + } + + if (so.sd.enabled) + { + p.scoring.sd = to_input(so.sd); + } + + if (auto* u = so.make_along_step.target()) + { + // Check if magnitude is zero + UniformFieldParams params = u->get_field(); + auto field_val = norm(params.field); + if (field_val > 0) + { + CELER_LOG(info) << "Using a uniform field: " << field_val << " [T]"; + inp::UniformField field; + field.strength = params.field; + field.driver_options = params.options; + p.field = std::move(field); + } + else + { + CELER_LOG(debug) << "No magnetic field"; + } + } + else if (auto* u = so.make_along_step.target()) + { + CELER_LOG(debug) << "Getting RZ map field"; + p.field = u->get_field(); + } + else + { + CELER_NOT_IMPLEMENTED("processing generic along-step factory"); + } + + p.diagnostics.export_files = [this] { + inp::ExportFiles ef; + ef.physics = so.physics_output_file; + ef.offload = so.offload_output_file; + ef.geometry = so.geometry_output_file; + return ef; + }(); + + p.diagnostics.timers.action = so.action_times; + + if (!so.slot_diagnostic_prefix.empty()) + { + p.diagnostics.slot = inp::SlotDiagnostic{so.slot_diagnostic_prefix}; + } +} + +//---------------------------------------------------------------------------// +} // namespace + //---------------------------------------------------------------------------// /*! * Find volumes by name for SDSetupOptions. @@ -31,5 +197,20 @@ FindVolumes(std::unordered_set names) return result; } +//---------------------------------------------------------------------------// +/*! + * Construct a framework input from setup options. + * + * \note The setup options *must* stay in scope until problem initialization! + */ +inp::FrameworkInput to_inp(SetupOptions const& so) +{ + inp::FrameworkInput result; + result.system = load_system(so); + result.geant.ignore_processes = so.ignore_processes; + result.adjuster = ProblemSetup{so}; + return result; +} + //---------------------------------------------------------------------------// } // namespace celeritas diff --git a/src/accel/SetupOptions.hh b/src/accel/SetupOptions.hh index 8efa596f0f..36a790b8d8 100644 --- a/src/accel/SetupOptions.hh +++ b/src/accel/SetupOptions.hh @@ -20,6 +20,11 @@ class G4LogicalVolume; namespace celeritas { +namespace inp +{ +struct FrameworkInput; +} + struct AlongStepFactoryInput; //---------------------------------------------------------------------------// /*! @@ -65,6 +70,9 @@ struct AlongStepFactoryInput; * \note These setup options affect only the \c HitManager construction that is * responsible for reconstructing CPU hits and sending directly to the Geant4 * detectors. It does not change the underlying physics. + * + * \note This class will be replaced in v1.0 + * by \c celeritas::inp::SensitiveDetector . */ struct SDSetupOptions { @@ -106,6 +114,9 @@ struct SDSetupOptions * * The interface for the "along-step factory" (input parameters and output) is * described in \c AlongStepFactoryInterface . + * + * \note This class will be replaced in v1.0 + * by \c celeritas::inp::FrameworkInput . */ struct SetupOptions { @@ -163,9 +174,7 @@ struct SetupOptions //!@{ //! \name Track reordering options - - TrackOrder track_order{Device::num_devices() ? TrackOrder::init_charge - : TrackOrder::none}; + TrackOrder track_order{TrackOrder::size_}; //!@} //! Set the number of streams (defaults to run manager # threads) @@ -222,5 +231,8 @@ struct SetupOptions std::unordered_set FindVolumes(std::unordered_set); +// Construct a framework input +inp::FrameworkInput to_inp(SetupOptions const& so); + //---------------------------------------------------------------------------// } // namespace celeritas diff --git a/src/accel/SharedParams.cc b/src/accel/SharedParams.cc index d3adbe77fe..69b77acdda 100644 --- a/src/accel/SharedParams.cc +++ b/src/accel/SharedParams.cc @@ -580,6 +580,13 @@ void SharedParams::initialize_core(SetupOptions const& options) input.capacity = options.initializer_capacity; input.max_events = 1; // TODO: use special "max events" case input.track_order = options.track_order; + if (input.track_order == TrackOrder::size_) + { + input.track_order = celeritas::device() ? TrackOrder::init_charge + : TrackOrder::none; + CELER_LOG(info) << "Set track ordering to default: " + << to_cstring(input.track_order); + } return std::make_shared(std::move(input)); }(); diff --git a/src/celeritas/CMakeLists.txt b/src/celeritas/CMakeLists.txt index 2fb38db517..6e51fe4d91 100644 --- a/src/celeritas/CMakeLists.txt +++ b/src/celeritas/CMakeLists.txt @@ -108,6 +108,8 @@ list(APPEND SOURCES random/CuHipRngParams.cc random/XorwowRngData.cc random/XorwowRngParams.cc + setup/Import.cc + setup/System.cc track/SimParams.cc track/SortTracksAction.cc track/TrackInitParams.cc diff --git a/src/celeritas/em/interactor/CombinedBremInteractor.hh b/src/celeritas/em/interactor/CombinedBremInteractor.hh index c01cfd0194..79e9244a00 100644 --- a/src/celeritas/em/interactor/CombinedBremInteractor.hh +++ b/src/celeritas/em/interactor/CombinedBremInteractor.hh @@ -38,7 +38,7 @@ namespace celeritas * interactor at the low energy (< 1 GeV) and the relativistic bremsstrahlung * interactor at the high energy for the e-/e+ bremsstrahlung process. * - * \todo: see if there's any occupancy/performance difference by defining the + * \todo See if there's any occupancy/performance difference by defining the * samplers *inside* the conditional on "is_relativistic". */ class CombinedBremInteractor diff --git a/src/celeritas/em/interactor/MuBremsstrahlungInteractor.hh b/src/celeritas/em/interactor/MuBremsstrahlungInteractor.hh index 0d07300264..642204108e 100644 --- a/src/celeritas/em/interactor/MuBremsstrahlungInteractor.hh +++ b/src/celeritas/em/interactor/MuBremsstrahlungInteractor.hh @@ -115,7 +115,7 @@ CELER_FUNCTION MuBremsstrahlungInteractor::MuBremsstrahlungInteractor( CELER_EXPECT(particle_.energy() > cutoffs.energy(shared.gamma)); // Calculate rejection envelope: *assume* the highest cross section - // is at its lowerst value + // is at its lowest value real_type gamma_cutoff = value_as(cutoffs.energy(shared.gamma)); envelope_ = gamma_cutoff * calc_dcs_(Energy{gamma_cutoff}); } diff --git a/src/celeritas/em/interactor/MuPairProductionInteractor.hh b/src/celeritas/em/interactor/MuPairProductionInteractor.hh index 772764e5f4..890eac45b1 100644 --- a/src/celeritas/em/interactor/MuPairProductionInteractor.hh +++ b/src/celeritas/em/interactor/MuPairProductionInteractor.hh @@ -111,7 +111,7 @@ CELER_FUNCTION MuPairProductionInteractor::MuPairProductionInteractor( //---------------------------------------------------------------------------// /*! - * Simulate electron-posiitron pair production by muons. + * Simulate electron-positron pair production by muons. */ template CELER_FUNCTION Interaction MuPairProductionInteractor::operator()(Engine& rng) @@ -139,7 +139,7 @@ CELER_FUNCTION Interaction MuPairProductionInteractor::operator()(Engine& rng) electron.direction = rotate(from_spherical(sample_costheta(rng), phi), inc_direction_); - // Create the secondary electron + // Create the secondary positron Secondary& positron = secondaries[1]; positron.particle_id = shared_.ids.positron; positron.energy = energy.positron; diff --git a/src/celeritas/em/model/CombinedBremModel.hh b/src/celeritas/em/model/CombinedBremModel.hh index abfa9783ce..33861b2c46 100644 --- a/src/celeritas/em/model/CombinedBremModel.hh +++ b/src/celeritas/em/model/CombinedBremModel.hh @@ -28,6 +28,8 @@ class ParticleParams; /*! * Set up and launch a combined model of SeltzerBergerModel at the low energy * and RelativisticBremModel at the high energy for e+/e- Bremsstrahlung. + * + * \deprecated Delete in v1.0: only implemented for one element */ class CombinedBremModel final : public Model, public StaticConcreteAction { diff --git a/src/celeritas/em/process/BremsstrahlungProcess.hh b/src/celeritas/em/process/BremsstrahlungProcess.hh index b6aaebf99e..4bd6bfd6dc 100644 --- a/src/celeritas/em/process/BremsstrahlungProcess.hh +++ b/src/celeritas/em/process/BremsstrahlungProcess.hh @@ -41,8 +41,8 @@ class BremsstrahlungProcess : public Process { BremsModelSelection selection{BremsModelSelection::all}; //!> Model //! selection - bool combined_model{true}; //!> Use a unified relativistic/SB - //! interactor + bool combined_model{false}; //!> Use a unified relativistic/SB + //! interactor bool enable_lpm{true}; //!> Account for LPM effect at very high //! energies bool use_integral_xs{true}; //!> Use integral method for sampling diff --git a/src/celeritas/ext/GeantPhysicsOptions.hh b/src/celeritas/ext/GeantPhysicsOptions.hh index c0b491ec75..2143a3af52 100644 --- a/src/celeritas/ext/GeantPhysicsOptions.hh +++ b/src/celeritas/ext/GeantPhysicsOptions.hh @@ -175,7 +175,7 @@ struct GeantPhysicsOptions double msc_safety_factor{0.6}; //! Lambda limit for MSC models [len] double msc_lambda_limit{0.1 * units::centimeter}; - //! Polar angle limii between single and multiple Coulomb scattering + //! Polar angle limit between single and multiple Coulomb scattering double msc_theta_limit{constants::pi}; //! Factor for dynamic computation of angular limit between SS and MSC double angle_limit_factor{1}; diff --git a/src/celeritas/field/FieldDriverOptions.hh b/src/celeritas/field/FieldDriverOptions.hh index 6ecaa89fb5..7f2f327075 100644 --- a/src/celeritas/field/FieldDriverOptions.hh +++ b/src/celeritas/field/FieldDriverOptions.hh @@ -21,6 +21,7 @@ namespace celeritas * it's a multiplicative factor for reducing the step, not anything with * geometry) * TODO: remove errcon + * TODO: for some of these we could probably use single-precision */ struct FieldDriverOptions { diff --git a/src/celeritas/field/RZMapFieldInput.hh b/src/celeritas/field/RZMapFieldInput.hh index d26b05070f..c946dba42a 100644 --- a/src/celeritas/field/RZMapFieldInput.hh +++ b/src/celeritas/field/RZMapFieldInput.hh @@ -30,6 +30,8 @@ namespace celeritas * unit strength is 1000*tesla. * * The field values are all indexed with R having stride 1: [Z][R] + * + * \todo Use C indexing instead of Fortran? Or rename to ZR field? */ struct RZMapFieldInput { @@ -42,6 +44,7 @@ struct RZMapFieldInput std::vector field_z; //!< Flattened Z field component [bfield] std::vector field_r; //!< Flattened R field component [bfield] + // TODO: remove from field input; should be a separate input FieldDriverOptions driver_options; //! Whether all data are assigned and valid diff --git a/src/celeritas/field/UniformField.hh b/src/celeritas/field/UniformField.hh index 62cf083444..11c22960eb 100644 --- a/src/celeritas/field/UniformField.hh +++ b/src/celeritas/field/UniformField.hh @@ -16,7 +16,7 @@ namespace celeritas * A uniform field. * * The values of the field should be in native units. For magnetic fields, this - * unit is gauss. + * unit is gauss for the CGS system. */ class UniformField { diff --git a/src/celeritas/inp/Control.hh b/src/celeritas/inp/Control.hh new file mode 100644 index 0000000000..50e4e46386 --- /dev/null +++ b/src/celeritas/inp/Control.hh @@ -0,0 +1,124 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Control.hh +//---------------------------------------------------------------------------// +#pragma once + +#include + +#include "celeritas/Types.hh" + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Set up per-process state/buffer capacities. + * + * Increasing these values increases resource requirements with the trade-off + * of (usually!) improving performance. A larger number of \c tracks in flight + * means improved performance on GPU because the standard kernel size + * increases, but it also means higher memory usage because of the larger + * number of full states. More \c initializers are necessary for more (and + * higher-energy) tracks when lots of particles are in flight and producing new + * child particles. More \c secondaries may be necessary if physical processes + * that produce many daughters (e.g., atomic relaxation or Bertini cascade) are + * active. The number of \c events in flight primarily increases the number of + * active tracks, possible initializers, and produced secondaries (NOTE: see + * [#1233](https://github.com/celeritas-project/celeritas/issues/1233) ). + * Finally, the number of \c primaries is the maximum number of pending tracks + * from an external application before running a kernel to construct \c + * initializers and execute the stpeping loop. + * + * Capacities are defined as the number per application process (task): this + * means that in a multithreaded context it implies "strong scaling" (i.e., the + * allocations are divided among threads), and in a multiprocess context it + * implies "weak scaling" (the problem size grows with the number of + * processes). + * In other words, if used in a multithread "event-parallel" context, each + * state gets the specified \c tracks divided by the number of threads. When + * used in MPI parallel (e.g., one process per GPU), each process \em rank has + * \c tracks total threads. + * + * \note The \c primaries was previously named \c auto_flush . + * \note Previously, \c SetupOptions and \c celer-g4 treated these quantities + * as "per stream" whereas \c celer-sim used "per process". + * + * Defaults: + * - \c secondary: twice the number of track slots. + * + * \todo Split this into "core" state capacity and "optical" state capacity? + * Core contains \c events and \c secondaries . + * \todo Instead of a special value \c events=0, make a variant or something + * more descriptive? + * \todo Some of these parameters will be more automated in the future. + */ +struct StateCapacity +{ + //! Maximum number of primaries that can be buffered before stepping + size_type primaries{}; + //! Maximum number of queued primaries+secondaries + size_type initializers{}; + //! Maximum number of track slots to be simultaneously stepped + size_type tracks{}; + //! Maximum number of secondaries created per step + std::optional secondaries; + + //! Maximum number of simultaneous events (zero for Geant4 integration) + size_type events{0}; +}; + +//---------------------------------------------------------------------------// +/*! + * When using GPU, change execution options that make it easier to debug. + * + * Defaults: + * - \c sync_stream: \c false unless \c timers.diagnostics.action is \c true. + */ +struct DeviceDebug +{ + //! Launch all kernels on the default stream + bool default_stream{false}; + //! Synchronize the stream after every kernel launch + std::optional sync_stream; +}; + +//---------------------------------------------------------------------------// +/*! + * Set up control/tuning parameters that do not affect physics. + * + * Defaults: + * - \c device_debug: absent unless device is enabled + * - \c optical_capacity: absent unless optical physics is enabled + * - \c track_order: \c init_charge on GPU, \c none on CPU + */ +struct Control +{ + //! Per-process state sizes + StateCapacity capacity; + + //! Per-process state sizes for *optical* tracking loop + std::optional optical_capacity; + + //! Number of streams + size_type num_streams{}; + + //! Track sorting and initialization + std::optional track_order; + + //! Debug options for device + std::optional device_debug; + + //! Perform a no-op step at the beginning to improve timing measurements + bool warm_up{false}; + + //! Random number generator seed + unsigned int seed{}; +}; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Diagnostics.hh b/src/celeritas/inp/Diagnostics.hh new file mode 100644 index 0000000000..1b54f70548 --- /dev/null +++ b/src/celeritas/inp/Diagnostics.hh @@ -0,0 +1,149 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Diagnostics.hh +//---------------------------------------------------------------------------// +#pragma once + +#include +#include + +#include "corecel/Types.hh" +#include "celeritas/user/RootStepWriterInput.hh" + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Write out problem data to separate files for debugging. + * + * These options are meant for use in the context of a larger experiment + * framework, for exporting physics settings, detector geometry, and offloaded + * EM tracks for reproducing externally. + * + * \todo Some of these will be one per run; others will be one per thread. + */ +struct ExportFiles +{ + //! Filename for ROOT dump of physics data + std::string physics; + //! Filename to dump a ROOT/HepMC3 copy of primaries + std::string offload; + //! Filename to dump a GDML file of the active Geant4 geometry + std::string geometry; +}; + +//---------------------------------------------------------------------------// +/*! + * Export (possibly large!) diagnostic output about track slot contents. + * + * \sa celeritas::SlotDiagnostic + */ +struct SlotDiagnostic +{ + //! Prefix of file names for outputting on each stream + std::string basename; +}; + +//---------------------------------------------------------------------------// +/*! + * Set up Celeritas timers. + */ +struct Timers +{ + //! Accumulate elapsed time for each action + bool action{false}; + //! Save elapsed time for each step + bool step{false}; +}; + +//---------------------------------------------------------------------------// +/*! + * Output track diagnostic counters. + * + * These include the number of tracks generated, active, aborted, and alive; + * as well as the number of initializers (or the high water mark thereof). + */ +struct Counters +{ + //! Write diagnostics for each step + bool step{false}; + //! Write diagnostics for each event (or run, if multiple events) + bool event{false}; +}; + +//---------------------------------------------------------------------------// +/*! + * Write out MC truth data. + * + * \sa celeritas::RootStepWriter + */ +struct McTruth +{ + //! Path to saved ROOT mc truth file + std::string output_file; + + //! Filter saved data by track ID, particle type + SimpleRootFilterInput filter; +}; + +//---------------------------------------------------------------------------// +/*! + * Accumulate distributions of the number of steps per particle type. + */ +struct StepDiagnostic +{ + //! Maximum number of steps per track to bin + size_type bins{1000}; +}; + +//---------------------------------------------------------------------------// +/*! + * Set up Celeritas built-in diagnostics. + */ +struct Diagnostics +{ + //! Write Celeritas diagnostics to this file ("-" is stdout) + std::string output_file{"-"}; + + //! Export problem setup + ExportFiles export_files; + + //! Write elapsed times for each step + Timers timers; + + //! Store step/track counts + Counters counters; + + //! Write Perfetto tracing data to this filename + std::string perfetto_file; + + //! Activate slot diagnostics + std::optional slot; + + /*! + * Accumulate post-step actions for each particle type. + * + * \sa celeritas::ActionDiagnostic + */ + bool action{false}; + + //! Add a 'status checker' for debugging new actions + bool status_checker{false}; + + //! Write detailed MC truth output + std::optional mctruth; + + //! Bin number of steps per track + std::optional step; + + //! Log the execution progress every N events + size_type log_frequency{1}; +}; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Events.hh b/src/celeritas/inp/Events.hh new file mode 100644 index 0000000000..a20fd0666c --- /dev/null +++ b/src/celeritas/inp/Events.hh @@ -0,0 +1,119 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Events.hh +//---------------------------------------------------------------------------// +#pragma once + +#include +#include + +#include "corecel/Types.hh" +#include "geocel/Types.hh" +#include "celeritas/Quantities.hh" +#include "celeritas/phys/PDGNumber.hh" + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +//! Generate at a single point +struct PointShape +{ + Real3 pos{0, 0, 0}; +}; + +//! Sample uniformly in a box +struct UniformBoxShape +{ + Real3 lower{0, 0, 0}; + Real3 upper{0, 0, 0}; +}; + +//! Choose a spatial distribution for the primary generator +using ShapeDistribution = std::variant; + +//---------------------------------------------------------------------------// +//! Generate angles isotropically +struct IsotropicAngle +{ +}; + +//! Generate angles in a single direction +struct MonodirectionalAngle +{ + Real3 dir{0, 0, 1}; +}; + +//! Choose an angular distribution for the primary generator +using AngleDistribution = std::variant; + +//---------------------------------------------------------------------------// +//! Generate primaries at a single energy value +struct Monoenergetic +{ + units::MevEnergy energy; +}; + +//! Choose an angular distribution for the primary generator +using EnergyDistribution = Monoenergetic; + +//---------------------------------------------------------------------------// +/*! + * Generate from a hardcoded distribution of primary particles. + * + * \todo Allow programmatic setting from particle ID as well + * \todo Units? + * \code using Particle = std::variant; \endcode + */ +struct PrimaryGenerator +{ + //! Random number seed + unsigned int seed{}; + //! Sample evenly from this vector of particle types + std::vector pdg; + //! Number of events to generate + size_type num_events{}; + //! Number of primaries per event + size_type primaries_per_event{}; + + //! Distribution for sampling source position + ShapeDistribution shape; + //! Distribution for sampling source direction + AngleDistribution angle; + //! Distribution for sampling source energy + EnergyDistribution energy; +}; + +//---------------------------------------------------------------------------// +//! Sample random events from an input file +struct SampleFileEvents +{ + //! Total number of events to sample + size_type num_events{}; + //! File events per sampled event + size_type num_merged{}; + + //! ROOT file input + std::string event_file; + + //! Random number generator seed + unsigned int seed{}; +}; + +//---------------------------------------------------------------------------// +//! Read all events from the given file +struct ReadFileEvents +{ + std::string event_file; +}; + +//---------------------------------------------------------------------------// +//! Mechanism for generating events for tracking +using Events = std::variant; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Field.hh b/src/celeritas/inp/Field.hh new file mode 100644 index 0000000000..31c91adac5 --- /dev/null +++ b/src/celeritas/inp/Field.hh @@ -0,0 +1,61 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Field.hh +//---------------------------------------------------------------------------// +#pragma once + +#include + +#include "geocel/Types.hh" +#include "celeritas/UnitTypes.hh" +#include "celeritas/field/RZMapFieldInput.hh" + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Build a problem without magnetic fields. + */ +struct NoField +{ +}; + +//---------------------------------------------------------------------------// +/*! + * Create a uniform nonzero field. + * + * \todo Field driver options will be separate from the magnetic field. They, + * plus the field type, will be specified in a FieldParams that maps + * region/particle/energy to field setup. + */ +struct UniformField +{ + //! Default field units are tesla + UnitSystem units{UnitSystem::si}; + + //! Field strength + Real3 strength{0, 0, 0}; + + //! Field driver options + FieldDriverOptions driver_options; +}; + +//---------------------------------------------------------------------------// +/*! + * Build a separable R-Z magnetic field from a file. + * + * \todo Move field input here + */ +using RZMapField = ::celeritas::RZMapFieldInput; + +//---------------------------------------------------------------------------// +//! Field type +using Field = std::variant; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/FrameworkInput.hh b/src/celeritas/inp/FrameworkInput.hh new file mode 100644 index 0000000000..711f855ef5 --- /dev/null +++ b/src/celeritas/inp/FrameworkInput.hh @@ -0,0 +1,50 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/FrameworkInput.hh +//---------------------------------------------------------------------------// +#pragma once + +#include +#include + +#include "Import.hh" +#include "System.hh" + +namespace celeritas +{ +namespace inp +{ +struct Problem; + +//---------------------------------------------------------------------------// +/*! + * Describe how to import data into celeritas via an \c Input data structure. + * + * The order of initialization and loading follows the member declarations: + * - System attributes (GPU activation etc.) are set + * - Geant4 data is loaded + * - External Geant4 data files (such as EM LOW) are loaded + * - Optional control/diagnostic overrides are loaded + * - Optional framework-defined adjustments are applied + */ +struct FrameworkInput +{ + //! Base system configuration + System system; + + //! Configure what data to load from Geant4 + GeantImport geant; + //! Load external data files + GeantDataImport geant_data; + //! Optionally add diagnostics and control parameters from an external file + std::optional update; + + //! User application/framework-defined adjustments + std::function adjuster; +}; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Import.hh b/src/celeritas/inp/Import.hh new file mode 100644 index 0000000000..24ac38c74d --- /dev/null +++ b/src/celeritas/inp/Import.hh @@ -0,0 +1,92 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Import.hh +//---------------------------------------------------------------------------// +#pragma once + +#include +#include + +#include "celeritas/ext/GeantImporter.hh" + +#include "System.hh" + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +struct Problem; +struct System; + +//---------------------------------------------------------------------------// +/*! + * Options for loading problem data from a ROOT/JSON file. + */ +struct FileImport +{ + //! Path to the problem input file + std::string input; +}; + +//---------------------------------------------------------------------------// +/*! + * Options for importing data from in-memory Geant4. + * + * \todo Update \c GeantImportDataSelection to control what Celeritas + * processes/particles are offloaded. + */ +struct GeantImport +{ + //! Do not use Celeritas physics for the given Geant4 process names + std::vector ignore_processes; + + //! Only import a subset of available Geant4 data + GeantImportDataSelection data_selection; +}; + +//---------------------------------------------------------------------------// +/*! + * Options for loading cross section data from Geant4 data files. + * + * \todo This is not yet used, but it will call LivermorePEReader, + * SeltzerBergerReader, AtomicRelaxationReader to fill cross section data. + * Since Geant4 data structures don't provide access to these, we must read + * them ourselves. + * + * Defaults: + * - \c livermore_dir: uses the \c G4LEDATA environment variable + * - \c particle_dir: uses the \c G4PARTICLEXS environment variable + */ +struct GeantDataImport +{ + //! Livermore photoelectric data directory (optional) + std::string livermore_dir; + //! Particle cross section data directory (optional) + std::string particle_dir; +}; + +//---------------------------------------------------------------------------// +/*! + * Update control and diagnostic options from an external input file. + * + * This is used in concert with \c FileImport : the output from another code + * can be used as input, but overlaid with diagnostic and control/tuning + * information. + */ +struct UpdateImport +{ + //! Replace existing diagnostics + bool diagnostics{true}; + //! Replace existing control parameters + bool control{true}; + + //! Path to the file + std::string input; +}; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Model.hh b/src/celeritas/inp/Model.hh new file mode 100644 index 0000000000..d308bd6852 --- /dev/null +++ b/src/celeritas/inp/Model.hh @@ -0,0 +1,33 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Model.hh +//---------------------------------------------------------------------------// +#pragma once + +#include +#include + +class G4VPhysicalVolume; + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Set up geometry/material model. + */ +struct Model +{ + //! Path to GDML (or ORANGE override) file, or Geant4 world + std::variant geometry; + + // TODO: Materials + // TODO: Regions +}; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Physics.hh b/src/celeritas/inp/Physics.hh new file mode 100644 index 0000000000..250b26ff86 --- /dev/null +++ b/src/celeritas/inp/Physics.hh @@ -0,0 +1,100 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Physics.hh +//---------------------------------------------------------------------------// +#pragma once + +#include +#include +#include + +#include "corecel/Types.hh" +#include "celeritas/Types.hh" +#include "celeritas/phys/AtomicNumber.hh" + +#include "PhysicsProcess.hh" + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Electromagnetic physics processes and options. + */ +struct EmPhysics +{ + //! Bremsstrahlung process + std::optional brems{std::in_place}; + //! Electron+positron pair production process + std::optional pair_production{std::in_place}; + + //!@{ + //! \name Energy loss and slowing down + + //! Use cubic spline interpolation for energy loss + bool eloss_spline{false}; +#if 0 + //! Energy loss fluctuations + bool eloss_fluct{true}; +#endif + // + //!@} +}; + +//---------------------------------------------------------------------------// +/*! + * Optical physics processes and options. + */ +struct OpticalPhysics +{ +}; + +//---------------------------------------------------------------------------// +/*! + * Hadronic physics processes and options. + * + * This can be used to enable or set up Geant4 hadronic physics. + */ +struct HadronicPhysics +{ +}; + +//---------------------------------------------------------------------------// +/*! + * Decay processes and options. + */ +struct DecayPhysics +{ +}; + +//---------------------------------------------------------------------------// +/*! + * Set up physics options. + * + * \todo Move optical and hadronic physics options from + * \c celeritas::GeantPhysicsOptions + * \todo Move particle data from \c celeritas::ImportParticle + * \todo Add function for injecting user processes for + * \c celeritas::PhysicsParams + */ +struct Physics +{ + //! Enable electromagnetic physics + std::optional em{std::in_place}; + + //! Enable optical photon physics + std::optional optical; + + //! Enable hadronic physics + std::optional hadronic; + + //! Enable decay physics + std::optional decay; +}; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/PhysicsModel.hh b/src/celeritas/inp/PhysicsModel.hh new file mode 100644 index 0000000000..399963f14a --- /dev/null +++ b/src/celeritas/inp/PhysicsModel.hh @@ -0,0 +1,75 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/PhysicsModel.hh +//---------------------------------------------------------------------------// +#pragma once + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Seltzer-Berger bremsstrahlung model. + * + * \todo Move \c sb_data from celeritas::ImportData here. + */ +struct SeltzerBergerModel +{ +}; + +//---------------------------------------------------------------------------// +/*! + * Relativistic bremsstrahlung model. + */ +struct RelBremsModel +{ + //! Account for LPM effect at very high energies + bool enable_lpm{true}; +}; + +//---------------------------------------------------------------------------// +/*! + * Muon bremsstrahlung model. + */ +struct MuBremsModel +{ +}; + +//---------------------------------------------------------------------------// +// PAIR PRODUCTION MODELS +//---------------------------------------------------------------------------// +/*! + * Bethe-Heitler relativistic pair production from gammas. + */ +struct BetheHeitlerModel +{ +}; + +//---------------------------------------------------------------------------// +/*! + * Pair production from muons. + * + * \todo Move MuPPET table celeritas::ImportMuPairProductionTable here. + */ +struct MuPairProductionModel +{ +}; + +//---------------------------------------------------------------------------// +// ALIASES +//---------------------------------------------------------------------------// +//!@{ +//! \name Model aliases +//! \todo rename `em/model` to match + +using MuBremsstrahlungModel = MuBremsModel; +using RelativisticBremModel = RelBremsModel; + +//!@} + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/PhysicsProcess.hh b/src/celeritas/inp/PhysicsProcess.hh new file mode 100644 index 0000000000..c08a3be73c --- /dev/null +++ b/src/celeritas/inp/PhysicsProcess.hh @@ -0,0 +1,57 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/PhysicsProcess.hh +//---------------------------------------------------------------------------// +#pragma once + +#include + +#include "PhysicsModel.hh" + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Construct a physics process for bremsstrahlung. + */ +struct BremsProcess +{ + std::optional sb{std::in_place}; + std::optional rel{std::in_place}; + std::optional mu; + + //! Use a unified relativistic/SB interactor + bool combined_model{false}; + //! Use integral method for sampling discrete interaction length + bool integral_xs{true}; +}; +//---------------------------------------------------------------------------// +/*! + * Construct a physics process for electron/positron pair production. + */ +struct PairProductionProcess +{ + //! Bethe-Heitler pair production + std::optional bethe_heitler; + //! Muonic pair production + std::optional mu; +}; + +//---------------------------------------------------------------------------// +//!@{ +//! \name Process aliases +//! \todo rename `em/model` to match, merge muon and electron proceses + +using BremsstrahlungProcess = BremsProcess; +using GammaConversionProcess = PairProductionProcess; +using MuPairProductionProcess = PairProductionProcess; + +//!@} + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Problem.hh b/src/celeritas/inp/Problem.hh new file mode 100644 index 0000000000..50271215d2 --- /dev/null +++ b/src/celeritas/inp/Problem.hh @@ -0,0 +1,68 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Problem.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "Control.hh" +#include "Diagnostics.hh" +#include "Field.hh" +#include "Model.hh" +#include "Physics.hh" +#include "Scoring.hh" +#include "Tracking.hh" + +namespace celeritas +{ +//---------------------------------------------------------------------------// +/*! + * Configure Celeritas input. + * + * Note that many of these input structs match up with the runtime classes that + * they help construct. Future restructuring of the code may result in more + * direct correspondence. + */ +namespace inp +{ +//---------------------------------------------------------------------------// +/*! + * Celeritas problem input definition. + * + * This should specify all the information necessary to track particles + * within Celeritas for offloading or standalone execution. (It does \em not + * contain system configuration such as GPU, or event/offload information.) + * + * Multiple problems can be run independently across the same program + * execution. + * + * Eventually this class and its daughters will subsume all the data in + * \c celeritas/io/ and all the input options from Models, Processes, + * Params, and other classes that are not implementation details. + * + * After loading, the struct will be able to be serialized to ROOT or JSON or + * some other struct for reproducibility. + */ +struct Problem +{ + //! Geometry, material, and region definitions + Model model; + //! Physics models and options + Physics physics; + //! Set up the magnetic field + Field field; + //! Manage scoring of hits and other quantities + Scoring scoring; + //! Tuning options that affect the physics + Tracking tracking; + + //! Low-level performance tuning and simulation control options + Control control; + //! Monte Carlo tracking, performance, and debugging diagnostics + Diagnostics diagnostics; +}; + +//---------------------------------------------------------------------------// +} // namespace inp +} // namespace celeritas diff --git a/src/celeritas/inp/Scoring.hh b/src/celeritas/inp/Scoring.hh new file mode 100644 index 0000000000..3e76955b71 --- /dev/null +++ b/src/celeritas/inp/Scoring.hh @@ -0,0 +1,136 @@ +//------------------------------- -*- C++ -*- -------------------------------// +// Copyright Celeritas contributors: see top-level COPYRIGHT file for details +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/inp/Scoring.hh +//---------------------------------------------------------------------------// +#pragma once + +#include +#include +#include +#include + +#include "corecel/io/Label.hh" + +class G4LogicalVolume; + +namespace celeritas +{ +namespace inp +{ +//---------------------------------------------------------------------------// +//! Options for saving attributes at each step point +struct GeantSDStepPointAttributes +{ + //! Store the time since the start of the event + bool global_time{true}; + //! Store the step point position + bool position{true}; + //! Store the step point direction (AKA momentum direction) + bool direction{true}; + //! Store the step point energy + bool kinetic_energy{true}; +}; + +//---------------------------------------------------------------------------// +/*! + * Control options for Geant4 sensitive detector integration. + * + * By default, Celeritas connects to Geant4 sensitive detectors so that it + * reconstructs full-fidelity hits with all available step information. + * + * - By default, steps that do not deposit energy do not generate any hits. + * - To improve performance and memory usage, determine what quantities (time, + * position, direction, touchable, ...) are required by your setup's + * sensitive detectors and set all other attributes to \c false. + * - Reconstructing the full geometry status using \c locate_touchable is the + * most expensive detector option. Disable it unless your SDs require (e.g.) + * the volume's copy number to locate a detector submodule. + * - Some reconstructed track attributes (such as post-step material) are + * currently never set because they are rarely used in practice. Contact the + * Celeritas team or submit a pull request to add this functionality. + * + * Various attributes on the step, track, and pre/post step points may be + * available depending on the selected options. + * + * - Disabling \c track will leave \c G4Step::GetTrack as \c nullptr . + * - Enabling \c track will set the \c Charge attribute on the + * pre-step. + * - Requested post-step data including \c GlobalTime, \c Position, \c + * KineticEnergy, and \c MomentumDirection will be copied to the \c Track + * when the combination of options is enabled. + * - Some pre-step properties (\c Material and \c MaterialCutsCouple, and + * sensitive detector) are always updated. Post-step values for those are not + * set. + * - Track and Parent IDs will \em never be a valid value since Celeritas track + * counters are independent from Geant4 track counters. Similarly, special + * Geant4 user-defined \c UserInformation and \c AuxiliaryTrackInformation + * are never set. + * + * The \c force_volumes option can be used for unusual cases (i.e., when using + * a custom run manager) that do not define SDs on the "master" thread. + * Similarly, the \c skip_volumes option allows optimized GPU-defined SDs to be + * used in place of a Geant4 callback. For both options, the \c + * FindVolumes helper function can be used to determine LV pointers from + * the volume names. + * + * \sa celeritas::HitManager + */ +struct GeantSensitiveDetector +{ + //! Provide either a set of labels or a set of pointers to Geant4 objects + using VariantSetVolume + = std::variant, std::set>; + + //! Skip steps that do not deposit energy locally + bool ignore_zero_deposition{true}; + //! Save energy deposition + bool energy_deposition{true}; + //! Set TouchableHandle for PreStepPoint + bool locate_touchable{true}; + //! Create a track with the dynamic particle type and post-step data + bool track{true}; + + //! Options for saving and converting beginning-of-step data + GeantSDStepPointAttributes pre; + //! Options for saving and converting end-of-step data + GeantSDStepPointAttributes post; + + //! Manually list LVs that don't have an SD on the master thread + VariantSetVolume force_volumes; + //! List LVs that should *not* have automatic hit mapping + VariantSetVolume skip_volumes; +}; + +//---------------------------------------------------------------------------// +/*! + * Integrate energy deposition in each volume over all events. + * + * \sa celeritas::SimpleCalo. + */ +struct SimpleCalo +{ + //! List of geometry volumes to score + std::vector