mcpField
F
fluids-package

fluids-package

github.com/soljourner其他9542 次安装51 周前更新
代码仓库

关于 fluids-package

这份技能指南介绍面向机械与化学工程师的 Python `fluids` 库,可用于流动、压降、泵和换热器计算。内容涵盖不可压缩、可压缩及两相流问题,并包含经过验证的关联式。

主要功能

  1. 01管道摩擦与压降计算
  2. 02泵性能及相似定律
  3. 03可压缩流计算
  4. 04换热器与两相流功能
  5. 05流体属性工具
  6. 06经过验证的工程关联式

适用场景

  1. 01计算摩擦因子和管道水头损失
  2. 02评估泵的运行工况
  3. 03分析气体流动与临界流
  4. 04设计或分析换热器

安装

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

$npx skills add https://github.com/soljourner/claude-engineering-skills --skill fluids-package

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

附带文件examples.pyreference.md

详细介绍

Fluids Package 技能

概述

fluids 库是一个功能全面的 Python 包,供处理流体流动问题的机械工程师和化学工程师使用。它提供经过验证的关联式和函数,用于:

  • 管道流动和摩擦因子计算
  • 泵选型和性能分析
  • 可压缩流和不可压缩流
  • 热交换器设计
  • 两相流
  • 压降计算
  • 流体属性

该库实现了 100 多种文献中的关联式,并针对已发表的测试案例进行了广泛验证。

安装

pip install fluids

如需完整功能(包括优化例程):

pip install fluids[complete]

主要模块

fluids.core

核心实用工具和量纲分析函数。

fluids.friction

管道流动的摩擦因子计算,包括:

  • Darcy-Weisbach 方程
  • Colebrook-White 关联式
  • Moody 图实现
  • 湍流和层流工况
fluids.pump

泵性能计算:

  • 相似定律
  • 比转速
  • NPSH 计算
  • 泵曲线和效率
fluids.compressible

可压缩流计算:

  • 马赫数关系
  • 壅塞流条件
  • 等熵流
  • 正激波
fluids.fittings

计算阀门、管件和管道组件中的压降。

常用函数及工程背景

雷诺数计算

雷诺数(Re)决定流动状态,是所有管道流动计算的基础。

from fluids.core import Reynolds

# For pipe flow: Re = ρVD/μ
Re = Reynolds(V=2.5, D=0.05, rho=1000, mu=0.001)
# Result: 125000 (turbulent flow)

# Interpretation:
# Re < 2300: Laminar flow
# 2300 < Re < 4000: Transition
# Re > 4000: Turbulent flow
摩擦因子(Darcy-Weisbach)

摩擦因子(f)用于 Darcy-Weisbach 方程:ΔP = f(L/D)(ρV²/2)

from fluids.friction import friction_factor

# Colebrook-White correlation (implicit, most accurate)
f = friction_factor(Re=125000, eD=0.0001)  # eD = roughness/diameter
# Result: ~0.0178

# Moody correlation (explicit approximation)
from fluids.friction import friction_factor_Moody
f_moody = friction_factor_Moody(Re=125000, eD=0.0001)

# For laminar flow (Re < 2300):
f_laminar = friction_factor(Re=1500, eD=0.0001)
# Result: 0.0427 (f = 64/Re)
管道水头损失

计算管道系统中的压降和水头损失。

from fluids.friction import friction_factor, head_from_P
from fluids.core import Reynolds

# Given: Water flow through steel pipe
D = 0.1  # m, pipe diameter
L = 100  # m, pipe length
V = 2.0  # m/s, velocity
rho = 1000  # kg/m³, density
mu = 0.001  # Pa·s, viscosity
epsilon = 0.000045  # m, roughness (steel)

# Step 1: Calculate Reynolds number
Re = Reynolds(V=V, D=D, rho=rho, mu=mu)

# Step 2: Calculate friction factor
eD = epsilon / D
f = friction_factor(Re=Re, eD=eD)

# Step 3: Calculate pressure drop
# Darcy-Weisbach: ΔP = f(L/D)(ρV²/2)
dP = f * (L/D) * (rho * V**2 / 2)

# Step 4: Convert to head loss
h_loss = head_from_P(dP, rho)  # meters of fluid

print(f"Reynolds: {Re:.0f}")
print(f"Friction factor: {f:.5f}")
print(f"Pressure drop: {dP:.0f} Pa")
print(f"Head loss: {h_loss:.2f} m")
泵相似定律

描述不同转速和叶轮直径下的泵性能关系。

