如何在OpenMDAO中处理大小为2D的参数?

时间:2016-01-13 16:48:23

标签: openmdao

我有一个2D数组的参数。它可以正常输出正确但当我尝试使用渐变(例如优化或check_total_derivatives)做任何事情时,我得到一个大小调整错误。我想知道处理2D大小的params最好的方法是什么。以下是示例代码:

import numpy as np
from openmdao.api import Group, Problem, Component, IndepVarComp, ExecComp

class C1(Component):
    def __init__(self, n):
        super(C1, self).__init__()
        self.add_param('grid', val=np.zeros((n, n)))
        self.add_output('x', shape=1)
        self.n = n

def solve_nonlinear(self, params, unknowns, resids):
    x = 0
    for i in range(self.n):
        for j in range(self.n):
            x += params['grid'][i][j]
    unknowns['x'] = x

def linearize(self, params, unknowns, resids):
    J = {}
    J['x', 'grid'] = np.ones((self.n, self.n))
    return J

class Group1(Group):
    def __init__(self, n):
        super(Group1, self).__init__()
        self.add('grid', IndepVarComp('grid', np.zeros((n, n))), promotes=['*'])
        self.add('c1', C1(n), promotes=['*'])
        self.add('obj_cmp', ExecComp('obj = -x', x=1.0), promotes=['*'])
n = 3
p = Problem()
p.root = Group1(n)
p.setup(check=False)
p['grid'] = np.ones((n, n))
p.run()
p.check_total_derivatives()
print p['x']

我收到错误:

ValueError: In component 'c1', the derivative of 'x' wrt 'grid' should have shape '(1, 3)' but has shape '(3, 3)' instead.

我觉得这种情况下的导数应该是大小(3,3),因为这是输入参数的大小。你如何处理2D参数?

2 个答案:

答案 0 :(得分:5)

雅各比派中有一个小错误;它应该是这样的:

def linearize(self, params, unknowns, resids):
    J = {}
    J['x', 'grid'] = np.ones((1, self.n*self.n))
    return J

输出x是长度1,而参数grid是n乘n,所以它是长度n * n,因此得到的J应该是1乘9。随着这个改变,我得到正确答案。

我确实注意到错误消息中有错误。应该说预期的形状是(1,9)而不是(1,3)。我会解决这个问题。

答案 1 :(得分:1)

当你有一个2D变量并且需要构造渐变时,将它展平(按行主要顺序)并根据展平版本制定渐变。