From 322cde70b948e184c987dd3fa3eb2aef61b119f5 Mon Sep 17 00:00:00 2001 From: "Ralph J. Steinhagen" Date: Mon, 2 Aug 2021 22:15:54 +0200 Subject: [PATCH] added HEP specific units and definitions in accordance with https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf#page=147 see also disccusion thread #292 --- src/systems/si/include/units/isq/si/area.h | 33 ++++++++++ src/systems/si/include/units/isq/si/energy.h | 48 ++++++++++++++ src/systems/si/include/units/isq/si/mass.h | 63 +++++++++++++++++++ .../si/include/units/isq/si/momentum.h | 48 ++++++++++++++ test/unit_test/static/quantity_test.cpp | 25 +++++++- 5 files changed, 215 insertions(+), 2 deletions(-) diff --git a/src/systems/si/include/units/isq/si/area.h b/src/systems/si/include/units/isq/si/area.h index 13d21a1a..fe401eae 100644 --- a/src/systems/si/include/units/isq/si/area.h +++ b/src/systems/si/include/units/isq/si/area.h @@ -59,10 +59,22 @@ struct square_zettametre : derived_unit struct square_yottametre : derived_unit {}; struct hectare : alias_unit {}; +struct barn : named_scaled_unit {}; template U, Representation Rep = double> using area = quantity; +namespace hep { +struct yocto_barn : prefixed_unit {}; +struct zepto_barn : prefixed_unit {}; +struct atto_barn : prefixed_unit {}; +struct femto_barn : prefixed_unit {}; +struct pico_barn : prefixed_unit {}; +struct nano_barn : prefixed_unit {}; +struct micro_barn : prefixed_unit {}; +struct milli_barn : prefixed_unit {}; +} + #ifndef UNITS_NO_LITERALS inline namespace literals { @@ -157,6 +169,27 @@ constexpr auto operator"" _q_ha(long double l) { return area(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_yb(long double l) { return area(l); } +constexpr auto operator"" _q_zb(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_zb(long double l) { return area(l); } +constexpr auto operator"" _q_ab(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_ab(long double l) { return area(l); } +constexpr auto operator"" _q_fb(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_fb(long double l) { return area(l); } +constexpr auto operator"" _q_pb(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_pb(long double l) { return area(l); } +constexpr auto operator"" _q_nb(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_nb(long double l) { return area(l); } +constexpr auto operator"" _q_ub(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_ub(long double l) { return area(l); } +constexpr auto operator"" _q_mb(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_mb(long double l) { return area(l); } +constexpr auto operator"" _q_b(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return area(static_cast(l)); } +constexpr auto operator"" _q_b(long double l) { return area(l); } +} // namespace hep::literals + #endif // UNITS_NO_LITERALS #ifndef UNITS_NO_REFERENCES diff --git a/src/systems/si/include/units/isq/si/energy.h b/src/systems/si/include/units/isq/si/energy.h index ddcbb270..1a17cfeb 100644 --- a/src/systems/si/include/units/isq/si/energy.h +++ b/src/systems/si/include/units/isq/si/energy.h @@ -53,6 +53,7 @@ struct exajoule : prefixed_unit {}; struct zettajoule : prefixed_unit {}; struct yottajoule : prefixed_unit {}; +// N.B. electron charge (and eV) is an exact constant: https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf#page=147 struct electronvolt : named_scaled_unit {}; struct gigaelectronvolt : prefixed_unit {}; @@ -61,6 +62,21 @@ struct dim_energy : isq::dim_energy {} template U, Representation Rep = double> using energy = quantity; +namespace hep { +struct feV : prefixed_unit {}; +struct peV : prefixed_unit {}; +struct neV : prefixed_unit {}; +struct ueV : prefixed_unit {}; +struct meV : prefixed_unit {}; +struct keV : prefixed_unit {}; +struct MeV : prefixed_unit {}; +using GeV = gigaelectronvolt; +struct TeV : prefixed_unit {}; +struct PeV : prefixed_unit {}; +struct EeV : prefixed_unit {}; +struct YeV : prefixed_unit {}; +} + #ifndef UNITS_NO_LITERALS inline namespace literals { @@ -143,6 +159,38 @@ constexpr auto operator"" _q_GeV(long double l) { return energy(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_feV(long double l) { return energy(l); } +constexpr auto operator"" _q_peV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_peV(long double l) { return energy(l); } +constexpr auto operator"" _q_neV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_neV(long double l) { return energy(l); } +constexpr auto operator"" _q_ueV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_ueV(long double l) { return energy(l); } +constexpr auto operator"" _q_meV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_meV(long double l) { return energy(l); } + +constexpr auto operator"" _q_eV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_eV(long double l) { return energy(l); } + +constexpr auto operator"" _q_keV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_keV(long double l) { return energy(l); } +constexpr auto operator"" _q_MeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_MeV(long double l) { return energy(l); } +constexpr auto operator"" _q_GeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_GeV(long double l) { return energy(l); } +constexpr auto operator"" _q_TeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_TeV(long double l) { return energy(l); } +constexpr auto operator"" _q_PeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_PeV(long double l) { return energy(l); } +constexpr auto operator"" _q_EeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_EeV(long double l) { return energy(l); } +constexpr auto operator"" _q_YeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return energy(static_cast(l)); } +constexpr auto operator"" _q_YeV(long double l) { return energy(l); } +} // hep::literals + #endif // UNITS_NO_LITERALS #ifndef UNITS_NO_REFERENCES diff --git a/src/systems/si/include/units/isq/si/mass.h b/src/systems/si/include/units/isq/si/mass.h index a13c4047..8966fffb 100644 --- a/src/systems/si/include/units/isq/si/mass.h +++ b/src/systems/si/include/units/isq/si/mass.h @@ -85,6 +85,25 @@ struct dim_mass : isq::dim_mass {}; template U, Representation Rep = double> using mass = quantity; +namespace hep { +struct eV_per_c2 : named_scaled_unit {}; +struct feV_per_c2 : prefixed_unit {}; +struct peV_per_c2 : prefixed_unit {}; +struct neV_per_c2 : prefixed_unit {}; +struct ueV_per_c2 : prefixed_unit {}; +struct meV_per_c2 : prefixed_unit {}; // approximate mass of an electron/positron (0.511 MeV/c2) +struct keV_per_c2 : prefixed_unit {}; +struct MeV_per_c2 : prefixed_unit {}; +struct GeV_per_c2 : prefixed_unit {}; // approximate mass of a proton (0.938 GeV/c2) or neutron +struct TeV_per_c2 : prefixed_unit {}; +struct PeV_per_c2 : prefixed_unit {}; +struct EeV_per_c2 : prefixed_unit {}; +struct YeV_per_c2 : prefixed_unit {}; +struct electron_mass : named_scaled_unit {}; +struct proton_mass : named_scaled_unit {}; +struct neutron_mass : named_scaled_unit {}; +} // namespace hep + #ifndef UNITS_NO_LITERALS inline namespace literals { @@ -262,8 +281,52 @@ constexpr auto operator"" _q_Yt(long double l) { return mass(l)); return mass(static_cast(l)); } constexpr auto operator"" _q_Da(long double l) { return mass(l); } +namespace units::isq::inline si::inline hep::literals { + +} + } // namespace literals +namespace hep::literals { +constexpr auto operator"" _q_feV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_feV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_peV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_peV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_neV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_neV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_ueV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_ueV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_meV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_meV_per_c2(long double l) { return mass(l); } + +// eV_per_c2 +constexpr auto operator"" _q_eV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_eV_per_c2(long double l) { return mass(l); } + +constexpr auto operator"" _q_keV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_keV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_MeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_MeV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_GeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_GeV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_TeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_TeV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_PeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_PeV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_EeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_EeV_per_c2(long double l) { return mass(l); } +constexpr auto operator"" _q_YeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_YeV_per_c2(long double l) { return mass(l); } + +// special HEP masses +constexpr auto operator"" _q_electron_mass(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_electron_mass(long double l) { return mass(l); } +constexpr auto operator"" _q_proton_mass(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_proton_mass(long double l) { return mass(l); } +constexpr auto operator"" _q_neutron_mass(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return mass(static_cast(l)); } +constexpr auto operator"" _q_neutron_mass(long double l) { return mass(l); } +} // namespace hep::literals + #endif // UNITS_NO_LITERALS #ifndef UNITS_NO_REFERENCES diff --git a/src/systems/si/include/units/isq/si/momentum.h b/src/systems/si/include/units/isq/si/momentum.h index 28151b6f..9c74f513 100644 --- a/src/systems/si/include/units/isq/si/momentum.h +++ b/src/systems/si/include/units/isq/si/momentum.h @@ -40,6 +40,22 @@ struct dim_momentum : isq::dim_momentum U, Representation Rep = double> using momentum = quantity; +namespace hep { +struct eV_per_c : named_scaled_unit {}; +struct feV_per_c : prefixed_unit {}; +struct peV_per_c : prefixed_unit {}; +struct neV_per_c : prefixed_unit {}; +struct ueV_per_c : prefixed_unit {}; +struct meV_per_c : prefixed_unit {}; +struct keV_per_c : prefixed_unit {}; +struct MeV_per_c : prefixed_unit {}; +struct GeV_per_c : prefixed_unit {}; +struct TeV_per_c : prefixed_unit {}; +struct PeV_per_c : prefixed_unit {}; +struct EeV_per_c : prefixed_unit {}; +struct YeV_per_c : prefixed_unit {}; +} + #ifndef UNITS_NO_LITERALS inline namespace literals { @@ -50,6 +66,38 @@ constexpr auto operator"" _q_kg_m_per_s(long double l) { return momentum(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_feV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_peV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_peV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_neV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_neV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_ueV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_ueV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_meV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_meV_per_c(long double l) { return momentum(l); } + +// eV_per_c + constexpr auto operator"" _q_eV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_eV_per_c(long double l) { return momentum(l); } + + constexpr auto operator"" _q_keV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_keV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_MeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_MeV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_GeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_GeV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_TeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_TeV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_PeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_PeV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_EeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_EeV_per_c(long double l) { return momentum(l); } + constexpr auto operator"" _q_YeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range(l)); return momentum(static_cast(l)); } + constexpr auto operator"" _q_YeV_per_c(long double l) { return momentum(l); } +} // namespace hep::literals + #endif // UNITS_NO_LITERALS } // namespace units::isq::si diff --git a/test/unit_test/static/quantity_test.cpp b/test/unit_test/static/quantity_test.cpp index c0b458f6..81d94a86 100644 --- a/test/unit_test/static/quantity_test.cpp +++ b/test/unit_test/static/quantity_test.cpp @@ -238,14 +238,35 @@ static_assert(length(1500_q_m).number() == 1.5); // derived quantities /////////////////////////////////////// -template +template struct derived_quantity : quantity { using dimension = typename Q::dimension; using unit = typename Q::unit; using rep = Rep; + using R = quantity; + + constexpr derived_quantity() : R(){}; + constexpr explicit(!std::is_trivial_v) derived_quantity(const R& t) : R(t) {} + constexpr explicit(!std::is_trivial_v) derived_quantity(R&& t) : R(std::move(t)) {} + + constexpr derived_quantity& operator=(const R& t) { R::operator=(t); return *this; } + constexpr derived_quantity& operator=(R&& t) { R::operator=(std::move(t)); return *this; } + + constexpr operator R&() & noexcept { return *this; } + constexpr operator const R&() const & noexcept { return *this; } + constexpr operator R&&() && noexcept { return *this; } + constexpr operator const R&&() const && noexcept { return *this; } }; -static_assert(units::detail::is_quantity, "NTTP type description">>); +static_assert(detail::is_quantity, "NTTP type description">>); +constexpr isq::Length auto get_length_derived_quantity() noexcept { + derived_quantity, "NTTP type description"> a; + a += 1_q_m; + a = a + 1_q_m; + a *= 0.5; + return a; +} +static_assert(get_length_derived_quantity() == 1_q_m); ///////// // CTAD