如何在 OpenMDAO 组件之间传递字符串值?
How to pass string values between OpenMDAO components?
我希望能够在组件之间传递字符串值。这在最新版本的 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
那 could not convert string to float: hill
,这是可以预料的。我只是想知道是否有办法在保持 para_shape
作为 PreProcessor
的字符串输出和 Parabola
.
的字符串输入的同时完成这项工作
除了在我的例子中传递字符串很方便之外,我认为这在使用支持离散值的优化算法(例如遗传算法)时也可能有帮助。在这些算法中,para_shape
可能是具有可能值 hill
或 canyon
的设计变量。在幕后,这样的字符串变量可能会映射到一个整数值,如 0:hill, 1:canyon
.
总而言之,我的问题是:对象传递(或允许我定义字符串的类似功能input/output)是否会为 OpenMDAO 2 实现,或者是否已经有这样做的方法?
好消息是当前版本的 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
和其他函数也需要额外的离散参数。
坏消息是您的示例在 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()
我希望能够在组件之间传递字符串值。这在最新版本的 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
那 could not convert string to float: hill
,这是可以预料的。我只是想知道是否有办法在保持 para_shape
作为 PreProcessor
的字符串输出和 Parabola
.
除了在我的例子中传递字符串很方便之外,我认为这在使用支持离散值的优化算法(例如遗传算法)时也可能有帮助。在这些算法中,para_shape
可能是具有可能值 hill
或 canyon
的设计变量。在幕后,这样的字符串变量可能会映射到一个整数值,如 0:hill, 1:canyon
.
总而言之,我的问题是:对象传递(或允许我定义字符串的类似功能input/output)是否会为 OpenMDAO 2 实现,或者是否已经有这样做的方法?
好消息是当前版本的 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
和其他函数也需要额外的离散参数。
坏消息是您的示例在 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()