我一直在使用SLSQP算法仅使用ExplicitComponents
运行一些MDO问题。每个组件的运行时间约为10秒,输入变量为60-100。大多数输入变量是静态输入变量,将在整个优化过程中保持不变。静态输入变量源自IndepVarComp
。 ExplicitComponents
是黑匣子,因此在局部上没有可用的信息。
我注意到,当在compute_totals()
中计算雅可比行列式时,组件将相对于其所有输入值进行线性化。在compute_approximations()
中,将对所有输入值(包括静态输入值)计算出有限的差异。所以,我的问题是:为什么要对这些静态输入变量执行有限差分计算?由于这些值保持不变,因此我不确定为什么这些信息会有用吗?
此外,如果我理解正确的话,可以对这些分量进行线性化以获得子雅各宾派,然后将其用于计算总雅可比行列式。但是,是否可以直接计算整个组的有限差分而不是线性化每个分量?由于组件的运行时和输入变量的数量,每个组件的线性化将花费很长时间。但是,优化问题只有3个设计变量。因此,如果我可以在整个MDA上执行三个有限差分计算以计算总Jacobian,则总运行时间将大大减少。
答案 0 :(得分:2)
以相反的顺序回答您的问题:
1)您可以FD整个模型而不是每个单独的组件吗?是!
您可以在模型(包括顶层组)中设置FD over any group。然后,FD将跨该组而不是跨该组中的每个组件获取。 我们称此为计算半总导数,因为通常您可以在模型中选择一个子组,在这种情况下,FD会逼近该组中的总导数,但是总导数仍然有效地是偏导数。对于整体模型。因此半总导数。
2)为什么要对这些静态输入变量执行有限差分计算?
从理论上讲,您是正确的,因为您实际上不需要不可更改的输入的偏导数。从OpenMDAO 2.4开始,我们不会自动处理这种情况,也没有计划在不久的将来添加这种情况。但是,该框架仅对您告诉它的部分进行FD。听起来您像这样声明自己的部分:
self.declare_partials(of=['*'], wrt=['*'], method='fd')
因此,您特别要求框架计算所有这些部分。相反,您可以在wrt
参数中仅指定您实际更改的输入。当然,这在数学上是不正确的,因为静态输入具有导数。如果以后有人将某些内容连接到这些输入并进行尝试和优化,他们将得到错误的答案。但是,只要您小心谨慎,就可以只从任何组件中只请求所需的部分,并简单地将不变的输入有效地保留为0。