Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

STUDIS Strongly Typed Units & Dimensions In SI

Copyright 2018 Morteza Jalalvand Licensed under the NDPL please see Licence for details.

Scientifically valid equations must be dimensionally homogeneous. It means that you can't compare quantities with different dimensions or add or subtract them. The argument of sine and many other mathematical functions must be a dimensionless quantity. Moreover, quantities of the same dimension but differing units should be converted to the same unit before comparing, adding or subtracting them. Breaking these rules in a program results in logical errors that can easily go undetected. STUDIS enforces the concept of dimensional homogeneity as syntax rules so that you get a compile error for violating it. It also internally converts all units to SI units so that quantities with differing units can be easily compared, added or subtracted.

Table of contents

Usage

What you see in this section is basically the content of example.cpp.

You should begin by

#include"studis.hpp"usingnamespacestudis::literals;usingnamespacestudis::constants;

Then you can define and use quantities easily

auto l1 = 1.5_m, l2 = 2_cm;
auto t = 3_s;
auto l3 = l1 + l2; // fine
std::cout << l3 << std::endl; // prints '1.52 m' (yes the unit is printed as well)
std::cout << l1 + l2 << std::endl; // same
std::cout << (l1 < l2) << std::endl; // works// std::cout << l1 + t << std::endl; // error// std::cout << (l1 < t) << std::endl; // errorauto speed = l1 / t;
std::cout << speed << std::endl; // prints '0.5 m/s'

All math functions that make sense for quantities with dimension are overloaded

std::cout << abs (-1_A) << std::endl; // prints '1 A'
std::cout << atan2 (7_m, 1_km) << std::endl; // prints some number// std::cout << atan2 (1_m, 1_s) << std::endl;// error
std::cout << hypot (3_m, 4_m) << std::endl; // prints '5 m'// std::cout << hypot (1_m, 1_s) << std::endl;// error

pow is the only function that has different signature than its std counterpart, this can't be avoided since the dimension of the output depends on the power

auto energy = 0.5 * 1_kg * pow<2> (speed);
std::cout << energy << std::endl; // prints '0.125 J (m2.kg/s2)'

sqrt, cbrt are overloaded for quantities whose result does not have a non-integer dimensional exponent

// pi, standard_gravity and many other constants are defined in the constants namespaceauto pendulum_frequency = sqrt (standard_gravity / 1_m) / (2*pi);
std::cout << pendulum_frequency << std::endl; // prints '0.498403 Hz (1/s)'
std::cout << cbrt (1_litre) << std::endl; // prints '0.1 m'

Fractional power dimensions are not supported

// std::cout << sqrt (1_s) << std::endl; // error// std::cout << cbrt (1_m2) << std::endl; // error

Dimensionless quantities can be used with any math function since they implicitly convert to a floating-point

auto pos = 1_cm * cos (2*pi*1_s*pendulum_frequency);
std::cout << pos << std::endl; // prints '-0.0099995 m'// std::cout << cos (1_s) << std::endl; // error

There are so many units and prefixes in STUDIS

auto resistance = 1.7_kOhm; // we don't have greek letters, so that's kiloohmauto inductance = 1_uH; // same, this is microhenryauto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
elseif (resistance == 2*sqrt (inductance/capacitance))
std::cout << "cricitally damped" << std::endl;
else std::cout << "underdamped" << std::endl;

You can use STUDIS simply as a unit convertor (to SI units)

std::cout << 10_ly << std::endl; // prints '9.46073e+16 m'
std::cout << 30_knot << std::endl; // prints '15.4333 m/s'
std::cout << 1_MeV << std::endl; // prints '1.60218e-13 J (m2.kg/s2)'
std::cout << 2000_kcal << std::endl; // prints '8.368e+09 J (m2.kg/s2)'
std::cout << 120_mmHg << std::endl; // prints '15998.7 Pa (kg/m.s2)'

And so many constants

auto radiative_power = Stefan_Boltzmann_constant * pow<4>(300_K) * 1_m2;
std::cout << radiative_power << std::endl; // prints '459.3 W (m2.kg/s3)'
std::cout << electron_mass << std::endl; // prints '9.10938e-31 kg'

Value of a (non-const) variable can change but its dimension can't

