微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

求解器选择:NonlinearBlockGS vs牛顿求解器

如何解决求解器选择:NonlinearBlockGS vs牛顿求解器

我有两个openmdao组,组之间具有循环依赖性。我使用“复杂”步骤计算导数。我有一个用于依赖项的非线性求解器,并使用SLSQP优化了我的目标函数。问题在于非线性求解器的选择。当我使用NonlinearBlockGS时,优化将在12次迭代中成功完成。但是,当我将NewtonSolverDirectsolverScipyKrylov一起使用时,即使使用maxiter=2000,优化也会失败(超过了迭代限制)。循环连接收敛,但是仅仅是设计变量没有达到最佳值。连续迭代中的设计变量之间的差约为1e-5。这就增加了所需的迭代次数。同样,当我将初始猜测值更改为更接近最佳值的值时,它也会起作用。

为了进一步检查,我将模型转换为IDF(通过创建耦合变量和一致性约束的副本),从而消除了对求解器的需求。现在,优化已经成功进行了5次迭代,其结果类似于使用NonlinearBlockGS时的结果。

为什么会这样?我想念什么吗?我何时应该在其他对象上使用NewtonSolver?我知道不看代码就很难回答。但这仅仅是我的代码中包含多个组件,而且我无法用玩具模型重现该问题。因此,任何一般见解都将受到赞赏。

解决方法

在没有看到代码的情况下,您说对了,很难提供详细的信息。

从广义上讲,牛顿收敛有时会比NLBGS麻烦得多(注意:这不是绝对正确的,但是是一个很好的经验法则)。因此,我猜测正在发生的是在您的第一次或第二次迭代中,牛顿求解器实际上并没有收敛。您可以通过设置newton.options['iprint']=2并在优化程序进行迭代时查看迭代历史记录来进行检查。

在优化过程中使用求解器时,至关重要的是,还要确保set it to throw an error on non-convergence.一些优化器可以处理此错误,并且会在行搜索中回溯。其他人只会死。无论哪种方式,它都很重要。否则,您最终会给优化器一个未知的情况,即它不知道是未收敛的。

这很糟糕,原因有两个。首先,它获得的目标和约束值将是错误的!其次,也许更重要的是,其计算的导数将是错误的!您可以阅读详细信息(在理论手册中),但总而言之,OpenMDAO使用的解析导数方法假设残差已变为0。如果不是这种情况,则数学会崩溃。即使您正在执行完整的模型有限差分,非收敛模型也是一个问题。当您尝试FD时,只会得到嘈杂的垃圾。2

因此,假设您正确设置了模型,并且线性求解器设置了问题(由于它与NLBGS兼容,听起来像是这样做的),那么牛顿求解器很可能没有收敛。使用iprint(可能与driver debug printing结合使用)亲自检查一下。如果真是那样,您需要弄清楚如何使牛顿表现得更好。

有些tips here很笼统。您也可以尝试使用armijo line search,它通常可以以一定的速度来稳定牛顿求解。

最后...牛顿并不是在所有情况下的最佳答案。如果NLBGS更稳定且计算便宜,则应使用它。我为您希望与牛顿一起工作感到高兴。您绝对应该找出原因,但事实并非如此,但是如果事实证明牛顿无法可靠地解决您的耦合问题,那也可以!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。