Как вы сказали, предоставленный скрипт не работает. Хотя я согласен с тем, что в теории кажется, что это должно работать, и это небольшая ошибка, я также не думаю, что вы должны на самом деле построить модель таким образом.
Я не понимаю, почему дочернему компоненту нужно создавать переменную на родительском уровне. В OpenMDAO дети ничего не знают о своих родителях по замыслу. Мы довольно строго следим за соблюдением этого во внутреннем коде фреймворка и в самих моделях.
Если вам нужно было добавить новую независимую переменную на каком-то более низком уровне иерархии (что, безусловно, происходит), тогда я предлагаю вам создать группу на этом более низком уровне и новый IndepVarComp для хранения новой переменной. Вот отредактированная версия вашего сценария с тем, как я предлагаю вам справиться с ситуацией.
from openmdao.api import Problem, ScipyOptimizeDriver, IndepVarComp, Group, ExplicitComponent
class SellarDis2(ExplicitComponent):
def setup(self):
self.add_input('try', val=2)
self.add_input('z', val=2)
self.add_output('y2', val=5.0)
def compute(self, inputs, outputs):
outputs['y2'] = inputs['z']*2+inputs['try']
class SubGroup(Group):
def setup(self):
indeps = self.add_subsystem('indeps', IndepVarComp(), promotes=['*'])
indeps.add_output('try', 1.0)
self.add_subsystem('d2', SellarDis2(), promotes=['*'])
class SellarMDA(Group):
def setup(self):
indeps = self.add_subsystem('indeps', IndepVarComp(), promotes=['*'])
indeps.add_output('z', 1.0)
self.add_subsystem('d2', SubGroup(), promotes=['*'])
prob = Problem()
prob.model = SellarMDA()
prob.driver = ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'COBYLA'
# prob.driver.options['maxiter'] = 100
prob.driver.options['tol'] = 1e-8
prob.model.add_design_var('z', lower=0, upper=10)
#prob.model.add_objective('obj')
prob.setup()
prob.final_setup()
prob.run_model()
Я следовал вашим соглашениям об именах, и, чтобы было ясно, я создал секундный IndepVarComp внутри подгруппы, но с тем же именем. Вот N2, чтобы прояснить структуру модели.