OpenMDAO:用正常组件替换ExecComps更改输出

时间:2016-02-26 03:51:14

标签: openmdao

我正在运行' Sellar exmaple'从教程。根据{{​​3}}上提供的文档,ExecComp只是宣告正常Component的简写。因此,我尝试将示例中的ExecComp重新定义为普通Component,并在同一示例中使用它们。

示例中的ExecComp定义如下 -

self.add('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',
                             z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0),
                             promotes=['*'])
self.add('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['*'])
self.add('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['*'])

我定义的正常Component如下 -

目标组件

class SellarObjective(Component):
    def __init__(self):
        super(SellarObjective, self).__init__()    
        self.add_param('x', val=0.0)
        self.add_param('y2', val=0.0)
        self.add_param('y1', val=0.0)
        self.add_param('z', val=np.zeros(2))    
        self.add_output('obj', val=0.0)

    def solve_nonlinear(self, params, unknowns, resids):
        unknowns['obj'] = params['x']**2 + params['z'][0] + params['y1'] + exp(-params['y2'])

    def linearize(self, params, unknowns, resids):
        J = {}
        J['obj', 'x'] = 2 * params['x']
        J['obj', 'y2'] = (-1) * exp(-params['y2'])
        J['obj', 'y1'] = 1.0
        J['obj', 'z[0]'] = 1.0
        return J

约束1

class SellarConstraint1(Component):
    def __init__(self):
        super(SellarConstraint1, self).__init__()

        self.add_param('y1', val=0.0)
        self.add_output('con1', val=0.0)

    def solve_nonlinear(self, params, unknowns, resids):
        unknowns['con1'] = 3.16 - params['y1']

    def linearize(self, params, unknowns, resids):
        J = {}
        J['con1', 'y1'] = -1.0
        return J

约束2

class SellarConstraint2(Component):
    def __init__(self):
        super(SellarConstraint2, self).__init__()
        self.add_param('y2', val=0.0)
        self.add_output('con2', val=0.0)

    def solve_nonlinear(self, params, unknowns, resids):
        unknowns['con2'] = params['y2'] - 24.0

    def linearize(self, params, unknowns, resids):
        J = {}
        J['con2', 'y2'] = 1.0
        return J

我在重写的实现中将这些新声明的Component实例化为 -

self.add('obj_cmp', SellarObjective(), promotes=['*'])
self.add('con_cmp1', SellarConstraint1(), promotes=['*'])
self.add('con_cmp2', SellarConstraint2(), promotes=['*'])

代码中的其他所有内容与教程相同。但在执行这两项操作后,当我比较结果时 - 结果不匹配。

我错过了一些明显的东西吗?谢谢你的时间。

1 个答案:

答案 0 :(得分:1)

您的替代目标类有两个小问题:

  1. 目标是z[1],无z[0]
  2. 的函数
  3. 目标相对于z的导数是一个数组,您不能使用z[1]作为关键字。您必须改为使用z
  4. 将您的目标comp更正为以下内容,它应该有效:

    class SellarObjective(Component):
        def __init__(self):
            super(SellarObjective, self).__init__()    
            self.add_param('x', val=0.0)
            self.add_param('y2', val=0.0)
            self.add_param('y1', val=0.0)
            self.add_param('z', val=np.zeros(2))    
            self.add_output('obj', val=0.0)
    
        def solve_nonlinear(self, params, unknowns, resids):
            unknowns['obj'] = params['x']**2 + params['z'][1] + params['y1'] + np.exp(-params['y2'])
    
        def linearize(self, params, unknowns, resids):
            J = {}
            J['obj', 'x'] = 2 * params['x']
            J['obj', 'y2'] = (-1) * np.exp(-params['y2'])
            J['obj', 'y1'] = 1.0
            J['obj', 'z'] = np.array([[0,1],])
            return J