【发布时间】:2021-08-28 17:37:29
【问题描述】:
我遇到了一些问题,我为某些组件实现了分析导数,而我对其余部分使用了复杂的步骤。它们之间存在循环依赖关系,因此我还使用求解器来收敛它们。当我使用NonlinearBlockGS 时它会收敛。但是当我将NewtonSolver 与线性求解器结合使用时,即使迭代次数很高,优化也会失败(超出迭代限制)。但是我发现当我使用prob.model.approx_totals() 时,它很容易收敛并且工作得很好。我读到approx_totals 使用fd 或cs 来查找模型渐变。所以我有两个问题。
-
一般来说,当我使用
approx_totals()时,我会失去混合分析方法的好处吗?有没有办法用混合分析策略找到整个模型(或组)的导数? (无论如何,在我的情况下,explicitcomponents耦合使用“复杂步骤”。但我只是对此感到好奇。) -
一般情况下(不是在这种情况下),Openmdao 会自动检测混合策略还是我应该如何指定它?
如果您能指出一些使用混合衍生物的示例,我将不胜感激。我自己没有找到它们。
编辑:添加示例。我无法在示例代码中重现该问题。另外我不想在我的代码上浪费你的时间(有超过 30 个 ExplicitComponents 和 7 个组)。所以我在下面做了一个简单的结构来更好地解释它。其中A to G 有7 个分量,只有F and G 没有解析导数并使用FD。
import openmdao.api as om
import numpy as np
class ComponentA_withDerivatives(om.ExplicitComponent):
def setup(self):
#setup inputs and outputs
def setup_partials(self):
#partial declaration
def compute(self, inputs, outputs):
def compute_partials(self, inputs, J):
#Partial definition
class ComponentB_withDerivatives(om.ExplicitComponent):
.....
class ComponentC_withDerivatives(om.ExplicitComponent):
......
class ComponentD_withDerivatives(om.ExplicitComponent):
......
class ComponentE_withDerivatives(om.ExplicitComponent):
......
class ComponentF(om.ExplicitComponent):
def setup(self):
#setup inputs and outputs
self.declare_partials(of='*', wrt='*', method='fd')
def compute(self,inputs,outputs):
# Computation
class ComponentG(om.ExplicitComponent):
def setup(self):
#setup inputs and outputs
self.declare_partials(of='*', wrt='*', method='fd')
def compute(self,inputs,outputs):
# Computation
class GroupAB(om.Group):
def setup(self):
self.add_subsystem('A', ComponentA_withDerivatives(), promotes_inputs=['x','y'], promotes_outputs=['z'])
self.add_subsystem('B', ComponentB_withDerivatives(), promotes_inputs=['x','y','w','u'], promotes_outputs=['k'])
class GroupCD(om.Group):
def setup(self):
self.add_subsystem('C', ComponentC_withDerivatives(), .....)
self.add_subsystem('D', ComponentD_withDerivatives(), ...)
class Final(om.Group):
def setup(self):
cycle1 = self.add_subsystem('cycle1', om.Group(), promotes=['*'])
cycle1.add_subsystem('GroupAB', GroupAB())
cycle1.add_subsystem('ComponentF', ComponentF())
cycle1.linear_solver = om.DirectSolver()
cycle1.nonlinear_solver = om.NewtonSolver(solve_subsystems=True)
cycle2 = self.add_subsystem('cycle2', om.Group(), promotes=['*'])
cycle2.add_subsystem('GroupCD', GroupCD())
cycle2.add_subsystem('ComponentE_withDerivatives', ComponentE_withDerivatives())
cycle2.linear_solver = om.DirectSolver()
cycle2.nonlinear_solver = om.NewtonSolver(solve_subsystems=True)
self.add_subsystem('ComponentG', ComponentG(), promotes_inputs=['a1','a2','a3'], promotes_outputs=['b1'])
prob = om.Problem()
prob.model = Final()
prob.driver = om.pyOptSparseDriver()
prob.driver.options['optimizer'] = 'SNOPT'
prob.driver.options['print_results']= True
## Design Variables
## Costraints
## Objectives
# Setup
prob.setup()
##prob.model.approx_totals(method='fd')
prob.run_model()
prob.run_driver()
这不起作用。 cycle1 不收敛。当我完全删除 cycle1 或使用 NonlinearBlockGS 而不是 Newton 或取消注释 prob.model.approx_total(method='FD') 时,该代码有效。 (cycle2没问题。和牛顿一起工作)
所以如果我不使用approx_totals(),我假设 Openmdao 使用混合策略。或者我应该以某种方式手动提及它?当我使用 approx_totals() 时,我会失去我拥有的分析导数的好处吗?
【问题讨论】:
-
您能否添加更多有关您的问题设置的详细信息。当您说它收敛时,您是在谈论求解器收敛还是有顶级优化器?求解器在模型层次结构中的什么位置?也是顶级的吗?也许提供一个显示模型结构和运行文件的概念示例,即使它没有给出相同的确切行为?
-
您好,我已经添加了一个代码结构来更好地解释它。抱歉之前的事。
标签: openmdao