Skip to content

Units

Simple helpers for working with physical quantities like distance, time, and force—with dimensional analysis built in.

Every quantity carries a 7-tuple of SI exponents — (m, kg, A, K, mol, cd, s) — and arithmetic operations compose those exponents and re-type the result automatically.

Please note, for continuous models units are to be applied at the boundaries. Calculation is performed with floats for speed. All continuous models use SI units: - Displacement: metres (m) - Velocity: m/s - Angles: radians (rad)

import simweave as sw

d = sw.Distance(120.0)              # 120 m
t = sw.TimeUnit(2.0, unit="mins")    # 2 minutes  (stored as 120.0 s)
m = sw.Mass(1500.0)                  # 1500 kg

v = d / t                            # -> Velocity(1.0 m/s)   (auto-typed)
a = v / sw.TimeUnit(10.0)            # -> Acceleration(0.1 m/s^2)
f = m * a                            # -> Force(150.0 N)

The base class:

  • SIUnit (base; carries the value, unit string, and exponents)

Available Units

Basic

  • Distance
  • TimeUnit
  • Mass

Derived

  • Velocity
  • Acceleration
  • Force
  • Energy
  • Power
  • Pressure
  • Area
  • Volume
  • Frequency
  • Temperature (absolute, e.g. Kelvin or Celsius)
  • TemperatureDelta (differences)
  • Voltage
  • Current
  • Resistance
  • Capacitance
  • Resistivity

Dimensionless

  • Angle

Unit Conversion

You can construct values using common units:

d = sw.Distance(10, "ft")      # feet → stored internally as metres
v = sw.Velocity(60, "mph")     # miles per hour
e = sw.Energy(1, "kWh")        # kilowatt-hour                    # -> Force(150.0 N)
Convert explicitly:

d.to("m")      # → 3.048
d.to("ft")     # → 10.0

Displaying Values

d = sw.Distance(10, "ft")

d.format()          # "3.048 [m]"
d.format("ft")      # "10.0 [ft]"

For nicer output:

e = sw.Energy(1500)

e.auto_format()     # "1.5 [kJ]"

Working with arrays (NumPy)

SimWeave supports NumPy arrays for vectorised calculations.

import numpy as np
import simweave as sw

d = sw.Distance(np.array([1, 2, 3]))
t = sw.TimeUnit(2)

v = d / t

print(v)
# [0.5, 1.0, 1.5] [m/s]

We can also use fractional powers when they produce valid physical dimensions (e.g. √area → distance):

import numpy as np
import simweave as sw

area = sw.Area(np.array([1, 4, 9]))

length = area ** 0.5

print(length)
# Distance([1.0, 2.0, 3.0]) [m]
or indeed distances from volumes:
volume = sw.Volume(np.array([1, 8, 27]))

length = volume ** (1/3)

print(length)
# Distance([1.0, 2.0, 3.0]) [m]

Temperature (special case)

Temperature supports both Kelvin and Celsius:

t = sw.Temperature(0, "C")

t.value        # 273.15 (stored in Kelvin)
t.to("C")      # 0.0

Differences are handled explicitly:

t1 = sw.Temperature(30, "C")
t2 = sw.Temperature(20, "C")

delta = t1 - t2    # TemperatureDelta
t3 = t2 + delta    # Temperature

Adding two absolute temperatures is not allowed:

t1 + t2   # ! raises TypeError

Angles

These are technically dimensionless however SimWeave allows conversion between Degrees and Radians

phi = Angle(np.pi / 2)
phi_deg = phi.to("deg")

Physical Constants

Convenience constants are available, for all SIunits and several physical constants:

from simweave.units.constants import kg, m, s, g, c

force = 10 * kg * m / s**2
weight = 80 * kg * g
energy = sw.Mass(1) * c**2

Full set of physical constants at current release:

# Acceleration due to gravity
g = 9.80665 * m / s**2

# Speed of light
c = 299_792_458 * m / s

