跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Python 实现活性污泥模型 ASM2d 参数校准与优化

基于 QSDSAN 库与 Optuna 框架,详解活性污泥模型 ASM2d 的参数校准流程。涵盖进水浓度迭代修正、OSA 灵敏度分析筛选关键参数、单目标优化策略及动态仿真核心函数实现。通过 Python 代码复现论文中的参数调优方法,解决污水处理模拟中参数不确定性问题,提供完整的静态与动态仿真逻辑。

CodeArtist发布于 2026/3/26更新于 2026/6/1217 浏览
Python 实现活性污泥模型 ASM2d 参数校准与优化

Python 实现活性污泥模型 ASM2d 参数校准与优化

活性污泥模型(ASM2d)是污水处理工艺模拟的核心工具。在实际工程中,模型参数的准确性直接决定了仿真结果的可信度。本文基于 QSDSAN 库与 Optuna 框架,详细解析如何从零开始实现 ASM2d 的参数校准流程。我们将通过 Python 代码复现论文中的参数调优方法,涵盖进水浓度修正、灵敏度分析筛选、单目标优化及动态仿真等关键环节。

1. 进水浓度调整

在运行仿真前,必须确保输入的水质数据与模型内部计算一致。由于 ASM2d 组分复杂,直接输入的 COD/TN/TP 往往无法直接映射到具体的组分浓度。我们需要通过迭代调整 WasteStream 的浓度输入,使得计算得到的实际值与目标值在小数位上保持一致。

核心逻辑如下:

  1. 设定初始调整值为目标值。
  2. 构建 WasteStream 并计算实际 COD/TN/TP。
  3. 比较计算值与目标值的差异。
  4. 若未收敛,则根据误差更新调整值,继续循环。
import qsdsan as qs
from qsdsan import WasteStream

def Adjusting_influent_concentration(first_inflow_value, input_COD_value, input_TN_value, input_TP_value):
    """
    目的:根据用户输入的目标进水 COD/TN/TP 值,迭代调整 WasteStream 的浓度输入,
    使得通过 WasteStream 计算得到的实际 COD/TN/TP 与目标值一致。
    """
    adjusting_COD_value = input_COD_value
    adjusting_TN_value = input_TN_value
    adjusting_TP_value = input_TP_value

    def simulate_influent_internal(first_inflow_value, adjusting_COD_value, adjusting_TN_value, adjusting_TP_value):
        Q_inf = first_inflow_value
        Temp = 273.15 + 20
        influent = WasteStream('influent', T=Temp)
        default_inf_kwargs = {
            'concentrations': {
                'S_I': 0, 'X_I': 0, 'S_F': 0, 'S_A': 0,
                'X_S': adjusting_COD_value,
                'S_NH4': 0, 'S_N2': 0, 'S_NO3': adjusting_TN_value,
                'S_PO4': adjusting_TP_value,
                'X_PP': 0, 'X_PHA': 0, 'X_H': 0.15,
                'X_AUT': 0, 'X_PAO': 0, 'S_ALK': 7 * 12,
            },
            'units': ('m3/d', 'mg/L'),
        }
        influent.set_flow_by_concentration(Q_inf, **default_inf_kwargs)
        return round(influent.COD, 2), round(influent.TN, 2), round(influent.TP, 2)

    iteration_count = 0
    while True:
        iteration_count += 1
        simulate_influent_COD, simulate_influent_TN, simulate_influent_TP = simulate_influent_internal(
            first_inflow_value, adjusting_COD_value, adjusting_TN_value, adjusting_TP_value)

        if (round(simulate_influent_COD, 3) == round(input_COD_value, 3) and
            round(simulate_influent_TN, 3) == round(input_TN_value, 3) and
            round(simulate_influent_TP, 3) == round(input_TP_value, 3)):
            break

        difference_COD = input_COD_value - simulate_influent_COD
        adjusting_COD_value += difference_COD
        difference_TN = input_TN_value - simulate_influent_TN
        adjusting_TN_value += difference_TN
        difference_TP = input_TP_value - simulate_influent_TP
        adjusting_TP_value += difference_TP

        if iteration_count > 100:
            print(f"警告:迭代次数超过 100 次,停止调整")
            break

    return adjusting_COD_value, adjusting_TN_value, adjusting_TP_value

2. 参数选择(OSA 方法)

为了减少优化维度,我们采用 OSA(基于统计/灵敏度文件)方法进行参数筛选。该步骤读取预先计算的敏感性分析文件,选取对目标指标(如 COD)影响最大的前 7 个参数作为优化变量。

这不仅能加快收敛速度,还能避免无关参数干扰优化结果。代码主要涉及读取 Excel 文件,提取参数名及平均值,并与原始默认参数字典进行匹配。

import pandas as pd

def OSA(name_1):
    """
    OSA: 读取预先计算的参数灵敏度文件,选取灵敏度最高(平均值最大)的前 7 个参数,
    并返回这些参数及其原始默认值作为优化或调参的输入。
    """
    file_path = fr'/root/autodl-tmp/data/raw/{name_1}_OSA_FP.xlsx'
    df = pd.read_excel(file_path)
    top_parameters = df[['Parameter', 'average_value']].sort_values(by='average_value', ascending=False).head(7)

    original_params = {
        'f_SI': 0, 'Y_H': 0.625, 'f_XI_H': 0.1, 'Y_PAO': 0.625, 'Y_PO4': 0.4,
        # ... 更多默认参数 ...
        'mu_AUT': 1, 'b_AUT': 0.15, 'K_O2_AUT': 0.5
    }

    params = []
    for param in top_parameters['Parameter']:
        if param in original_params:
            params.append({'name': param, 'initial_value': original_params[param]})

    param_names = [p['name'] for p in params]
    param_initial_values = [p['initial_value'] for p in params]
    return param_names, param_initial_values

3. 单目标优化

选定参数后,利用 Optuna 进行单目标优化。我们以最小化出水 COD 或 TN 的百分比误差为目标函数。

在 objective 函数中,Optuna 会采样一组参数,调用仿真函数计算误差。如果仿真失败(如出现 NaN),则剪枝该试验。优化过程中,系统会自动记录参数重要性(灵敏度),并生成可视化图表(平行坐标图、优化历史图),帮助我们理解参数间的关联。

import optuna

def OT(param_names, param_initial_values, day, name_1):
    """
    使用 Optuna 对单一目标(COD 或 TN)进行参数优化。
    """
    # 定义目标函数
    def objective(trial):
        parameter_adjustments = []
        for i in range(len(param_names)):
            adjustment = trial.suggest_uniform(
                param_names[i], 
                param_initial_values[i] * 0.5, 
                param_initial_values[i] * 1.5
            )
            parameter_adjustments.append(adjustment)

        try:
            # 调用仿真函数获取误差
            cod_err, tn_err, tp_err = simulate_one(..., parameter_adjustments, ...)
            
            if np.isnan(cod_err) or np.isinf(cod_err):
                raise optuna.exceptions.TrialPruned()

            if name_1 == "COD":
                trial.set_user_attr('TN_percentage_difference', tn_err)
                return cod_err
            elif name_1 == "TN":
                trial.set_user_attr('COD_percentage_difference', cod_err)
                return tn_err
        except Exception as e:
            raise optuna.exceptions.TrialPruned()

    # 创建 Study 对象
    sqlite_path = fr"../data/process/{day}_{name}.db"
    storage_url = f"sqlite:///{sqlite_path.replace(os.sep, '/')}"
    study = optuna.create_study(direction="minimize", storage=storage_url, load_if_exists=True)

    # 执行优化
    study.optimize(objective, n_trials=70, n_jobs=-1)

    # 保存结果与可视化
    # ... 保存 HTML 图表与最优参数 ...
    return study

4. 仿真函数核心

仿真是整个流程的引擎。simulate_one 函数负责搭建反应器系统(厌氧池、好氧池、沉淀池),设置生物过程模型(ASM2d),并执行动态求解。

关键点在于:

  • 正确配置反应器容积与回流比。
  • 初始化各单元浓度(通常从 Excel 加载)。
  • 设置求解器容差(BDF 方法)。
  • 提取出水数据并计算误差。
def simulate_one(first_inflow_value, external_return_flow_value, input_COD_value, output_COD_value,
                 adjusting_COD_value, input_TN_value, output_TN_value, adjusting_TN_value,
                 input_TP_value, output_TP_value, adjusting_TP_value, param_names,
                 param_initial_values, parameter_adjustments, day, name, trial):
    # 1. 设置流量与温度
    Q_inf = first_inflow_value
    Q_was = 385
    Q_ext = external_return_flow_value
    Temp = 273.15 + 20

    # 2. 创建 WasteStream 对象
    influent = WasteStream('influent', T=Temp)
    effluent = WasteStream('effluent', T=Temp)
    # ... 其他流股 ...

    # 3. 设置进水组成
    default_inf_kwargs = { ... } # 同上文
    influent.set_flow_by_concentration(Q_inf, **default_inf_kwargs)

    # 4. 配置反应器系统
    V_an = 1000 * 33.33
    V_ae = 1333 * 33.33
    aer1 = pc.DiffusedAeration('aer1', DO_ID='S_O2', KLa=240, DOsat=8.0, V=V_ae)
    # ... 构建 CSTR 单元 A1, A2, O1, O2, O3, C1 ...

    # 5. 设置生物过程模型
    asm2d = pc.ASM2d()
    p2 = asm2d.aero_hydrolysis
    adjusted_params = {}
    for i in range(len(param_names)):
        adjusted_params[param_names[i]] = parameter_adjustments[i]
    p2.set_parameters(**adjusted_params)

    # 6. 构建系统并初始化
    sys = System('example_system', path=(...), recycle=(...))
    # ... 加载初始数据 ...

    # 7. 运行仿真
    sys.simulate(t_span=(0, 50), method='BDF')

    # 8. 计算误差
    simulate_COD = effluent.COD
    simulate_TN = effluent.TN
    simulate_TP = effluent.TP

    COD_pct_diff = abs((output_COD_value - simulate_COD) / output_COD_value * 100)
    TN_pct_diff = abs((output_TN_value - simulate_TN) / output_TN_value * 100)
    TP_pct_diff = abs((output_TP_value - simulate_TP) / output_TP_value * 100)

    return COD_pct_diff, TN_pct_diff, TP_pct_diff

5. 主流程整合

最后,将上述模块整合到主循环中。程序逐日读取进水与出水观测数据,自动执行参数选择与调优,并将最优结果保存至本地。通过这种方式,我们可以实现对污水处理厂长期运行的自动化参数校准。

def main():
    # 读取输入数据
    file_path = r'..\data\raw\input.xlsx'
    df = pd.read_excel(file_path)

    # 主循环:逐日执行
    for day in range(1, 50):
        # 提取当日数据
        first_inflow_value = df['inflow_flow'].iloc[day]
        # ... 其他参数 ...

        # 配置优化目标
        name_1 = 'TN'  # 优化目标
        name_2 = 'FP'  # 参数选择方法
        name_3 = 'TT'  # 调优方法
        name = f'{name_1}_{name_2}_{name_3}'

        # 动态加载函数
        param_function = globals().get(name_2)
        tuning_function = globals().get(name_3)

        # 执行流程
        param_names, param_initial_values = param_function(name_1)
        tuning_function(param_names, param_initial_values, day, name_1)

if __name__ == "__main__":
    main()

通过以上步骤,我们完成了一个完整的 ASM2d 参数校准框架。实际应用中,请根据具体项目路径修改文件引用,并根据水质特性调整优化策略。

目录

  1. Python 实现活性污泥模型 ASM2d 参数校准与优化
  2. 1. 进水浓度调整
  3. 2. 参数选择(OSA 方法)
  4. 3. 单目标优化
  5. 4. 仿真函数核心
  6. 5. 主流程整合
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • SLAM 与室内绝对定位融合:终结机器人导航漂移
  • 鸿蒙 Flutter 智能家居应用开发实战指南
  • Java 助力充电桩物联网与新能源深度融合
  • Stable Diffusion 的 3 个主流替代方案
  • iceoryx 附录:C++ 内存模型与原子操作详解
  • MySQL 用户权限配置与 C/C++ 客户端连接实战
  • AI 驱动 PDF 文档智能解析:MinerU 本地部署与 API 调用
  • 扩散模型原理与图像生成实战
  • Python 爬取财富中国 500 强数据示例
  • Claude 官方 Skill-Creator:AI 技能工程化完整体系解析
  • 基于 KSWEB 在安卓手机部署 Typecho 博客并配置外网访问
  • 人工智能学习指南:从基础语法到大模型实战
  • 多模态大模型:开启通用人工智能新篇章
  • 免费 AI 大模型 API 汇总及国内大模型使用教程
  • AI 领域为何全面转向 AI Agent 方向?
  • Llama 3:Meta 新一代开源大语言模型详解
  • 国内大模型公司面试经历与技术复盘
  • 人工智能产品经理:AI 时代的产品经理进阶手册
  • AI 大模型开发必备书籍推荐:从入门到实战
  • AI 大模型工程师成长路径:从零基础到就业

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online