我希望能够在组件之间传递字符串值。在最新版本的OpenMDAO中有可能吗?在将来的版本中有可能吗?
如果我理解正确,那么在早期版本的带有传递对象的OpenMDAO(V <= 1)中支持字符串的传递。当前,我使用一种解决方法,将工具的字符串输入和输出写入单独的文件,并在需要时从这些文件中获取。然后,这不在OpenMDAO模型之内。
这是一个小示例,说明如果可以将字符串用作输入和输出,将支持的模型类型。当然,这只是一个演示案例。
from openmdao.core.explicitcomponent import ExplicitComponent
from openmdao.core.group import Group
from openmdao.core.indepvarcomp import IndepVarComp
from openmdao.core.problem import Problem
from openmdao.devtools.problem_viewer.problem_viewer import view_model
class PreProcessor(ExplicitComponent):
def setup(self):
self.add_input('a', val=0.)
self.add_output('para_shape', val='hill')
def compute(self, inputs, outputs):
if inputs['a'] <= 0.:
outputs['para_shape'] = 'hill'
else:
outputs['para_shape'] = 'canyon'
class Parabola(ExplicitComponent):
def setup(self):
self.add_input('x', val=0.)
self.add_input('para_shape', val='hill')
self.add_output('y', val=0.)
def compute(self, inputs, outputs):
if inputs['para_shape'] == 'hill':
outputs['y'] = -inputs['x']**2
elif inputs['para_shape'] == 'canyon':
outputs['y'] = inputs['x']**2
else:
raise IOError('Invalid "para_shape" value "{}" provided.'.format(inputs['para_shape']))
if __name__ == "__main__":
model = Group()
ivc = IndepVarComp()
ivc.add_output('a', 2.)
ivc.add_output('x', 4.)
model.add_subsystem('vars', ivc, promotes=['*'])
model.add_subsystem('preprocessor', PreProcessor(), promotes=['*'])
model.add_subsystem('parabola', Parabola(), promotes=['*'])
prob = Problem(model)
prob.setup()
view_model(prob, outfile='n2_pass_by_object_example.html')
prob.run_model()
如果运行此命令,我将得到ValueError
的{{1}},这是可以预期的。我只是想知道是否有一种方法可以使could not convert string to float: hill
保留为para_shape
的字符串输出,而保留PreProcessor
的字符串输入。
除此以外,在我的情况下,很方便地传递字符串,我认为当使用支持离散值的优化算法(例如遗传算法)时,这也可能会有所帮助。在这些算法中,Parabola
可以是一个设计变量,可能的值为para_shape
或hill
。在幕后,这样的字符串变量可能会映射为整数值,例如canyon
。
总而言之,我的问题是:将为OpenMDAO 2实现传递对象(或类似的功能,使我能够定义字符串输入/输出)吗?
答案 0 :(得分:1)
好消息是,当前版本的OpenMDAO确实支持离散变量。我已经更新了您的示例,以使用当前语法声明离散变量并将其传递给计算函数。基本上,更改是您必须使用add_discrete_input
和add_discrete_output
声明离散变量。另外,您必须将discrete_inputs
和discrete_outputs
作为参数添加到compute
函数中,因此新版本看起来像:def compute(self, inputs, outputs, discrete_inputs, discrete_outputs)
。还要注意,如果您的组件碰巧使用了其他函数,例如compute_partials
,compute_jacvec_product
和其他函数,则还需要其他离散的args。
坏消息是您的示例发现了view_model
中的错误。看来view_model
当前不正确支持离散变量。我在错误跟踪器中放入了一个描述问题的错误,因此希望我们尽快予以解决。
from openmdao.core.explicitcomponent import ExplicitComponent
from openmdao.core.group import Group
from openmdao.core.indepvarcomp import IndepVarComp
from openmdao.core.problem import Problem
from openmdao.devtools.problem_viewer.problem_viewer import view_model
class PreProcessor(ExplicitComponent):
def setup(self):
self.add_input('a', val=0.)
self.add_discrete_output('para_shape', val='hill')
def compute(self, inputs, outputs, discrete_inputs, discrete_outputs):
if inputs['a'] <= 0.:
discrete_outputs['para_shape'] = 'hill'
else:
discrete_outputs['para_shape'] = 'canyon'
class Parabola(ExplicitComponent):
def setup(self):
self.add_input('x', val=0.)
self.add_discrete_input('para_shape', val='hill')
self.add_output('y', val=0.)
def compute(self, inputs, outputs, discrete_inputs, discrete_outputs):
if discrete_inputs['para_shape'] == 'hill':
outputs['y'] = -inputs['x']**2
elif discrete_inputs['para_shape'] == 'canyon':
outputs['y'] = inputs['x']**2
else:
raise IOError('Invalid "para_shape" value "{}" provided.'.format(inputs['para_shape']))
if __name__ == "__main__":
model = Group()
ivc = IndepVarComp()
ivc.add_output('a', 2.)
ivc.add_output('x', 4.)
model.add_subsystem('vars', ivc, promotes=['*'])
model.add_subsystem('preprocessor', PreProcessor(), promotes=['*'])
model.add_subsystem('parabola', Parabola(), promotes=['*'])
prob = Problem(model)
prob.setup()
view_model(prob, outfile='n2_pass_by_object_example.html')
prob.run_model()