# Planck constant
h = 6.62607015e-34 * J * s

# Boltzmann constant
k_B = 1.380649e-23 * J / K

What it does

  • Combines units correctly when multiplying/dividing
  • Prevents invalid operations (e.g. adding distance and time)
  • Converts units at construction time
  • Keeps everything internally in standard SI units
  • NumPy array support (ufunc planned in future releases)
  • Ability to use non-integer powers e.g. sqrt as **0.5 for area, and cuberoot for volume

What it does not do (yet)

  • Full unit parsing (e.g. "kg*m/s^2" strings)
  • Complex unit systems beyond SI

For a runnable walkthrough see demos/15_units_dimensional.py.

API

Dimensional quantities with SI exponent tracking.

SIUnit dataclass

SIUnit(value: float, unit: str = 'dimensionless', exponents: list[int] = (lambda: [0] * 7)())

Generic SI quantity with exponent-tracked dimensional analysis.

TimeUnit

TimeUnit(value: float | SIUnit, unit: str = 's')

Bases: SIUnit

Time, stored canonically in seconds regardless of input unit.

Source code in src/simweave/units/si.py
def __init__(self, value: float | SIUnit, unit: str = "s"):
    if isinstance(value, SIUnit):
        value = value.value
    if unit not in self._SCALE_MAP:
        raise ValueError(f"Unsupported time unit: {unit}")
    super().__init__(
        value=value * self._SCALE_MAP[unit],
        unit="s",
        exponents=[0, 0, 0, 0, 0, 0, 1],
    )

Temperature

Temperature(value: float | SIUnit, unit: str = 'K')

Bases: SIUnit

Source code in src/simweave/units/si.py
def __init__(self, value: float | SIUnit, unit: str = "K"):
    if isinstance(value, SIUnit):
        value = value.value

    if unit not in self._SCALE_MAP:
        raise ValueError(f"Unsupported temperature unit: {unit}")

    # Convert to Kelvin
    kelvin_value = value * self._SCALE_MAP[unit] + self._OFFSET_MAP[unit]

    super().__init__(
        value=kelvin_value,
        unit="K",
        exponents=[0, 0, 0, 1, 0, 0, 0],
    )

to

to(unit: str) -> float

Convert temperature units. For temperatures, note an offset as well as scaling

Source code in src/simweave/units/si.py
def to(self, unit: str) -> float:
    """ Convert temperature units. For temperatures, note an offset as well as scaling """
    if unit not in self._SCALE_MAP:
        raise ValueError(f"Unsupported temperature unit: {unit}")

    # Convert from Kelvin
    return (self.value - self._OFFSET_MAP[unit]) / self._SCALE_MAP[unit]

TemperatureDelta

TemperatureDelta(value: float | SIUnit, unit: str = 'K')

Bases: SIUnit

Delta temperature to allow relative and absolute

Source code in src/simweave/units/si.py
def __init__(self, value: float | SIUnit, unit: str = "K"):
    if isinstance(value, SIUnit):
        value = value.value
    if unit not in self._SCALE_MAP:
        raise ValueError(f"Unsupported temperature difference unit: {unit}")
    super().__init__(
        value=value * self._SCALE_MAP[unit],
        unit="K",
        exponents=[0, 0, 0, 1, 0, 0, 0],
    )

ThermalConductance

ThermalConductance(value: float | SIUnit, unit: str = 'W/K')

Bases: SIUnit

Thermal conductance (W/K).

Source code in src/simweave/units/si.py
def __init__(self, value: float | SIUnit, unit: str = "W/K"):
    if isinstance(value, SIUnit):
        value = value.value
    if unit not in self._SCALE_MAP:
        raise ValueError(f"Unsupported thermal conductance unit: {unit}")
    super().__init__(
        value=float(value) * self._SCALE_MAP[unit],
        unit="W/K",
        exponents=[2, 1, 0, -1, 0, 0, -3],  # W/K = J/s/K
    )