4#ifndef DLG4MODUSIM_DLG4UNITS_HH
5#define DLG4MODUSIM_DLG4UNITS_HH
7#include "G4ExceptionSeverity.hh"
9#include <CLHEP/Units/SystemOfUnits.h>
10#include <G4ThreeVector.hh>
133 class ThreeVecDimensioner;
136 template <
typename T>
141 template <>
inline G4double global_default_unit<Units::Length> = CLHEP::mm;
142 template <>
inline G4double global_default_unit<Units::Mass> = CLHEP::g;
143 template <>
inline G4double global_default_unit<Units::Volume> = CLHEP::mL;
171 operator G4double()
const {
return (*
this)(); }
176 if (is >> val) ap.
parent.NativeValue_ = val * ap.
scale;
192 [[nodiscard]] G4double
NativeValue()
const {
return GetScaled(1.0); }
193 explicit operator G4double()
const {
return GetScaled(1.0); }
206 if (
this != &other) {
214 explicit Unit(
double f, Derived u)
219 virtual G4double GetScaled(G4double scalar)
const {
224 G4Exception(
"Unit::GetScaled",
"InvalidScale", FatalException,
225 "\n Attempted to scale a Measure by a negative Unit\n");
229 G4Exception(
"Unit::GetScaled",
"InvalidScale", FatalException,
230 "\n Attempted to read a Unit (or measure) before setting it;\n");
235 virtual void ScaleSet(G4double value, G4double scale) {
255 return T(native_value);
298 template <
typename T>
390 inline const Mass
Mass::mg{CLHEP::mg};
391 inline const Mass
Mass::g{CLHEP::g};
392 inline const Mass
Mass::kg{CLHEP::kg};
410 template<
typename Scalar,
typename = std::enable_if_t<std::is_arithmetic_v<Scalar>>>
417 template<
typename T,
typename U>
418 using ResultType = std::conditional_t<std::is_base_of_v<UnitTag, T>, T, U>;
421 template<
typename T,
typename U,
422 typename = std::enable_if_t<std::is_base_of_v<UnitTag, T> != std::is_base_of_v<UnitTag, U>> >
429 template<
typename T,
typename U,
430 typename = std::enable_if_t<std::is_base_of_v<UnitTag, T> && !std::is_base_of_v<UnitTag, U>> >
433 return T(
UnitOrValue<T>(a).val /
static_cast<double>(b), T::native);
437 template <
typename T,
typename = std::enable_if_t<std::is_base_of_v<UnitTag, T>>>
440 return T::FromNative(a.Native() + b.Native());
444 template <
typename T,
typename = std::enable_if_t<std::is_base_of_v<UnitTag, T>>>
446 return T::FromNative(a.Native() - b.Native());
464 if (
this != &other) {
500 G4Exception(
"Unit3Vec::InUnits",
"Uninitialized", FatalException,
501 "Attempted to read Unit3Vec before setting it.");
509 G4Exception(
"Unit3Vec::GetRaw",
"Uninitialized", FatalException,
510 "Attempted to read Unit3Vec before setting it.");
520 G4ThreeVector& EnsureInternalVec() {
552 template <
typename T>
555 static_assert(std::is_base_of_v<DLG4::Units::UnitTag, T>,
556 "\n\n ERROR: SetGlobalDefaultUnit only accepts DLG4Unit types! \n"
557 " You tried to pass a type that does not inherit from UnitTag.\n");
558 DLG4::Units::global_default_unit<T> = unit.Native;
static const Density g_per_cm3
Density(double raw, Density u)
static const Density mg_per_cm3
static const Density g_per_L
static const Length fermi
Length(double raw, Length u)
static const Length angstrom
static const Length micron
A 3 vector that is scalable with/to Units.
Unit3Vec(const Length &x, const Length &y, const Length &z)
void y(const Length &val)
G4ThreeVector InUnits(const Length &u) const
Unit3Vec FromNative(const G4ThreeVector &v)
Unit3Vec(const G4ThreeVector &v, const Length &u)
void x(const Length &val)
Unit3Vec(const Unit3Vec &other)
Unit3Vec & operator=(const Unit3Vec &other)
std::optional< G4ThreeVector > NativeVec_
Unit3Vec(double x, double y, double z, const Length &u)
G4ThreeVector InUnits() const
void z(const Length &val)
G4ThreeVector Native() const
CRTP base methods for Unit classes.
static T FromNative(G4double)
std::optional< G4double > NativeValue_
PropertySetter InUnits(const Unit< T > &u)
G4double NativeValue() const
G4double InDefaultUnits() const
Unit(double f, Derived u)
static Derived GetGlobalDefault()
PropertySetter InDefaultUnits()
Unit & operator=(const Unit &other)
G4double InUnits(const Unit< T > &u) const
Volume(double raw, Volume u)
void SetGlobalDefaultUnit(T unit)
Set the default unit for all VolumeBuilder methods.
Typesafe units!! No accidental mixing values and units.
T operator+(const T &a, const T &b)
G4double global_default_unit
T operator-(const T &a, const T &b)
G4Transform3D UnitlessG4Transform3D
std::conditional_t< std::is_base_of_v< UnitTag, T >, T, U > ResultType
auto operator*(const T &a, const U &b)
Density operator/(Mass m, Volume v)
DLG4::Units::Density Density
DLG4::Units::Volume Volume
DLG4::Units::Length Length
Type-erases unit or value to just a value.
UnitOrValue(const Unit< T > &u)
Tag type for inheritance.
PropertySetter(const PropertySetter &)=delete
G4double operator()() const
friend std::istream & operator>>(std::istream &is, const PropertySetter &ap)
void operator=(G4double val)
PropertySetter & operator=(const PropertySetter &)=delete