You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenMDAO(IPOPT运行时)获取设计变量值调试轨迹优化?

在OpenMDAO/Dymos中调试求解器中间解的方法

完全可以在OpenMDAO(及基于它的Dymos)中访问求解器运行时的设计变量与中间值,以下是几种实用实现方式:

1. 利用IPOPT回调函数(针对IPOPT优化器)

如果你的Dymos问题使用IPOPT作为优化器,可直接通过设置IPOPT的回调函数来实时获取迭代过程中的变量值:

步骤与示例代码

def ipopt_iteration_callback(alg_mod, iter_count, obj_value, inf_pr, inf_du, mu, d_norm, regularization_size, alpha_du, alpha_pr, ls_trials, user_data):
    # user_data传入OpenMDAO问题实例
    prob = user_data
    # 获取目标设计变量(替换为你实际的变量路径)
    des_var_val = prob.get_val('trajectory.phases.phase0.design_vars:velocity', units='m/s')
    # 打印迭代信息
    print(f"Iteration {iter_count:3d} | Objective: {obj_value:.6f} | Velocity: {des_var_val[0]:.3f} m/s")
    # 可将数据存入列表用于后续绘图
    # global iteration_data
    # iteration_data.append((iter_count, obj_value, des_var_val[0]))
    return 0  # 返回0继续迭代,返回1终止优化

# 配置IPOPT求解器
prob.driver = om.pyOptSparseDriver()
prob.driver.options['optimizer'] = 'IPOPT'
# 绑定回调函数与问题实例
prob.driver.opt_settings['callback'] = ipopt_iteration_callback
prob.driver.opt_settings['user_data'] = prob

2. 求解器迭代钩子(针对非线性/线性求解器)

如果需要调试Dymos底层的求解器迭代(比如配点法的非线性求解器),可使用OpenMDAO的post_iteration钩子:

步骤与示例代码

def post_iteration_hook(solver):
    prob = solver._problem()
    iter_num = solver.iter_count
    # 获取约束或状态变量(替换为实际路径)
    constraint_val = prob.get_val('trajectory.phases.phase0.constraints:path_constraint')
    print(f"Solver Iter {iter_num:2d} | Path Constraint: {constraint_val.mean():.4f}")

# 获取Dymos相位中的非线性求解器实例
nl_solver = prob.model.trajectory.phases.phase0.nonlinear_solver
# 添加迭代后钩子
nl_solver.add_post_iteration_callback(post_iteration_hook)

3. CaseRecorder记录迭代数据(事后分析)

若无需实时输出,可通过CaseRecorder将所有迭代数据存入SQLite文件,事后加载分析:

步骤与示例代码

# 创建Recorder并绑定到驱动
recorder = om.SqliteRecorder('trajectory_iterations.sql')
prob.driver.add_recorder(recorder)
# 设置需要记录的内容
prob.driver.recording_options['record_desvars'] = True
prob.driver.recording_options['record_objectives'] = True
prob.driver.recording_options['record_constraints'] = True

# 运行优化
prob.run_driver()

# 事后加载数据
case_reader = om.CaseReader('trajectory_iterations.sql')
driver_cases = case_reader.list_cases('driver')
for case_id in driver_cases:
    case = case_reader.get_case(case_id)
    des_vars = case.get_desvars()
    obj_val = case.get_objectives()
    print(f"Case {case_id}: Objective = {obj_val['trajectory.objective'][0]:.6f}")

注意事项

  • 变量路径可通过prob.list_inputs()或prob.list_outputs()命令查看,确保get_val使用正确的路径格式;
  • 若使用pyOptSparseDriver以外的驱动(比如ScipyOptimizeDriver),回调方式会略有差异,但核心思路一致——通过驱动或求解器的钩子函数访问问题实例。

内容的提问来源于stack exchange,提问作者LordCat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:01:14