在 OpenMDAO 的 ExecComp 中,shape_by_conn 是否与 has_diag_partials 兼容?

问题描述

我有一个执行简单操作的 om.ExecComp

"d_sq = x**2 + y**2"

其中 xyd_sq 始终是一维 np.array。我希望能够在不分配大型密集矩阵的情况下将其与大型数组一起使用。我还希望根据连接的形状配置阵列的长度。 但是,如果我指定 x={"shape_by_conn": True} 而不是 x={"shape":100000},即使我也有 has_diag_partials=True,它也会尝试分配一个 100000^2 的数组。有没有办法让这两个选项兼容?

解决方法

首先,我会注意到您使用 ExecComp 有点超出其设计预期用途。这并不是说你完全无效,但一般来说 ExecComp 是为小型、廉价的计算而设计的。将巨型数组传递给它不是我们测试的内容。

话虽如此,我认为你想要的会奏效。当您在此使用 shape_by_conn 时,您需要确保调整输入和输出的大小。我已经提供了一个例子,以及一个手动定义的组件,它可以做同样的事情。由于您的方程式非常简单,因此总体上会快一些。

import numpy as np

import openmdao.api as om

class SparseCalc(om.ExplicitComponent): 


    def setup(self): 
        self.add_input('x',shape_by_conn=True)
        self.add_input('y',shape_by_conn=True)

        self.add_output('d_sq',shape_by_conn=True,copy_shape='x')

    def setup_partials(self): 

        # when using shape_by_conn,you need to delcare partials 
        # in this secondary method
        md = self.get_io_metadata(iotypes='input')

        # everything should be the same shape,so just need this one
        x_shape = md['x']['shape']

        row_col = np.arange(x_shape[0])
        self.declare_partials('d_sq','x',rows=row_col,cols=row_col)
        self.declare_partials('d_sq','y',cols=row_col)

    def compute(self,inputs,outputs): 

        outputs['d_sq'] = inputs['x']**2 + inputs['y']**2

    def compute_partials(self,J): 

        J['d_sq','x'] = 2*inputs['x']
        J['d_sq','y'] = 2*inputs['y']



if __name__ == "__main__": 

    p = om.Problem()

    # use IVC here,because you have to have something connected to 
    # in order to use shape_by_conn. Normally IVC is not needed
    ivc = p.model.add_subsystem('ivc',om.IndepVarComp(),promotes=['*'])
    ivc.add_output('x',3*np.ones(10))
    ivc.add_output('y',2*np.ones(10))

    # p.model.add_subsystem('sparse_calc',SparseCalc(),promotes=['*'])

    p.model.add_subsystem('sparse_exec_calc',om.ExecComp('d_sq = x**2 + y**2',x={'shape_by_conn':True},y={'shape_by_conn':True},d_sq={'shape_by_conn':True,'copy_shape':'x'},has_diag_partials=True),promotes=['*'])


    p.setup(force_alloc_complex=True)

    p.run_model()

如果您仍然发现这没有按预期工作,请随时submit a bug report 使用一个测试用例来清楚地显示问题(即会引发您看到的错误)。在这种情况下,提供的手动组件可以作为一种解决方法。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...