auto mass = 1_kg;
mass = 300_g; // fine// mass = 1_m3; // error
std::cin >> mass; // you can also read its value
std::cout << mass << std::endl;

If you don't want to specify an initial value (not recommended), you have to specify the dimension of the quantity

studis::Density d;
std::cin >> d;
std::cout << d << std::endl;

Many common dimensions are there, but in the case you can't find it there, you can specify the power for all 7 base dimensions of the SI yourself

studis::Quantity<studis::Dimension<1,0,-3,0,0,0,0>> jerk;
std::cin >> jerk;
std::cout << jerk << std::endl;

Performance

STUDIS should not incur any noticeable overhead at runtime. Information about dimension of quantities are encoded in the type system so they are not stored and only the value itself consumes memory. All dimension checks are of course performed during compilation and incur no cost at runtime.

How many dimensions are there?

Really a lot. Much more than any reasonable use case scenario. The dimensional exponents of quantities can always range from -127 to 127 (it could actually be more), so at least about 256. In other words a quantity Q with dimension

dim Q = Lα Mβ Tγ Iδ Θε Nζ Jη

is guaranteed to be in STUDIS as long as all of α, β, γ, δ, ε, ζ, and η are integers in interval -127 to 127.

Common dimensions have type-aliases for easy access

type-aliasdimension
Dimmensionless1
LengthL
MassM
Time, DurationT
ElectricCurrentI
TemperatureΘ
AmountOfSubstanceN
LuminousIntensityJ
LuminousFluxJ
WavenumberL-1
AreaL2
VolumeL3
CurrentDensityL-2 I
DensityL-3 M
ConcentrationL-3 N
Velocity, SpeedL T-1
AccelerationL T-2
MomentumL M T-1
ActionL2 M T-1
FrequencyT-1
RadioactivityT-1
ForceL M T-2
Pressure, StressL-1 M T-2
DynamicViscosityL-1 M T-1
KinematicViscosityL2 T-2
TorqueL2 M T-2
Energy, Work, HeatL2 M T-2
Power, RadiantFluxL2 M T-3
HeatCapacityL2 M T-2 Θ-1
EntropyL2 M T-2 Θ-1
ElectricChargeT I
ElectricPotential, ElectromotiveForce, VoltageL2 M T-3 I-1
CapacitanceL-2 M-1 T4 I2
Resistance, ImpedanceL2 M T-3 I-2
Conductance, AdmittanceL-2 M-1 T3 I2
MagneticFluxL2 M T-2 I-1
MagneticFluxDensityM T-3 I-1
InductanceL2 M T-2 I-2
IlluminanceL-2 J
CatalyticActivityT-1 N

List of units

