为什么 "Specifying sparse partial derivatives for a simple vectorized component" 视频中有些变量附加到 self 上?

Why are some variables attached to self in the "Specifying sparse partial derivatives for a simple vectorized component" video?

this 视频中,Justin 在其组件的计算函数中编写了以下内容。

def compute(self, inputs, outputs):

    self.alp_sc = 0.91
    T0 = 28. #reference temperature
    eff0 = .285 #efficiency at ref temp
    T1 = -150.
    eff1 = 0.335

    delta_T = inputs['T'] - T0
    self.slope = (eff1 - eff0) / (T1 - T0)

    outputs['eta'] = (eff0 + self.slope * delta_T)/self.alp_sc

为什么他选择使用 self.slopeself.alp_sc 而不是简单的变量?它对 openMDAO/vectorised 个组件很重要,还是只是一个任意选择?

从代码片段看,def compute(self, inputs, outputs) 是 object/class 中的一个方法。这可以从 self 被包含在其初始化中看出。

self.slope 和'self.alp_scwill be variables that are declared within the scope of the object that thecompute()` 方法是.

的一部分

有关详细信息,请参阅 classes in Python

属性(例如 self.alp_sc)是从未打算针对该示例组件更改的常量。它们不需要是输入变量,因为它们永远不会被连接到。

定义关于任何组件中所有输入的所有输出的偏导数。因此,通过创建这些值属性,我们可以尊重最佳实践并避免为我们知道永远不会改变的事物声明部分。

如果继续看videoself.slopeself.alp_sc也用在compute_partials的方法中。 self.alp_sc 是常量,所以我认为它可以在 class 的 initialize 方法中声明(如果它是一个参数,您可能希望针对不同的实例进行更改),或者在 class 之外(如果它真的是一个常量)。 self.slope 在这种情况下也是一个常数,所以同样适用。但是想象一下,斜率将取决于组件的输入,并且您需要在每次迭代中重新计算它(并且假设它的计算量也非常大,在示例中显然不是)。在这种情况下,您可以通过将值存储在 class 属性 (self.slope) 中并在导数计算中重复使用它来节省一些计算。 必须确保的一件事是,在每次迭代中 computecompute_partials 之前被调用(否则你最终可能会在导数计算中使用上一次迭代的过时值),但我认为在当前的 OpenMDAO 3.0 中始终如此。

您需要为函数和导数计算相同的数量是很常见的。将它存储在一个属性中是一种方法(更少的计算),或者在计算和 compute_partials 中调用相同的函数(两倍的计算,更少的内存)是另一种方法。