检查线性结构元模型的偏导数时出错

问题描述

我正在使用 metamodelStructuredComp 组件在 2D 网格中执行插值。

当检查使用 'slinear' 方法计算它的选项时,插值似乎可以正常工作,但是当检查具有复杂步骤的偏导数时,它会为导数返回一个错误(10^-1 的数量级)相对于第二维和第二个节点(它们属于一个网格点,也属于第一个节点)。

使用所有其他方法进行检查时不会发生这种情况(三次返回顺序为 10-15,scipy_slinear 以 10-10 的顺序进行有限差分检查)。 scipy_slinear 检查返回该分量的解析和数值有限差分,该差分与 slinear 方法的数值有限差分返回的几乎相同(大约 -0.03338752,但请注意解析返回 -0.05107948)

我不确定它是否是我遗漏的东西,或者线性分析的部分分析是否有错误

在我的代码中,第一维是 alpha,训练数据的形状为 (12,),第二维马赫数为 (5,)。我正在检查两个输出(C_D (12,5) 和 C_L (12,5),两者都有相同的大错误

LiftDragCoefficientsmetamodelPretrimmedGroup 代码是:

class LiftDragCoefficientsmetamodelPretrimmedGroup(om.Group):
def initialize(self):
    self.options.declare('num_nodes',types=int,desc='Number of nodes to be evaluated in the RHS')
    self.options.declare('machs',default=np.arange(10),desc='Vector of machs defining grid')
    self.options.declare('alphas',desc='Vector of alphas defining grid')
    self.options.declare('C_D_grid',default=np.zeros(10),desc='Drag coefficients from grid')
    self.options.declare('C_L_grid',desc='Lift coefficients from grid')
    self.options.declare('extrapolate',types=bool,desc='Allow extrapolation if true',default=True)
    self.options.declare('interp_method',types=str,desc='Interlopation Method',default='slinear')

def setup(self):
    comp=om.metamodelStructuredComp(method=self.options['interp_method'],extrapolate=self.options['extrapolate'],vec_size=self.options['num_nodes'] )
    comp.add_output('C_L',self.options['C_L_grid'].mean(),self.options['C_L_grid'])
    comp.add_output('C_D',self.options['C_D_grid'].mean(),self.options['C_D_grid'])
    comp.add_input('alpha',self.options['alphas'].mean(),self.options['alphas'])
    comp.add_input('mach',self.options['machs'].mean(),self.options['machs'])

    self.add_subsystem('comp',comp,promotes=["*"])
    self.comp._no_check_partials = False  # override skipping of check_partials

使用的代码例程是:

model = om.Group()
model.add_subsystem('InterpSubsystem',LiftDragCoefficientsmetamodelPretrimmedGroup(num_nodes=3,machs=rw.machs,alphas=rw.alphas*np.pi/180.0,C_L_grid=rw.c_Lt_grid,C_D_grid=rw.c_Dt_grid,interp_method='slinear',extrapolate=False))
p = om.Problem(model)
p.setup(force_alloc_complex=True)

p.set_val('InterpSubsystem.alpha',np.array([35 * np.pi / 180,10 * np.pi / 180,8.5 * np.pi / 180]))
p.set_val('InterpSubsystem.mach',np.array([5,7,7.5]))
p.run_model()
print(p['InterpSubsystem.C_L'])
print(p['InterpSubsystem.C_L']-np.array([rw.c_Lt_grid[8,1],rw.c_Lt_grid[3,3],0]))
print(p['InterpSubsystem.C_D'])
print(p['InterpSubsystem.C_D']-np.array([rw.c_Dt_grid[8,rw.c_Dt_grid[3,0]))

cpd = p.check_partials(compact_print=False,method='cs')
assert_check_partials(cpd,atol=1.0E-7,rtol=1.0E-7)

错误代码如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  InterpSubsystem.comp: 'C_L' wrt 'alpha'
    Analytic Magnitude : 1.313053e+01
          Fd Magnitude : 1.313053e+01 (cs:None)
    Absolute Error (Jan - Jfd) : 8.881784e-16

    Relative Error (Jan - Jfd) / Jfd : 6.764226e-17

    Raw Analytic Derivative (Jfor)
[[7.45312355 0.         0.        ]
 [0.         8.300603   0.        ]
 [0.         0.         6.92543442]]

    Raw FD Derivative (Jfd)
[[7.45312355 0.         0.        ]
 [0.         8.300603   0.        ]
 [0.         0.         6.92543442]]

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  InterpSubsystem.comp: 'C_L' wrt 'mach'
    Analytic Magnitude : 1.331524e-01
          Fd Magnitude : 1.274173e-01 (cs:None)
    Absolute Error (Jan - Jfd) : 1.769196e-02 *

    Relative Error (Jan - Jfd) / Jfd : 1.388505e-01 *

    Raw Analytic Derivative (Jfor)
[[-0.11945724  0.          0.        ]
 [ 0.         -0.05107948  0.        ]
 [ 0.          0.         -0.02916183]]

    Raw FD Derivative (Jfd)
[[-0.11945724  0.          0.        ]
 [ 0.         -0.03338752  0.        ]
 [ 0.          0.         -0.02916183]]


--------------------------------
Component: InterpSubsystem.comp
--------------------------------
< output > wrt < variable > | abs/rel | norm   | norm value          
--------------------------- | ------- | ------ | --------------------
C_L wrt mach                | abs     | fwd-fd | 0.017691955836769413
C_L wrt mach                | rel     | fwd-fd | 0.13885048495831204 
C_D wrt mach                | abs     | fwd-fd | 0.004933779456698817
C_D wrt mach                | rel     | fwd-fd | 0.05287403976054622 

解决方法

所以,我认为这里发生的事情(以及我在随机表中偶然发现的)是 7.0 是定义 Mach 数据的点之一。当您使用“线性”方法时,导数在该点是不连续的。这只是该方法的缺点之一。

检查中的差异发生是因为括号算法,它确定您正在插值哪个 bin,当您在网格点上时选择“左”bin,但有限差分或复杂步骤选择“右”bin因为默认检查方向是“向前”。

为了减轻未来的混淆,只要选择“减线”方法,我们将要将检查方向设置为“后向”为结构化元模型组件。当我进行此更改时,衍生产品“匹配”。此更改应使其包含在 OpenMDAO 3.11 中。

相关问答

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