OpenMDAO:如何处理ExplicitComponent.compute中的非聚合点?

时间:2018-05-09 14:41:06

标签: openmdao

我已按照What is the best way to tell openMDAO driver or solver that it is impossible to evaluate the model at some point?中的建议({3}}提出compute来尝试处理我ExplicitComponent AnalysisError方法中的非聚合点我想在这个帖子中发表评论,但由于我的Stack Overflow信誉得分低,我不被允许。但是,这似乎并没有解决我的问题。我所期望的是错误将被捕获,设计点将被跳过,优化器将继续评估其他点以便找到解决方案。捕获错误是正确的,但由于某种原因,错误随后在ScipyOptimizeDriver.run中重新加载。这是什么目的?

这是用于复制行为的示例脚本:

import numpy as np
from openmdao.api import Problem, Group, IndepVarComp, ExplicitComponent, ScipyOptimizeDriver, ScipyKrylov, AnalysisError


class Test1Comp(ExplicitComponent):

    def setup(self):
        self.add_input('design_x', 1.0)
        self.add_input('design_y', 1.0)
        self.add_input('design_z', 0.5)
        self.add_output('y', val=0.1)
        self.add_output('z', val=0.1)
        self.add_output('obj', val=0.0)

        self.declare_partials(of='*', wrt='*', method='fd', form='central', step=1.0e-4)

    def compute(self, inputs, outputs):
        design_z = inputs['design_z']
        design_x = inputs['design_x']
        design_y = inputs['design_y']

        # Let's assume we have a model that has problems converging around design_x = 5.0
        if 0.49999 < design_x < 0.500001:
            raise AnalysisError()

        z = 4/(design_z + 1)
        y = - design_z - 2*z
        obj = (y/5.833333 - design_x)**2 + z/2.666667*100*(design_y - design_x**2)**2

        outputs["z"] = z
        outputs["y"] = y
        outputs['obj'] = obj


if __name__ == "__main__":

    prob = Problem()
    model = prob.model = Group()

    model.add_subsystem('d1', IndepVarComp('design_x', 1.0))
    model.add_subsystem('d2', IndepVarComp('design_y', 1.0))
    model.add_subsystem('d3', IndepVarComp('design_z', 0.5))
    model.add_subsystem('comp', Test1Comp())

    model.connect('d1.design_x', 'comp.design_x')
    model.connect('d2.design_y', 'comp.design_y')
    model.connect('d3.design_z', 'comp.design_z')

    prob.driver = ScipyOptimizeDriver()
    prob.driver.options["optimizer"] = 'SLSQP'
    prob.driver.options['tol'] = 1e-8
    model.add_design_var("d1.design_x", lower=0.5, upper=1.5)
    model.add_design_var("d2.design_y", lower=0.5, upper=1.5)
    model.add_design_var("d3.design_z", lower=0.0, upper=1.0)
    model.add_objective('comp.obj')

    model.linear_solver = ScipyKrylov()
    model.linear_solver.options['maxiter'] = int(1200)
    model.linear_solver.options['restart'] = int(20)

    # prob.model.approx_totals()
    prob.setup()
    prob.run_driver()
    print(prob['comp.y'])
    print(prob['comp.z'])

此外,在查看调用ExplicitComponent._solve_nonlinear的方法的ExplicitComponent.compute时,在我看来,与OpenMDAO进行通信的自然方式是点不会收敛{{1 }}返回ExplicitComponent.compute。请参阅方法的源代码:

True

总之,有人可以澄清在def _solve_nonlinear(self): """ Compute outputs. The model is assumed to be in a scaled state. Returns ------- boolean Failure flag; True if failed to converge, False is successful. float absolute error. float relative error. """ super(ExplicitComponent, self)._solve_nonlinear() with Recording(self.pathname + '._solve_nonlinear', self.iter_count, self): with self._unscaled_context( outputs=[self._outputs], residuals=[self._residuals]): self._residuals.set_const(0.0) failed = self.compute(self._inputs, self._outputs) return bool(failed), 0., 0. 中处理非融合计算的推荐方法是什么?

1 个答案:

答案 0 :(得分:1)

我查看了您的代码,并且您指定了一切正确的方法来告诉优化器组件无法评估设计点。问题是scipy.minimize(这是ScipyOptimizeDriver下面的优化器)不知道当它遇到失败点时做什么(除了引发异常),并且无法报告故障(至少据我所知。)

但是,pyOptSparseDriver可以在某个点失败时执行某些操作:尝试在渐变方向上再次进行,但步长较小。我接受了你的代码,并将ScipyOptimizeDriverpyOptSparseDriver交换,在该软件包中使用了“SLSQP”优化器,它解决了这个有问题的问题就好了,达到我认为是一个很好的优化:

[0.69651727]
[-5.]
[2.]

我的驱动程序选项代码如下所示:

prob.driver = pyOptSparseDriver()
prob.driver.options["optimizer"] = 'SLSQP'
prob.driver.opt_settings['ACC'] = 1e-8

如果您还没有pyoptsparse,这是我们未维护的单独软件包,您可以从https://github.com/mdolab/pyoptsparse获取它 - 您可以使用以下代码构建和安装它:

python setup.py build
python setup.py install

对于您的其他问题,我查看了我们的代码,发现_solve_nonlinear上的失败标志返回从未用于任何事情。因此,将非收敛状态传递给驱动程序或更高级别解算器的唯一方法是引发AnalysisError。如果AE没有收敛,求解器可以在其选项中将“err_on_maxiter”设置为True(默认值为False)。

作为最后一点,我认为虽然我们正在使用我们的错误处理机制,但我们并没有考虑所有事情,并且总是乐于接受改进建议。

相关问题