Skip to content

Commit

Permalink
Add option to use CLHEP and SI unit systems instead of Gaussian CGS (#…
Browse files Browse the repository at this point in the history
…1076)

* Add compile time switch for unit system

Due to units like "gram" and "centimeter" being non-integer, more
floating point error is accumulated, leading to slight mismatches for
eps_electric and atomic_mass.

* Update documentation to reflect native unit system

* Update lldb script

* Define molarity units

* Add inverse length for macro cross section

* Add unit traits for unit systems

* Rename NativeUnit to Native and replace some custom units

* Use unit-independent nomenclature for IO data

* Define SI units and add unit test

* fixup! Define SI units and add unit test

* Fix unit mass for CLHEP system

* Add magnetic field in CLHEP

* Address review feedback

* Move helper traits classes out of Quantity.hh

* fixup! Move helper traits classes out of Quantity.hh

* Address review feedback

* Fix clhep unit mass and field

* Use `if constexpr` to avoid sensitive FP arithmetic

* Address @pcanal comments
  • Loading branch information
sethrj committed Jan 4, 2024
1 parent f9b51d7 commit f5fa7b8
Show file tree
Hide file tree
Showing 52 changed files with 778 additions and 352 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ else()
set(_allow_single_prec TRUE)
endif()

celeritas_setup_option(CELERITAS_UNITS CGS)
celeritas_setup_option(CELERITAS_UNITS SI)
celeritas_setup_option(CELERITAS_UNITS CLHEP)
celeritas_define_options(CELERITAS_UNITS
"Native unit system for Celeritas")