from fluids.pump import affinity_law_volume, affinity_law_head, affinity_law_power

# Original pump operating point
Q1 = 100  # m³/h, flow rate
H1 = 50   # m, head
P1 = 20   # kW, power
N1 = 1450 # rpm, speed
D1 = 0.3  # m, impeller diameter

# New speed
N2 = 1750  # rpm

# Affinity laws (constant impeller diameter):
# Q2/Q1 = N2/N1
# H2/H1 = (N2/N1)²
# P2/P1 = (N2/N1)³

Q2 = affinity_law_volume(Q1, N1, N2)
H2 = affinity_law_head(H1, N1, N2)
P2 = affinity_law_power(P1, N1, N2)

print(f"New flow: {Q2:.1f} m³/h")
print(f"New head: {H2:.1f} m")
print(f"New power: {P2:.1f} kW")
比转速计算

比转速(Ns)用于表征泵的类型和效率。

from fluids.pump import specific_speed

# Pump operating conditions
Q = 0.05  # m³/s, flow rate
H = 40    # m, head
N = 1450  # rpm, rotational speed

# Calculate specific speed (dimensionless)
Ns = specific_speed(Q, H, N)

# Interpretation:
# Ns < 0.5: Centrifugal (radial flow)
# 0.5 < Ns < 1.0: Francis (mixed flow)
# 1.0 < Ns < 4.0: Propeller (axial flow)

print(f"Specific speed: {Ns:.2f}")
if Ns < 0.5:
    pump_type = "Centrifugal (radial flow)"
elif Ns < 1.0:
    pump_type = "Francis (mixed flow)"
else:
    pump_type = "Propeller (axial flow)"
print(f"Recommended pump type: {pump_type}")
可压缩流 — 马赫数

用于管道和喷嘴中的气体流动。

from fluids.compressible import Mach

# Calculate Mach number from velocity
V = 200  # m/s, velocity
c = 340  # m/s, speed of sound in air at 15°C

Ma = Mach(V, c)
# Result: 0.588

# Flow classification:
# Ma < 0.3: Incompressible
# 0.3 < Ma < 0.8: Subsonic
# 0.8 < Ma < 1.2: Transonic
# Ma > 1.2: Supersonic
可压缩流 — 壅塞流

确定喷嘴或孔口中的流动是否发生壅塞。

from fluids.compressible import P_critical_flow

# Gas properties
P_upstream = 500000  # Pa, upstream pressure
k = 1.4  # heat capacity ratio (air)

# Critical pressure for choked flow
P_crit = P_critical_flow(P=P_upstream, k=k)
# Result: ~264,000 Pa

# If downstream pressure < P_crit, flow is choked
P_downstream = 200000  # Pa
if P_downstream < P_crit:
    print("Flow is choked - mass flow is at maximum")
    print(f"Critical pressure: {P_crit:.0f} Pa")
else:
    print("Flow is not choked")

完整工程示例

示例 1:泵选型和系统曲线
import numpy as np
from fluids.friction import friction_factor
from fluids.core import Reynolds
import matplotlib.pyplot as plt

def system_curve(Q_range, static_head, pipe_specs):
    """
    Calculate system head curve for a piping system.

    Parameters:
    -----------
    Q_range : array, flow rates (m³/s)
    static_head : float, static lift (m)
    pipe_specs : dict with keys:
        - L: pipe length (m)
        - D: pipe diameter (m)
        - epsilon: roughness (m)
        - rho: fluid density (kg/m³)
        - mu: fluid viscosity (Pa·s)

    Returns:
    --------
    H_system : array, required head at each flow rate (m)
    """
    L = pipe_specs['L']
    D = pipe_specs['D']
    rho = pipe_specs['rho']
    mu = pipe_specs['mu']
    epsilon = pipe_specs['epsilon']

    # Calculate cross-sectional area
    A = np.pi * D**2 / 4

    H_system = np.zeros_like(Q_range)

    for i, Q in enumerate(Q_range):
        if Q == 0:
            H_system[i] = static_head
            continue

        # Calculate velocity
        V = Q / A

        # Reynolds number
        Re = Reynolds(V=V, D=D, rho=rho, mu=mu)

        # Friction factor
        eD = epsilon / D
        f = friction_factor(Re=Re, eD=eD)

        # Friction head loss (Darcy-Weisbach)
        h_friction = f * (L/D) * (V**2 / (2*9.81))

        # Total system head
        H_system[i] = static_head + h_friction

    return H_system

