OpenMDAO:用普通组件替换 ExecComps 更改输出

OpenMDAO: Replacing ExecComps with normal Components changes output

我是 运行 教程中 'Sellar exmaple' 的代码。根据 tutorial page 上给出的文档,ExecComp 只是用于声明正常 Component 的 shorthand。所以我尝试将示例中的 ExecComps 重新定义为正常的 Components 并在同一示例中使用它们。

例子中的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如下-

Objective分量

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=['*'])

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

我是不是遗漏了什么明显的东西?谢谢你的时间。

您的替换有两个小问题 objective class:

  1. objective是z[1]的函数,没有z[0]
  2. objective对z的导数是一个数组,不能用z[1]作为key。您必须改用 z

将您的 objective 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