Skip to content

Commit

Permalink
Add remaining exact SI constants (#336)
Browse files Browse the repository at this point in the history
All values were taken from [this section] of the wikipedia page on the
2019 revision of the SI.

Admittedly, two of them --- `Delta_nu_Cs` and `K_cd` --- have horribly
awkward names.  The best I could do for the constant names was
`CESIUM_HYPERFINE_TRANSITION_FREQUENCY` and
`LUMINOUS_EFFICACY_540_TERAHERTZ`, respectively.  That's fine; we expect
most users to do something like this in their programs:

```cpp
constexpr auto K_cd = au::LUMINOUS_EFFICACY_540_TERAHERTZ;
```

Helps #90.

[this section]:
https://en.wikipedia.org/wiki/2019_revision_of_the_SI#Defining_constants
  • Loading branch information
chiphogg authored Dec 2, 2024
1 parent 827edd8 commit b955046
Show file tree
Hide file tree
Showing 15 changed files with 600 additions and 0 deletions.
14 changes: 14 additions & 0 deletions au/code/au/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
37 changes: 37 additions & 0 deletions au/code/au/constants/avogadro_constant.hh
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct AvogadroConstantLabel {
static constexpr const char label[] = "N_A";
};
template <typename T>
constexpr const char AvogadroConstantLabel<T>::label[];
struct AvogadroConstantUnit : decltype(inverse(Moles{}) * mag<602'214'076>() * pow<15>(mag<10>())),
AvogadroConstantLabel<void> {
using AvogadroConstantLabel<void>::label;
};
} // namespace detail

constexpr auto AVOGADRO_CONSTANT = make_constant(detail::AvogadroConstantUnit{});

} // namespace au
39 changes: 39 additions & 0 deletions au/code/au/constants/boltzmann_constant.hh
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct BoltzmannConstantLabel {
static constexpr const char label[] = "k_B";
};
template <typename T>
constexpr const char BoltzmannConstantLabel<T>::label[];
struct BoltzmannConstantUnit
: decltype((Joules{} / Kelvins{}) * mag<1'380'649>() * pow<-29>(mag<10>())),
BoltzmannConstantLabel<void> {
using BoltzmannConstantLabel<void>::label;
};
} // namespace detail

constexpr auto BOLTZMANN_CONSTANT = make_constant(detail::BoltzmannConstantUnit{});

} // namespace au
38 changes: 38 additions & 0 deletions au/code/au/constants/cesium_hyperfine_transition_frequency.hh
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct CesiumHyperfineTransitionFrequencyLabel {
static constexpr const char label[] = "Delta_nu_Cs";
};
template <typename T>
constexpr const char CesiumHyperfineTransitionFrequencyLabel<T>::label[];
struct CesiumHyperfineTransitionFrequencyUnit : decltype(Hertz{} * mag<9'192'631'770>()),
CesiumHyperfineTransitionFrequencyLabel<void> {
using CesiumHyperfineTransitionFrequencyLabel<void>::label;
};
} // namespace detail

constexpr auto CESIUM_HYPERFINE_TRANSITION_FREQUENCY =
make_constant(detail::CesiumHyperfineTransitionFrequencyUnit{});

} // namespace au
37 changes: 37 additions & 0 deletions au/code/au/constants/elementary_charge.hh
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct ElementaryChargeLabel {
static constexpr const char label[] = "e";
};
template <typename T>
constexpr const char ElementaryChargeLabel<T>::label[];
struct ElementaryChargeUnit : decltype(Coulombs{} * mag<1'602'176'634>() * pow<-28>(mag<10>())),
ElementaryChargeLabel<void> {
using ElementaryChargeLabel<void>::label;
};
} // namespace detail

constexpr auto ELEMENTARY_CHARGE = make_constant(detail::ElementaryChargeUnit{});

} // namespace au
39 changes: 39 additions & 0 deletions au/code/au/constants/luminous_efficacy_540_terahertz.hh
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct LuminousEfficacy540TerahertzLabel {
static constexpr const char label[] = "K_cd";
};
template <typename T>
constexpr const char LuminousEfficacy540TerahertzLabel<T>::label[];
struct LuminousEfficacy540TerahertzUnit : decltype((Lumens{} / Watts{}) * mag<683>()),
LuminousEfficacy540TerahertzLabel<void> {
using LuminousEfficacy540TerahertzLabel<void>::label;
};
} // namespace detail

constexpr auto LUMINOUS_EFFICACY_540_TERAHERTZ =
make_constant(detail::LuminousEfficacy540TerahertzUnit{});

} // namespace au
39 changes: 39 additions & 0 deletions au/code/au/constants/planck_constant.hh
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct PlanckConstantLabel {
static constexpr const char label[] = "h";
};
template <typename T>
constexpr const char PlanckConstantLabel<T>::label[];
struct PlanckConstantUnit
: decltype(Joules{} * Seconds{} * mag<662'607'015>() * pow<-42>(mag<10>())),
PlanckConstantLabel<void> {
using PlanckConstantLabel<void>::label;
};
} // namespace detail

constexpr auto PLANCK_CONSTANT = make_constant(detail::PlanckConstantUnit{});

} // namespace au
39 changes: 39 additions & 0 deletions au/code/au/constants/reduced_planck_constant.hh
Original file line number Diff line number Diff line change
@@ -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 <typename T>
struct ReducedPlanckConstantLabel {
static constexpr const char label[] = "h_bar";
};
template <typename T>
constexpr const char ReducedPlanckConstantLabel<T>::label[];
struct ReducedPlanckConstantUnit : decltype(Joules{} * Seconds{} * mag<662'607'015>() *
pow<-42>(mag<10>()) / mag<2>() / Magnitude<Pi>{}),
ReducedPlanckConstantLabel<void> {
using ReducedPlanckConstantLabel<void>::label;
};
} // namespace detail

constexpr auto REDUCED_PLANCK_CONSTANT = make_constant(detail::ReducedPlanckConstantUnit{});

} // namespace au
45 changes: 45 additions & 0 deletions au/code/au/constants/test/avogadro_constant_test.cc
Original file line number Diff line number Diff line change
@@ -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<double>(inverse(moles)), IsNear(val, err));

// Test exact value.
EXPECT_THAT(AVOGADRO_CONSTANT.in<int>(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
48 changes: 48 additions & 0 deletions au/code/au/constants/test/boltzmann_constant_test.cc
Original file line number Diff line number Diff line change
@@ -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<double>(J / K), IsNear(val, err));

// Test exact value.
EXPECT_THAT(BOLTZMANN_CONSTANT.in<int>(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
Loading

0 comments on commit b955046

Please sign in to comment.