# Define system
pipe_specs = {
    'L': 200,  # m
    'D': 0.15,  # m
    'epsilon': 0.000045,  # m (steel)
    'rho': 1000,  # kg/m³
    'mu': 0.001  # Pa·s
}
static_head = 30  # m

# Generate system curve
Q_range = np.linspace(0, 0.1, 50)  # m³/s
H_system = system_curve(Q_range, static_head, pipe_specs)

# Example pump curve (quadratic fit)
# H = H0 - A*Q - B*Q²
H0 = 80  # m, shutoff head
A = 200  # head loss coefficient
B = 3000  # quadratic coefficient
H_pump = H0 - A*Q_range - B*Q_range**2

# Find operating point (intersection)
idx = np.argmin(np.abs(H_pump - H_system))
Q_op = Q_range[idx]
H_op = H_system[idx]

print(f"Operating Point:")
print(f"  Flow rate: {Q_op*3600:.1f} m³/h ({Q_op:.4f} m³/s)")
print(f"  Head: {H_op:.1f} m")

# Verification: At Q=0.05 m³/s
# V = Q/A = 0.05/(π*0.15²/4) = 2.83 m/s
# Re = 1000*2.83*0.15/0.001 = 424,500 (turbulent)
# f ≈ 0.0175 (from Moody chart)
# h_f = 0.0175*(200/0.15)*(2.83²/(2*9.81)) = 9.5 m
# H_total = 30 + 9.5 = 39.5 m ✓
示例 2:并联泵配置
from fluids.pump import affinity_law_volume, affinity_law_head

def parallel_pumps(Q_total, n_pumps, single_pump_curve):
    """
    Calculate operating point for parallel pump configuration.

    For pumps in parallel:
    - Flow rates add: Q_total = n * Q_single
    - Head remains the same: H_total = H_single
    """
    # Single pump flow rate
    Q_single = Q_total / n_pumps

    # Head from single pump curve
    H = single_pump_curve(Q_single)

    return Q_single, H

# Single pump curve: H = 60 - 500*Q² (simplified)
def pump_curve(Q):
    return 60 - 500*Q**2

# System requires 150 m³/h at 40 m head
Q_required = 150/3600  # m³/s
n_pumps = 2

Q_single, H_operating = parallel_pumps(Q_required, n_pumps, pump_curve)

print(f"Parallel Pump Configuration ({n_pumps} pumps):")
print(f"  Total flow: {Q_required*3600:.1f} m³/h")
print(f"  Flow per pump: {Q_single*3600:.1f} m³/h")
print(f"  Operating head: {H_operating:.1f} m")

# Verification:
# Each pump delivers 75 m³/h (0.0208 m³/s)
# H = 60 - 500*(0.0208)² = 60 - 0.22 = 59.8 m ✓
示例 3:摩擦因子验证
from fluids.friction import friction_factor, friction_factor_laminar

# Test Case 1: Laminar Flow (Poiseuille)
# Analytical solution: f = 64/Re
Re_laminar = 1000
f_calculated = friction_factor(Re=Re_laminar, eD=0)
f_analytical = 64/Re_laminar

print("Test 1: Laminar Flow")
print(f"  Re = {Re_laminar}")
print(f"  f (calculated) = {f_calculated:.6f}")
print(f"  f (analytical) = {f_analytical:.6f}")
print(f"  Error = {abs(f_calculated - f_analytical):.9f}")
assert abs(f_calculated - f_analytical) < 1e-9, "Laminar flow test failed"
print("  ✓ PASSED\n")

# Test Case 2: Turbulent Flow - Smooth Pipe
# From Moody diagram: Re=1e5, smooth pipe → f ≈ 0.0183
Re_turbulent = 1e5
f_smooth = friction_factor(Re=Re_turbulent, eD=0)

print("Test 2: Turbulent Flow (Smooth Pipe)")
print(f"  Re = {Re_turbulent:.0f}")
print(f"  f (calculated) = {f_smooth:.6f}")
print(f"  f (Moody chart) ≈ 0.0183")
print(f"  Error = {abs(f_smooth - 0.0183):.6f}")
assert abs(f_smooth - 0.0183) < 0.0005, "Smooth pipe test failed"
print("  ✓ PASSED\n")

# Test Case 3: Turbulent Flow - Rough Pipe
# Commercial steel: ε/D = 0.0002, Re = 1e6 → f ≈ 0.0144
Re_rough = 1e6
eD_rough = 0.0002
f_rough = friction_factor(Re=Re_rough, eD=eD_rough)

