0

在 OpenMDAO 中,如果模型由多个组/循环和多个非线性求解器组成,是否有关于如何记录和读取求解器案例的建议?

我有一个由 2 个周期(cycle1 和 cycle2)构建的模型,其中一个包含两个子周期(cycle1_1 和 cycle1_2)。现在我将一个求解器附加到我的每个非线性求解器:

solver1 = model.cycle1.nonlinear_solver
solver1_1 = model.cycle1.cycle1_1.nonlinear_solver
solver1_2 = model.cycle1.cycle1_2.nonlinear_solver
solver2 = model.cycle2.nonlinear_solver

solver1.add_recorder(recorder)
solver1_1.add_recorder(recorder)
solver1_2.add_recorder(recorder)
solver2.add_recorder(recorder)

当试图读取结果时:

cr = om.CaseReader(results)

我收到以下错误:

RuntimeError:无法解析求解器迭代坐标:rank0:root._solve_nonlinear|0|NLRunOnce|0|cycle1._solve_nonlinear|0|NonlinearBlockGS|1|cycle1.cycle1_1._solve_nonlinear|1|NonlinearBlockGS|1

我正在寻找有关收敛历史的信息和一些关于耦合变量的图。

编辑:我的代码的结构类似于https://openmdao.org/newdocs/versions/latest/basic_user_guide/multiplastic_optimization/sellar.html中的结构,组在设置中定义:

import openmdao.api as om

class MDA(om.Group):
    
    # class ObjCmp(om.ExplicitComponent):
        # some objective component
    # class ConCmp(om.ExplicitComponent):
        # some constraint component
    
    def setup(self):
        
        cycle1 = self.add_subsystem('cycle1', om.Group(), promotes=['*'])
        
        cycle1_1 = cycle1.add_subsystem('cycle1_1', om.Group(), promotes=['*'])
        cycle1_1_comp = cycle1_1.add_subsystem('comp', om.ExecComp('x1 = 3 + x2'), promotes=["*"])

        cycle1_2 = cycle1.add_subsystem('cycle1_2', om.Group(), promotes=['*'])
        cycle1_2_comp = cycle1_2.add_subsystem('comp',  om.ExecComp('x2 = 3 + x1 + y'), promotes=["*"])

        cycle2 = self.add_subsystem('cycle2', om.Group(), promotes=['*'])
        cycle2.add_subsystem('comp', om.ExecComp('y = x1 + 2'), promotes=['*'])

p = om.Problem(model=MDA())
model = p.model

p.setup()

p.run_model()
4

1 回答 1

0

不幸的是,从 OpenMDAO V3.16 开始,这看起来像是一个错误。它被记录为 OpenMDAO 开发积压的高优先级问题:问题 #2453

我可以使用以下脚本复制它:

import openmdao.api as om

p = om.Problem()

model = p.model

cycle1 = p.model.add_subsystem('cycle1', om.Group(), promotes=['*'])
cycle1_1 = cycle1.add_subsystem('cycle1_1', om.Group(), promotes=['*'])
cycle1_1_comp = cycle1_1.add_subsystem('comp', om.ExecComp('x1 = 3 + x2'), promotes=["*"])

cycle1_2 = cycle1.add_subsystem('cycle1_2', om.Group(), promotes=['*'])
cycle1_2_comp = cycle1_2.add_subsystem('comp',  om.ExecComp('x2 = 3 + x1 + y'), promotes=["*"])

cycle2 = p.model.add_subsystem('cycle2', om.Group(), promotes=['*'])
cycle2.add_subsystem('comp', om.ExecComp('y = x1 + 2'), promotes=['*'])


solver1 = model.cycle1.nonlinear_solver
solver1_1 = model.cycle1.cycle1_1.nonlinear_solver
solver1_2 = model.cycle1.cycle1_2.nonlinear_solver
solver2 = model.cycle2.nonlinear_solver

print(solver1, solver1_1, solver1_2, solver2)

recorder = om.SqliteRecorder('cases.db')

solver1.add_recorder(recorder)

# recorders on nested solvers trigger the bug 
# solver1_1.add_recorder(recorder)
# solver1_2.add_recorder(recorder)

# Kind-of workaround, put the recorder on the child component/group instead
cycle1_1_comp.add_recorder(recorder)
cycle1_2_comp.add_recorder(recorder)

solver2.add_recorder(recorder)

p.setup()

p.run_model()


reader = om.CaseReader('cases.db')

print(reader.list_sources())

似乎是嵌套记录器触发了该错误。作为一种解决方法,您可以将记录器粘贴在较低级别的组/组件上。这将使知道哪些情况来自哪个求解器迭代变得有点困难,但是迭代坐标的命名方案至少应该在那里有所帮助。希望这能让你在此期间继续前进,同时修复错误。

于 2022-02-28T23:51:18.510 回答