Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/src/torch/reference/misc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Supported base units
Unit expressions are built from the following base units. Matching is
case-insensitive, and whitespace is ignored.


**Temperature**:
``Kelvin`` (``K``)

**Length**:
``angstrom`` (``A``), ``Bohr``, ``meter`` (``m``), ``centimeter`` (``cm``),
``millimeter`` (``mm``), ``micrometer`` (``um``, ``µm``), ``nanometer`` (``nm``)
Expand All @@ -35,11 +39,17 @@ case-insensitive, and whitespace is ignored.
``nanosecond`` (``ns``), ``picosecond`` (``ps``), ``femtosecond`` (``fs``)

**Mass**:
``u`` (``Dalton``), ``kilogram`` (``kg``), ``gram`` (``g``), ``electron_mass`` (``m_e``)
``Dalton`` (``u``), ``kilogram`` (``kg``), ``gram`` (``g``), ``electron_mass`` (``m_e``)

**Charge**:
``e``, ``Coulomb`` (``C``)

**Pressure**:
``Pascal`` (``Pa``), ``kiloPascal`` (``kPa``), ``MegaPascal`` (``MPa``), ``GigaPascal`` (``GPa``), ``bar``, ``atm``

**Electric Dipole Moment**:
``Debye`` (``D``)

**Dimensionless**:
``mol``

Expand Down
86 changes: 63 additions & 23 deletions metatomic-torch/src/units.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@
*
* @subsection dimensions Dimensional Analysis
*
* Each unit has an associated 5-element dimension vector [L, T, M, Q, Th]
* representing exponents of Length, Time, Mass, Charge, and Temperature.
* For example:
* Each unit has an associated 5-element dimension vector [L, T, M, I, Θ]
* representing exponents of Length, Time, Mass, Electric current, and
* Temperature. For example:
* - Length: [1, 0, 0, 0, 0]
* - Energy: [2, -2, 1, 0, 0] (M L^2 T^-2)
* - Force: [1, -2, 1, 0, 0] (M L T^-2)
* - Pressure: [-1, -2, 1, 0, 0] (M L^-1 T^-2)
*
* Dimensional compatibility is checked by comparing these vectors with a
* tolerance of 1e-10 to accommodate floating-point accumulation from
* fractional powers.
* tolerance of 1e-10 to accommodate floating-point accumulation from fractional
* powers.
*
* @subsection conversion Conversion Factor Calculation
*
Expand All @@ -58,14 +58,16 @@
*/

/// Dimension indices for the 5-element exponent vector.
/// Order: [Length, Time, Mass, Charge, Temperature]
/// Order: [Length, Time, Mass, Electric Current, Temperature]
enum class DimIndex {
LENGTH = 0,
TIME = 1,
MASS = 2,
CHARGE = 3,
TEMPERATURE = 4,
COUNT = 5 // Number of dimensions
LENGTH,
TIME,
MASS,
ELECTRIC_CURRENT,
TEMPERATURE,
// we exclude amount of substance and luminous intensity

COUNT // Number of dimensions
};

/// Physical dimension vector: [Length, Time, Mass, Charge, Temperature]
Expand Down Expand Up @@ -116,11 +118,27 @@ struct Dimension {
return !(*this == other);
}

static const char* dim_index_as_string(size_t index) {
switch (index) {
case static_cast<size_t>(DimIndex::LENGTH):
return "L";
case static_cast<size_t>(DimIndex::TIME):
return "T";
case static_cast<size_t>(DimIndex::MASS):
return "M";
case static_cast<size_t>(DimIndex::ELECTRIC_CURRENT):
return "I";
case static_cast<size_t>(DimIndex::TEMPERATURE):
return "T";
default:
return "<ERROR, should not reach this line>";
}
}

