实例化Dymos中Birkhoff转录时出现KeyError错误
问题描述
运行以下代码时触发KeyError:
import dymos as dm tx = dm.Birkhoff(num_nodes=5)
报错信息:
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) File ~/miniconda3/envs/cp2/lib/python3.11/site-packages/openmdao/utils/options_dictionary.py:514, in OptionsDictionary.__setitem__(self, name, value) 513 try: ---> 514 meta = self._dict[name] 515 except KeyError: 516 # The key must not have been declared. KeyError: 'num_nodes' During handling of the above exception, another exception occurred: KeyError Traceback (most recent call last) Cell In[2], line 1 ----> 1 dm.Birkhoff(num_nodes=5) File ~/miniconda3/envs/cp2/lib/python3.11/site-packages/dymos/transcriptions/pseudospectral/birkhoff.py:30, in Birkhoff.__init__(self, **kwargs) 29 def __init__(self, **kwargs): ---> 30 super(Birkhoff, self).__init__(**kwargs) 31 self._rhs_source = 'ode_iter_group.ode_all' File ~/miniconda3/envs/cp2/lib/python3.11/site-packages/dymos/transcriptions/transcription_base.py:46, in TranscriptionBase.__init__(self, **kwargs) 44 self._declare_options() 45 self.initialize() ---> 46 self.options.update(kwargs) 47 self.init_grid() 49 # Where to query var info. File ~/miniconda3/envs/cp2/lib/python3.11/site-packages/openmdao/utils/options_dictionary.py:473, in OptionsDictionary.update(self, in_dict) 464 """ 465 Update the internal dictionary with the given one. 466 (...) 470 The incoming dictionary to add to the internal one. 471 """ 472 for name in in_dict: ---> 473 self[name] = in_dict[name] File ~/miniconda3/envs/cp2/lib/python3.11/site-packages/openmdao/utils/options_dictionary.py:517, in OptionsDictionary.__setitem__(self, name, value) 514 meta = self._dict[name] 515 except KeyError: 516 # The key must not have been declared. ---> 517 self._raise(f"Option '{name}' cannot be set because it has not been declared.", 518 exc_type=KeyError) 520 if self._read_only: 521 self._raise(f"Tried to set read-only option '{name}'.", exc_type=KeyError) File ~/miniconda3/envs/cp2/lib/python3.11/site-packages/openmdao/utils/options_dictionary.py:245, in OptionsDictionary._raise(self, msg, exc_type) 243 else: 244 full_msg = '{}: {}'.format(self._parent_name, msg) ---> 245 raise exc_type(full_msg) KeyError: "Option 'num_nodes' cannot be set because it has not been declared."
当前环境:dymos 1.10.0,openmdao 3.34.2,怀疑是版本适配问题,想确认Birkhoff转录对应的OpenMDAO版本,或排查其他原因。
问题分析与解决
1. 直接原因:参数传递错误
num_nodes不是dm.Birkhoff类的初始化参数,该参数属于dm.Phase的配置项,用来控制转录的节点数量。正确用法是在创建Phase时指定节点数,而非直接传给Birkhoff构造函数:
import dymos as dm from openmdao.api import Problem prob = Problem() # 示例:创建Phase时指定转录和节点数 phase = prob.model.add_subsystem('phase0', dm.Phase( transcription=dm.Birkhoff(), num_nodes=5, ode_class=YourODEClass # 替换为实际的ODE类 ))
2. 版本兼容性说明
Dymos 1.10.0官方兼容的OpenMDAO版本范围是3.25.0 ~ 3.34.x,你当前使用的OpenMDAO 3.34.2在兼容范围内,版本不是导致该错误的原因。
3. 额外排查点
- 确认Dymos安装完整:若安装过程中出现损坏,可能导致类参数声明异常,可尝试重新安装Dymos 1.10.0:
pip install --force-reinstall dymos==1.10.0 - 检查代码是否混淆了转录类与Phase的参数:所有节点数、时间范围等配置都应在Phase层级设置,转录类仅负责数值方法的实现。
内容的提问来源于stack exchange,提问作者wonderboy3489
相关产品推荐
相关产品推荐