print("Test 3: Turbulent Flow (Rough Pipe)")
print(f"  Re = {Re_rough:.0f}")
print(f"  ε/D = {eD_rough}")
print(f"  f (calculated) = {f_rough:.6f}")
print(f"  f (Moody chart) ≈ 0.0144")
print(f"  Error = {abs(f_rough - 0.0144):.6f}")
assert abs(f_rough - 0.0144) < 0.0005, "Rough pipe test failed"
print("  ✓ PASSED\n")

# Test Case 4: From Crane TP-410 (Standard reference)
# Example 4-9: Water in 6-inch Schedule 40 pipe
D = 0.1541  # m (6-inch Schedule 40 ID)
V = 3.05  # m/s
rho = 998  # kg/m³
mu = 0.001  # Pa·s
epsilon = 0.000045  # m (steel)

Re_crane = Reynolds(V=V, D=D, rho=rho, mu=mu)
eD_crane = epsilon/D
f_crane = friction_factor(Re=Re_crane, eD=eD_crane)

# Crane TP-410 gives f ≈ 0.0172
print("Test 4: Crane TP-410 Example 4-9")
print(f"  Re = {Re_crane:.0f}")
print(f"  ε/D = {eD_crane:.6f}")
print(f"  f (calculated) = {f_crane:.6f}")
print(f"  f (Crane TP-410) ≈ 0.0172")
print(f"  Error = {abs(f_crane - 0.0172):.6f}")
assert abs(f_crane - 0.0172) < 0.0003, "Crane TP-410 test failed"
print("  ✓ PASSED\n")

print("All friction factor tests passed! ✓")
示例 4:管道中的可压缩流
from fluids.compressible import isothermal_gas

# Gas pipeline calculation
# Problem: Natural gas (methane) pipeline
P1 = 5e6  # Pa, inlet pressure
T = 288.15  # K, temperature (15°C)
L = 50000  # m, pipeline length (50 km)
D = 0.5  # m, diameter
m = 10  # kg/s, mass flow rate
MW = 16.04  # g/mol, molecular weight (CH4)
k = 1.31  # heat capacity ratio

# Calculate outlet pressure using isothermal flow
# This accounts for friction and compressibility
from fluids.compressible import isothermal_gas
P2 = isothermal_gas(rho=None, P1=P1, P2=None, L=L, D=D, m=m,
                    T=T, Z=1, fd=0.012)  # Assuming f=0.012

print("Gas Pipeline Calculation:")
print(f"  Inlet pressure: {P1/1e6:.2f} MPa")
print(f"  Outlet pressure: {P2/1e6:.2f} MPa")
print(f"  Pressure drop: {(P1-P2)/1e6:.2f} MPa")
print(f"  Length: {L/1000:.0f} km")
print(f"  Mass flow: {m:.1f} kg/s")

最佳实践

  1. 选择摩擦因子关联式前,务必检查雷诺数
  2. 根据已知测试案例或手册数据验证结果
  3. 使用一致的单位——fluids 全程使用 SI 单位
  4. 泵选型时考虑安全系数(通常预留 10-15% 的余量)
  5. 检查物理限制——不可压缩假设下应确保马赫数 < 0.3
  6. 使用文献中的适当粗糙度值(Moody、Crane TP-410)

常见管道粗糙度值

材料粗糙度 ε(m)
拉制管0.0000015
商用钢0.000045
镀锌铁0.00015
铸铁0.00026
混凝土0.0003 to 0.003
铆接钢0.0009 to 0.009

故障排查

问题:摩擦因子无法收敛
  • 原因:雷诺数或 ε/D 比值无效
  • 解决方案:检查 Re > 0 且 0 ≤ ε/D < 0.5
问题:泵曲线与系统曲线没有交点
  • 原因:泵选型过小或过大
  • 解决方案:使用相似定律调整泵速,或选择其他泵
问题:可压缩流结果不合理
  • 原因:马赫数 > 0.3,但使用了不可压缩流方程
  • 解决方案:使用 fluids.compressible 中的可压缩流函数

参考资料

  • Crane Technical Paper 410(TP-410):“阀门、管件和管道中的流体流动”
  • Moody, L.F.(1944):“管道流动的摩擦因子”
  • Colebrook, C.F.(1939):“管道中的湍流”
  • Karassik's Pump Handbook(第 4 版)
  • GPSA Engineering Data Book(第 14 版)

延伸阅读

评论

支持 Markdown