thermo-package について
thermo-package は、Python の thermo ライブラリで化学物性や相平衡を計算するためのエンジニア向けスキルです。温度依存物性、混合物、フラッシュ計算など、ポンプやプロセス流体の解析を扱います。
主な機能
- 01純物質の物性計算
- 02混合物とプロセス流体の計算
- 03VLE とフラッシュ計算
- 04PR・SRK などの状態方程式
- 05ポンプ向けの熱・相状態解析
活用シーン
- 01温度依存粘度を考慮したポンプ計算
- 02NPSH とキャビテーションリスクの推定
- 03混合物や多相ポンプ流体の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ soljourner/ claude-engineering-skills --skill thermo-packageインストール後、Claude Code で/thermo-packageを入力して読み込まれたか確認します。
同梱ファイルexamples.pyreference.md
詳細
Thermo パッケージスキル
概要
thermo ライブラリは、熱力学特性や相平衡を扱う化学エンジニアや機械エンジニア向けの包括的な Python パッケージです。以下の項目について、検証済みの相関式を提供します。
- 純物質の熱力学特性
- 混合物の物性計算
- 気液平衡(VLE)
- エンタルピー、エントロピー、熱容量の計算
- 温度依存性の流体物性
- 状態方程式(EOS)の実装
- 混合物の相平衡
このライブラリには幅広い化学物質データベースが含まれており、DIPPR、NIST、および文献に基づく業界標準の相関式を実装しています。温度依存性の物性、混合物、多相流を扱うポンプ用途に不可欠です。
インストール
pip install thermo chemicals
chemicals パッケージは必須の依存関係であり、化学物質データベースと純物質の物性相関式を提供します。
主なモジュール
thermo.chemical
以下を含む、純物質の物性インターフェースです。
- 温度依存性の粘度、密度、熱伝導率
- 蒸気圧と相挙動
- 熱容量(Cp、Cv)
- エンタルピーとエントロピー
thermo.mixture
混合物の物性計算です。
- 組成で重み付けした物性
- EOS の混合則
- 部分モル物性
- 過剰物性
thermo.stream
プロセスストリームの計算です。
- 物質収支とエネルギー収支
- フラッシュ計算(VLE)
- 相分率の決定
- ストリームのエンタルピー
thermo.eos
状態方程式の実装です。
- Peng-Robinson(PR)
- Soave-Redlich-Kwong(SRK)
- 理想気体の状態方程式
- 三次状態方程式
ポンプエンジニアリングに役立つ主な機能
1. 温度依存性の粘度
運転温度範囲全体にわたるポンプ性能の評価に不可欠です。
from thermo.chemical import Chemical
# Water viscosity variation with temperature
water = Chemical('water', T=298.15, P=101325) # 25°C, 1 atm
# At different temperatures
temps = [20, 40, 60, 80, 100] # °C
for T_c in temps:
water.T = T_c + 273.15
print(f"T = {T_c}°C: μ = {water.mu*1000:.4f} cP, ρ = {water.rho:.1f} kg/m³")
# Output demonstrates viscosity decreasing with temperature:
# T = 20°C: μ = 1.0016 cP, ρ = 998.2 kg/m³
# T = 40°C: μ = 0.6529 cP, ρ = 992.2 kg/m³
# T = 60°C: μ = 0.4665 cP, ρ = 983.2 kg/m³
2. 温度に応じたポンプ動力の補正
異なる温度でポンプを運転する際の、粘度と密度の変化を考慮します。
from thermo.chemical import Chemical
def pump_power_correction(fluid_name, T_design, T_actual, Q, H, eta=0.75):
"""
Calculate pump power at actual temperature vs design temperature.
Parameters:
-----------
fluid_name : str, chemical name
T_design : float, design temperature (K)
T_actual : float, actual temperature (K)
Q : float, flow rate (m³/s)
H : float, head (m)
eta : float, pump efficiency
Returns:
--------
Power correction factor and actual power required
"""
# Properties at design temperature
fluid_design = Chemical(fluid_name, T=T_design, P=101325)
rho_design = fluid_design.rho
mu_design = fluid_design.mu
# Properties at actual temperature
fluid_actual = Chemical(fluid_name, T=T_actual, P=101325)
rho_actual = fluid_actual.rho
mu_actual = fluid_actual.mu
# Power calculation: P = ρ*g*Q*H/η
g = 9.81 # m/s²
P_design = rho_design * g * Q * H / eta
P_actual = rho_actual * g * Q * H / eta
# Viscosity affects efficiency (simplified)
# Higher viscosity reduces efficiency
eta_correction = (mu_design / mu_actual) ** 0.1 # Empirical
eta_actual = eta * eta_correction
P_actual_corrected = rho_actual * g * Q * H / eta_actual
return {
'P_design': P_design / 1000, # kW
'P_actual': P_actual / 1000, # kW
'P_corrected': P_actual_corrected / 1000, # kW
'rho_ratio': rho_actual / rho_design,
'mu_ratio': mu_actual / mu_design,
'eta_correction': eta_correction
}
# Example: Pumping water at elevated temperature
result = pump_power_correction('water', T_design=298.15, T_actual=353.15,
Q=0.05, H=50, eta=0.75)
print(f"Design power: {result['P_design']:.2f} kW")
print(f"Actual power (density only): {result['P_actual']:.2f} kW")
print(f"Actual power (with efficiency): {result['P_corrected']:.2f} kW")
3. 混合物の物性
混合流体やプロセスストリームを扱うポンプに不可欠です。
from thermo.mixture import Mixture
# Ethanol-water mixture (common in chemical processing)
mixture = Mixture(['ethanol', 'water'], ws=[0.3, 0.7], T=298.15, P=101325)
print(f"Mixture density: {mixture.rho:.1f} kg/m³")
print(f"Mixture viscosity: {mixture.mu*1000:.3f} cP")
print(f"Mixture heat capacity: {mixture.Cp:.1f} J/kg·K")
# Compare to pure components
from thermo.chemical import Chemical
ethanol = Chemical('ethanol', T=298.15, P=101325)
water = Chemical('water', T=298.15, P=101325)
print(f"\nPure ethanol: ρ = {ethanol.rho:.1f} kg/m³, μ = {ethanol.mu*1000:.3f} cP")
print(f"Pure water: ρ = {water.rho:.1f} kg/m³, μ = {water.mu*1000:.3f} cP")
4. 蒸気圧と NPSH の計算
利用可能な NPSH とキャビテーションのリスクを判定します。
from thermo.chemical import Chemical
def calculate_NPSHa(fluid_name, T, P_suction, z_suction, v_suction):
"""
Calculate Net Positive Suction Head Available.
Parameters:
-----------
fluid_name : str, chemical name
T : float, fluid temperature (K)
P_suction : float, suction pressure (Pa absolute)
z_suction : float, suction elevation relative to pump (m)
v_suction : float, velocity at suction (m/s)
Returns:
--------
NPSHa in meters
"""
fluid = Chemical(fluid_name, T=T, P=P_suction)
rho = fluid.rho # kg/m³
Psat = fluid.Psat # Vapor pressure, Pa
g = 9.81 # m/s²
# NPSHa = (P_suction - Psat)/(ρ*g) + v²/(2g) - z_suction
pressure_head = (P_suction - Psat) / (rho * g)
velocity_head = v_suction**2 / (2 * g)
NPSHa = pressure_head + velocity_head - z_suction
return {
'NPSHa': NPSHa,
'P_suction': P_suction / 1000, # kPa
'Psat': Psat / 1000, # kPa
'rho': rho,
'margin': (P_suction - Psat) / 1000 # kPa
}
# Example: Water at 80°C (elevated temperature)
result = calculate_NPSHa('water', T=353.15, P_suction=150000,
z_suction=2.0, v_suction=2.5)
print(f"NPSHa = {result['NPSHa']:.2f} m")
print(f"Suction pressure = {result['P_suction']:.1f} kPa")
print(f"Vapor pressure = {result['Psat']:.1f} kPa")
print(f"Pressure margin = {result['margin']:.1f} kPa")
# Warning if NPSHa is low
if result['NPSHa'] < 3.0:
print("⚠ WARNING: Low NPSHa - high cavitation risk!")
5. ポンプ段間のエンタルピー計算
多段ポンプにおけるエンタルピー上昇と温度上昇を計算します。
from thermo.chemical import Chemical
def pump_temperature_rise(fluid_name, T_inlet, P_inlet, P_outlet, eta):
"""
Calculate temperature rise due to pump inefficiency.
Energy not converted to useful work appears as heat in the fluid:
ΔT = (1-η) * ΔP / (ρ * Cp)
Parameters:
-----------
fluid_name : str
T_inlet : float, inlet temperature (K)
P_inlet : float, inlet pressure (Pa)
P_outlet : float, outlet pressure (Pa)
eta : float, pump efficiency
"""
fluid = Chemical(fluid_name, T=T_inlet, P=P_inlet)
rho = fluid.rho # kg/m³
Cp = fluid.Cp # J/kg·K
delta_P = P_outlet - P_inlet # Pa
# Temperature rise from inefficiency
delta_T = (1 - eta) * delta_P / (rho * Cp)
# Recalculate properties at outlet
T_outlet = T_inlet + delta_T
fluid_out = Chemical(fluid_name, T=T_outlet, P=P_outlet)
# Enthalpy change
H_inlet = fluid.H # J/kg
H_outlet = fluid_out.H # J/kg
delta_H = H_outlet - H_inlet
return {
'T_inlet': T_inlet - 273.15, # °C
'T_outlet': T_outlet - 273.15, # °C
'delta_T': delta_T, # K
'delta_H': delta_H / 1000, # kJ/kg
'delta_P': delta_P / 1e6 # MPa
}
# Example: Multistage boiler feed pump
result = pump_temperature_rise('water', T_inlet=333.15, P_inlet=500000,
P_outlet=15000000, eta=0.82)
print(f"Inlet temperature: {result['T_inlet']:.1f} °C")
print(f"Outlet temperature: {result['T_outlet']:.1f} °C")
print(f"Temperature rise: {result['delta_T']:.2f} K")
print(f"Enthalpy rise: {result['delta_H']:.1f} kJ/kg")
print(f"Pressure rise: {result['delta_P']:.1f} MPa")
6. 多相ポンプの相平衡
ポンプ内で二相流が発生するかどうかを判定します。
from thermo.chemical import Chemical
def check_phase_state(fluid_name, T, P):
"""
Check if fluid is single-phase or will flash to vapor.
"""
fluid = Chemical(fluid_name, T=T, P=P)
Psat = fluid.Psat # Vapor pressure
Tsat = fluid.Tb # Boiling point at 1 atm
# Determine phase
if P > Psat:
phase = "Liquid (subcooled)"
margin = (P - Psat) / Psat * 100 # % margin
elif P < Psat:
phase = "Two-phase or Vapor (FLASHING!)"
margin = (Psat - P) / P * 100 # % above operating pressure
else:
phase = "Saturated liquid"
margin = 0
return {
'phase': phase,
'T': T - 273.15,
'P': P / 1000, # kPa
'Psat': Psat / 1000, # kPa
'margin': margin
}
# Example: Check if water will flash at pump suction
temps = [40, 60, 80, 100] # °C
P_suction = 120000 # Pa (1.2 bar absolute)
for T_c in temps:
result = check_phase_state('water', T=T_c+273.15, P=P_suction)
print(f"T = {result['T']:.0f}°C, P = {result['P']:.1f} kPa: {result['phase']}")
if 'subcooled' in result['phase']:
print(f" Margin = {result['margin']:.1f}%")
print()
# Output will show flashing occurs above ~105°C at 1.2 bar
状態方程式の用途
高圧ポンプ向け Peng-Robinson EOS
from thermo import ChemicalConstantsPackage, PRMIX, CEOSGas, CEOSLiquid, FlashVL
from thermo.interaction_parameters import IPDB
# High-pressure natural gas mixture
constants = ChemicalConstantsPackage.constants_from_IDs(['methane', 'ethane', 'propane'])
# Operating conditions
T = 298.15 # K
P = 10e6 # Pa (100 bar)
zs = [0.85, 0.10, 0.05] # Mole fractions
# Peng-Robinson EOS
kijs = IPDB.get_ip_asymmetric_matrix('ChemSep PR', constants.CASs, 'kij')
eos_kwargs = {'Tcs': constants.Tcs, 'Pcs': constants.Pcs, 'omegas': constants.omegas, 'kijs': kijs}
gas = CEOSGas(PRMIX, eos_kwargs, HeatCapacityGases=constants.HeatCapacityGases, T=T, P=P, zs=zs)
liquid = CEOSLiquid(PRMIX, eos_kwargs, HeatCapacityGases=constants.HeatCapacityGases, T=T, P=P, zs=zs)
# Flash calculation
flasher = FlashVL(constants, HeatCapacityGases=constants.HeatCapacityGases, gas=gas, liquids=[liquid])
res = flasher.flash(T=T, P=P, zs=zs)
print(f"Temperature: {T-273.15:.1f} °C")
print(f"Pressure: {P/1e6:.1f} MPa")
print(f"Phase: {res.phase}")
if res.phase == 'L':
print(f"Liquid density: {res.rho_mass():.1f} kg/m³")
print(f"Liquid viscosity: {res.mu()*1e6:.2f} μPa·s")
エンジニアリングの完全な例
検証済みですぐに実運用できる例については、examples.py を参照してください。以下が含まれています。
- ポンプ曲線に対する温度・粘度補正
- 温度変化を考慮した NPSH の計算
- 混合燃料の物性計算
- 多段ポンプのエンタルピー上昇
- ポンプ吐出条件のフラッシュ計算
- 化学物質データベースのクエリ
ポンプ用途の概要
Thermo パッケージを使用する場面
- 温度依存性の物性:流体温度が大きく変化する場合
- 混合物の取り扱い:混合流体やプロセスストリームをポンプで送る場合
- 高温用途:ボイラー給水ポンプ、熱媒油ポンプ
- キャビテーション解析:NPSH の計算に必要な正確な蒸気圧
- 多相流:フラッシングが発生するかどうかの判定
- エネルギー計算:ポンプによる温度上昇の熱収支
Fluids パッケージとの統合
thermo パッケージは fluids を補完し、ポンプ解析を包括的に行えます。
- thermo:温度依存性の物性(ρ、μ、Psat)を提供します
- fluids:これらの物性を水力計算(摩擦、損失水頭)に使用します
from thermo.chemical import Chemical
from fluids.core import Reynolds
from fluids.friction import friction_factor
# Get properties from thermo
water = Chemical('water', T=333.15, P=101325) # 60°C
rho = water.rho
mu = water.mu
# Use in fluids calculations
Re = Reynolds(V=2.0, D=0.1, rho=rho, mu=mu)
f = friction_factor(Re=Re, eD=0.0001)
print(f"At 60°C: Re = {Re:.0f}, f = {f:.5f}")
一般的な化学物質のデータベース
CAS 番号または名称を使って、20,000 種類以上の化学物質にアクセスできます。
- 工業用流体(水、油、グリコール)
- 炭化水素(メタン、プロパン、ガソリン)
- 冷媒(R-134a、アンモニア)
- 酸と塩基(HCl、NaOH)
- 有機溶媒(エタノール、アセトン)
データベースの詳細とポンプでよく使用する流体については、reference.md を参照してください。
ベストプラクティス
- 化学物質オブジェクトを作成するときは、必ずTとPの両方を指定してください
- 液体の物性値を使用する前に、相の状態を確認してください
- 既知のデータ(蒸気表、RefProp、NIST)と照合してください
- 高圧用途(>20 bar)では適切なEOSを使用してください
- 相関式の適用温度範囲を考慮してください(150°C未満に制限されているものもあります)
- 反復計算のパフォーマンスを高めるために、化学物質オブジェクトをキャッシュしてください
単位
すべての物性値はSI単位です:
- 温度:K(°Cからの変換:T_K = T_C + 273.15)
- 圧力:Pa(1 bar = 100,000 Pa)
- 密度:kg/m³
- 粘度:Pa·s(1 cP = 0.001 Pa·s)
- エンタルピー:J/kg
- 熱容量:J/kg·K
トラブルシューティング
問題:物性値がNoneを返す
- 原因:その化学物質では物性値を取得できない、または有効範囲外です
- 解決策:有効な温度範囲を確認するには、Chemical.Tmin、Chemical.Tmaxを確認してください
問題:混合物の物性値が現実的ではない
- 原因:相互作用パラメーターがない、または組成が無効です
- 解決策:質量分率またはモル分率の合計が1.0になることを確認してください
問題:フラッシュ計算に失敗する
- 原因:初期推定値が有効領域外にある、またはEOSパラメーターが不適切です
- 解決策:より単純なEOS(理想気体)を使用するか、初期のT/P推定値を調整してください
参考資料
- DIPPR 801 Database(AIChE Design Institute for Physical Properties)
- NIST Chemistry WebBook
- Poling, B.E., Prausnitz, J.M., O'Connell, J.P., "The Properties of Gases and Liquids"(第5版)
- Perry's Chemical Engineers' Handbook(第9版)
- Peng, D.Y., Robinson, D.B., "A New Two-Constant Equation of State"(1976)
関連資料
- 公式ドキュメント:https://thermo.readthedocs.io/
- Chemicalsのドキュメント:https://chemicals.readthedocs.io/
- ソースコード:https://github.com/CalebBell/thermo
- チュートリアルノートブック:https://github.com/CalebBell/thermo/tree/master/docs