string - 如何在 OpenMDAO 组件之间传递字符串值?

标签 string openmdao

我希望能够在组件之间传递字符串值。这在最新版本的 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无法将字符串转换为float:hill,这是预期的。我只是想知道是否有一种方法可以使这项工作同时保持 para_shape 作为 PreProcessor 的字符串输出和 Parabola 的字符串输入.

除此之外,在我的例子中传递字符串会很方便,我认为当使用支持离散值的优化算法(例如遗传算法)时,这也可能会有所帮助。在这些算法中,para_shape 可以是一个设计变量,其可能值为 hillcanyon。在幕后,这样的字符串变量可能会映射到整数值,例如 0:hill, 1:canyon

总而言之,我的问题是:OpenMDAO 2 是否会实现传递对象(或允许我定义字符串输入/输出的类似功能),或者是否已经有办法做到这一点?

最佳答案

好消息是当前版本的 OpenMDAO 确实支持离散变量。我已经更新了您的示例,以使用当前语法来声明离散变量并将它们传递给计算函数。基本上,更改是您必须使用 add_discrete_inputadd_discrete_output 声明离散变量。此外,您必须将 discrete_inputsdiscrete_outputs 作为参数添加到 compute 函数中,因此新版本如下所示:defcompute (自身、输入、输出、离散输入、离散输出)。另请注意,如果您的组件碰巧使用其他函数,例如 compute_partialscompute_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()

关于string - 如何在 OpenMDAO 组件之间传递字符串值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55968555/

相关文章:

python - 如何向 openmdao 驱动程序添加整数变量?

openmdao - 在 Openmdao 中使用 APOPT (MINLP) 求解器

python - 如何通过删除python中的重复项进行压缩?

编译中间有空终止符的 char 数组

python - 如何计算python3中大文本中排列(重叠)的出现次数?

openmdao - 检查优化器是否支持梯度

multi-level - 如何在 OpenMDAO 1.x 中使用嵌套问题?

php - 多个辅音的正则表达式

c++ - 如何在C++中将字符串转换为json格式?

optimization - SLSQP 优化算法是如何工作的?