You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pint中程序化注册单位系统及实现LJ约化单位转换?

1. 在Pint中程序化定义单位系统

要创建像"real"这样的自定义单位系统,直接用Pint的UnitRegistry的add_system方法即可,指定系统对应的基础量单位:

from pint import UnitRegistry

# 初始化单位注册表
ureg = UnitRegistry()

# 定义"real"系统,指定各基础物理量的单位
ureg.add_system(
    "real",
    base_units={
        "mass": "gram/mole",
        "length": "angstrom",
        "time": "femtosecond",
        "temperature": "kelvin",
        "amount": "mole"
    }
)

# 可选:切换到"real"系统,之后默认单位会用系统内的定义
ureg.set_system("real")

# 验证玻尔兹曼常数的单位转换
boltzmann_const = ureg.boltzmann
print(boltzmann_const.to("kcal/(mole*kelvin)"))

定义完成后,所有带单位的量都可以通过to()方法转换到该系统下的单位,切换系统后也能直接用系统内的默认单位输出结果。

2. 转换为约化/LJ单位(遵循LAMMPS规则)

LAMMPS的LJ约化单位基于特征参数σ(长度)、ε(能量)、m₀(质量)推导,最优方案是用Pint的**上下文(Context)**实现——它能自动处理量纲匹配,支持正向/反向转换,比自定义转换函数更健壮。

实现代码:

from pint import UnitRegistry

ureg = UnitRegistry()

# 定义LJ特征参数(以氩原子为例,对应LAMMPS默认LJ参数)
sigma = 3.4 * ureg.angstrom
epsilon = 0.0103 * ureg.kcal / ureg.mole
m0 = 39.948 * ureg.gram / ureg.mole

# 创建LJ约化单位上下文
lj_context = ureg.Context("lj")

# 为各基础物理量添加转换规则
# 长度:L* = L/σ
lj_context.add_transformation(
    "[length]",
    lambda ureg, x: x / sigma,
    lambda ureg, x: x * sigma
)
# 质量:m* = m/m0
lj_context.add_transformation(
    "[mass]",
    lambda ureg, x: x / m0,
    lambda ureg, x: x * m0
)
# 能量:E* = E/ε
lj_context.add_transformation(
    "[energy]",
    lambda ureg, x: x / epsilon,
    lambda ureg, x: x * epsilon
)
# 温度:T* = kBT/ε
lj_context.add_transformation(
    "[temperature]",
    lambda ureg, x: (x * ureg.boltzmann).to("kcal/mole") / epsilon,
    lambda ureg, x: (x * epsilon / ureg.boltzmann).to("kelvin")
)
# 时间:t* = t * sqrt(m0/(εσ²))
lj_context.add_transformation(
    "[time]",
    lambda ureg, x: x * (m0 / (epsilon * sigma**2))**0.5,
    lambda ureg, x: x / (m0 / (epsilon * sigma**2))**0.5
)

# 将上下文注册到单位注册表
ureg.add_context(lj_context)

# 使用示例
# 转换长度到约化单位
length = 10 * ureg.angstrom
with ureg.context("lj"):
    print(length.to("dimensionless"))  # 输出≈2.941(10/3.4)

# 转换温度到约化单位
temp = 300 * ureg.kelvin
with ureg.context("lj"):
    print(temp.to("dimensionless"))  # 输出≈1.16(kBT/ε计算值)

方案正确性验证:

如果你的自定义方法是手动计算各量的约化值,对比上述方案:

  • 上下文会自动处理导出量(比如压力P* = Pσ³/ε),无需单独写转换逻辑
  • 转换过程严格遵循量纲一致性,避免手动计算的错误
  • 支持反向转换(从约化单位转回真实单位),只需在上下文环境中调用to()方法指定真实单位即可

内容的提问来源于stack exchange,提问作者Roy Kid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 22:50:19