空气污染控制设计技能
空气污染控制设备的选择和设计,包括湿式洗涤器、布袋除尘器、电除尘器、氧化器和BACT/LAER确定。
目的
这项技能提供了设计空气污染控制系统的全面能力,包括技术选择、设备尺寸、效率计算和法规合规性展示(BACT/LAER/MACT)。
能力
洗涤器设计
- 湿式洗涤器技术选择
- 填充塔设计和尺寸
- 喷雾塔配置
- 文氏洗涤器设计
- 压降计算
- 液气比优化
- 化学剂量要求
布袋除尘器和织物过滤器尺寸
- 过滤介质选择
- 气布比确定
- 分隔设计
- 脉冲喷射与反吹风清洁
- 压降估计
- 布袋寿命预测
- 灰斗尺寸
电除尘器设计
- 收集效率计算
- 特定收集面积(SCA)确定
- 板间距和配置
- 电场强度
- 敲击系统设计
- 电阻率考虑
- 电源尺寸
热和催化氧化器规格
- 破坏效率要求
- 温度和停留时间
- 热回收选项(再生、回收)
- 催化氧化器催化剂选择
- 辅助燃料需求
- 转换能力
活性炭吸附系统设计
- 活性炭选择
- 吸附容量计算
- 穿透时间估计
- 床尺寸
- 再生系统设计
- 碳更换频率
控制效率计算
- 出口排放率确定
- 去除效率验证
- 烟气测试相关性
- 连续监测要求
压降和能量分析
- 系统压降计算
- 风机功率要求
- 运营成本估计
- 能源优化机会
BACT/LAER/MACT确定
- 控制技术识别
- 成本效益分析
- 技术可行性评估
- 法规数据库研究
- 从上到下的BACT分析
先决条件
安装
pip install numpy scipy pandas matplotlib
可选依赖
# 用于化学属性查找
pip install chemicals thermo
# 用于可视化
pip install plotly
使用模式
布袋除尘器设计
import numpy as np
from dataclasses import dataclass
from typing import Dict, List, Optional
@dataclass
class GasStreamData:
"""气体流特性"""
flow_rate_acfm: float
temperature_f: float
moisture_pct: float
particulate_loading_gr_acf: float
particle_size_micron: float
gas_composition: Dict[str, float] = None
@dataclass
class BaghouseDesign:
"""布袋除尘器设计参数"""
filter_media: str
bag_diameter_in: float
bag_length_ft: float
air_to_cloth_ratio: float
cleaning_type: str # 'pulse_jet', 'reverse_air', 'shaker'
class BaghouseCalculator:
"""脉冲喷射布袋除尘器尺寸计算"""
# 按应用推荐的气布比(acfm/ft2)
AC_RATIOS = {
'cement': {'gross': 4.0, 'net': 3.5},
'coal': {'gross': 6.0, 'net': 5.0},
'foundry': {'gross': 4.5, 'net': 3.5},
'steel': {'gross': 5.0, 'net': 4.0},
'chemical': {'gross': 5.5, 'net': 4.5},
'pharmaceutical': {'gross': 3.5, 'net': 3.0},
'general': {'gross': 5.0, 'net': 4.0}
}
# 过滤介质属性
MEDIA_PROPERTIES = {
'polyester': {'max_temp_f': 275, 'cost_factor': 1.0, 'acid_resist': 'good'},
'polypropylene': {'max_temp_f': 200, 'cost_factor': 0.9, 'acid_resist': 'excellent'},
'nomex': {'max_temp_f': 400, 'cost_factor': 3.0, 'acid_resist': 'good'},
'fiberglass': {'max_temp_f': 500, 'cost_factor': 2.5, 'acid_resist': 'excellent'},
'ptfe': {'max_temp_f': 500, 'cost_factor': 8.0, 'acid_resist': 'excellent'},
'p84': {'max_temp_f': 500, 'cost_factor': 5.0, 'acid_resist': 'good'}
}
def select_filter_media(self, gas: GasStreamData) -> str:
"""根据气体条件选择合适的过滤介质"""
temp = gas.temperature_f
suitable = []
for media, props in self.MEDIA_PROPERTIES.items():
if props['max_temp_f'] >= temp:
suitable.append((media, props))
# 返回成本最低的合适介质
suitable.sort(key=lambda x: x[1]['cost_factor'])
return suitable[0][0] if suitable else 'ptfe'
def calculate_filter_area(self, gas: GasStreamData,
application: str = 'general',
use_net_ratio: bool = True) -> Dict:
"""计算所需过滤面积"""
ratios = self.AC_RATIOS.get(application, self.AC_RATIOS['general'])
ac_ratio = ratios['net'] if use_net_ratio else ratios['gross']
filter_area = gas.flow_rate_acfm / ac_ratio
return {
'gas_flow_acfm': gas.flow_rate_acfm,
'air_to_cloth_ratio': ac_ratio,
'filter_area_sqft': filter_area
}
def size_baghouse(self, gas: GasStreamData,
bag_diameter_in: float = 6.0,
bag_length_ft: float = 10.0,
application: str = 'general') -> Dict:
"""尺寸完整的布袋除尘器系统"""
# 过滤介质选择
media = self.select_filter_media(gas)
# 计算过滤面积
area_calc = self.calculate_filter_area(gas, application)
required_area = area_calc['filter_area_sqft']
# 布袋面积计算
bag_area = np.pi * (bag_diameter_in / 12) * bag_length_ft # 每袋平方英尺
# 布袋数量
num_bags = np.ceil(required_area / bag_area)
# 分隔(通常每排8-16个布袋,每个分隔2-4排)
bags_per_compartment = 32 # 典型
num_compartments = np.ceil(num_bags / bags_per_compartment)
# 压降估计(脉冲喷射的典型值)
dp_filter = 2.5 # 英寸水柱,用于清洁过滤器
dp_tubesheet = 0.5
dp_inlet_outlet = 1.0
total_dp = dp_filter + dp_tubesheet + dp_inlet_outlet
# 灰斗尺寸(4:1转换,8小时存储)
dust_rate_lb_hr = gas.particulate_loading_gr_acf * gas.flow_rate_acfm * 60 / 7000
hopper_volume = dust_rate_lb_hr * 8 / 50 # 50 lb/cf 堆积密度
return {
'filter_media': media,
'required_filter_area_sqft': required_area,
'bag_diameter_in': bag_diameter_in,
'bag_length_ft': bag_length_ft,
'area_per_bag_sqft': bag_area,
'total_bags': int(num_bags),
'num_compartments': int(num_compartments),
'air_to_cloth_gross': gas.flow_rate_acfm / (num_bags * bag_area),
'pressure_drop_in_wc': total_dp,
'dust_rate_lb_hr': dust_rate_lb_hr,
'hopper_volume_cf': hopper_volume,
'max_temp_f': self.MEDIA_PROPERTIES[media]['max_temp_f']
}
# 示例用法
gas = GasStreamData(
flow_rate_acfm=50000,
temperature_f=350,
moisture_pct=8,
particulate_loading_gr_acf=2.0,
particle_size_micron=5
)
calculator = BaghouseCalculator()
design = calculator.size_baghouse(gas, application='cement')
print(f"Filter media: {design['filter_media']}")
print(f"Total bags: {design['total_bags']}")
print(f"Compartments: {design['num_compartments']}")
print(f"A/C ratio: {design['air_to_cloth_gross']:.2f} acfm/sqft")
print(f"Pressure drop: {design['pressure_drop_in_wc']:.1f} in w.c.")
湿式洗涤器设计
class WetScrubberDesign:
"""湿式洗涤器设计计算"""
def packed_tower_sizing(self, gas_flow_acfm: float,
pollutant: str,
inlet_conc_ppm: float,
outlet_conc_ppm: float,
scrubbing_liquid: str = 'water') -> Dict:
"""尺寸填充塔进行气体吸收"""
# 去除效率
efficiency = (inlet_conc_ppm - outlet_conc_ppm) / inlet_conc_ppm
# 气体速度(填充塔的典型范围3-6 ft/s)
gas_velocity_fps = 4.5
# 横截面积
area_sqft = (gas_flow_acfm / 60) / gas_velocity_fps
# 直径
diameter_ft = np.sqrt(4 * area_sqft / np.pi)
# 基于NTU的高度(简化)
ntu = -np.log(1 - efficiency) # 传递单元数
htu = 2.5 # 传递单元高度(ft)- 2"填料典型
packing_height = ntu * htu
# L/G比率(液气比)
lg_ratio = 10 # gpm每1000 acfm典型
# 液体流量
liquid_flow_gpm = gas_flow_acfm * lg_ratio / 1000
# 压降(填料每英尺1-2英寸水柱典型)
pressure_drop = packing_height * 1.5
return {
'diameter_ft': diameter_ft,
'packing_height_ft': packing_height,
'total_height_ft': packing_height * 1.5, # 内部件增加
'cross_section_sqft': area_sqft,
'gas_velocity_fps': gas_velocity_fps,
'liquid_flow_gpm': liquid_flow_gpm,
'lg_ratio_gpm_per_kacfm': lg_ratio,
'pressure_drop_in_wc': pressure_drop,
'removal_efficiency_pct': efficiency * 100,
'ntu': ntu
}
def venturi_scrubber_sizing(self, gas_flow_acfm: float,
particulate_loading_gr_acf: float,
target_efficiency_pct: float) -> Dict:
"""尺寸文氏洗涤器进行颗粒物去除"""
# 压降与效率相关性(Johnstone方程)
# 效率随压降增加而增加
# 对于99%效率,通常需要30-50英寸水柱
if target_efficiency_pct >= 99:
pressure_drop = 50
elif target_efficiency_pct >= 95:
pressure_drop = 30
elif target_efficiency_pct >= 90:
pressure_drop = 20
else:
pressure_drop = 10
# L/G比率(效率越高,比率越高)
lg_ratio = 8 + (target_efficiency_pct - 90) * 0.2
# 喉部速度(通常12,000-24,000 fpm)
throat_velocity = 15000 # fpm
# 喉部面积
throat_area = gas_flow_acfm / throat_velocity
# 液体流量
liquid_flow = gas_flow_acfm * lg_ratio / 1000
return {
'throat_area_sqft': throat_area,
'throat_velocity_fpm': throat_velocity,
'pressure_drop_in_wc': pressure_drop,
'liquid_flow_gpm': liquid_flow,
'lg_ratio': lg_ratio,
'expected_efficiency_pct': target_efficiency_pct
}
# 示例用法
scrubber = WetScrubberDesign()
# SO2去除填充塔
packed = scrubber.packed_tower_sizing(
gas_flow_acfm=30000,
pollutant='SO2',
inlet_conc_ppm=1000,
outlet_conc_ppm=50
)
print(f"Packed tower diameter: {packed['diameter_ft']:.1f} ft")
print(f"Packing height: {packed['packing_height_ft']:.1f} ft")
print(f"Removal efficiency: {packed['removal_efficiency_pct']:.1f}%")
# 颗粒物文氏
venturi = scrubber.venturi_scrubber_sizing(
gas_flow_acfm=30000,
particulate_loading_gr_acf=5.0,
target_efficiency_pct=95
)
print(f"
Venturi pressure drop: {venturi['pressure_drop_in_wc']} in w.c.")
print(f"Liquid flow: {venturi['liquid_flow_gpm']:.0f} gpm")
BACT分析
class BACTAnalysis:
"""最佳可用控制技术分析"""
# 控制技术数据库(简化)
CONTROL_TECHNOLOGIES = {
'PM': [
{'name': 'Baghouse', 'efficiency': 99.9, 'cost_per_ton': 500},
{'name': 'ESP', 'efficiency': 99.5, 'cost_per_ton': 400},
{'name': 'Cyclone', 'efficiency': 90, 'cost_per_ton': 100},
{'name': 'Wet Scrubber', 'efficiency': 95, 'cost_per_ton': 600}
],
'SO2': [
{'name': 'Wet FGD', 'efficiency': 98, 'cost_per_ton': 800},
{'name': 'Dry FGD', 'efficiency': 95, 'cost_per_ton': 600},
{'name': 'SDA', 'efficiency': 92, 'cost_per_ton': 500}
],
'NOx': [
{'name': 'SCR', 'efficiency': 90, 'cost_per_ton': 2000},
{'name': 'SNCR', 'efficiency': 60, 'cost_per_ton': 500},
{'name': 'Low-NOx Burner', 'efficiency': 50, 'cost_per_ton': 200}
],
'VOC': [
{'name': 'RTO', 'efficiency': 99, 'cost_per_ton': 3000},
{'name': 'Catalytic Oxidizer', 'efficiency': 98, 'cost_per_ton': 2500},
{'name': 'Carbon Adsorption', 'efficiency': 95, 'cost_per_ton': 1500},
{'name': 'Condenser', 'efficiency': 85, 'cost_per_ton': 800}
]
}
def top_down_bact(self, pollutant: str, uncontrolled_tpy: float,
cost_threshold: float = 15000) -> List[Dict]:
"""执行自上而下的BACT分析
参数:
pollutant: 污染物类型(PM, SO2, NOx, VOC)
uncontrolled_tpy: 未控制排放量(吨/年)
cost_threshold: 最大可接受成本($/吨移除)
"""
technologies = self.CONTROL_TECHNOLOGIES.get(pollutant, [])
# 按效率排序(最高优先)- 自上而下的方法
technologies = sorted(technologies, key=lambda x: x['efficiency'], reverse=True)
results = []
for tech in technologies:
tons_removed = uncontrolled_tpy * tech['efficiency'] / 100
controlled_emissions = uncontrolled_tpy - tons_removed
annual_cost = tech['cost_per_ton'] * tons_removed
cost_effectiveness = tech['cost_per_ton']
is_feasible = cost_effectiveness <= cost_threshold
results.append({
'technology': tech['name'],
'efficiency_pct': tech['efficiency'],
'controlled_emissions_tpy': controlled_emissions,
'tons_removed_tpy': tons_removed,
'annual_cost': annual_cost,
'cost_effectiveness': cost_effectiveness,
'is_cost_effective': is_feasible,
'bact_candidate': is_feasible
})
if is_feasible:
break # 第一个成本效益选项是BACT
return results
def generate_bact_report(self, pollutant: str,
uncontrolled_tpy: float) -> str:
"""生成BACT确定报告"""
analysis = self.top_down_bact(pollutant, uncontrolled_tpy)
report = f"""
BACT DETERMINATION - {pollutant}
================================
Uncontrolled Emissions: {uncontrolled_tpy:.1f} tpy
TOP-DOWN ANALYSIS:
"""
for i, tech in enumerate(analysis, 1):
status = "BACT SELECTED" if tech['bact_candidate'] else \
"Eliminated - Cost" if not tech['is_cost_effective'] else "Evaluated"
report += f"""
Step {i}: {tech['technology']}
Control Efficiency: {tech['efficiency_pct']}%
Controlled Emissions: {tech['controlled_emissions_tpy']:.2f} tpy
Cost Effectiveness: ${tech['cost_effectiveness']:,.0f}/ton
Status: {status}
"""
# 找到BACT
bact = next((t for t in analysis if t['bact_candidate']), None)
if bact:
report += f"""
BACT DETERMINATION:
Selected Technology: {bact['technology']}
Emission Limit: {bact['controlled_emissions_tpy']:.2f} tpy
Control Efficiency: {bact['efficiency_pct']}%
"""
return report
# 示例用法
bact = BACTAnalysis()
report = bact.generate_bact_report('NOx', uncontrolled_tpy=100)
print(report)
# VOC BACT
voc_analysis = bact.top_down_bact('VOC', uncontrolled_tpy=50)
for tech in voc_analysis:
print(f"{tech['technology']}: {tech['efficiency_pct']}% - "
f"${tech['cost_effectiveness']}/ton - "
f"{'BACT' if tech['bact_candidate'] else 'Eliminated'}")
使用指南
何时使用此技能
- 空气污染控制系统设计
- 许可证申请准备
- BACT/LAER/MACT确定
- 控制设备优化
- 减排项目
最佳实践
- 在设计前彻底表征排放
- 考虑多个控制选项用于BACT
- 在尺寸中考虑变化的操作条件
- 在设计中包括维护通道
- 设计时考虑负载变化
- 计划监测以验证性能
流程集成
- AQ-002: 空气污染控制系统设计(所有阶段)
- AQ-001: 空气许可证申请开发(BACT确定)
依赖关系
- numpy: 数值计算
- scipy: 工程相关性
参考资料
- EPA空气污染控制技术概况
- OAQPS控制成本手册
- EPA RACT/BACT/LAER信息中心