如何将Gekko微分方程求解从时间维度改为距离维度?
平推流反应器稳态浓度分布的Gekko建模优化
问题背景
需要求解平推流反应器中基于距离维度的稳态微分方程,Gekko默认使用m.time定义时间范围、y.dt()表示对时间的导数,希望通过类似m.distance和y.dx()的写法提升模型可读性,无需处理动态偏微分方程(PDE),仅需稳态浓度分布。
尝试代码及报错
尝试自定义m.distance和y.dx()的代码:
from gekko import GEKKO import numpy as np import matplotlib.pyplot as plt m = GEKKO() k = 10 m.distance = np.linspace(0,20,100) y = m.Var(value=5) t = m.Param(value=m.time) m.Equation(k*y.dx()==-t*y) m.options.IMODE=4 m.solve(disp=False) plt.plot(m.distance,y.value) plt.xlabel('distance') plt.ylabel('y') plt.show()
运行后报错:
Traceback (most recent call last): File "C:\Users\johnh\Desktop\test1.py", line 11, in <module> m.Equation(k*y.dx()==-t*y) File "C:\Users\johnh\Python311\Lib\site-packages\gekko\gk_operators.py", line 36, in __getattr__ raise AttributeError(name) AttributeError: dx. Did you mean: 'dt'?
简便解决方案
Gekko未提供原生的dx()方法和m.distance维度,但可通过两种方式实现距离维度的可读性优化:
方法1:复用m.time并明确变量语义
将m.time直接定义为距离范围,通过变量命名和注释明确物理意义,导数仍用dt()但注释说明是对距离的导数:
from gekko import GEKKO import numpy as np import matplotlib.pyplot as plt m = GEKKO() k = 10 # 用距离数组替代时间数组 distance = np.linspace(0,20,100) m.time = distance y = m.Var(value=5) # 定义距离参数,替代原时间参数 x = m.Param(value=m.time) # dt()实际表示对距离的导数,添加注释明确 m.Equation(k * y.dt() == -x * y) m.options.IMODE=4 # 稳态ODE积分求解模式 m.solve(disp=False) plt.plot(distance, y.value) plt.xlabel('距离') plt.ylabel('y浓度') plt.show()
方法2:自定义dx别名进一步简化写法
给变量添加dx属性指向dt方法,直接用y.dx()编写方程,语义更贴合距离维度:
from gekko import GEKKO import numpy as np import matplotlib.pyplot as plt m = GEKKO() k = 10 distance = np.linspace(0,20,100) m.time = distance y = m.Var(value=5) # 给变量绑定dx属性,指向dt方法 y.dx = y.dt x = m.Param(value=m.time) # 直接用dx()表示对距离的导数 m.Equation(k * y.dx() == -x * y) m.options.IMODE=4 m.solve(disp=False) plt.plot(distance, y.value) plt.xlabel('距离') plt.ylabel('y浓度') plt.show()
原理说明
Gekko的IMODE=4模式本质是求解常微分方程(ODE)的积分问题,核心是处理单向递增的独立变量,时间和距离在稳态场景下都是单向变量,因此可以直接复用m.time维度,通过变量命名或别名来匹配物理意义,既不改变Gekko的求解逻辑,又能大幅提升模型可读性。
内容的提问来源于stack exchange,提问作者TexasEngineer
相关产品推荐
相关产品推荐