QuantityUnitSymbols
Lengthmetrefm, pm, nm, um, mm, cm, m, km, micron
Lengthangstromangstrom
Lengthinchin
Lengthfootft
Lengthyardyd
Lengthmilemile
Lengthnautical milenautical_mile
Lengthastronomical unitau
Lengthlight yearly, kly, Mly, Gly
Lengthparsecpc, kpc, Mpc, Gpc
Massgramfg, pg, ng, ug, mg, g, gr, kg
MassdaltonDa, kDa, MDa
Masspoundlb
Massounceoz
Masstonnet
Timesecondfs, ps, ns, us, ms, s, sec
TimesvedbergSvedberg
Timeminutemin
Timehourh, hour
Timedayd, day
TimeJulian yearjulian_year
ElectricCurrentamperenA, uA, mA, A, kA
TemperaturekelvinK
Temperaturedegree Celsiusdeg_C, degree_Celsius
Temperaturedegree Fahrenheitdeg_F, degree_Fahrenheit
AmountOfSubstancemolenmol, umol, mmol, mol, kmol
LuminousIntensitycandelacd
Areamm2, cm2, m2, km2
Areain2, ft2, yd2, mile2
Areabarnbarn
Areahectareha, hectare
Volumecm3, m3
Volumelitreul, uL, ml, mL, l, L, litre
Densitygram per cubic centimetregr_per_cm3, gr_per_ml, gr_per_mL
Densitykilogram per litrekg_per_l, kg_per_L
Densitykilogram per cubic metrekg_per_m3
ConcentrationmolarpM, nM, uM, mM, M
Velocitymetre per secondm_per_s
Velocityfoot per secondft_per_s, ft_per_sec
Velocitykilometre per hourkm_per_hour
Velocitymile per hourmile_per_hour
Velocityknotknot
Accelerationmetre per square secondm_per_s2
Accelerationfoot per square secondft_per_s2
AccelerationgalGal
Momentummetre kilogram per secondm_kg_per_s
Actionjoule secondJ_s
FrequencyhertzHz, kHz, MHz, GHz, THz
FrequencyBaudBd, kBd, MBd, GBd
FrequencyFLOPSFLOPS, kFLOPS, MFLOPS, GFLOPS, TFLOPS
Frequencyrevolutions per minuterpm
Frequencyframes per secondfps
RadioactivitybecquerelBq
ForcenewtonpN, nN, uN, mN, N, kN
Forcedynedyn, dyne
Forcepound forcelbf
PressurepascalPa, kPa, MPa, GPa
PressuretorrmTorr, Torr
Pressuremillimetre of mercurymmHg, cmHg
Pressurepsipsi
Pressurebarmbar, bar
Pressurestandard atmosphereatm
DynamicViscositypascal secondPa_s
DynamicViscositypoisecP, P
KinematicViscositysquare metre per secondm2_per_s
KinematicViscositystokescSt, St
Torquenewton metreN_m
EnergyjouleJ, kJ, MJ, GJ
EnergyelectronvolteV, keV, MeV, GeV
Energyergerg
Energywatt hourWh, kWh
Energybritish thermal unitBTU
Energycaloriecal, kcal
PowerwattnW, uW, mW, W, kW, MW, GW
ElectricChargecoulombpC, nC, uC, mC, C
ElectricChargeampere hourmAh, Ah
ElectricPotentialvoltuV, mV, V, kV, MV
CapacitancefaradpF, nF, uF, mF, F
ResistanceohmuOhm, mOhm, Ohm, kOhm, MOhm, GOhm
ConductancesiemensS
MagneticFluxwebernWb, uWb, mWb, Wb
MagneticFluxmaxwellMx
MagneticFluxDensityteslauT, mT, T
MagneticFluxDensitygaussmG, G
InductancehenryuH, mH, H
Illuminanceluxlx
CatalyticActivitykatalkat

List of constants

Fundamental constants defining the 7 base units of the 2018 SI system

ConstantsDefined valueUnit
speed_of_lightc = 299792458m/s
Planck_constantℎ = 6.62607015 * 10-34J s
elementary_chargee = 1.602176634 * 10-19C
Boltzmann_constantk = 1.380649 * 10-23J/K
Avogadro_constantNA = 6.02214076 * 10231/mol
hyperfine_transition_frequency_of_Cs_133ΔνCs = 9192631770Hz
luminous_efficacyKcd = 873lm/W

Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants

ConstantsValueUnit
reduced_Planck_constantℏ = ℎ / (2 π)J s
magnetic_flux_quantum𝛷0 = ℎ / (2 e)Wb
Josephson_constantKJ = 2 e / ℎ1/Wb
conductance_quantumG0 = 2 e2 / ℎS
inverse_of_conductance_quantum1 / G0
von_Klitzing_constantRK = ℎ / e2
Faraday_constantF = eNAC/mol
molar_gas_constant,
universal_gas_constant, gas_constant
R = kNAJ/(mol K)
Stefan_Boltzmann_constantσ = (π2 / 60) k4 / (ℏ3c2)W/(m2 K4)
first_radiation_constantc1 = 2 π ℎ c2W m2
second_radiation_constantc2 = ℎ c / km K
Wien_displacement_law_constant,
Wien_constant
b = 2.897771955185172... * 10-3K m

Fundamental constants whose values are determined empirically

These values are based on the 2018 and 2019 set of values of the constants and conversion factors of physics and chemistry recommended by the Committee on Data for Science and Technology (CODATA).

