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.
- Usage
- Performance
- How many dimensions are there
- List of units
- List of constants
- Acknowledgement
- Dedication
- Licence
What you see in this section is basically the content of example.cpp.
You should begin by
#include "studis.hpp"
using namespace studis::literals;
using namespace studis::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; // error
auto 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 namespace
auto 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 kiloohm
auto inductance = 1_uH; // same, this is microhenry
auto capacitance = 1_pF;
if (resistance > 2*sqrt (inductance/capacitance))
std::cout << "overdamped" << std::endl;
else if (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;
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.
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-alias | dimension |
---|---|
Dimmensionless |
1 |
Length |
L |
Mass |
M |
Time , Duration |
T |
ElectricCurrent |
I |
Temperature |
Θ |
AmountOfSubstance |
N |
LuminousIntensity |
J |
LuminousFlux |
J |
Wavenumber |
L-1 |
Area |
L2 |
Volume |
L3 |
CurrentDensity |
L-2 I |
Density |
L-3 M |
Concentration |
L-3 N |
Velocity , Speed |
L T-1 |
Acceleration |
L T-2 |
Momentum |
L M T-1 |
Action |
L2 M T-1 |
Frequency |
T-1 |
Radioactivity |
T-1 |
Force |
L M T-2 |
Pressure , Stress |
L-1 M T-2 |
DynamicViscosity |
L-1 M T-1 |
KinematicViscosity |
L2 T-2 |
Torque |
L2 M T-2 |
Energy , Work , Heat |
L2 M T-2 |
Power , RadiantFlux |
L2 M T-3 |
HeatCapacity |
L2 M T-2 Θ-1 |
Entropy |
L2 M T-2 Θ-1 |
ElectricCharge |
T I |
ElectricPotential , ElectromotiveForce , Voltage |
L2 M T-3 I-1 |
Capacitance |
L-2 M-1 T4 I2 |
Resistance , Impedance |
L2 M T-3 I-2 |
Conductance , Admittance |
L-2 M-1 T3 I2 |
MagneticFlux |
L2 M T-2 I-1 |
MagneticFluxDensity |
M T-3 I-1 |
Inductance |
L2 M T-2 I-2 |
Illuminance |
L-2 J |
CatalyticActivity |
T-1 N |
Quantity | Unit | Symbols |
---|---|---|
Length |
metre | fm , pm , nm , um , mm , cm , m , km , micron |
Length |
angstrom | angstrom |
Length |
inch | in |
Length |
foot | ft |
Length |
yard | yd |
Length |
mile | mile |
Length |
nautical mile | nautical_mile |
Length |
astronomical unit | au |
Length |
light year | ly , kly , Mly , Gly |
Length |
parsec | pc , kpc , Mpc , Gpc |
Mass |
gram | fg , pg , ng , ug , mg , g , gr , kg |
Mass |
dalton | Da , kDa , MDa |
Mass |
pound | lb |
Mass |
ounce | oz |
Mass |
tonne | t |
Time |
second | fs , ps , ns , us , ms , s , sec |
Time |
svedberg | Svedberg |
Time |
minute | min |
Time |
hour | h , hour |
Time |
day | d , day |
Time |
Julian year | julian_year |
ElectricCurrent |
ampere | nA , uA , mA , A , kA |
Temperature |
kelvin | K |
Temperature |
degree Celsius | deg_C , degree_Celsius |
Temperature |
degree Fahrenheit | deg_F , degree_Fahrenheit |
AmountOfSubstance |
mole | nmol , umol , mmol , mol , kmol |
LuminousIntensity |
candela | cd |
Area |
mm2 , cm2 , m2 , km2 |
|
Area |
in2 , ft2 , yd2 , mile2 |
|
Area |
barn | barn |
Area |
hectare | ha , hectare |
Volume |
cm3 , m3 |
|
Volume |
litre | ul , uL , ml , mL , l , L , litre |
Density |
gram per cubic centimetre | gr_per_cm3 , gr_per_ml , gr_per_mL |
Density |
kilogram per litre | kg_per_l , kg_per_L |
Density |
kilogram per cubic metre | kg_per_m3 |
Concentration |
molar | pM , nM , uM , mM , M |
Velocity |
metre per second | m_per_s |
Velocity |
foot per second | ft_per_s , ft_per_sec |
Velocity |
kilometre per hour | km_per_hour |
Velocity |
mile per hour | mile_per_hour |
Velocity |
knot | knot |
Acceleration |
metre per square second | m_per_s2 |
Acceleration |
foot per square second | ft_per_s2 |
Acceleration |
gal | Gal |
Momentum |
metre kilogram per second | m_kg_per_s |
Action |
joule second | J_s |
Frequency |
hertz | Hz , kHz , MHz , GHz , THz |
Frequency |
Baud | Bd , kBd , MBd , GBd |
Frequency |
FLOPS | FLOPS , kFLOPS , MFLOPS , GFLOPS , TFLOPS |
Frequency |
revolutions per minute | rpm |
Frequency |
frames per second | fps |
Radioactivity |
becquerel | Bq |
Force |
newton | pN , nN , uN , mN , N , kN |
Force |
dyne | dyn , dyne |
Force |
pound force | lbf |
Pressure |
pascal | Pa , kPa , MPa , GPa |
Pressure |
torr | mTorr , Torr |
Pressure |
millimetre of mercury | mmHg , cmHg |
Pressure |
psi | psi |
Pressure |
bar | mbar , bar |
Pressure |
standard atmosphere | atm |
DynamicViscosity |
pascal second | Pa_s |
DynamicViscosity |
poise | cP , P |
KinematicViscosity |
square metre per second | m2_per_s |
KinematicViscosity |
stokes | cSt , St |
Torque |
newton metre | N_m |
Energy |
joule | J , kJ , MJ , GJ |
Energy |
electronvolt | eV , keV , MeV , GeV |
Energy |
erg | erg |
Energy |
watt hour | Wh , kWh |
Energy |
british thermal unit | BTU |
Energy |
calorie | cal , kcal |
Power |
watt | nW , uW , mW , W , kW , MW , GW |
ElectricCharge |
coulomb | pC , nC , uC , mC , C |
ElectricCharge |
ampere hour | mAh , Ah |
ElectricPotential |
volt | uV , mV , V , kV , MV |
Capacitance |
farad | pF , nF , uF , mF , F |
Resistance |
ohm | uOhm , mOhm , Ohm , kOhm , MOhm , GOhm |
Conductance |
siemens | S |
MagneticFlux |
weber | nWb , uWb , mWb , Wb |
MagneticFlux |
maxwell | Mx |
MagneticFluxDensity |
tesla | uT , mT , T |
MagneticFluxDensity |
gauss | mG , G |
Inductance |
henry | uH , mH , H |
Illuminance |
lux | lx |
CatalyticActivity |
katal | kat |
Constants | Defined value | Unit |
---|---|---|
speed_of_light |
c = 299792458 | m/s |
Planck_constant |
ℎ = 6.62607015 * 10-34 | J s |
elementary_charge |
e = 1.602176634 * 10-19 | C |
Boltzmann_constant |
k = 1.380649 * 10-23 | J/K |
Avogadro_constant |
NA = 6.02214076 * 1023 | 1/mol |
hyperfine_transition_frequency_of_Cs_133 |
ΔνCs = 9192631770 | Hz |
luminous_efficacy |
Kcd = 873 | lm/W |
Fundamental constants whose values are exactly calculable in terms of the defined fundamental constants
Constants | Value | Unit |
---|---|---|
reduced_Planck_constant |
ℏ = ℎ / (2 π) | J s |
magnetic_flux_quantum |
𝛷0 = ℎ / (2 e) | Wb |
Josephson_constant |
KJ = 2 e / ℎ | 1/Wb |
conductance_quantum |
G0 = 2 e2 / ℎ | S |
inverse_of_conductance_quantum |
1 / G0 | Ω |
von_Klitzing_constant |
RK = ℎ / e2 | Ω |
Faraday_constant |
F = e NA | C/mol |
molar_gas_constant , universal_gas_constant , gas_constant |
R = k NA | J/(mol K) |
Stefan_Boltzmann_constant |
σ = (π2 / 60) k4 / (ℏ3 c2) | W/(m2 K4) |
first_radiation_constant |
c1 = 2 π ℎ c2 | W m2 |
second_radiation_constant |
c2 = ℎ c / k | m K |
Wien_displacement_law_constant , Wien_constant |
b = 2.897771955185172... * 10-3 | K m |
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).
Constants | Value | Unit | Relative standard uncertainty |
---|---|---|---|
magnetic_constant , vacuum_permeability |
μ0 = 1.25663706212 * 10-6 | N/A2 | 1.5 * 10-10 |
electric_constant , vacuum_permittivity |
ε0 = 8.8541878128 * 10-12 | F/m | 1.5 * 10-10 |
characteristic_impedance_of_vacuum |
Z0 = 376.730313668 | Ω | 1.5 * 10-10 |
Newtonian_constant_of_gravitation , universal_gravitational_constant , gravitational_constant |
G = 6.67430 * 10-11 | N/(m2 kg2) | 2.2 * 10-5 |
atomic_mass_constant , atomic_mass_unit , Dalton |
mu = 9.66053906660 * 10-27 | kg | 3.0 * 10-10 |
electron_mass |
me = 9.1093837015 * 10-31 | kg | 3.0 * 10-10 |
proton_mass |
mp = 1.67262192369 * 10-27 | kg | 3.1 * 10-10 |
proton_electron_mass_ratio |
mp / me = 1836.15267343 | 6.0 * 10-11 | |
fine_structure_constant |
α = e2 / (4 π ε0 ℏ c) = 0.0072973525693 | 1.5 * 10-10 | |
inverse_fine_structure_constant |
α-1 = 137.035999084 | 1.5 * 10-10 | |
Rydberg_constant |
R∞ = α2 me c / (2 ℎ) = 10973731.568160 | 1/m | 1.9 * 10-12 |
Bohr_magneton |
μB = e ℏ / (2 me) = 9.2740100783 * 10-24 | J/T | 3.0 * 10-10 |
nuclear_magneton |
μB = e ℏ / (2 mp) = 5.0507837461 * 10-27 | J/T | 3.1 * 10-10 |
Bohr_radius |
a0 = ℏ / (α me c) = 5.29177210903 * 10-11 | m | 1.5 * 10-10 |
Constant | Value |
---|---|
minute |
1 min = 60 s |
hour |
1 h = 60 min = 3600 s |
day |
1 d = 24 h = 86400 s |
degree |
1° = (π/180) rad |
arcminute |
1′ = (1/60)° = (π/10800) rad |
arcsecond |
1″ = (1/60)′ = (π/648000) rad |
hectare |
1 ha = 104 m2 |
litre |
1 L = 1 l = 10-3 m3 |
tonne |
1 t = 103 kg |
Constants holding the value of non-SI units associated with the CGS and the CGS-Gaussian system of units
Constant | Value |
---|---|
erg |
1 erg = 10-7 J |
dyne |
1 dyn = 10-5 N |
poise |
1 P = 1 dyn s cm-2 = 0.1 Pa s |
stokes |
1 St = 1 cm2/s = 10-4 m2/s |
gauss |
1 G = 1 Mx/cm2 = 10-4 T |
maxwell |
1 Mx = 1 G cm2 = 10-8 Wb |
Constant | Value |
---|---|
julian_year |
365.25 day |
astronomical_unit |
149597870700 m |
light_year |
Product of Julian year and speed of light |
parsec |
(648000/π) astronomical units |
Constant | Value | Unit | Remarks |
---|---|---|---|
standard_gravity |
gn = 9.80665 | m/s2 | |
standard_atmosphere |
atm = 101325 | Pa | |
standard_state_pressure |
ssp = 100000 | Pa | |
mercury_density |
ρHg = 13595.1 | kg/m3 | Density used in the definition of mmHg |
Constant | Value |
---|---|
inch |
1 in = 2.54 cm |
foot |
1 ft = 12 in |
yard |
1 yd = 3 ft |
mile |
1 mile = 1760 yd |
nautical_mile |
1 nautical mile = 1852 m |
knot |
1 knot = 1 nautical mile per hour |
pound |
1 lb = 0.45359237 kg |
ounce |
1 oz = (1/16) lb |
pound_force |
1 lbf = 1 lb * gn |
pound_force_per_squared_inch |
1 psi = 1 lbf/in2 |
british_thermal_unit |
1 BTU = 788169 ft lbf |
thermochemical_calorie |
1 cal = 4184 J |
Constant | Value |
---|---|
angstrom |
1 Å = 10-10 m |
svedberg |
1 S = 10-13 s |
torr |
1 Torr = (1/760) atm |
millimeter_of_mercury |
1 mmHg = ρHg * gn * 1 mm |
watt_hour |
1 Wh = 1 W * 1 h |
ampere_hour |
1 Ah = 1 A * 1 h |
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.
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.
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.