celeritas_setup_option(CELERITAS_REAL_TYPE double)
celeritas_setup_option(CELERITAS_REAL_TYPE float)
celeritas_define_options(CELERITAS_REAL_TYPE
Expand Down
6 changes: 3 additions & 3 deletions scripts/dev/celerlldb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"""
Add LLDB wrappers for Celeritas types.
To use::
(lldb) command script import celeritas/scripts/dev/celerlldb.py --allow-reload
(lldb) type synthetic add -x "^celeritas::Span<.+>$" --python-class celerlldb.SpanSynthetic
To use from inside ``${SOURCE}/build``::
(lldb) command script import ../scripts/dev/celerlldb.py --allow-reload
(lldb) type synthetic add -x "^celeritas::Span<.+>$" --python-class celerlldb.SpanSynthetic
"""

Expand Down
5 changes: 2 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ set(CELERITAS_USE_VECGEOM ${CELERITAS_USE_VecGeom})
# the C preprocessor, so any unavailable options (e.g. CELERITAS_USE_CURAND
# when HIP is in use) will implicitly be zero.
celeritas_generate_option_config(CELERITAS_CORE_RNG)
# Same, but with CELERITAS_CORE_GEO_CONFIG
celeritas_generate_option_config(CELERITAS_CORE_GEO)
# Same, but with CELERITAS_REAL_TYPE
celeritas_generate_option_config(CELERITAS_UNITS)
celeritas_generate_option_config(CELERITAS_REAL_TYPE)
celeritas_configure_file("celeritas_config.h.in" "celeritas_config.h" @ONLY)

Expand All @@ -48,7 +47,7 @@ endif()

set(CELERITAS_CMAKE_STRINGS)
set(CELERITAS_BUILD_TYPE ${CMAKE_BUILD_TYPE})
foreach(_var BUILD_TYPE HOSTNAME REAL_TYPE CORE_GEO CORE_RNG)
foreach(_var BUILD_TYPE HOSTNAME REAL_TYPE CORE_GEO CORE_RNG UNITS)
set(_var "CELERITAS_${_var}")
string(TOLOWER "${_var}" _lower)
string(APPEND CELERITAS_CMAKE_STRINGS
Expand Down
4 changes: 2 additions & 2 deletions src/accel/detail/TouchableUpdater.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ namespace detail
class TouchableUpdater
{
public:
//! Maximum step to try within the current volume [cm]
//! Maximum step to try within the current volume [len]
static constexpr double max_step() { return 1 * units::millimeter; }

//! Warn when the step is greater than this amount [cm]
//! Warn when the step is greater than this amount [len]
static constexpr double max_quiet_step()
{
return 1e-3 * units::millimeter;
Expand Down
9 changes: 8 additions & 1 deletion src/celeritas/Constants.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ namespace constants
* lambdabar_electron | electron_Compton_length | Reduced Compton wavelength
* stable_decay_constant| [none] | Decay for a stable particle
*
* In the CLHEP unit system, the value of the constant \c e_electron is defined
* to be 1 and \c coulomb is derivative from that. To avoid floating point
* arithmetic issues that would lead to the "units" and "constants" having
* different values for it, a special case redefines the value for CLHEP.
*
* Some experimental physical constants are derived from the other physical
* constants, but for consistency and clarity they are presented numerically
* with the units provided in the CODATA 2018 dataset. The \c Constants.test.cc
Expand All @@ -56,7 +61,9 @@ namespace constants
//! \name Physical constants with *exact* value as defined by SI
CELER_ICRT c_light = 299792458. * units::meter / units::second;
CELER_ICRT h_planck = 6.62607015e-34 * units::joule * units::second;
CELER_ICRT e_electron = 1.602176634e-19 * units::coulomb;
CELER_ICRT e_electron = (CELERITAS_UNITS == CELERITAS_UNITS_CLHEP
? 1
: 1.602176634e-19 * units::coulomb);
CELER_ICRT k_boltzmann = 1.380649e-23 * units::joule / units::kelvin;
CELER_ICRT na_avogadro = 6.02214076e23;
CELER_ICRT kcd_luminous = 683;
Expand Down
119 changes: 14 additions & 105 deletions src/celeritas/Quantities.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,132 +4,41 @@
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file celeritas/Quantities.hh
//! \brief Unit struct definitions for use with the Quantity class
//! \brief Derivative unit classes and annotated Quantity values
//---------------------------------------------------------------------------//
#pragma once

#include "corecel/Macros.hh"
#include "corecel/math/Quantity.hh" // IWYU pragma: export

#include "Constants.hh"
#include "Units.hh"
#include "UnitTypes.hh" // IWYU pragma: export

namespace celeritas
{
namespace units
{
//---------------------------------------------------------------------------//
//! Special case for annotating that values are in the native unit system
struct NativeUnit
{
//! The conversion factor of the resulting unit is always unity
static CELER_CONSTEXPR_FUNCTION int value() { return 1; }
};

//! Unit for quantity such that the numeric value of 1 MeV is unity
struct Mev
{
//! Conversion factor from the unit to CGS
static CELER_CONSTEXPR_FUNCTION real_type value()
{
return real_type(1e6) * constants::e_electron * units::volt;
}
//! Text label for output
static char const* label() { return "MeV"; }
};

//! Unit for annotating the logarithm of (E/MeV)
struct LogMev
{
//! Conversion factor is not multiplicative
static CELER_CONSTEXPR_FUNCTION real_type value() { return 1; }
};

//! Unit for relativistic speeds
struct CLight
{
//! Conversion factor from the unit to CGS
static CELER_CONSTEXPR_FUNCTION real_type value()
{
return constants::c_light;
}
};

//! Unit for precise representation of particle charges
struct EElectron
{
//! Conversion factor from the unit to CGS
static CELER_CONSTEXPR_FUNCTION real_type value()
{
return constants::e_electron; // *Positive* sign
}
//! Text label for output
static char const* label() { return "e"; }
};

//! Unit for atomic masses
struct Amu
{
//! Conversion factor from the unit to CGS
static CELER_CONSTEXPR_FUNCTION real_type value()
{
return constants::atomic_mass;
}
//! Text label for output
static char const* label() { return "amu"; }
};

//! Unit for cross sections
struct Barn
{
//! Conversion factor from the unit to CGS
static CELER_CONSTEXPR_FUNCTION real_type value() { return units::barn; }
};

//! Unit for cross sections
struct Millibarn
{
//! Conversion factor from the unit to CGS
static CELER_CONSTEXPR_FUNCTION real_type value()
{
return real_type(1e-3) * units::barn;
}
};

//! Unit for field
struct Tesla
{
//! Conversion factor from the unit to CGS
static CELER_CONSTEXPR_FUNCTION real_type value() { return units::tesla; }
};

//---------------------------------------------------------------------------//
//!@{
//! \name Derivative units

struct CLightSq : UnitProduct<CLight, CLight>
{
static char const* label() { return "c^2"; }
};
struct MevPerCsq : UnitDivide<Mev, CLightSq>
{
static char const* label() { return "MeV/c^2"; }
};
//!@}

//---------------------------------------------------------------------------//
//!@{
//! \name Units for particle quantities
using ElementaryCharge = Quantity<EElectron>;
using MevEnergy = Quantity<Mev>;
using LogMevEnergy = Quantity<LogMev>;
using MevMass = Quantity<MevPerCsq>;
using MevMomentum = Quantity<UnitDivide<Mev, CLight>>;
using MevMomentumSq = Quantity<UnitDivide<UnitProduct<Mev, Mev>, CLightSq>>;
using MevMomentum = Quantity<MevPerC>;
using MevMomentumSq = Quantity<UnitProduct<MevPerC, MevPerC>>;
using LightSpeed = Quantity<CLight>;
using AmuMass = Quantity<Amu>;
using FieldTesla = Quantity<Tesla>;
//!@}

//---------------------------------------------------------------------------//
//!@{
//! \name Units for manual input and/or test harnesses
using CmLength = Quantity<Centimeter>;
using InvCmXs = Quantity<UnitInverse<Centimeter>>;
using InvCcDensity = Quantity<InvCentimeterCubed>;
using MolCcDensity = Quantity<MolPerCentimeterCubed>;
using FieldTesla = Quantity<Tesla>;
//!@}
//---------------------------------------------------------------------------//
} // namespace units
} // namespace celeritas

0 comments on commit f5fa7b8

Please sign in to comment.