diff --git a/au/code/au/CMakeLists.txt b/au/code/au/CMakeLists.txt index a182fd30..ca41ca31 100644 --- a/au/code/au/CMakeLists.txt +++ b/au/code/au/CMakeLists.txt @@ -43,6 +43,13 @@ header_only_library( unit_symbol.hh wrapper_operations.hh zero.hh + constants/avogadro_constant.hh + constants/boltzmann_constant.hh + constants/cesium_hyperfine_transition_frequency.hh + constants/elementary_charge.hh + constants/luminous_efficacy_540_terahertz.hh + constants/planck_constant.hh + constants/reduced_planck_constant.hh constants/speed_of_light.hh stdx/experimental/is_detected.hh stdx/functional.hh @@ -224,6 +231,13 @@ gtest_based_test( gtest_based_test( NAME constants_test SRCS + constants/test/avogadro_constant_test.cc + constants/test/boltzmann_constant_test.cc + constants/test/cesium_hyperfine_transition_frequency_test.cc + constants/test/elementary_charge_test.cc + constants/test/luminous_efficacy_540_terahertz_test.cc + constants/test/planck_constant_test.cc + constants/test/reduced_planck_constant_test.cc constants/test/speed_of_light_test.cc DEPS au diff --git a/au/code/au/constants/avogadro_constant.hh b/au/code/au/constants/avogadro_constant.hh new file mode 100644 index 00000000..c593fe19 --- /dev/null +++ b/au/code/au/constants/avogadro_constant.hh @@ -0,0 +1,37 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constant.hh" +#include "au/units/moles.hh" + +namespace au { + +namespace detail { +// DO NOT follow this pattern to define your own units. This is for library-defined units. +// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/). +template +struct AvogadroConstantLabel { + static constexpr const char label[] = "N_A"; +}; +template +constexpr const char AvogadroConstantLabel::label[]; +struct AvogadroConstantUnit : decltype(inverse(Moles{}) * mag<602'214'076>() * pow<15>(mag<10>())), + AvogadroConstantLabel { + using AvogadroConstantLabel::label; +}; +} // namespace detail + +constexpr auto AVOGADRO_CONSTANT = make_constant(detail::AvogadroConstantUnit{}); + +} // namespace au diff --git a/au/code/au/constants/boltzmann_constant.hh b/au/code/au/constants/boltzmann_constant.hh new file mode 100644 index 00000000..8909a354 --- /dev/null +++ b/au/code/au/constants/boltzmann_constant.hh @@ -0,0 +1,39 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constant.hh" +#include "au/units/joules.hh" +#include "au/units/kelvins.hh" + +namespace au { + +namespace detail { +// DO NOT follow this pattern to define your own units. This is for library-defined units. +// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/). +template +struct BoltzmannConstantLabel { + static constexpr const char label[] = "k_B"; +}; +template +constexpr const char BoltzmannConstantLabel::label[]; +struct BoltzmannConstantUnit + : decltype((Joules{} / Kelvins{}) * mag<1'380'649>() * pow<-29>(mag<10>())), + BoltzmannConstantLabel { + using BoltzmannConstantLabel::label; +}; +} // namespace detail + +constexpr auto BOLTZMANN_CONSTANT = make_constant(detail::BoltzmannConstantUnit{}); + +} // namespace au diff --git a/au/code/au/constants/cesium_hyperfine_transition_frequency.hh b/au/code/au/constants/cesium_hyperfine_transition_frequency.hh new file mode 100644 index 00000000..a09511e4 --- /dev/null +++ b/au/code/au/constants/cesium_hyperfine_transition_frequency.hh @@ -0,0 +1,38 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constant.hh" +#include "au/units/hertz.hh" + +namespace au { + +namespace detail { +// DO NOT follow this pattern to define your own units. This is for library-defined units. +// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/). +template +struct CesiumHyperfineTransitionFrequencyLabel { + static constexpr const char label[] = "Delta_nu_Cs"; +}; +template +constexpr const char CesiumHyperfineTransitionFrequencyLabel::label[]; +struct CesiumHyperfineTransitionFrequencyUnit : decltype(Hertz{} * mag<9'192'631'770>()), + CesiumHyperfineTransitionFrequencyLabel { + using CesiumHyperfineTransitionFrequencyLabel::label; +}; +} // namespace detail + +constexpr auto CESIUM_HYPERFINE_TRANSITION_FREQUENCY = + make_constant(detail::CesiumHyperfineTransitionFrequencyUnit{}); + +} // namespace au diff --git a/au/code/au/constants/elementary_charge.hh b/au/code/au/constants/elementary_charge.hh new file mode 100644 index 00000000..1b75a075 --- /dev/null +++ b/au/code/au/constants/elementary_charge.hh @@ -0,0 +1,37 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constant.hh" +#include "au/units/coulombs.hh" + +namespace au { + +namespace detail { +// DO NOT follow this pattern to define your own units. This is for library-defined units. +// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/). +template +struct ElementaryChargeLabel { + static constexpr const char label[] = "e"; +}; +template +constexpr const char ElementaryChargeLabel::label[]; +struct ElementaryChargeUnit : decltype(Coulombs{} * mag<1'602'176'634>() * pow<-28>(mag<10>())), + ElementaryChargeLabel { + using ElementaryChargeLabel::label; +}; +} // namespace detail + +constexpr auto ELEMENTARY_CHARGE = make_constant(detail::ElementaryChargeUnit{}); + +} // namespace au diff --git a/au/code/au/constants/luminous_efficacy_540_terahertz.hh b/au/code/au/constants/luminous_efficacy_540_terahertz.hh new file mode 100644 index 00000000..adcc4826 --- /dev/null +++ b/au/code/au/constants/luminous_efficacy_540_terahertz.hh @@ -0,0 +1,39 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constant.hh" +#include "au/units/lumens.hh" +#include "au/units/watts.hh" + +namespace au { + +namespace detail { +// DO NOT follow this pattern to define your own units. This is for library-defined units. +// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/). +template +struct LuminousEfficacy540TerahertzLabel { + static constexpr const char label[] = "K_cd"; +}; +template +constexpr const char LuminousEfficacy540TerahertzLabel::label[]; +struct LuminousEfficacy540TerahertzUnit : decltype((Lumens{} / Watts{}) * mag<683>()), + LuminousEfficacy540TerahertzLabel { + using LuminousEfficacy540TerahertzLabel::label; +}; +} // namespace detail + +constexpr auto LUMINOUS_EFFICACY_540_TERAHERTZ = + make_constant(detail::LuminousEfficacy540TerahertzUnit{}); + +} // namespace au diff --git a/au/code/au/constants/planck_constant.hh b/au/code/au/constants/planck_constant.hh new file mode 100644 index 00000000..8bf31d47 --- /dev/null +++ b/au/code/au/constants/planck_constant.hh @@ -0,0 +1,39 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constant.hh" +#include "au/units/joules.hh" +#include "au/units/seconds.hh" + +namespace au { + +namespace detail { +// DO NOT follow this pattern to define your own units. This is for library-defined units. +// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/). +template +struct PlanckConstantLabel { + static constexpr const char label[] = "h"; +}; +template +constexpr const char PlanckConstantLabel::label[]; +struct PlanckConstantUnit + : decltype(Joules{} * Seconds{} * mag<662'607'015>() * pow<-42>(mag<10>())), + PlanckConstantLabel { + using PlanckConstantLabel::label; +}; +} // namespace detail + +constexpr auto PLANCK_CONSTANT = make_constant(detail::PlanckConstantUnit{}); + +} // namespace au diff --git a/au/code/au/constants/reduced_planck_constant.hh b/au/code/au/constants/reduced_planck_constant.hh new file mode 100644 index 00000000..5ada7977 --- /dev/null +++ b/au/code/au/constants/reduced_planck_constant.hh @@ -0,0 +1,39 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constant.hh" +#include "au/units/joules.hh" +#include "au/units/seconds.hh" + +namespace au { + +namespace detail { +// DO NOT follow this pattern to define your own units. This is for library-defined units. +// Instead, follow instructions at (https://aurora-opensource.github.io/au/main/howto/new-units/). +template +struct ReducedPlanckConstantLabel { + static constexpr const char label[] = "h_bar"; +}; +template +constexpr const char ReducedPlanckConstantLabel::label[]; +struct ReducedPlanckConstantUnit : decltype(Joules{} * Seconds{} * mag<662'607'015>() * + pow<-42>(mag<10>()) / mag<2>() / Magnitude{}), + ReducedPlanckConstantLabel { + using ReducedPlanckConstantLabel::label; +}; +} // namespace detail + +constexpr auto REDUCED_PLANCK_CONSTANT = make_constant(detail::ReducedPlanckConstantUnit{}); + +} // namespace au diff --git a/au/code/au/constants/test/avogadro_constant_test.cc b/au/code/au/constants/test/avogadro_constant_test.cc new file mode 100644 index 00000000..4f299b80 --- /dev/null +++ b/au/code/au/constants/test/avogadro_constant_test.cc @@ -0,0 +1,45 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constants/avogadro_constant.hh" + +#include "au/testing.hh" +#include "au/units/moles.hh" +#include "gtest/gtest.h" + +namespace au { +namespace { + +using ::testing::StrEq; + +TEST(AvogadroConstant, HasExpectedValue) { + // N_A = 6.02214076e23 mol^(-1) + + // Test approximate value (guard against powers-of-10 type errors). + constexpr auto defining_units = inverse(moles) * pow<23>(mag<10>()); + constexpr auto val = defining_units(6.02214076); + constexpr auto err = defining_units(0.00000001); + EXPECT_THAT(AVOGADRO_CONSTANT.as(inverse(moles)), IsNear(val, err)); + + // Test exact value. + EXPECT_THAT(AVOGADRO_CONSTANT.in(defining_units / pow<8>(mag<10>())), + SameTypeAndValue(602'214'076)); +} + +TEST(AvogadroConstant, HasExpectedLabel) { + EXPECT_THAT(unit_label(AVOGADRO_CONSTANT), StrEq("N_A")); +} + +} // namespace +} // namespace au diff --git a/au/code/au/constants/test/boltzmann_constant_test.cc b/au/code/au/constants/test/boltzmann_constant_test.cc new file mode 100644 index 00000000..2b411ec9 --- /dev/null +++ b/au/code/au/constants/test/boltzmann_constant_test.cc @@ -0,0 +1,48 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constants/boltzmann_constant.hh" + +#include "au/testing.hh" +#include "au/units/joules.hh" +#include "au/units/kelvins.hh" +#include "gtest/gtest.h" + +namespace au { +namespace { + +using symbols::J; +using symbols::K; +using ::testing::StrEq; + +TEST(BoltzmannConstant, HasExpectedValue) { + // k_B = 1.380649e-23 J/K + + // Test approximate value (guard against powers-of-10 type errors). + constexpr auto defining_units = (joules / kelvin) * pow<-23>(mag<10>()); + constexpr auto val = defining_units(1.380649); + constexpr auto err = defining_units(0.000001); + EXPECT_THAT(BOLTZMANN_CONSTANT.as(J / K), IsNear(val, err)); + + // Test exact value. + EXPECT_THAT(BOLTZMANN_CONSTANT.in(defining_units / pow<6>(mag<10>())), + SameTypeAndValue(1'380'649)); +} + +TEST(BoltzmannConstant, HasExpectedLabel) { + EXPECT_THAT(unit_label(BOLTZMANN_CONSTANT), StrEq("k_B")); +} + +} // namespace +} // namespace au diff --git a/au/code/au/constants/test/cesium_hyperfine_transition_frequency_test.cc b/au/code/au/constants/test/cesium_hyperfine_transition_frequency_test.cc new file mode 100644 index 00000000..ac94ce72 --- /dev/null +++ b/au/code/au/constants/test/cesium_hyperfine_transition_frequency_test.cc @@ -0,0 +1,39 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constants/cesium_hyperfine_transition_frequency.hh" + +#include "au/testing.hh" +#include "au/units/hertz.hh" +#include "gtest/gtest.h" + +namespace au { +namespace { + +using ::testing::StrEq; + +TEST(CesiumHyperfineTransitionFrequency, HasExpectedValue) { + // Delta_nu_Cs = 9'192'631'770 Hz + + // Test exact value. + EXPECT_THAT(CESIUM_HYPERFINE_TRANSITION_FREQUENCY.in(hertz), + SameTypeAndValue(uint64_t{9'192'631'770})); +} + +TEST(CesiumHyperfineTransitionFrequency, HasExpectedLabel) { + EXPECT_THAT(unit_label(CESIUM_HYPERFINE_TRANSITION_FREQUENCY), StrEq("Delta_nu_Cs")); +} + +} // namespace +} // namespace au diff --git a/au/code/au/constants/test/elementary_charge_test.cc b/au/code/au/constants/test/elementary_charge_test.cc new file mode 100644 index 00000000..e146d374 --- /dev/null +++ b/au/code/au/constants/test/elementary_charge_test.cc @@ -0,0 +1,44 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constants/elementary_charge.hh" + +#include "au/testing.hh" +#include "au/units/coulombs.hh" +#include "gtest/gtest.h" + +namespace au { +namespace { + +using symbols::C; +using ::testing::StrEq; + +TEST(ElementaryCharge, HasExpectedValue) { + // e = 1.602176634e-19 C + + // Test approximate value (guard against powers-of-10 type errors). + constexpr auto defining_units = coulombs * pow<-19>(mag<10>()); + constexpr auto val = defining_units(1.602176634); + constexpr auto err = defining_units(0.000000001); + EXPECT_THAT(ELEMENTARY_CHARGE.as(C), IsNear(val, err)); + + // Test exact value. + EXPECT_THAT(ELEMENTARY_CHARGE.in(defining_units / pow<9>(mag<10>())), + SameTypeAndValue(1'602'176'634)); +} + +TEST(PlanckConstant, HasExpectedLabel) { EXPECT_THAT(unit_label(ELEMENTARY_CHARGE), StrEq("e")); } + +} // namespace +} // namespace au diff --git a/au/code/au/constants/test/luminous_efficacy_540_terahertz_test.cc b/au/code/au/constants/test/luminous_efficacy_540_terahertz_test.cc new file mode 100644 index 00000000..bba9f2f3 --- /dev/null +++ b/au/code/au/constants/test/luminous_efficacy_540_terahertz_test.cc @@ -0,0 +1,41 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constants/luminous_efficacy_540_terahertz.hh" + +#include "au/testing.hh" +#include "au/units/lumens.hh" +#include "au/units/watts.hh" +#include "gtest/gtest.h" + +namespace au { +namespace { + +using symbols::lm; +using symbols::W; +using ::testing::StrEq; + +TEST(LuminousEfficacy540Terahertz, HasExpectedValue) { + // K_cd = 683 lm/W + + // Test exact value. + EXPECT_THAT(LUMINOUS_EFFICACY_540_TERAHERTZ.in(lm / W), SameTypeAndValue(683)); +} + +TEST(LuminousEfficacy540Terahertz, HasExpectedLabel) { + EXPECT_THAT(unit_label(LUMINOUS_EFFICACY_540_TERAHERTZ), StrEq("K_cd")); +} + +} // namespace +} // namespace au diff --git a/au/code/au/constants/test/planck_constant_test.cc b/au/code/au/constants/test/planck_constant_test.cc new file mode 100644 index 00000000..fdbe601c --- /dev/null +++ b/au/code/au/constants/test/planck_constant_test.cc @@ -0,0 +1,46 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constants/planck_constant.hh" + +#include "au/testing.hh" +#include "au/units/joules.hh" +#include "au/units/seconds.hh" +#include "gtest/gtest.h" + +namespace au { +namespace { + +using symbols::J; +using symbols::s; +using ::testing::StrEq; + +TEST(PlanckConstant, HasExpectedValue) { + // h = 6.62607015e-34 J s = 662607015e-41 J s + + // Test approximate value (guard against powers-of-10 type errors). + constexpr auto defining_units = joule * seconds * pow<-34>(mag<10>()); + constexpr auto val = defining_units(6.62607015); + constexpr auto err = defining_units(0.00000001); + EXPECT_THAT(PLANCK_CONSTANT.as(J * s), IsNear(val, err)); + + // Test exact value. + EXPECT_THAT(PLANCK_CONSTANT.in(defining_units / pow<8>(mag<10>())), + SameTypeAndValue(662'607'015)); +} + +TEST(PlanckConstant, HasExpectedLabel) { EXPECT_THAT(unit_label(PLANCK_CONSTANT), StrEq("h")); } + +} // namespace +} // namespace au diff --git a/au/code/au/constants/test/reduced_planck_constant_test.cc b/au/code/au/constants/test/reduced_planck_constant_test.cc new file mode 100644 index 00000000..183262d3 --- /dev/null +++ b/au/code/au/constants/test/reduced_planck_constant_test.cc @@ -0,0 +1,55 @@ +// Copyright 2024 Aurora Operations, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "au/constants/reduced_planck_constant.hh" + +#include "au/constants/planck_constant.hh" +#include "au/testing.hh" +#include "au/units/joules.hh" +#include "au/units/seconds.hh" +#include "gtest/gtest.h" + +namespace au { +namespace { + +using symbols::J; +using symbols::s; +using ::testing::StrEq; + +TEST(ReducedPlanckConstant, HasExpectedValue) { + // h_bar = (6.62607015e-34 / (2 pi)) J s ~= 1.054571817e-34 J s + + // Test approximate value (guard against powers-of-10 type errors). + constexpr auto defining_units = joule * seconds * pow<-34>(mag<10>()); + constexpr auto val = defining_units(1.054571817); + constexpr auto err = defining_units(0.000000001); + EXPECT_THAT(REDUCED_PLANCK_CONSTANT.as(J * s), IsNear(val, err)); +} + +TEST(ReducedPlanckConstant, ExactlyPlanckConstantDividedByTwoPi) { + constexpr auto ratio = (REDUCED_PLANCK_CONSTANT * mag<2>() * Magnitude{}) / PLANCK_CONSTANT; + + // We know that `.as()` could not succeed unless the result were exactly expressible with + // `int` as a rep, and we know that the comparison to `1` would not compile unless all + // dimensions had cancelled out. + constexpr int result = ratio.as(); + EXPECT_EQ(result, 1); +} + +TEST(ReducedPlanckConstant, HasExpectedLabel) { + EXPECT_THAT(unit_label(REDUCED_PLANCK_CONSTANT), StrEq("h_bar")); +} + +} // namespace +} // namespace au