ConstantsValueUnitRelative standard uncertainty
magnetic_constant, vacuum_permeabilityμ0 = 1.25663706212 * 10-6N/A21.5 * 10-10
electric_constant, vacuum_permittivityε0 = 8.8541878128 * 10-12F/m1.5 * 10-10
characteristic_impedance_of_vacuumZ0 = 376.7303136681.5 * 10-10
Newtonian_constant_of_gravitation,
universal_gravitational_constant,
gravitational_constant
G = 6.67430 * 10-11N/(m2 kg2)2.2 * 10-5
atomic_mass_constant,
atomic_mass_unit, Dalton
mu = 9.66053906660 * 10-27kg3.0 * 10-10
electron_massme = 9.1093837015 * 10-31kg3.0 * 10-10
proton_massmp = 1.67262192369 * 10-27kg3.1 * 10-10
proton_electron_mass_ratiomp / me = 1836.152673436.0 * 10-11
fine_structure_constantα = e2 / (4 π ε0c) = 0.00729735256931.5 * 10-10
inverse_fine_structure_constantα-1 = 137.0359990841.5 * 10-10
Rydberg_constantR = α2mec / (2 ℎ) = 10973731.5681601/m1.9 * 10-12
Bohr_magnetonμB = e ℏ / (2 me) = 9.2740100783 * 10-24J/T3.0 * 10-10
nuclear_magnetonμB = e ℏ / (2 mp) = 5.0507837461 * 10-27J/T3.1 * 10-10
Bohr_radiusa0 = ℏ / (αme c) = 5.29177210903 * 10-11m1.5 * 10-10

Constants holding the value of non-SI units accepted for use with the International System of Units

ConstantValue
minute1 min = 60 s
hour1 h = 60 min = 3600 s
day1 d = 24 h = 86400 s
degree1° = (π/180) rad
arcminute1′ = (1/60)° = (π/10800) rad
arcsecond1″ = (1/60)′ = (π/648000) rad
hectare1 ha = 104 m2
litre1 L = 1 l = 10-3 m3
tonne1 t = 103 kg

Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units

ConstantValue
erg1 erg = 10-7 J
dyne1 dyn = 10-5 N
poise1 P = 1 dyn s cm-2 = 0.1 Pa s
stokes1 St = 1 cm2/s = 10-4 m2/s
gauss1 G = 1 Mx/cm2 = 10-4 T
maxwell1 Mx = 1 G cm2 = 10-8 Wb

Constants holding the value of non-SI units defined by the International Astronomical Union (IAU)

ConstantValue
julian_year365.25 day
astronomical_unit149597870700 m
light_yearProduct of Julian year and speed of light
parsec(648000/π) astronomical units

Adopted values

ConstantValueUnitRemarks
standard_gravitygn = 9.80665m/s2
standard_atmosphereatm = 101325Pa
standard_state_pressuressp = 100000Pa
mercury_densityρHg = 13595.1kg/m3Density used in the definition of mmHg

Constants holding the value of UK and US custmary units

ConstantValue
inch1 in = 2.54 cm
foot1 ft = 12 in
yard1 yd = 3 ft
mile1 mile = 1760 yd
nautical_mile1 nautical mile = 1852 m
knot1 knot = 1 nautical mile per hour
pound1 lb = 0.45359237 kg
ounce1 oz = (1/16) lb
pound_force1 lbf = 1 lb * gn
pound_force_per_squared_inch1 psi = 1 lbf/in2
british_thermal_unit1 BTU = 788169 ft lbf
thermochemical_calorie1 cal = 4184 J

Constants holding the value of other non-SI units

ConstantValue
angstrom1 Å = 10-10 m
svedberg1 S = 10-13 s
torr1 Torr = (1/760) atm
millimeter_of_mercury1 mmHg = ρHg * gn * 1 mm
watt_hour1 Wh = 1 W * 1 h
ampere_hour1 Ah = 1 A * 1 h

Acknowledgement

This is inspired by the idea of a strongly typed template MKS unit system discussed in the book The C++ Programming Language by Bjarne Stroustrup.

Dedication

This library is dedicated to all my mentors particularly Seyed Mehdi Vaez Allaei and Mohammad A. Charsooghi to whom I am grateful for both their teachings and friendship.

Licence

This library is distributed under the terms of Non-Discriminatory Public Licence. You can read the exact licence terms in the 'LICENSE' file, but here is a summary:

  • You can use and modify the software
  • You can distribute the original or the modified version of the software under the same terms in a non-discriminatory manner if you also provide the source code

If you have to comply with laws that compels you to restrict access of certain groups of people (such as export control laws), you can only use and modify this software for your own purposes, but you can no longer distribute it.

About

STUDIS Strongly Typed Units & Dimensions In SI

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages