Engee 文档
Notebook

反应的化学动力学

在宏观尺度上对化学中动态过程的研究通常指的是化学动力学。

这门学科涉及随着时间的推移化学反应的模式,它们对外部条件的依赖以及化学转化的机制。

让我们从这个领域实现一些基本的例子。 由于研究动态过程的数学基础是微分方程,我们将需要库中的几个基本功能。 DifferentialEquations.

In [ ]:
Pkg.add("DifferentialEquations")

作为研究化学动力学简单模型的小项目的一部分,我们将通过四个例子:

  1. 三种物质的抽象化学反应作为模型 DifferentialEquations,

  2. 切换到库 Catalyst 简化模型的语法,

  3. 过渡到物质的实际名称(硫化氢氧化),

  4. 向模型中添加方程:考虑温度对反应速率的影响(Arrhenius模型)。

反应作为微分方程

在第一个例子中,我们计算一个顺序化学反应,其中物质A变成B,然后B变成C。 该过程由常微分方程(ODES)系统描述,其中每种物质浓度的变化率取决于反应常数 . 方程如下所示:

  • (物质A被消耗),

  • (物质BA形成,但分解为C),

  • (物质C积累)。

该模型使我们能够预测反应中所有参与者的浓度如何随时间变化。

In [ ]:
using DifferentialEquations

# Определяем систему ОДУ: dA/dt = -k1*A, dB/dt = k1*A - k2*B, dC/dt = k2*B
function kinetics!(du, u, p, t)
    A, B, C = u
    k1, k2 = p
    du[1] = -k1 * A          # dA/dt
    du[2] = k1 * A - k2 * B  # dB/dt
    du[3] = k2 * B           # dC/dt
end

# Начальные условия и параметры
u0 = [1.0, 0.0, 0.0]  # [A0, B0, C0]
p = [0.5, 0.2]        # константы скорости k1, k2
tspan = (0.0, 10.0)   # интервал времени

# Решаем систему
prob = ODEProblem(kinetics!, u0, tspan, p)
sol = DifferentialEquations.solve(prob, Tsit5())

# Визуализация
plot(sol, label=["A" "B" "C"], xlabel="Время", ylabel="Концентрация", lw=2)
Out[0]:

当计算具有参数的系统时,会观察到这样的图形 = 0.5, =0.2且在初始浓度下( = 1, = 0, = 0 ). 采用标准数值积分法求解. Tsit5().

我们已经展示了如何解决中等复杂性化学动力学讲座的典型例子。 现在让我们探讨如何简化其描述,并使整个方法学更适合解决现实任务。 让我们使用库中提供的域特定语言(DSL)命令来描述这种反应。 Catalyst.

使用催化剂库

让我们设置相同的一致反应 使用库中的命令给出的更短的描述 Catalyst.jl (通过首先安装此库)。

In [ ]:
Pkg.add("Catalyst")

该库包含许多简化化学动力学问题解决方案的工具。 例如,用于创建反应链的符号API(@variables, @species, Reaction, ReactionSystem)、分析反应网络的工具(连接类、稀缺性、可逆性、守恒定律的检测),以及通过 GraphMakieCairoMakie、将反应系统转换为ODE、随机双或跳频过程、与GPU上的计算包集成等。

但我们将使用的主要技术是Catalyst DSL命令(一种描述反应的语言),基本块是构造 @reaction_network begin .. end.

``'茱莉亚
rn=@reaction_network开始
k1,A-->B
k2,B-->C
结束


每个反应都设置在块内部的单独行中。 `begin..end`. 描述的第一个元素是反应的速率,然后是反应中包括的化学符号的比率。 在技术特征中,我们需要设置以下附加参数:

*初始条件,
*步数(有限时间矢量),
*参数值。

由此产生的系统可以设计为ODE(对象 `ODEProblem`),使用命令计算 `solve` 并使用命令将其显示在图形上 `plot`.

In [ ]:
using Catalyst, DifferentialEquations
using Catalyst: solve # Неважно, из какой библиотеки брать эту функцию

# Определяем реакционную сеть
rn = @reaction_network begin
    k1, A --> B
    k2, B --> C
end

# Задаем параметры и начальные условия
p = [:k1 => 0.5, :k2 => 0.2]           # константы скорости
u0 = [:A => 1.0, :B => 0.0, :C => 0.0] # начальные концентрации
tspan = (0.0, 10.0)                    # интервал времени

# Создаем и решаем задачу ОДУ
prob = ODEProblem(rn, u0, tspan, p)
sol = solve(prob, Tsit5())

# Визуализация
plot(sol, label=["A" "B" "C"], xlabel="Время", ylabel="Концентрация", lw=2)
Out[0]:

我们可以看到我们在与第一种情况相同的初始条件和反应速率下获得的熟悉的图表。

现实变量名称

让我们向更方便的反应描述迈出半步。 要描绘一个现实的反应,你只需要改变变量的名称。

考虑硫化氢的氧化反应( )首先到硫(),然后到二氧化硫( 氧存在下)。 简化:( ). 这是一个训练示例,其中所有阶段都具有一阶动力学。

In [ ]:
using Catalyst, DifferentialEquations
using Catalyst: solve

# Определяем реакционную сеть
rn = @reaction_network begin
    k1, H2S --> S      # H₂S → S
    k2, S --> SO2      # S → SO₂
end

# Параметры и начальные условия
p = [:k1 => 0.3, :k2 => 0.1]               # константы скорости (условные, 1/с)
u0 = [:H2S => 1.0, :S => 0.0, :SO2 => 0.0] # начальные концентрации (моль/л)
tspan = (0.0, 20.0)                        # интервал времени (с)

# Решаем задачу ОДУ
prob = ODEProblem(rn, u0, tspan, p)
sol = solve(prob, Tsit5())

# Визуализация
plot(sol, label=["H₂S" "S" "SO₂"], xlabel="Время (с)", ylabel="Концентрация (моль/л)", lw=2 )
Out[0]:

这是一个简化的模型,但它反映了真正的化学,例如,从硫化氢净化气体的过程。

我们用Arrhenius模型补充反应的描述

最后,让我们看一个示例,显示如何补充氧化示例。 通过向其添加额外的依赖性,即反应速率对温度的依赖性。

对于第一个近似值,物质之间的化学反应仅作为这些物质的分子碰撞的结果而发生(简单碰撞模型)。 为了克服能垒,分子必须具有一定的最小活化能,因此模型 ,在哪里 表征碰撞的频率, -温度, -通用气体常数, -活化能。 参与化学反应的分子数量由玻尔兹曼分布确定为比例 .

现在我们的反应有一个现实的流速,明显高于前面例子中的速度。 新的观察间隔反映在参数中tspan.

In [ ]:
using Catalyst, DifferentialEquations
using Catalyst: solve
using Plots.PlotMeasures

# Функции для констант скорости (например, уравнение Аррениуса)
k_1(T) = 1e5 * exp(-5000 / (8.314 * T))  # A * exp(-Ea/RT), условные параметры
k_2(T) = 2e4 * exp(-3000 / (8.314 * T))  # разные A и Ea

# Реакционная сеть с функциональными константами
rn = @reaction_network begin
    k_1(T), H2S --> S    # k1 зависит от температуры T
    k_2(T), S --> SO2    # k2 тоже зависит от T
end

# Параметры и начальные условия
tspan = (0.0, 0.0002)
p = [:T => 273.0]
u0 = [:H2S => 1.0, :S => 0.0, :SO2 => 0.0]

# Решаем ОДУ
prob1 = ODEProblem(rn, u0, tspan, p)
sol1 = solve(prob1, Tsit5())

# График
p1 = plot(sol1, label=["H₂S" "S" "SO₂"], xlabel="Время (с)", ylabel="Концентрация (моль/л)", lw=2,
          title="Реакция окисления H₂S при 273 K", titlefont=font(11), guidefont=font(8),
          bottommargin=30px)

# Параметры и начальные условия
p = [:T => 400.0]
u0 = [:H2S => 1.0, :S => 0.0, :SO2 => 0.0]
prob2 = ODEProblem(rn, u0, tspan, p)
sol2 = solve(prob2, Tsit5())

p2 = plot(sol2, label=[false false false], xlabel="Время (с)", ylabel="Концентрация (моль/л)", lw=2,
          title="Реакция окисления H₂S при 400 K", titlefont=font(11), guidefont=font(8))

plot(p1, p2, layout=(2,1))
Out[0]:

结论

这些示例演示了使用Julia语言在Engee中建模化学动力学的两种方法。 第一个选项,手动设置微分方程组,使您可以完全控制计算,并有助于理解基础知识。 第二种方法,使用催化剂。jl,允许您以简洁的格式描述反应,自动生成方程。 这对于开发速度和误差最小化非常重要的复杂系统尤其有用。

此外,我们还研究了如何在模型中添加额外的方程,并使整个方法学更适合解决化学动力学的现实世界问题。