复杂步骤在OpenMDAO组件中未按预期工作

复杂步骤在OpenMDAO组件中未按预期工作,openmdao,Openmdao,我尝试使用复杂步骤来获得OpenMDAO中一个简单组件的导数。虽然我有解析导数,但我想比较复杂步骤的性能。这是一个更大的设计问题的一部分 下面是一个简单的例子: import numpy as np from openmdao.api import IndepVarComp, Component, Problem, Group class SpatialBeamDisp(Component): def __init__(self, ny): super(Spatial

我尝试使用复杂步骤来获得OpenMDAO中一个简单组件的导数。虽然我有解析导数,但我想比较复杂步骤的性能。这是一个更大的设计问题的一部分

下面是一个简单的例子:

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

class SpatialBeamDisp(Component):

    def __init__(self, ny):
        super(SpatialBeamDisp, self).__init__()

        self.ny = ny

        self.add_param('disp_aug', val=np.zeros(((self.ny+1)*6), dtype='complex'))
        self.add_output('disp', val=np.zeros((self.ny, 6), dtype='complex'))

        # Comment out this line to use analytic derivatives
        self.deriv_options['type'] = 'cs'

    def solve_nonlinear(self, params, unknowns, resids):
        # Obtain the relevant portions of disp_aug and store the reshaped
        # displacements in disp
        unknowns['disp'] = params['disp_aug'][:-6].reshape((self.ny, 6))

    def linearize(self, params, unknowns, resids):
        jac = self.alloc_jacobian()
        n = self.ny * 6
        jac['disp', 'disp_aug'] = np.hstack((np.eye((n)), np.zeros((n, 6))))
        return jac

top = Problem()

root = top.root = Group()

n = 5

disp_aug = np.random.random(((n+1) * 6))

root.add('disp_input', IndepVarComp('disp_aug', disp_aug), promotes=['*'])

root.add('disp_', SpatialBeamDisp(n), promotes=['*'])

top.setup()
top.run_once()
top.check_partial_derivatives(compact_print=True)
按原样运行此代码会生成错误的雅可比矩阵,同时注释掉
self.deriv_选项['type'='cs'
行,并使用分析表达式生成正确的雅可比矩阵

我在Ubuntu上使用OpenMDAO 1.7.3和numpy 1.10.2


我是否错误地设置了复杂的阶跃导数?如果是,我应该如何编写此组件以使其具有复杂的阶跃能力?

问题是与内存/指针相关的问题。本质上,当您进行切片和重塑时,您最终得到了原始数组的视图,然后将其分配给
unknowns['disp']
。此分配破坏了OpenMDAO指向其用于执行复杂步长计算的原始数据的指针。您可以通过更改分配来明确修复它,改为请求将数据的副本复制到当前内存位置:

def solve_nonlinear(self, params, unknowns, resids):
    # Obtain the relevant portions of disp_aug and store the reshaped
    # displacements in disp
    unknowns['disp'][:] = params['disp_aug'][:-6].reshape((self.ny, 6))

OpenMDAO的CS代码中一定有一个潜在的错误,这使得这种分配保护成为必要。fd中没有出现这个问题,只有CS出现。

为了我的目的,我已经解决了这个问题,去掉了重塑行并用显式分配循环替换它,尽管我仍然觉得原始代码显示了ha我工作过。