对于由ExplicitComponents
组成的MDO系统,我一直使用NonLinearBlockGS
作为nonlinear_solver
,这一点与预期一样有效。首先,我将它用于简单的数学函数(因此是runtime<;<;1s),但现在我还实现了一个包含多个显式组件的系统,这些组件的运行时大约为一分钟或更长。这时我注意到NonLinearBlockGS
解算器实际上需要在耦合系统中每次迭代运行两次工具。这些运行源自解算器的_run_iterator()
方法中的self._iter_execute()
和self._run_apply()
(文件solver.py
中的类Solver
)。你知道吗
我的主要问题是,每个迭代是否真的需要两次运行,如果需要,为什么?你知道吗
似乎第一个组件运行(self.iter_execute()
)对需要收敛的反馈变量使用初始猜测,然后在更新任何前馈数据时按顺序运行组件。这是我对高斯·塞德尔的期望。但是第二个组件运行(self._run_apply()
)使用第一次运行产生的更新的反馈变量再次运行组件,同时保持前馈与第一次运行中的一样。如果我没有弄错的话,那么这个信息(仅)用于评估迭代的收敛性(self._iter_get_norm()
)。你知道吗
与其在迭代中运行第二次,直接继续下一次迭代不是更有效吗?在该迭代中,我们可以使用反馈变量的新值,并对前馈数据进行另一次更新,然后根据这两次迭代结果之间的差异来评估收敛性。当然,这意味着我们至少需要两次迭代来评估收敛性,但是每次迭代可以节省一次组件运行。(这实际上是我在MATLAB中为这些组件的收敛而使用的现有实现,并且工作正常,因此它找到了相同的收敛设计,但是组件运行量只有原来的一半。)
另一种说法是:为什么在进行Gauss-Seidel收敛时,每次迭代都需要self._run_apply()
?(这个可以关掉吗?)你知道吗
你的问题有几个不同的方面。首先,我将讨论
solve_nonlinear
与apply_nonlinear
的细节。利用OpenMDAO的底层数学算法,基于MAUD framework,solve_nonlinear
只计算输出值的值(不设置残差)。apply_nonlinear
只计算残差(不设置输出)。 对于ExplicitComponent
的子类,用户只实现compute
方法,基类使用compute
实现solve_nonlinear
和apply_nonlinear
。你知道吗正如您所描述的,在openmdaov2.4中,对于每个迭代,当前的非线性blockgaussseidel实现对其组执行一个递归的
solve_nonlinear
调用,然后调用apply_nonlinear
来检查残差并寻找收敛性。你知道吗不过,你也说得对,我们可以更有效地做到这一点。您建议对算法进行的修改将起作用,我们将把它放在V2.6的开发管道上(截至本文发布时,我们即将发布V2.5,没有时间将其添加到该版本中)
相关问题 更多 >
编程相关推荐