OpenMDAO 分层求解器记录

发布于 2025-01-10 14:50:38 字数 2018 浏览 1 评论 0原文

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

我有一个由 2 个周期(周期 1 和周期 2)构建的模型,其中一个包含两个子周期(周期 1_1 和周期 1_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)

我收到以下错误:

运行时错误:无法解析求解器迭代坐标: 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/multisubject_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()

In OpenMDAO, is there any recommendation on how to record and read solver cases if the model is composed of multiple groups/cycles, and multiple nonlinear solvers?

I have a model built of 2 cycles (cycle1 and cycle2), one of them containing two subcycles (cycle1_1 and cycle1_2). For now I am attaching a solver to each of my nonlinear solvers:

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)

When trying to read the results with:

cr = om.CaseReader(results)

I am getting the following error:

RuntimeError: Can't parse solver iteration coordinate:
rank0:root._solve_nonlinear|0|NLRunOnce|0|cycle1._solve_nonlinear|0|NonlinearBlockGS|1|cycle1.cycle1_1._solve_nonlinear|1|NonlinearBlockGS|1

I am looking to get information about the convergence history and some plots on the coupling variables.

EDIT: My code has a structure similar to that in https://openmdao.org/newdocs/versions/latest/basic_user_guide/multidisciplinary_optimization/sellar.html, with the groups defined in setup:

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挖个坑埋了你 2025-01-17 14:50:38

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

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

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())

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

Unfortunately, as of OpenMDAO V3.16 this looks like a bug. Its been logged as a high priority issue on the OpenMDAO development backlog: Issue #2453

I can replicate it with the following script:

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())

It seems to be the nested recorders that are triggering the bug. As a kind-of workaround you can stick the recorder on the lower level group/component instead. That will make it a bit harder to know which cases are from which solver iteration, but the naming scheme of the iteration coordinates should at least help a little there. Hopefully that gets you moving in the meantime, while the bug is fixed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文