qnty 0.0.2__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qnty-0.0.2 → qnty-0.0.3}/PKG-INFO +1 -1
- {qnty-0.0.2 → qnty-0.0.3}/pyproject.toml +1 -1
- qnty-0.0.3/src/qnty/__init__.py +175 -0
- qnty-0.0.3/src/qnty/dimension.py +184 -0
- qnty-0.0.3/src/qnty/prefixes.py +229 -0
- {qnty-0.0.2 → qnty-0.0.3}/src/qnty/unit.py +68 -0
- qnty-0.0.3/src/qnty/unit_types/__init__.py +0 -0
- qnty-0.0.3/src/qnty/unit_types/base.py +47 -0
- qnty-0.0.3/src/qnty/units.py +8092 -0
- {qnty-0.0.2 → qnty-0.0.3}/src/qnty/variable.py +2 -1
- qnty-0.0.3/src/qnty/variable_types/__init__.py +0 -0
- qnty-0.0.3/src/qnty/variable_types/base.py +58 -0
- qnty-0.0.3/src/qnty/variable_types/expression_variable.py +68 -0
- qnty-0.0.3/src/qnty/variable_types/typed_variable.py +92 -0
- qnty-0.0.3/src/qnty/variables.py +2303 -0
- qnty-0.0.3/src/qnty/variables.pyi +6097 -0
- qnty-0.0.2/src/qnty/__init__.py +0 -3
- qnty-0.0.2/src/qnty/dimension.py +0 -86
- qnty-0.0.2/src/qnty/units.py +0 -46
- qnty-0.0.2/src/qnty/variables.py +0 -229
- {qnty-0.0.2 → qnty-0.0.3}/README.md +0 -0
- {qnty-0.0.2 → qnty-0.0.3}/src/qnty/equation.py +0 -0
- {qnty-0.0.2 → qnty-0.0.3}/src/qnty/expression.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: qnty
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.3
|
4
4
|
Summary: High-performance unit system library for Python with dimensional safety and fast unit conversions
|
5
5
|
License: Apache-2.0
|
6
6
|
Keywords: units,dimensional analysis,engineering,physics,quantities,measurements
|
@@ -0,0 +1,175 @@
|
|
1
|
+
"""
|
2
|
+
Qnty - High-Performance Unit System for Engineering
|
3
|
+
====================================================
|
4
|
+
|
5
|
+
A fast, type-safe unit system library for Python with dimensional safety
|
6
|
+
and optimized unit conversions for engineering calculations.
|
7
|
+
"""
|
8
|
+
|
9
|
+
from .dimension import BaseDimension, DimensionSignature
|
10
|
+
from .equation import Equation
|
11
|
+
from .expression import Expression
|
12
|
+
from .unit import registry
|
13
|
+
from .units import register_all_units
|
14
|
+
from .variable import FastQuantity, TypeSafeSetter, TypeSafeVariable
|
15
|
+
from .variables import (
|
16
|
+
AbsorbedDose,
|
17
|
+
Acceleration,
|
18
|
+
ActivationEnergy,
|
19
|
+
AmountOfSubstance,
|
20
|
+
AnglePlane,
|
21
|
+
AngleSolid,
|
22
|
+
AngularAcceleration,
|
23
|
+
AngularMomentum,
|
24
|
+
Area,
|
25
|
+
AreaPerUnitVolume,
|
26
|
+
AtomicWeight,
|
27
|
+
Concentration,
|
28
|
+
DynamicFluidity,
|
29
|
+
ElectricCapacitance,
|
30
|
+
ElectricCharge,
|
31
|
+
ElectricCurrentIntensity,
|
32
|
+
ElectricDipoleMoment,
|
33
|
+
ElectricFieldStrength,
|
34
|
+
ElectricInductance,
|
35
|
+
ElectricPotential,
|
36
|
+
ElectricResistance,
|
37
|
+
ElectricalConductance,
|
38
|
+
ElectricalPermittivity,
|
39
|
+
ElectricalResistivity,
|
40
|
+
EnergyFlux,
|
41
|
+
EnergyHeatWork,
|
42
|
+
EnergyPerUnitArea,
|
43
|
+
Force,
|
44
|
+
ForceBody,
|
45
|
+
ForcePerUnitMass,
|
46
|
+
FrequencyVoltageRatio,
|
47
|
+
FuelConsumption,
|
48
|
+
HeatOfCombustion,
|
49
|
+
HeatOfFusion,
|
50
|
+
HeatOfVaporization,
|
51
|
+
HeatTransferCoefficient,
|
52
|
+
Illuminance,
|
53
|
+
KineticEnergyOfTurbulence,
|
54
|
+
Length,
|
55
|
+
LinearMassDensity,
|
56
|
+
LinearMomentum,
|
57
|
+
LuminanceSelf,
|
58
|
+
LuminousFlux,
|
59
|
+
LuminousIntensity,
|
60
|
+
MagneticField,
|
61
|
+
MagneticFlux,
|
62
|
+
MagneticInductionFieldStrength,
|
63
|
+
MagneticMoment,
|
64
|
+
MagneticPermeability,
|
65
|
+
MagnetomotiveForce,
|
66
|
+
Mass,
|
67
|
+
MassDensity,
|
68
|
+
MassFlowRate,
|
69
|
+
MassFlux,
|
70
|
+
MassFractionOfI,
|
71
|
+
MassTransferCoefficient,
|
72
|
+
MolalityOfSoluteI,
|
73
|
+
MolarConcentrationByMass,
|
74
|
+
MolarFlowRate,
|
75
|
+
MolarFlux,
|
76
|
+
MolarHeatCapacity,
|
77
|
+
MolarityOfI,
|
78
|
+
MoleFractionOfI,
|
79
|
+
MomentOfInertia,
|
80
|
+
MomentumFlowRate,
|
81
|
+
MomentumFlux,
|
82
|
+
NormalityOfSolution,
|
83
|
+
ParticleDensity,
|
84
|
+
Permeability,
|
85
|
+
PhotonEmissionRate,
|
86
|
+
PowerPerUnitMass,
|
87
|
+
PowerPerUnitVolume,
|
88
|
+
PowerThermalDuty,
|
89
|
+
Pressure,
|
90
|
+
RadiationDoseEquivalent,
|
91
|
+
RadiationExposure,
|
92
|
+
Radioactivity,
|
93
|
+
SecondMomentOfArea,
|
94
|
+
SecondRadiationConstantPlanck,
|
95
|
+
SpecificEnthalpy,
|
96
|
+
SpecificGravity,
|
97
|
+
SpecificHeatCapacityConstantPressure,
|
98
|
+
SpecificLength,
|
99
|
+
SpecificSurface,
|
100
|
+
SpecificVolume,
|
101
|
+
Stress,
|
102
|
+
SurfaceMassDensity,
|
103
|
+
SurfaceTension,
|
104
|
+
Temperature,
|
105
|
+
ThermalConductivity,
|
106
|
+
Time,
|
107
|
+
Torque,
|
108
|
+
TurbulenceEnergyDissipationRate,
|
109
|
+
VelocityAngular,
|
110
|
+
VelocityLinear,
|
111
|
+
ViscosityDynamic,
|
112
|
+
ViscosityKinematic,
|
113
|
+
Volume,
|
114
|
+
VolumeFractionOfI,
|
115
|
+
VolumetricCalorificHeatingValue,
|
116
|
+
VolumetricCoefficientOfExpansion,
|
117
|
+
VolumetricFlowRate,
|
118
|
+
VolumetricFlux,
|
119
|
+
VolumetricMassFlowRate,
|
120
|
+
Wavenumber
|
121
|
+
)
|
122
|
+
|
123
|
+
# Register all units to the global registry
|
124
|
+
register_all_units(registry)
|
125
|
+
|
126
|
+
# Finalize registry after all registrations
|
127
|
+
registry.finalize_registration()
|
128
|
+
|
129
|
+
# Version information
|
130
|
+
__version__ = "0.0.3"
|
131
|
+
|
132
|
+
# Define public API
|
133
|
+
__all__ = [
|
134
|
+
# Core variable types (most commonly used)
|
135
|
+
"Length", "Pressure", "Temperature", "Time", "Mass", "Volume", "Area",
|
136
|
+
"Force", "EnergyHeatWork", "PowerThermalDuty",
|
137
|
+
|
138
|
+
# Core classes for advanced usage
|
139
|
+
"FastQuantity", "TypeSafeVariable", "TypeSafeSetter",
|
140
|
+
"DimensionSignature", "BaseDimension",
|
141
|
+
"Expression", "Equation",
|
142
|
+
|
143
|
+
# All other variable types (95 additional types)
|
144
|
+
"AbsorbedDose", "Acceleration", "ActivationEnergy", "AmountOfSubstance",
|
145
|
+
"AnglePlane", "AngleSolid", "AngularAcceleration", "AngularMomentum",
|
146
|
+
"AreaPerUnitVolume", "AtomicWeight", "Concentration", "DynamicFluidity",
|
147
|
+
"ElectricCapacitance", "ElectricCharge", "ElectricCurrentIntensity",
|
148
|
+
"ElectricDipoleMoment", "ElectricFieldStrength", "ElectricInductance",
|
149
|
+
"ElectricPotential", "ElectricResistance", "ElectricalConductance",
|
150
|
+
"ElectricalPermittivity", "ElectricalResistivity", "EnergyFlux",
|
151
|
+
"EnergyPerUnitArea", "ForceBody", "ForcePerUnitMass",
|
152
|
+
"FrequencyVoltageRatio", "FuelConsumption", "HeatOfCombustion",
|
153
|
+
"HeatOfFusion", "HeatOfVaporization", "HeatTransferCoefficient",
|
154
|
+
"Illuminance", "KineticEnergyOfTurbulence", "LinearMassDensity",
|
155
|
+
"LinearMomentum", "LuminanceSelf", "LuminousFlux", "LuminousIntensity",
|
156
|
+
"MagneticField", "MagneticFlux", "MagneticInductionFieldStrength",
|
157
|
+
"MagneticMoment", "MagneticPermeability", "MagnetomotiveForce",
|
158
|
+
"MassDensity", "MassFlowRate", "MassFlux", "MassFractionOfI",
|
159
|
+
"MassTransferCoefficient", "MolalityOfSoluteI", "MolarConcentrationByMass",
|
160
|
+
"MolarFlowRate", "MolarFlux", "MolarHeatCapacity", "MolarityOfI",
|
161
|
+
"MoleFractionOfI", "MomentOfInertia", "MomentumFlowRate", "MomentumFlux",
|
162
|
+
"NormalityOfSolution", "ParticleDensity", "Permeability",
|
163
|
+
"PhotonEmissionRate", "PowerPerUnitMass", "PowerPerUnitVolume",
|
164
|
+
"RadiationDoseEquivalent", "RadiationExposure", "Radioactivity",
|
165
|
+
"SecondMomentOfArea", "SecondRadiationConstantPlanck", "SpecificEnthalpy",
|
166
|
+
"SpecificGravity", "SpecificHeatCapacityConstantPressure",
|
167
|
+
"SpecificLength", "SpecificSurface", "SpecificVolume", "Stress",
|
168
|
+
"SurfaceMassDensity", "SurfaceTension", "ThermalConductivity", "Torque",
|
169
|
+
"TurbulenceEnergyDissipationRate", "VelocityAngular", "VelocityLinear",
|
170
|
+
"ViscosityDynamic", "ViscosityKinematic", "VolumeFractionOfI",
|
171
|
+
"VolumetricCalorificHeatingValue", "VolumetricCoefficientOfExpansion",
|
172
|
+
"VolumetricFlowRate", "VolumetricFlux", "VolumetricMassFlowRate",
|
173
|
+
"Wavenumber",
|
174
|
+
]
|
175
|
+
|
@@ -0,0 +1,184 @@
|
|
1
|
+
"""
|
2
|
+
Dimension System
|
3
|
+
================
|
4
|
+
|
5
|
+
Compile-time dimensional analysis using type system for ultra-fast operations.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from dataclasses import dataclass
|
9
|
+
from enum import IntEnum
|
10
|
+
from typing import final
|
11
|
+
|
12
|
+
|
13
|
+
class BaseDimension(IntEnum):
|
14
|
+
"""Base dimensions as prime numbers for efficient bit operations."""
|
15
|
+
LENGTH = 2
|
16
|
+
MASS = 3
|
17
|
+
TIME = 5
|
18
|
+
CURRENT = 7
|
19
|
+
TEMPERATURE = 11
|
20
|
+
AMOUNT = 13
|
21
|
+
LUMINOSITY = 17
|
22
|
+
|
23
|
+
|
24
|
+
@final
|
25
|
+
@dataclass(frozen=True)
|
26
|
+
class DimensionSignature:
|
27
|
+
"""Immutable dimension signature for zero-cost dimensional analysis."""
|
28
|
+
|
29
|
+
# Store as bit pattern for ultra-fast comparison
|
30
|
+
_signature: int = 1
|
31
|
+
|
32
|
+
@classmethod
|
33
|
+
def create(cls, length=0, mass=0, time=0, current=0, temp=0, amount=0, luminosity=0):
|
34
|
+
"""Create dimension from exponents."""
|
35
|
+
signature = 1
|
36
|
+
if length != 0:
|
37
|
+
signature *= BaseDimension.LENGTH ** length
|
38
|
+
if mass != 0:
|
39
|
+
signature *= BaseDimension.MASS ** mass
|
40
|
+
if time != 0:
|
41
|
+
signature *= BaseDimension.TIME ** time
|
42
|
+
if current != 0:
|
43
|
+
signature *= BaseDimension.CURRENT ** current
|
44
|
+
if temp != 0:
|
45
|
+
signature *= BaseDimension.TEMPERATURE ** temp
|
46
|
+
if amount != 0:
|
47
|
+
signature *= BaseDimension.AMOUNT ** amount
|
48
|
+
if luminosity != 0:
|
49
|
+
signature *= BaseDimension.LUMINOSITY ** luminosity
|
50
|
+
|
51
|
+
return cls(signature)
|
52
|
+
|
53
|
+
def __mul__(self, other):
|
54
|
+
return DimensionSignature(self._signature * other._signature)
|
55
|
+
|
56
|
+
def __truediv__(self, other):
|
57
|
+
return DimensionSignature(self._signature // other._signature)
|
58
|
+
|
59
|
+
def __pow__(self, power):
|
60
|
+
return DimensionSignature(self._signature ** power)
|
61
|
+
|
62
|
+
def is_compatible(self, other):
|
63
|
+
"""Ultra-fast dimensional compatibility check."""
|
64
|
+
return self._signature == other._signature
|
65
|
+
|
66
|
+
def __eq__(self, other):
|
67
|
+
"""Fast equality check for dimensions."""
|
68
|
+
return isinstance(other, DimensionSignature) and self._signature == other._signature
|
69
|
+
|
70
|
+
def __hash__(self):
|
71
|
+
"""Enable dimensions as dictionary keys."""
|
72
|
+
return hash(self._signature)
|
73
|
+
|
74
|
+
|
75
|
+
# Pre-defined dimension constants (alphabetically ordered)
|
76
|
+
ABSORBED_DOSE = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
|
77
|
+
ACCELERATION = DimensionSignature.create(length=1, time=-2) # L T^-2
|
78
|
+
ACTIVATION_ENERGY = DimensionSignature.create(amount=-1, length=2, time=-2) # N^-1 L^2 T^-2
|
79
|
+
AMOUNT = DimensionSignature.create(amount=1) # N
|
80
|
+
AMOUNT_OF_SUBSTANCE = DimensionSignature.create(amount=1) # N
|
81
|
+
ANGLE_PLANE = DimensionSignature.create() # Dimensionless
|
82
|
+
ANGLE_SOLID = DimensionSignature.create() # Dimensionless
|
83
|
+
ANGULAR_ACCELERATION = DimensionSignature.create(time=-2) # T^-2
|
84
|
+
ANGULAR_MOMENTUM = DimensionSignature.create(length=2, mass=1, time=-1) # L^2 M T^-1
|
85
|
+
AREA = DimensionSignature.create(length=2) # L^2
|
86
|
+
AREA_PER_UNIT_VOLUME = DimensionSignature.create(length=-1) # L^-1
|
87
|
+
ATOMIC_WEIGHT = DimensionSignature.create(amount=-1, mass=1) # N^-1 M
|
88
|
+
CONCENTRATION = DimensionSignature.create(length=-3, mass=1) # L^-3 M
|
89
|
+
CURRENT = DimensionSignature.create(current=1) # A
|
90
|
+
DIMENSIONLESS = DimensionSignature.create() # Dimensionless
|
91
|
+
DYNAMIC_FLUIDITY = DimensionSignature.create(length=1, mass=-1, time=1) # L M^-1 T
|
92
|
+
ELECTRICAL_CONDUCTANCE = DimensionSignature.create(current=2, length=-2, mass=-1, time=3) # A^2 L^-2 M^-1 T^3
|
93
|
+
ELECTRICAL_PERMITTIVITY = DimensionSignature.create(current=2, length=-3, mass=-1, time=4) # A^2 L^-3 M^-1 T^4
|
94
|
+
ELECTRICAL_RESISTIVITY = DimensionSignature.create(current=-2, length=3, mass=1, time=-3) # A^-2 L^3 M T^-3
|
95
|
+
ELECTRIC_CAPACITANCE = DimensionSignature.create(current=2, length=-2, mass=-1, time=4) # A^2 L^-2 M^-1 T^4
|
96
|
+
ELECTRIC_CHARGE = DimensionSignature.create(amount=-1, current=1, time=1) # N^-1 A T
|
97
|
+
ELECTRIC_CURRENT_INTENSITY = DimensionSignature.create(current=1) # A
|
98
|
+
ELECTRIC_DIPOLE_MOMENT = DimensionSignature.create(current=1, length=1, time=1) # A L T
|
99
|
+
ELECTRIC_FIELD_STRENGTH = DimensionSignature.create(current=-1, length=1, mass=1, time=-3) # A^-1 L M T^-3
|
100
|
+
ELECTRIC_INDUCTANCE = DimensionSignature.create(current=-2, length=2, mass=1, time=-2) # A^-2 L^2 M T^-2
|
101
|
+
ELECTRIC_POTENTIAL = DimensionSignature.create(current=-1, length=2, mass=1, time=-3) # A^-1 L^2 M T^-3
|
102
|
+
ELECTRIC_RESISTANCE = DimensionSignature.create(current=-2, length=2, mass=1, time=-3) # A^-2 L^2 M T^-3
|
103
|
+
ENERGY_FLUX = DimensionSignature.create(mass=1, time=-3) # M T^-3
|
104
|
+
ENERGY_HEAT_WORK = DimensionSignature.create(length=2, mass=1, time=-2) # L^2 M T^-2
|
105
|
+
ENERGY_PER_UNIT_AREA = DimensionSignature.create(mass=1, time=-2) # M T^-2
|
106
|
+
FORCE = DimensionSignature.create(length=1, mass=1, time=-2) # L M T^-2
|
107
|
+
FORCE_BODY = DimensionSignature.create(length=-2, mass=1, time=-2) # L^-2 M T^-2
|
108
|
+
FORCE_PER_UNIT_MASS = DimensionSignature.create(length=1, time=-2) # L T^-2
|
109
|
+
FREQUENCY_VOLTAGE_RATIO = DimensionSignature.create(current=1, length=-2, mass=-1, time=3) # A L^-2 M^-1 T^3
|
110
|
+
FUEL_CONSUMPTION = DimensionSignature.create(length=-2) # L^-2
|
111
|
+
HEAT_OF_COMBUSTION = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
|
112
|
+
HEAT_OF_FUSION = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
|
113
|
+
HEAT_OF_VAPORIZATION = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
|
114
|
+
HEAT_TRANSFER_COEFFICIENT = DimensionSignature.create(mass=1, temp=-1, time=-3) # M Θ^-1 T^-3
|
115
|
+
ILLUMINANCE = DimensionSignature.create(length=-2, luminosity=1) # L^-2 J
|
116
|
+
KINETIC_ENERGY_OF_TURBULENCE = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
|
117
|
+
LENGTH = DimensionSignature.create(length=1) # L
|
118
|
+
LINEAR_MASS_DENSITY = DimensionSignature.create(length=-1, mass=1) # L^-1 M
|
119
|
+
LINEAR_MOMENTUM = DimensionSignature.create(length=1, mass=1, time=-1) # L M T^-1
|
120
|
+
LUMINANCE_SELF = DimensionSignature.create(length=-2, luminosity=1) # L^-2 J
|
121
|
+
LUMINOSITY = DimensionSignature.create(luminosity=1) # J
|
122
|
+
LUMINOUS_FLUX = DimensionSignature.create(luminosity=1) # J
|
123
|
+
LUMINOUS_INTENSITY = DimensionSignature.create(luminosity=1) # J
|
124
|
+
MAGNETIC_FIELD = DimensionSignature.create(current=1, length=-1) # A L^-1
|
125
|
+
MAGNETIC_FLUX = DimensionSignature.create(current=-1, length=2, mass=1, time=-2) # A^-1 L^2 M T^-2
|
126
|
+
MAGNETIC_INDUCTION_FIELD_STRENGTH = DimensionSignature.create(current=-1, mass=1, time=-2) # A^-1 M T^-2
|
127
|
+
MAGNETIC_MOMENT = DimensionSignature.create(current=1, length=2) # A L^2
|
128
|
+
MAGNETIC_PERMEABILITY = DimensionSignature.create(current=-2, length=2, mass=1, time=-2) # A^-2 L^2 M T^-2
|
129
|
+
MAGNETOMOTIVE_FORCE = DimensionSignature.create(current=1) # A
|
130
|
+
MASS = DimensionSignature.create(mass=1) # M
|
131
|
+
MASS_DENSITY = DimensionSignature.create(length=-3, mass=1) # L^-3 M
|
132
|
+
MASS_FLOW_RATE = DimensionSignature.create(mass=1, time=-1) # M T^-1
|
133
|
+
MASS_FLUX = DimensionSignature.create(length=-2, mass=1, time=-1) # L^-2 M T^-1
|
134
|
+
MASS_FRACTION_OF_I = DimensionSignature.create() # Dimensionless
|
135
|
+
MASS_TRANSFER_COEFFICIENT = DimensionSignature.create(length=-2, mass=1, time=-1) # L^-2 M T^-1
|
136
|
+
MOLALITY_OF_SOLUTE_I = DimensionSignature.create(amount=1, mass=-1) # N M^-1
|
137
|
+
MOLARITY_OF_I = DimensionSignature.create(amount=1, length=-3) # N L^-3
|
138
|
+
MOLAR_CONCENTRATION_BY_MASS = DimensionSignature.create(amount=1) # N
|
139
|
+
MOLAR_FLOW_RATE = DimensionSignature.create(amount=1, time=-1) # N T^-1
|
140
|
+
MOLAR_FLUX = DimensionSignature.create(amount=1, length=-2, time=-1) # N L^-2 T^-1
|
141
|
+
MOLAR_HEAT_CAPACITY = DimensionSignature.create(amount=-1, length=2, temp=-1, time=-2) # N^-1 L^2 Θ^-1 T^-2
|
142
|
+
MOLE_FRACTION_OF_I = DimensionSignature.create() # Dimensionless
|
143
|
+
MOMENTUM_FLOW_RATE = DimensionSignature.create(length=1, mass=1, time=-2) # L M T^-2
|
144
|
+
MOMENTUM_FLUX = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
|
145
|
+
MOMENT_OF_INERTIA = DimensionSignature.create(length=2, mass=1) # L^2 M
|
146
|
+
NORMALITY_OF_SOLUTION = DimensionSignature.create(amount=1, length=-3) # N L^-3
|
147
|
+
PARTICLE_DENSITY = DimensionSignature.create(length=-3) # L^-3
|
148
|
+
PERMEABILITY = DimensionSignature.create(length=2) # L^2
|
149
|
+
PHOTON_EMISSION_RATE = DimensionSignature.create(length=-2, time=-1) # L^-2 T^-1
|
150
|
+
POWER_PER_UNIT_MASS = DimensionSignature.create(length=2, time=-3) # L^2 T^-3
|
151
|
+
POWER_PER_UNIT_VOLUME = DimensionSignature.create(length=-1, mass=1, time=-3) # L^-1 M T^-3
|
152
|
+
POWER_THERMAL_DUTY = DimensionSignature.create(length=2, mass=1, time=-3) # L^2 M T^-3
|
153
|
+
PRESSURE = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
|
154
|
+
RADIATION_DOSE_EQUIVALENT = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
|
155
|
+
RADIATION_EXPOSURE = DimensionSignature.create(current=1, mass=-1, time=1) # A M^-1 T
|
156
|
+
RADIOACTIVITY = DimensionSignature.create(time=-1) # T^-1
|
157
|
+
SECOND_MOMENT_OF_AREA = DimensionSignature.create(length=4) # L^4
|
158
|
+
SECOND_RADIATION_CONSTANT_PLANCK = DimensionSignature.create(length=1, temp=1) # L Θ
|
159
|
+
SPECIFIC_ENTHALPY = DimensionSignature.create(length=2, time=-2) # L^2 T^-2
|
160
|
+
SPECIFIC_GRAVITY = DimensionSignature.create() # Dimensionless
|
161
|
+
SPECIFIC_HEAT_CAPACITY_CONSTANT_PRESSURE = DimensionSignature.create(length=2, mass=1, temp=-1, time=-2) # L^2 M Θ^-1 T^-2
|
162
|
+
SPECIFIC_LENGTH = DimensionSignature.create(length=1, mass=-1) # L M^-1
|
163
|
+
SPECIFIC_SURFACE = DimensionSignature.create(length=2, mass=-1) # L^2 M^-1
|
164
|
+
SPECIFIC_VOLUME = DimensionSignature.create(length=3, mass=-1) # L^3 M^-1
|
165
|
+
STRESS = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
|
166
|
+
SURFACE_MASS_DENSITY = DimensionSignature.create(length=-2, mass=1) # L^-2 M
|
167
|
+
SURFACE_TENSION = DimensionSignature.create(mass=1, time=-2) # M T^-2
|
168
|
+
TEMPERATURE = DimensionSignature.create(temp=1) # Θ
|
169
|
+
THERMAL_CONDUCTIVITY = DimensionSignature.create(length=1, mass=1, temp=1, time=-3) # L M Θ T^-3
|
170
|
+
TIME = DimensionSignature.create(time=1) # T
|
171
|
+
TORQUE = DimensionSignature.create(length=2, mass=1, time=-2) # L^2 M T^-2
|
172
|
+
TURBULENCE_ENERGY_DISSIPATION_RATE = DimensionSignature.create(length=2, time=-3) # L^2 T^-3
|
173
|
+
VELOCITY_ANGULAR = DimensionSignature.create(time=-1) # T^-1
|
174
|
+
VELOCITY_LINEAR = DimensionSignature.create(length=1, time=-1) # L T^-1
|
175
|
+
VISCOSITY_DYNAMIC = DimensionSignature.create(length=-1, mass=1, time=-1) # L^-1 M T^-1
|
176
|
+
VISCOSITY_KINEMATIC = DimensionSignature.create(length=2, time=-1) # L^2 T^-1
|
177
|
+
VOLUME = DimensionSignature.create(length=3) # L^3
|
178
|
+
VOLUMETRIC_CALORIFIC_HEATING_VALUE = DimensionSignature.create(length=-1, mass=1, time=-2) # L^-1 M T^-2
|
179
|
+
VOLUMETRIC_COEFFICIENT_OF_EXPANSION = DimensionSignature.create(length=-3, mass=1, temp=-1) # L^-3 M Θ^-1
|
180
|
+
VOLUMETRIC_FLOW_RATE = DimensionSignature.create(length=3, time=-1) # L^3 T^-1
|
181
|
+
VOLUMETRIC_FLUX = DimensionSignature.create(length=1, time=-1) # L T^-1
|
182
|
+
VOLUMETRIC_MASS_FLOW_RATE = DimensionSignature.create(length=-3, mass=1, time=-1) # L^-3 M T^-1
|
183
|
+
VOLUME_FRACTION_OF_I = DimensionSignature.create() # Dimensionless
|
184
|
+
WAVENUMBER = DimensionSignature.create(length=-1) # L^-1
|
@@ -0,0 +1,229 @@
|
|
1
|
+
"""
|
2
|
+
SI Prefix System
|
3
|
+
================
|
4
|
+
|
5
|
+
Standard SI prefixes for unit multiplication/division.
|
6
|
+
Provides systematic handling of metric prefixes like kilo-, milli-, micro-, etc.
|
7
|
+
"""
|
8
|
+
|
9
|
+
from dataclasses import dataclass
|
10
|
+
from enum import Enum
|
11
|
+
|
12
|
+
|
13
|
+
@dataclass(frozen=True)
|
14
|
+
class SIPrefix:
|
15
|
+
"""
|
16
|
+
Standard SI prefix definition.
|
17
|
+
|
18
|
+
Attributes:
|
19
|
+
name: Full prefix name (e.g., "kilo", "milli")
|
20
|
+
symbol: Standard symbol (e.g., "k", "m")
|
21
|
+
factor: Multiplication factor relative to base unit (e.g., 1000, 0.001)
|
22
|
+
"""
|
23
|
+
name: str
|
24
|
+
symbol: str
|
25
|
+
factor: float
|
26
|
+
|
27
|
+
def apply_to_name(self, base_name: str) -> str:
|
28
|
+
"""Apply prefix to a base unit name."""
|
29
|
+
if not self.name:
|
30
|
+
return base_name
|
31
|
+
return f"{self.name}{base_name}"
|
32
|
+
|
33
|
+
def apply_to_symbol(self, base_symbol: str) -> str:
|
34
|
+
"""Apply prefix to a base unit symbol."""
|
35
|
+
if not self.symbol:
|
36
|
+
return base_symbol
|
37
|
+
return f"{self.symbol}{base_symbol}"
|
38
|
+
|
39
|
+
|
40
|
+
class StandardPrefixes(Enum):
|
41
|
+
"""
|
42
|
+
Standard SI prefixes with their multiplication factors.
|
43
|
+
|
44
|
+
From yotta (10^24) to yocto (10^-24).
|
45
|
+
"""
|
46
|
+
# Larger prefixes (10^3 to 10^24)
|
47
|
+
YOTTA = SIPrefix("yotta", "Y", 1e24)
|
48
|
+
ZETTA = SIPrefix("zetta", "Z", 1e21)
|
49
|
+
EXA = SIPrefix("exa", "E", 1e18)
|
50
|
+
PETA = SIPrefix("peta", "P", 1e15)
|
51
|
+
TERA = SIPrefix("tera", "T", 1e12)
|
52
|
+
GIGA = SIPrefix("giga", "G", 1e9)
|
53
|
+
MEGA = SIPrefix("mega", "M", 1e6)
|
54
|
+
KILO = SIPrefix("kilo", "k", 1e3)
|
55
|
+
HECTO = SIPrefix("hecto", "h", 1e2)
|
56
|
+
DECA = SIPrefix("deca", "da", 1e1)
|
57
|
+
|
58
|
+
# Base (no prefix)
|
59
|
+
NONE = SIPrefix("", "", 1.0)
|
60
|
+
|
61
|
+
# Smaller prefixes (10^-1 to 10^-24)
|
62
|
+
DECI = SIPrefix("deci", "d", 1e-1)
|
63
|
+
CENTI = SIPrefix("centi", "c", 1e-2)
|
64
|
+
MILLI = SIPrefix("milli", "m", 1e-3)
|
65
|
+
MICRO = SIPrefix("micro", "μ", 1e-6)
|
66
|
+
NANO = SIPrefix("nano", "n", 1e-9)
|
67
|
+
PICO = SIPrefix("pico", "p", 1e-12)
|
68
|
+
FEMTO = SIPrefix("femto", "f", 1e-15)
|
69
|
+
ATTO = SIPrefix("atto", "a", 1e-18)
|
70
|
+
ZEPTO = SIPrefix("zepto", "z", 1e-21)
|
71
|
+
YOCTO = SIPrefix("yocto", "y", 1e-24)
|
72
|
+
|
73
|
+
|
74
|
+
# Common prefix groups for different unit types
|
75
|
+
COMMON_LENGTH_PREFIXES = [
|
76
|
+
StandardPrefixes.KILO,
|
77
|
+
StandardPrefixes.CENTI,
|
78
|
+
StandardPrefixes.MILLI,
|
79
|
+
StandardPrefixes.MICRO,
|
80
|
+
StandardPrefixes.NANO,
|
81
|
+
]
|
82
|
+
|
83
|
+
COMMON_MASS_PREFIXES = [
|
84
|
+
StandardPrefixes.KILO, # Note: kilogram is the SI base unit
|
85
|
+
StandardPrefixes.MILLI,
|
86
|
+
StandardPrefixes.MICRO,
|
87
|
+
]
|
88
|
+
|
89
|
+
COMMON_TIME_PREFIXES = [
|
90
|
+
StandardPrefixes.MILLI,
|
91
|
+
StandardPrefixes.MICRO,
|
92
|
+
StandardPrefixes.NANO,
|
93
|
+
StandardPrefixes.PICO,
|
94
|
+
]
|
95
|
+
|
96
|
+
COMMON_ELECTRIC_PREFIXES = [
|
97
|
+
StandardPrefixes.KILO,
|
98
|
+
StandardPrefixes.MILLI,
|
99
|
+
StandardPrefixes.MICRO,
|
100
|
+
StandardPrefixes.NANO,
|
101
|
+
StandardPrefixes.PICO,
|
102
|
+
]
|
103
|
+
|
104
|
+
COMMON_ENERGY_PREFIXES = [
|
105
|
+
StandardPrefixes.KILO,
|
106
|
+
StandardPrefixes.MEGA,
|
107
|
+
StandardPrefixes.GIGA,
|
108
|
+
]
|
109
|
+
|
110
|
+
COMMON_POWER_PREFIXES = [
|
111
|
+
StandardPrefixes.KILO,
|
112
|
+
StandardPrefixes.MEGA,
|
113
|
+
StandardPrefixes.GIGA,
|
114
|
+
StandardPrefixes.MILLI,
|
115
|
+
StandardPrefixes.MICRO,
|
116
|
+
]
|
117
|
+
|
118
|
+
COMMON_PRESSURE_PREFIXES = [
|
119
|
+
StandardPrefixes.KILO,
|
120
|
+
StandardPrefixes.MEGA,
|
121
|
+
StandardPrefixes.GIGA,
|
122
|
+
]
|
123
|
+
|
124
|
+
|
125
|
+
def get_prefix_by_name(name: str) -> SIPrefix | None:
|
126
|
+
"""Get a prefix by its name (e.g., 'kilo', 'milli')."""
|
127
|
+
for prefix_enum in StandardPrefixes:
|
128
|
+
if prefix_enum.value.name == name:
|
129
|
+
return prefix_enum.value
|
130
|
+
return None
|
131
|
+
|
132
|
+
|
133
|
+
def get_prefix_by_symbol(symbol: str) -> SIPrefix | None:
|
134
|
+
"""Get a prefix by its symbol (e.g., 'k', 'm')."""
|
135
|
+
for prefix_enum in StandardPrefixes:
|
136
|
+
if prefix_enum.value.symbol == symbol:
|
137
|
+
return prefix_enum.value
|
138
|
+
return None
|
139
|
+
|
140
|
+
|
141
|
+
def get_prefix_by_factor(factor: float, tolerance: float = 1e-10) -> SIPrefix | None:
|
142
|
+
"""Get a prefix by its multiplication factor."""
|
143
|
+
for prefix_enum in StandardPrefixes:
|
144
|
+
if abs(prefix_enum.value.factor - factor) < tolerance:
|
145
|
+
return prefix_enum.value
|
146
|
+
return None
|
147
|
+
|
148
|
+
|
149
|
+
# Define which units should get automatic prefixes
|
150
|
+
PREFIXABLE_UNITS = {
|
151
|
+
# Base SI units
|
152
|
+
'meter': COMMON_LENGTH_PREFIXES,
|
153
|
+
'gram': COMMON_MASS_PREFIXES,
|
154
|
+
'second': COMMON_TIME_PREFIXES,
|
155
|
+
'ampere': COMMON_ELECTRIC_PREFIXES,
|
156
|
+
'kelvin': [], # Temperature usually doesn't use prefixes
|
157
|
+
'mole': [
|
158
|
+
StandardPrefixes.MILLI,
|
159
|
+
StandardPrefixes.MICRO
|
160
|
+
],
|
161
|
+
'candela': [], # Luminous intensity rarely uses prefixes
|
162
|
+
|
163
|
+
# Derived SI units
|
164
|
+
'pascal': COMMON_PRESSURE_PREFIXES,
|
165
|
+
'joule': COMMON_ENERGY_PREFIXES,
|
166
|
+
'watt': COMMON_POWER_PREFIXES,
|
167
|
+
'coulomb': COMMON_ELECTRIC_PREFIXES,
|
168
|
+
'volt': COMMON_ELECTRIC_PREFIXES,
|
169
|
+
'farad': [
|
170
|
+
StandardPrefixes.MILLI,
|
171
|
+
StandardPrefixes.MICRO,
|
172
|
+
StandardPrefixes.NANO,
|
173
|
+
StandardPrefixes.PICO
|
174
|
+
],
|
175
|
+
'ohm': [
|
176
|
+
StandardPrefixes.KILO,
|
177
|
+
StandardPrefixes.MEGA,
|
178
|
+
StandardPrefixes.MILLI
|
179
|
+
],
|
180
|
+
'siemens': [
|
181
|
+
StandardPrefixes.MILLI,
|
182
|
+
StandardPrefixes.MICRO
|
183
|
+
],
|
184
|
+
'weber': [
|
185
|
+
StandardPrefixes.MILLI,
|
186
|
+
StandardPrefixes.MICRO
|
187
|
+
],
|
188
|
+
'tesla': [
|
189
|
+
StandardPrefixes.MILLI,
|
190
|
+
StandardPrefixes.MICRO,
|
191
|
+
StandardPrefixes.NANO
|
192
|
+
],
|
193
|
+
'henry': [
|
194
|
+
StandardPrefixes.MILLI,
|
195
|
+
StandardPrefixes.MICRO,
|
196
|
+
StandardPrefixes.NANO
|
197
|
+
],
|
198
|
+
'lumen': [],
|
199
|
+
'lux': [],
|
200
|
+
'becquerel': [
|
201
|
+
StandardPrefixes.KILO,
|
202
|
+
StandardPrefixes.MEGA,
|
203
|
+
StandardPrefixes.GIGA
|
204
|
+
],
|
205
|
+
'gray': [
|
206
|
+
StandardPrefixes.MILLI,
|
207
|
+
StandardPrefixes.MICRO
|
208
|
+
],
|
209
|
+
'sievert': [
|
210
|
+
StandardPrefixes.MILLI,
|
211
|
+
StandardPrefixes.MICRO
|
212
|
+
],
|
213
|
+
'hertz': [
|
214
|
+
StandardPrefixes.KILO,
|
215
|
+
StandardPrefixes.MEGA,
|
216
|
+
StandardPrefixes.GIGA
|
217
|
+
],
|
218
|
+
'newton': [
|
219
|
+
StandardPrefixes.KILO,
|
220
|
+
StandardPrefixes.MILLI
|
221
|
+
],
|
222
|
+
'bar': [
|
223
|
+
StandardPrefixes.MILLI
|
224
|
+
], # Common non-SI unit
|
225
|
+
'liter': [
|
226
|
+
StandardPrefixes.MILLI,
|
227
|
+
StandardPrefixes.MICRO
|
228
|
+
], # Common non-SI unit
|
229
|
+
}
|