【发布时间】:2018-11-02 13:27:12
【问题描述】:
我遇到了Group 的问题,其中包括 OpenMDAO 中子系统之间的反馈。我正在使用NonlinearBlockBS 求解器。我希望 Gauss-Seidel 求解器顺序运行子系统,将早期模块的输出传递到其他模块的输入。但是,当我在 OpenMDAO 中实现这一点时,这似乎不会发生。
我制作了一个示例脚本来演示这个问题:
class A(ExplicitComponent):
def setup(self):
self.add_input('x', shape=1)
self.add_input('b', shape=1)
self.add_output('a', shape=1)
def compute(self, inputs, outputs):
outputs['a'] = inputs['x'] + 2 * inputs['b']
print('A: x = {:1.0f}, b = {:1.0f}, a = {:1.0f}'.format(inputs['x'][0], inputs['b'][0], outputs['a'][0]))
class B(ExplicitComponent):
def setup(self):
self.add_input('x', shape=1)
self.add_input('a', shape=1)
self.add_output('b', shape=1)
def compute(self, inputs, outputs):
outputs['b'] = inputs['x'] - 0.5 * inputs['a']
print('B: x = {:1.0f}, a = {:1.0}, b = {:1.0f}'.format(inputs['x'][0], inputs['a'][0], outputs['b'][0]))
if __name__ == '__main__':
ivc = IndepVarComp()
ivc.add_output('x', val=3.)
coupled_group = Group()
coupled_group.add_subsystem('A', A(), promotes=['*'])
coupled_group.add_subsystem('B', B(), promotes=['*'])
coupled_group.nonlinear_solver = NonlinearBlockGS()
prob = Problem()
model = prob.model = Group()
model.add_subsystem('I', ivc, promotes=['*'])
model.add_subsystem('C', coupled_group, promotes=['*'])
prob.setup()
prob.run_model()
A 和 B 这两个组件通过它们的输出 a 和 b 耦合。它们还共享一个参数x,最初由IndepVarComp 设置。运行时,代码会产生以下输出:
=
C
=
A: x = 3, b = 1, a = 7
B: x = 3, a = 1, b = 4
A: x = 3, b = 1, a = 7
B: x = 3, a = 7, b = 1
A: x = 3, b = 1, a = 7
B: x = 3, a = 7, b = 1
NL: NLBGS Converged in 1 iterations
b 参数作为A 的输入,在A 首先运行时尚未定义。因此,它的初始值为 1。这与预期一致。然后运行B,它应该从A、a = 7 获取输出,但a 也设置为初始猜测值1。这不是我在使用Gauss-Seidel 方法时所期望的。
B 在运行A 后没有获得a 的更新值这一事实并不影响该系统在这种情况下收敛到正确解决方案的事实。但是,在我的情况下,a = 1 不是B 的有效输入。因此系统无法收敛。
我在这里做错了吗?我可以做些什么来确保B 在第一次运行时获得a 的更新值?
【问题讨论】: