mcpField
P
pint-units

pint-units

github.com/soljourner开发9543 次安装51 周前更新
代码仓库

关于 pint-units

pint-units 是介绍 Python Pint 的技能,面向需要处理物理量的工程与科学计算。内容涵盖单位转换、量纲校验及带单位运算。

主要功能

  1. 01自动转换兼容单位
  2. 02检查量纲一致性
  3. 03执行带单位的算术运算
  4. 04与 NumPy 数组集成
  5. 05定义自定义单位
  6. 06处理温度及偏移单位

适用场景

  1. 01转换工程计算中的压力与流量
  2. 02验证速度、力等公式的量纲
  3. 03对 NumPy 数组进行带单位计算

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/soljourner/claude-engineering-skills --skill pint-units

安装后在 Claude Code 中输入/pint-units确认已加载。

附带文件examples.py

详细介绍

Pint Units 技能

概述

Pint 是一个用于处理带单位物理量的 Python 软件包。它提供:

  • 自动单位换算
  • 量纲分析和一致性检查
  • 支持单位的算术运算
  • 与 NumPy 数组集成
  • 支持自定义单位定义
  • 温度换算(包括偏移单位)
  • 科学计数法和格式化

Pint 可消除单位换算错误,并确保工程计算中的量纲一致性,因此对于任何涉及物理量的技术工作都不可或缺。

安装

pip install pint

要与 NumPy 和 Pandas 集成:

pip install pint[numpy]

基本用法

创建物理量

Pint 中的物理量由一个大小(数值)和一个单位组成。

from pint import UnitRegistry

# Create unit registry (do this once per module)
ureg = UnitRegistry()

# Define quantities with units
distance = 100 * ureg.meter
time = 5 * ureg.second
pressure = 50 * ureg.psi

# Alternative syntax using string parsing
flow_rate = ureg('250 gallons/minute')
temperature = ureg('75 degF')
viscosity = ureg('1.5 centipoise')

# Access magnitude and units
print(f"Distance magnitude: {distance.magnitude}")  # 100
print(f"Distance units: {distance.units}")  # meter
单位换算

自动在兼容单位之间换算:

# Length conversions
distance = 100 * ureg.meter
print(distance.to('feet'))  # 328.084 foot
print(distance.to('kilometer'))  # 0.1 kilometer

# Pressure conversions
pressure = 100 * ureg.psi
print(pressure.to('bar'))  # 6.895 bar
print(pressure.to('pascal'))  # 689475.7 pascal

# Flow rate conversions
flow = 500 * ureg.gallons / ureg.minute
print(flow.to('liter/second'))  # 31.546 liter/second
print(flow.to('m**3/hour'))  # 113.562 meter**3/hour

# Temperature conversions (handles offset units)
temp = 75 * ureg.degF
print(temp.to('degC'))  # 23.889 degree_Celsius
print(temp.to('kelvin'))  # 297.039 kelvin

量纲分析

Pint 可确保计算中的量纲一致性:

# Velocity = Distance / Time
distance = 100 * ureg.meter
time = 5 * ureg.second
velocity = distance / time
print(velocity)  # 20.0 meter/second

# Force = Mass × Acceleration
mass = 10 * ureg.kg
acceleration = 9.81 * ureg.meter / ureg.second**2
force = mass * acceleration
print(force)  # 98.1 kilogram·meter/second²
print(force.to('newton'))  # 98.1 newton

# Dimensional consistency check
try:
    invalid = (100 * ureg.meter) + (50 * ureg.second)  # ❌ ERROR
except Exception as e:
    print(f"Error: Cannot add length and time")

# Correct operation
total_distance = (100 * ureg.meter) + (50 * ureg.feet)  # ✓ OK
print(total_distance)  # 115.24 meter

支持单位的计算

流体流量计算
# Calculate volumetric flow rate from velocity and area
velocity = 3.5 * ureg.meter / ureg.second
diameter = 150 * ureg.millimeter
area = 3.14159 * (diameter/2)**2

flow_rate = velocity * area
print(flow_rate.to('liter/second'))  # 61.86 liter/second
print(flow_rate.to('gpm'))  # 1638.1 gallon/minute

