Gekko单次仿真中能否多次修改参数设置分段时变输入ib
Gekko分段常值参数实现方法
Gekko的IMODE=4动态联立求解模式原生支持时变分段参数,不需要拆分仿真多次求解,单次运行即可实现你需要的分段恒定ib输入。
具体实现步骤
- 首先构建仿真时间网格
因为你要求每个ib取值对应的仿真区间时长相等,先按照分段长度、仿真步长生成所有计算时间点,赋值给m.time。示例代码如下:import numpy as np # 按需修改参数:分段数量、单段时长、仿真步长 n_seg = 5 # 分段总数,对应ib的取值个数 seg_dur = 2e-9 # 单段时长 dt = 1e-11 # 仿真计算步长 # 生成时间点序列 m.time = np.linspace(0, n_seg*seg_dur, int(n_seg*seg_dur/dt) + 1) - 定义分段常值的
ib参数
不要把ib设为固定Python常数,要定义为Gekko的Param类型,传入和m.time长度完全匹配的数组,每个时间点对应所在分段的ib取值。示例代码如下:# 替换为你实际的ib分段取值列表,长度和n_seg一致 ib_seg_vals = [0, 1.5e-6, 0, -1.5e-6, 0] # 生成逐时间点的ib取值数组 ib_arr = np.zeros_like(m.time) for idx, t in enumerate(m.time): current_seg = min(int(t // seg_dur), n_seg - 1) ib_arr[idx] = ib_seg_vals[current_seg] # 定义为Gekko参数 ib = m.Param(value=ib_arr)提示:如果跳变点处出现求解不收敛的问题,可以把跳变位置放在时间网格节点上,或者将跳变点前后1-2个步长设为线性过渡区间,避免参数突变带来的数值刚性。
- 代入方程正常求解
把你原方程最后一行的固定ib替换为上面定义的ib参数即可,其余代码(变量定义、方程书写、求解设置)不需要改动,直接调用m.solve()就能完成全段联立仿真,ib会自动按照设定的分段值随时间变化。
简便写法(可选)
如果分段数量较多,不需要手动生成numpy数组,可以直接用Gekko内置的阶跃函数m.step()拼接生成分段参数:
# 初始值取第一段的ib ib = m.Param(value=ib_seg_vals[0]) # 逐段叠加阶跃变化 for seg_id in range(1, n_seg): step_t = seg_id * seg_dur ib += (ib_seg_vals[seg_id] - ib_seg_vals[seg_id-1]) * m.step(m.time - step_t, 1)
求解优化建议
- 如果参数跳变处结果精度不足,可以把
m.options.NODES从默认值2调整为3或4,增加正交配置点数量提高计算精度。 - 你当前手动定义一阶导、二阶导中间变量的写法可以正常运行,也可以直接用
phi.dt()表示一阶导、phi.dt().dt()表示二阶导,减少冗余变量定义,不影响求解结果。
内容的提问来源于stack exchange,提问作者Mengfei Zhao
相关产品推荐
相关产品推荐

