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



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

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

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

我不确定是否我错过了什么,或者是否在线性的解析偏导数中存在错误。

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

liftdragentsmetamodelpretrimmedgroup代码为:

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', default=np.arange(10),
                         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', default=np.zeros(10),
                         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,1],rw.c_Dt_grid[3,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是定义马赫数据的点之一。当你使用'线性'方法时,导数在该点是不连续的。这只是这种方法的缺点之一。

检查中出现差异是因为括号法算法选择了"左侧",该算法会找出你要插入的是哪个箱子。当你在一个网格点上,但有限差分或复步选择"右"时;Bin,因为默认的检查方向是"forward"。

为了避免以后的混淆,我们将检查方向设置为"向后"。对于结构化元模型组件,只要选择'slinear'方法。衍生品"匹配"当我做出这个改变的时候。这个更改应该会进入OpenMDAO 3.11。

最新更新