# Reynolds number calculation
density = 998 * ureg.kg / ureg.meter**3
viscosity = 1.0 * ureg.centipoise  # Common unit in industry
Re = (density * velocity * diameter) / viscosity
print(Re.to_base_units())  # Dimensionless: 523170.0
泵功率计算
# Hydraulic power: P = ρ × g × Q × H
flow_rate = 100 * ureg.meter**3 / ureg.hour
head = 50 * ureg.meter
density = 1000 * ureg.kg / ureg.meter**3
gravity = 9.81 * ureg.meter / ureg.second**2

hydraulic_power = density * gravity * flow_rate * head
print(hydraulic_power.to('kilowatt'))  # 13.625 kilowatt
print(hydraulic_power.to('horsepower'))  # 18.27 horsepower

# With pump efficiency
efficiency = 0.75 * ureg.dimensionless
shaft_power = hydraulic_power / efficiency
print(shaft_power.to('kilowatt'))  # 18.17 kilowatt
压降计算
# Darcy-Weisbach equation: ΔP = f × (L/D) × (ρV²/2)
friction_factor = 0.018 * ureg.dimensionless
length = 100 * ureg.meter
diameter = 0.15 * ureg.meter
velocity = 2.5 * ureg.meter / ureg.second
density = 1000 * ureg.kg / ureg.meter**3

pressure_drop = friction_factor * (length/diameter) * (density * velocity**2 / 2)
print(pressure_drop.to('pascal'))  # 37500.0 pascal
print(pressure_drop.to('psi'))  # 5.44 pound_force_per_square_inch
print(pressure_drop.to('bar'))  # 0.375 bar

# Convert to head loss
head_loss = pressure_drop / (density * gravity)
print(head_loss.to('meter'))  # 3.822 meter
print(head_loss.to('feet'))  # 12.54 foot

处理数组

Pint 可与 NumPy 无缝集成,执行数组运算:

import numpy as np
from pint import UnitRegistry

ureg = UnitRegistry()

# Create array with units
flow_rates = np.array([50, 75, 100, 125, 150]) * ureg.gpm
heads = np.array([80, 75, 65, 50, 30]) * ureg.meter

# Array operations preserve units
powers = (flow_rates * heads * ureg.kg/ureg.meter**3 * 9.81*ureg.meter/ureg.second**2)
print(powers.to('kilowatt'))
# [2.48 3.72 4.95 6.19 7.43] kilowatt

# Statistical operations
mean_flow = np.mean(flow_rates)
std_flow = np.std(flow_rates)
print(f"Mean flow: {mean_flow.to('liter/minute'):.1f}")
print(f"Std dev: {std_flow.to('liter/minute'):.1f}")

# Unit-aware interpolation
target_head = 70 * ureg.meter
target_flow = np.interp(target_head.magnitude, heads[::-1].magnitude,
                        flow_rates[::-1].magnitude) * ureg.gpm
print(f"Flow at {target_head}: {target_flow.to('m**3/hour'):.1f}")

自定义单位定义

定义特定领域的单位:

# Add custom units to registry
ureg.define('barrel_oil = 42 * gallon = bbl')
ureg.define('standard_cubic_foot = foot**3 = scf')
ureg.define('darcy = centipoise * centimeter**2 / (second * atmosphere) = D')

# Use custom units
oil_volume = 1000 * ureg.barrel_oil
print(oil_volume.to('gallon'))  # 42000.0 gallon
print(oil_volume.to('liter'))  # 158987.3 liter

gas_flow = 5000 * ureg.standard_cubic_foot / ureg.day
print(gas_flow.to('m**3/hour'))  # 5.90 meter**3/hour

permeability = 100 * ureg.darcy
print(permeability.to_base_units())  # Base SI units

单位系统的上下文管理器

轻松切换单位系统:

from pint import UnitRegistry

ureg = UnitRegistry()

length = 100 * ureg.meter
mass = 50 * ureg.kg

# Default SI units
print(f"Length: {length}")  # 100 meter
print(f"Mass: {mass}")  # 50 kilogram

# Use US customary units
with ureg.context('US'):
    print(f"Length: {length.to('feet')}")  # 328.084 foot
    print(f"Mass: {mass.to('pound')}")  # 110.231 pound

# Use imperial units
with ureg.context('imperial'):
    print(f"Length: {length.to('yard')}")  # 109.361 yard

温度换算

正确处理绝对温度和相对温度:

# Absolute temperatures
temp1 = 25 * ureg.degC
temp2 = temp1.to('degF')
print(temp2)  # 77.0 degree_Fahrenheit