/// Convert dimension to a human-readable string format.
/// Output format: "L^2 M T^-2" style (only non-zero exponents shown).
/// Exponent 1 is omitted, negative exponents use "^-N" format.
std::string to_string() const {
static const char* NAMES[] = {"L", "T", "M", "Q", "Th"};
std::string result;
bool first = true;

Expand All @@ -136,7 +154,7 @@ struct Dimension {
}
first = false;

result += NAMES[i];
result += dim_index_as_string(i);

// Only show exponent if not 1 or -1
if (std::fabs(v - 1.0) >= 1e-10 && std::fabs(v + 1.0) >= 1e-10) {
Expand Down Expand Up @@ -168,15 +186,16 @@ struct UnitValue {
Dimension dim;
};

// Dimension constants for readability
// L T M Q Th
static const Dimension DIM_LENGTH = {{ 1, 0, 0, 0, 0 }};
static const Dimension DIM_TIME = {{ 0, 1, 0, 0, 0 }};
static const Dimension DIM_MASS = {{ 0, 0, 1, 0, 0 }};
static const Dimension DIM_CHARGE = {{ 0, 0, 0, 1, 0 }};
static const Dimension DIM_TEMPERATURE = {{ 0, 0, 0, 0, 1 }};
static const Dimension DIM_ENERGY = {{ 2, -2, 1, 0, 0 }};
static const Dimension DIM_NONE = {{ 0, 0, 0, 0, 0 }};
// Dimension constants for readability L T M I Θ
static const Dimension DIM_LENGTH = {{ 1, 0, 0, 0, 0 }};
static const Dimension DIM_TIME = {{ 0, 1, 0, 0, 0 }};
static const Dimension DIM_MASS = {{ 0, 0, 1, 0, 0 }};
static const Dimension DIM_CHARGE = {{ 0, 1, 0, 1, 0 }};
static const Dimension DIM_TEMPERATURE = {{ 0, 0, 0, 0, 1 }};
static const Dimension DIM_ENERGY = {{ 2, -2, 1, 0, 0 }};
static const Dimension DIM_PRESSURE = {{ -1, -2, 1, 0, 0 }};
static const Dimension DIM_ELECTRIC_DIPOLE = {{ 1, 1, 0, 1, 0 }};
static const Dimension DIM_NONE = {{ 0, 0, 0, 0, 0 }};

/// Lowercase a string in place and return it.
static std::string to_lower(std::string s) {
Expand All @@ -194,6 +213,10 @@ static std::string to_lower(std::string s) {
/// Case-insensitive lookup: names are lowercased before searching.

static const auto BASE_UNITS = std::unordered_map<std::string, UnitValue>{
// --- Temperature ---
{"kelvin", {1.0, DIM_TEMPERATURE}},
{"k", {1.0, DIM_TEMPERATURE}},

// --- Length ---
{"angstrom", {1e-10, DIM_LENGTH}},
{"a", {1e-10, DIM_LENGTH}},
Expand All @@ -211,6 +234,7 @@ static const auto BASE_UNITS = std::unordered_map<std::string, UnitValue>{
{"micrometer", {1e-6, DIM_LENGTH}},

// --- Energy ---
{"electronvolt", {1.602176634e-19, DIM_ENERGY}},
{"ev", {1.602176634e-19, DIM_ENERGY}},
{"mev", {1.602176634e-19 * 1e-3, DIM_ENERGY}},
{"hartree", {4.359744722206048e-18, DIM_ENERGY}},
Expand Down Expand Up @@ -251,6 +275,22 @@ static const auto BASE_UNITS = std::unordered_map<std::string, UnitValue>{
{"coulomb", {1.0, DIM_CHARGE}},
{"c", {1.0, DIM_CHARGE}},

// --- Pressure ---
{"pa", {1.0, DIM_PRESSURE}},
{"pascal", {1.0, DIM_PRESSURE}},
{"kpa", {1e3, DIM_PRESSURE}},
{"kilopascal", {1e3, DIM_PRESSURE}},
{"mpa", {1e6, DIM_PRESSURE}},
{"megapascal", {1e6, DIM_PRESSURE}},
{"gpa", {1e9, DIM_PRESSURE}},
{"gigapascal", {1e9, DIM_PRESSURE}},
{"bar", {100000.0, DIM_PRESSURE}},
{"atm", {101325.0, DIM_PRESSURE}},

// --- Electric dipole moment ---
{"debye", {1/299792458.0 * 1e-21, DIM_ELECTRIC_DIPOLE}},
{"d", {1/299792458.0 * 1e-21, DIM_ELECTRIC_DIPOLE}},

// --- Dimensionless ---
{"mol", {6.02214076e23, DIM_NONE}},

Expand Down
Loading