Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
UnitSystem.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
20#include "Names.hpp"
21#include <cmath>
22
24#define addget(uname) \
25 template< \
26 UnitPrefix pref = None, \
27 units::UnitName u, \
28 int power = 1, \
29 std::enable_if_t<u == units::uname, int> = 0> \
30 inline constexpr T get() const noexcept
31
33#define Uget(unitname, mult_pow) get<pref, units::unitname, (mult_pow) * power>()
35#define Cget(constant_name, mult_pow) \
36 details::pow_constexpr_fast_inv<(mult_pow) * power>(constant_name, T(1) / constant_name)
38#define PREF Cget((get_prefix_val<T, pref>()), 1)
39
40namespace shamunits {
41
76 template<class T>
77 class UnitSystem {
78
79 template<int power>
80 inline static constexpr T pow_constexpr(T a, T a_inv) noexcept {
81 return details::pow_constexpr_fast_inv<power>(a, a_inv);
82 }
83
84 inline T pown(T a, int n) { return std::pow(a, n); }
85
87
88 public:
134 T s, m, kg, A, K, mol, cd;
136
148 explicit UnitSystem(
149 T unit_time = 1,
150 T unit_length = 1,
151 T unit_mass = 1,
152 T unit_current = 1,
153 T unit_temperature = 1,
154 T unit_qte = 1,
155 T unit_lumint = 1)
156 : s(1 / unit_time), m(1 / unit_length), kg(1 / unit_mass), A(1 / unit_current),
157 K(1 / unit_temperature), mol(1 / unit_qte), cd(1 / unit_lumint), s_inv(unit_time),
158 m_inv(unit_length), kg_inv(unit_mass), A_inv(unit_current), K_inv(unit_temperature),
159 mol_inv(unit_qte), cd_inv(unit_lumint) {}
160
161#ifdef DOXYGEN
170 template<UnitPrefix pref = None, units::UnitName u, int power = 1>
171 inline constexpr T get() const noexcept;
172#else
173
174 // clang-format off
175 addget(second) { return PREF* pow_constexpr<power>(s , s_inv); }
176 addget(metre) { return PREF* pow_constexpr<power>(m , m_inv); }
177 addget(kilogram) { return PREF* pow_constexpr<power>(kg , kg_inv); }
178 addget(Ampere) { return PREF* pow_constexpr<power>(A , A_inv); }
179 addget(Kelvin) { return PREF* pow_constexpr<power>(K , K_inv); }
180 addget(mole) { return PREF* pow_constexpr<power>(mol, mol_inv); }
181 addget(candela) { return PREF* pow_constexpr<power>(cd , cd_inv); }
182
183 addget(Hertz) { return PREF* Uget(s, -1); }
184 //addget(mps) { return PREF* Uget(m, 1) * Uget(s, -1); }
185 addget(Newton) { return PREF* Uget(kg, 1) * Uget(m, 1) * Uget(s, -2); }
186 addget(Pascal) { return PREF* Uget(kg, 1) * Uget(m, -1) * Uget(s, -2); }
187 addget(Joule) { return PREF* Uget(Newton, 1) * Uget(m, 1); }
188 addget(Watt) { return PREF* Uget(Joule, 1) * Uget(s, -1); }
189 addget(Coulomb) { return PREF* Uget(s, 1) * Uget(A, 1); }
190 addget(Volt) { return PREF* Uget(Watt, 1) * Uget(A, -1); }
191 addget(Farad) { return PREF* Uget(Coulomb, 1) * Uget(Volt, -1); }
192 addget(Ohm) { return PREF* Uget(Volt, 1) * Uget(Ampere, -1); }
193 addget(Siemens) { return PREF* Uget(Ohm, -1); }
194 addget(Weber) { return PREF* Uget(Volt, 1) * Uget(second, 1); }
195 addget(Tesla) { return PREF* Uget(Weber, 1) * Uget(m, -2); }
196 addget(Henry) { return PREF* Uget(Weber, 1) * Uget(A, -1); }
197 addget(lumens) { return PREF* Uget(candela, 1); }
198 addget(lux) { return PREF* Uget(lumens, 1) * Uget(m, -2); }
199 addget(Bequerel){ return PREF* Uget(s, -1); }
200 addget(Gray) { return PREF* Uget(m, 2) *Uget(s, -2) ; }
201 addget(Sievert) { return PREF* Uget(m, 2) *Uget(s, -2) ; }
202 addget(katal) { return PREF* Uget(mol, 1) *Uget(s, -1) ; }
203
204
205 // alternative base units
206 addget(minutes){ return PREF* Uget(s, 1) * Cget(Uconvert::mn_to_s, 1); }
207 addget(hours) { return PREF* Uget(s, 1) * Cget(Uconvert::hr_to_s, 1); }
208 addget(days) { return PREF* Uget(s, 1) * Cget(Uconvert::dy_to_s, 1); }
209 addget(years) { return PREF* Uget(s, 1) * Cget(Uconvert::yr_to_s, 1); }
210
211 addget(astronomical_unit) { return PREF* Uget(m, 1) * Cget(Uconvert::au_to_m, 1); }
212 addget(light_year) { return PREF* Uget(m, 1) * Cget(Uconvert::ly_to_m, 1); }
213 addget(parsec) { return PREF* Uget(m, 1) * Cget(Uconvert::pc_to_m, 1); }
214 addget(solar_radius) { return PREF* Uget(m, 1) * Cget(Uconvert::rsol_to_m, 1); }
215 addget(earth_radius) { return PREF* Uget(m, 1) * Cget(Uconvert::rearth_to_m, 1); }
216
217 addget(eV) {return PREF* Uget(Joule, 1) * Cget(Uconvert::eV_to_J,1);}
218 addget(erg) {return PREF* Uget(Joule, 1) * Cget(Uconvert::erg_to_J,1);}
219
220 addget(pint) {return PREF* Uget(m, 3) * Cget(Uconvert::litre_to_pint/1000,1);}
221 #endif
222
223 // clang-format on
224
233 template<UnitPrefix pref = None, units::UnitName u, int power = 1>
234 inline constexpr T to() {
235 return get<u, -power>();
236 }
237
239 template<units::UnitName u, int power = 1>
240 inline constexpr T get() {
241 return get<None, u, power>();
242 }
243
245 template<units::UnitName u, int power = 1>
246 inline constexpr T to() {
247 return to<None, u, power>();
248 }
249
250 private:
251 template<UnitPrefix pref = None>
252 inline T getter_1(units::UnitName name) {
253 switch (name) {
254
255 case units::second : return get<pref, units::second>(); break;
256 case units::metre : return get<pref, units::metre>(); break;
257 case units::kilogram: return get<pref, units::kilogram>(); break;
258 case units::Ampere : return get<pref, units::Ampere>(); break;
259 case units::Kelvin : return get<pref, units::Kelvin>(); break;
260 case units::mole : return get<pref, units::mole>(); break;
261 case units::candela : return get<pref, units::candela>(); break;
262 // case units::mps: return get<pref, units::mps>(); break;
263 case units::Hertz : return get<pref, units::Hertz>(); break;
264 case units::Newton : return get<pref, units::Newton>(); break;
265 case units::Pascal : return get<pref, units::Pascal>(); break;
266 case units::Joule : return get<pref, units::Joule>(); break;
267 case units::Watt : return get<pref, units::Watt>(); break;
268 case units::Coulomb : return get<pref, units::Coulomb>(); break;
269 case units::Volt : return get<pref, units::Volt>(); break;
270 case units::Farad : return get<pref, units::Farad>(); break;
271 case units::Ohm : return get<pref, units::Ohm>(); break;
272 case units::Siemens : return get<pref, units::Siemens>(); break;
273 case units::Weber : return get<pref, units::Weber>(); break;
274 case units::Tesla : return get<pref, units::Tesla>(); break;
275 case units::Henry : return get<pref, units::Henry>(); break;
276 case units::lumens : return get<pref, units::lumens>(); break;
277 case units::lux : return get<pref, units::lux>(); break;
278 case units::Bequerel : return get<pref, units::Bequerel>(); break;
279 case units::Gray : return get<pref, units::Gray>(); break;
280 case units::Sievert : return get<pref, units::Sievert>(); break;
281 case units::katal : return get<pref, units::katal>(); break;
282 case units::minutes : return get<pref, units::minutes>(); break;
283 case units::hours : return get<pref, units::hours>(); break;
284 case units::days : return get<pref, units::days>(); break;
285 case units::years : return get<pref, units::years>(); break;
286 case units::astronomical_unit: return get<pref, units::astronomical_unit>(); break;
287 case units::light_year : return get<pref, units::light_year>(); break;
288 case units::parsec : return get<pref, units::parsec>(); break;
289 case units::solar_radius : return get<pref, units::solar_radius>(); break;
290 case units::earth_radius : return get<pref, units::earth_radius>(); break;
291 case units::eV : return get<pref, units::eV>(); break;
292 case units::erg : return get<pref, units::erg>(); break;
293 case units::pint : return get<pref, units::pint>(); break;
294 }
295 }
296
297 inline T getter_2(UnitPrefix pref, units::UnitName name) {
298 switch (pref) {
299
300 case tera : return getter_1<tera>(name); break;
301 case giga : return getter_1<giga>(name); break;
302 case mega : return getter_1<mega>(name); break;
303 case kilo : return getter_1<kilo>(name); break;
304 case hecto: return getter_1<hecto>(name); break;
305 case deca : return getter_1<deca>(name); break;
306 case None : return getter_1<None>(name); break;
307 // case deci: return getter_1<deci>(name); break;
308 case centi: return getter_1<centi>(name); break;
309 case milli: return getter_1<milli>(name); break;
310 case micro: return getter_1<micro>(name); break;
311 case nano : return getter_1<nano>(name); break;
312 case pico : return getter_1<pico>(name); break;
313 case femto: return getter_1<femto>(name); break;
314 }
315 }
316
317 public:
319 inline T runtime_get(UnitPrefix pref, units::UnitName name, int power) {
320 return pown(getter_2(pref, name), power);
321 }
322
324 inline T runtime_to(UnitPrefix pref, units::UnitName name, int power) {
325 return pown(getter_2(pref, name), -power);
326 }
327 };
328
329} // namespace shamunits
330
331#undef addget
332#undef PREF
333#undef Uget
334#undef Cget
#define Uget(unitname, mult_pow)
Utility macro to get the value of a unit in the current unit system with its power.
Definition Constants.hpp:37
#define Cget(constant_name, mult_pow)
Utility macro to get the value of a constant in the current unit system with its power.
Definition Constants.hpp:40
UnitName
List of all units name.
Definition Names.hpp:154
#define addget(uname)
Macro to add a unit getter.
#define PREF
Shorthand for prefix handling.
Defines a unit system.
constexpr T to()
Simplified signature for to without prefix.
T cd_inv
inverse value of a candela in this system
constexpr T get() const noexcept
get the value of a units in the current system
T K_inv
inverse value of a Kelvin in this system
T mol
value of a mol in this system
T m
value of a meter in this system
T kg_inv
inverse value of a kilogram in this system
constexpr T to()
To the si units (convert a system unit to si ones). This function is the inverse of get.
T kg
value of a kilogram in this system
T K
value of a Kelvin in this system
constexpr T get()
Simplified signature for get without prefix.
T m_inv
inverse value of a meter in this system
T s_inv
inverse value of a second in this system
T mol_inv
inverse value of a mol in this system
T runtime_to(UnitPrefix pref, units::UnitName name, int power)
Non templated version of to.
UnitSystem(T unit_time=1, T unit_length=1, T unit_mass=1, T unit_current=1, T unit_temperature=1, T unit_qte=1, T unit_lumint=1)
Construct a new UnitSystem from either supplied base units or SI by default.
T A_inv
inverse value of a Ampere in this system
T runtime_get(UnitPrefix pref, units::UnitName name, int power)
Non templated version of get.
T A
value of a Ampere in this system
T cd
value of a candela in this system
T s
value of a second in this system
namespace containing the units library
UnitPrefix
Enum of all prefixes.
Definition Names.hpp:89
static constexpr T pc_to_m
conversion factor from parsecs to meters
static constexpr T dy_to_s
conversion factor from days to seconds
static constexpr T erg_to_J
conversion factor from ergs to joules
static constexpr T litre_to_pint
conversion offset from litre to british pint
static constexpr T hr_to_s
conversion factor from hours to seconds
static constexpr T ly_to_m
conversion factor from light years to meters
static constexpr T yr_to_s
conversion factor from years to seconds
static constexpr T eV_to_J
conversion factor from electron volts to joules
static constexpr T rsol_to_m
conversion factor from solar radii to meters
static constexpr T rearth_to_m
conversion factor from earth equatorial radii to meters
static constexpr T au_to_m
conversion factor from au to meters
static constexpr T mn_to_s
conversion factor from minutes to seconds