temp3 = 300 * ureg.kelvin
print(temp3.to('degC'))  # 26.85 degree_Celsius

# Temperature differences (delta)
temp_rise = ureg.Quantity(20, ureg.delta_degC)
print(temp_rise.to(ureg.delta_degF))  # 36.0 delta_degree_Fahrenheit

# Heat transfer calculation
mass = 10 * ureg.kg
specific_heat = 4.18 * ureg.kJ / (ureg.kg * ureg.kelvin)
temp_change = 50 * ureg.delta_degC

heat = mass * specific_heat * temp_change
print(heat.to('kJ'))  # 2090.0 kilojoule
print(heat.to('BTU'))  # 1981.9 BTU

格式化和显示

控制物理量的显示方式:

pressure = 150000 * ureg.pascal

# Default format
print(pressure)  # 150000 pascal

# Compact notation
print(f"{pressure:~}")  # 150000 Pa

# Specific precision
print(f"{pressure:.2f}")  # 150000.00 pascal

# Scientific notation
print(f"{pressure:~.2e}")  # 1.50e+05 Pa

# Pretty format
print(f"{pressure:~P}")  # 150000 Pa

# Custom format
print(f"{pressure.to('bar'):.3f~P}")  # 1.500 bar

常见工程单位换算

压力
pressure = 100 * ureg.psi
# Common conversions
print(pressure.to('bar'))  # 6.895 bar
print(pressure.to('kPa'))  # 689.476 kilopascal
print(pressure.to('MPa'))  # 0.689 megapascal
print(pressure.to('atm'))  # 6.805 atmosphere
print(pressure.to('mmHg'))  # 5171.5 millimeter_Hg
print(pressure.to('inch_H2O'))  # 2767.7 inch_H2O
流量
flow = 100 * ureg.gpm  # gallons per minute
# Common conversions
print(flow.to('liter/minute'))  # 378.541 liter/minute
print(flow.to('m**3/hour'))  # 22.712 meter**3/hour
print(flow.to('ft**3/second'))  # 0.223 foot**3/second
print(flow.to('barrel_oil/day'))  # 3428.57 barrel_oil/day (if defined)
黏度
# Dynamic viscosity
mu = 1.0 * ureg.centipoise
print(mu.to('pascal*second'))  # 0.001 pascal·second
print(mu.to('lbf*second/ft**2'))  # 2.089e-05 pound_force·second/foot²

# Kinematic viscosity
nu = 1.0 * ureg.centistokes
print(nu.to('m**2/second'))  # 1e-06 meter²/second
print(nu.to('ft**2/second'))  # 1.076e-05 foot²/second
能量和功率
energy = 100 * ureg.kWh
print(energy.to('MJ'))  # 360.0 megajoule
print(energy.to('BTU'))  # 341214.2 BTU
print(energy.to('therm'))  # 3.412 therm

power = 50 * ureg.horsepower
print(power.to('kilowatt'))  # 37.285 kilowatt
print(power.to('BTU/hour'))  # 127259.0 BTU/hour
质量流量
mass_flow = 1000 * ureg.kg / ureg.hour
print(mass_flow.to('lb/minute'))  # 36.74 pound/minute
print(mass_flow.to('ton/day'))  # 0.024 metric_ton/day
print(mass_flow.to('g/second'))  # 277.78 gram/second

最佳实践

  1. 仅创建一次 UnitRegistry:在模块级别定义 ureg = UnitRegistry(),不要在函数内部定义
  2. 使用基本单位存储:在数据库中使用一致的基本单位(SI)存储数值
  3. 验证输入单位:始终检查输入物理量是否具有预期的量纲
  4. 处理无量纲物理量:对于无单位比值,使用 ureg.dimensionless
  5. 在边界处换算:仅在展示结果时换算为显示单位
  6. 检查兼容性:使用 quantity.check(dimension) 验证量纲一致性
  7. 明确指定:使用明确的单位定义,不要依赖默认值
  8. 谨慎处理温度:对于温差,使用 delta_ 前缀;对于绝对温度则不使用

量纲一致性检查

