OpenMDAO框架中子系统通用变量传递问题求助
这是OpenMDAO项目中常见的代码组织与参数传递问题,我给你几个实用的解决方案,按照推荐程度排序:
方案1:使用OpenMDAO官方推荐的Options机制
这是最符合OpenMDAO设计规范的做法,组件的options就是用来传递配置类参数的,完美适配你的场景:
首先在单独的somemodule.py脚本中定义子系统时,通过initialize()方法声明需要接收的参数:
import openmdao.api as om class SomeModule(om.ExplicitComponent): def initialize(self): # 声明需要接收的输入参数字典,指定类型确保安全性 self.options.declare('input_params', types=dict) def setup(self): # 在setup中通过self.options访问传递过来的参数 d = self.options['input_params'] # 比如你可以用d里的键值对来定义变量、设置初始值等 self.add_input('x1', val=d.get('x1_initial', 0.0)) self.add_input('x2', val=d.get('x2_initial', 0.0)) self.add_output('y1') self.add_output('y2') def compute(self, inputs, outputs): # 计算逻辑中同样可以访问self.options['input_params'] params = self.options['input_params'] outputs['y1'] = inputs['x1'] * params['scale_factor'] outputs['y2'] = inputs['x2'] + params['offset']
然后在主脚本中,读取输入文件后,在添加子系统时通过参数传递input_params:
import openmdao.api as om from Inertia import Inertia from somemodule import SomeModule # 读取输入文件 d = hf.read_input(fin) class MDA(om.Group): class ObjCmp(om.ExplicitComponent): def setup(self): self.add_input('y1') self.add_output('obj') def compute(self, inputs, outputs): outputs['obj'] = inputs['y1'] ** 2 def setup(self): # 添加子系统时,直接把读取到的参数字典传入 self.add_subsystem('d1', SomeModule(input_params=d), promotes_inputs=['x1','x2'], promotes_outputs=['y1','y2']) self.add_subsystem('obj_cmp', self.ObjCmp(), promotes_inputs=['y1'], promotes_outputs=['obj'])
这个方法的优势在于参数传递清晰、符合框架规范,而且OpenMDAO会自动处理options的序列化等问题,后续扩展子系统时也能保持一致的代码风格。
方案2:使用全局配置类(适合简单场景)
如果你的框架是单实例运行,且不想给每个子系统都手动传参,可以用一个全局配置类来存储参数:
首先在主脚本的最顶部定义配置类并赋值:
# 主脚本开头 class GlobalConfig: input_params = None # 读取输入文件后赋值 d = hf.read_input(fin) GlobalConfig.input_params = d
然后在子系统脚本中直接导入这个配置类使用:
# somemodule.py import openmdao.api as om from main_script import GlobalConfig class SomeModule(om.ExplicitComponent): def setup(self): d = GlobalConfig.input_params # 后续逻辑直接用d里的变量即可 self.add_input('x1', val=d['x1_initial']) # ... 其他代码 ...
这个方法实现简单,但要注意全局变量的副作用——如果你的框架需要同时运行多个实例,参数会互相干扰,所以仅推荐单实例的简单场景使用。
方案3:通过Group的Options传递给内部组件
如果你的MDA Group本身也需要访问输入参数,同时要传递给内部所有子组件,可以先在Group层面声明options,再向下传递:
# 主脚本 import openmdao.api as om from somemodule import SomeModule d = hf.read_input(fin) class MDA(om.Group): def initialize(self): # Group层面声明需要接收的参数 self.options.declare('input_params', types=dict) class ObjCmp(om.ExplicitComponent): def initialize(self): self.options.declare('input_params', types=dict) def setup(self): self.add_input('y1') self.add_output('obj') def compute(self, inputs, outputs): params = self.options['input_params'] outputs['obj'] = inputs['y1'] * params['obj_weight'] def setup(self): group_params = self.options['input_params'] # 传递给子系统 self.add_subsystem('d1', SomeModule(input_params=group_params), promotes_inputs=['x1','x2'], promotes_outputs=['y1','y2']) self.add_subsystem('obj_cmp', self.ObjCmp(input_params=group_params), promotes_inputs=['y1'], promotes_outputs=['obj']) # 实例化MDA时传入参数 mda = MDA(input_params=d)
这个方法适合Group和内部子组件都依赖同一套配置的场景,结构更规整。
内容的提问来源于stack exchange,提问作者Kasia
相关产品推荐
相关产品推荐