def calculate_reynolds_number(velocity, diameter, density, viscosity):
    """
    Calculate Reynolds number with automatic dimensional checking.

    Re = ρVD/μ (dimensionless)
    """
    # Pint automatically checks dimensions
    Re = (density * velocity * diameter) / viscosity

    # Verify result is dimensionless
    assert Re.dimensionality == ureg.dimensionless.dimensionality

    # Return magnitude (pure number)
    return Re.to_base_units().magnitude

# Correct usage
rho = 1000 * ureg.kg / ureg.meter**3
V = 2.5 * ureg.meter / ureg.second
D = 0.15 * ureg.meter
mu = 1e-3 * ureg.pascal * ureg.second

Re = calculate_reynolds_number(V, D, rho, mu)
print(f"Reynolds number: {Re:.0f}")  # 375000

# Incorrect usage will raise error
try:
    Re_wrong = calculate_reynolds_number(V, D, rho, rho)  # Wrong dimension
except Exception as e:
    print("Error: Dimensional inconsistency detected")

与工程工作流集成

示例:泵性能曲线
import numpy as np
from pint import UnitRegistry

ureg = UnitRegistry()

def pump_curve(flow_rates, coefficients):
    """
    Calculate pump head from flow rate using curve fit.
    H = H0 - A*Q - B*Q²

    Parameters
    ----------
    flow_rates : Quantity array
        Flow rates with units
    coefficients : dict
        'H0', 'A', 'B' with appropriate units

    Returns
    -------
    heads : Quantity array
        Pump heads with units
    """
    H0 = coefficients['H0']
    A = coefficients['A']
    B = coefficients['B']

    heads = H0 - A * flow_rates - B * flow_rates**2
    return heads

# Define pump curve coefficients
coeffs = {
    'H0': 80 * ureg.meter,
    'A': 200 * ureg.meter / (ureg.meter**3/ureg.second),
    'B': 3000 * ureg.meter / (ureg.meter**3/ureg.second)**2
}

# Calculate performance at different flow rates
Q = np.linspace(0, 0.1, 11) * ureg.meter**3 / ureg.second
H = pump_curve(Q, coeffs)

# Display in different units
print("Flow (GPM)  Head (ft)  Head (m)")
print("-" * 40)
for q, h in zip(Q, H):
    print(f"{q.to('gpm'):8.0f~P}  {h.to('feet'):8.1f~P}  {h.to('meter'):7.1f~P}")

故障排除

问题:DimensionalityError

原因:尝试对单位不兼容的物理量进行相加或比较 解决方案:检查所有项是否具有相同量纲,或进行显式换算

问题:UndefinedUnitError

原因:使用注册表中未定义的单位 解决方案:使用 ureg.define() 定义自定义单位,或检查拼写

问题:偏移单位(温度)错误

原因:混用绝对温度单位和相对温度单位 解决方案:温差使用 delta_degC,绝对温度使用 degC

问题:计算中单位丢失

原因:在计算中过早使用 .magnitude 解决方案:在最终输出前,始终将物理量保留为 Pint 对象

速查卡

常用单位
数量单位
长度米、英尺、英寸、英里、千米
面积meter2、foot2、英亩、公顷
体积升、加仑、桶(石油)、ft3、m3
质量千克、磅、吨、吨(公制)
时间秒、分钟、小时、天
速度meter/second、ft/second、mph、kph
流量(体积)m3/hour、gpm、liter/minute、ft3/second
流量(质量)kg/second、lb/minute、ton/hour
压力帕斯卡、巴、psi、atm、mmHg
力牛顿、lbf、kgf
功率瓦、马力、BTU/hour
能量焦耳、kWh、BTU、卡路里
温度degC、degF、kelvin、rankine
黏度(动力)pascal*second、poise、centipoise
黏度(运动)m**2/second、stokes、centistokes
快速换算
# Create quantity
Q = 100 * ureg.gpm

# Convert
Q.to('liter/minute')  # To specific unit
Q.to_base_units()     # To SI base units
Q.to_compact()        # To compact SI (kilo, mega, etc)

# Check dimensionality
Q.dimensionality      # [length]³/[time]
Q.check('[volume]/[time]')  # Verify dimension

# Access components
Q.magnitude          # Numeric value
Q.units              # Unit object

参考资料

延伸阅读

  • NIST 特别出版物 811:《国际单位制(SI)使用指南》
  • ISO 80000:量和单位
  • 石油行业单位相关的 API 标准
  • 工程计算相关的 ASME 标准

评论

支持 Markdown