Я пытаюсь сделать игрушечную задачу, чтобы немного узнать о программном обеспечении OpenMDAO, прежде чем применять уроки к более крупной проблеме.У меня есть проблема, настроенная так, чтобы целевая функция была минимизирована, когда обе проектные переменные минимальны.Однако оба значения остаются на своих первоначально присвоенных значениях, несмотря на получение сообщения «Оптимизация успешно завершена».
Я начал с написания кода, основанного на примерах проблемы Sellar.(http://openmdao.org/twodocs/versions/latest/basic_guide/sellar.html) Кроме того, я столкнулся с вопросом переполнения стека, который, кажется, та же самая проблема, но решение там не работает.( OpenMDAO: Solver сходится к неоптимальной точке ) (Когда я добавляю строку Declare_partials в IntermediateCycle или ScriptForTest, я получаю сообщение о том, что либо self не определено, либо что у объекта нет атрибута Declare_partials)
Это скрипт, который запускает все
import openmdao.api as om
from IntermediateForTest import IntermediateCycle
prob = om.Problem()
prob.model = IntermediateCycle()
prob.driver = om.ScipyOptimizeDriver()
#prob.driver.options['optimizer'] = 'SLSQP'
#prob.driver.options['tol'] = 1e-9
prob.model.add_design_var('n_gear', lower=2, upper=6)
prob.model.add_design_var('stroke', lower=0.0254, upper=1)
prob.model.add_objective('objective')
prob.setup()
prob.model.approx_totals()
prob.run_driver()
print(prob['objective'])
print(prob['cycle.f1.total_weight'])
print(prob['cycle.f1.stroke'])
print(prob['cycle.f1.n_gear'])
Вызывает промежуточную группу, как в примере с Sellar
import openmdao.api as om
from FunctionsForTest import FunctionForTest1
from FunctionsForTest import FunctionForTest2
class IntermediateCycle(om.Group):
def setup(self):
indeps = self.add_subsystem('indeps', om.IndepVarComp(), promotes=['*'])
indeps.add_output('n_gear', 3.0)
indeps.add_output('stroke', 0.2)
indeps.add_output('total_weight', 26000.0)
cycle = self.add_subsystem('cycle', om.Group())
cycle.add_subsystem('f1', FunctionForTest1())
cycle.add_subsystem('f2', FunctionForTest2())
cycle.connect('f1.landing_gear_weight','f2.landing_gear_weight')
cycle.connect('f2.total_weight','f1.total_weight')
self.connect('n_gear','cycle.f1.n_gear')
self.connect('stroke','cycle.f1.stroke')
#cycle.nonlinear_solver = om.NonlinearBlockGS()
self.nonlinear_solver = om.NonlinearBlockGS()
self.add_subsystem('objective', om.ExecComp('objective = total_weight', objective=26000, total_weight=26000), promotes=['objective', 'total_weight'])
Наконец, есть файл с двумяфункции в нем:
import openmdao.api as om
class FunctionForTest1(om.ExplicitComponent):
def setup(self):
self.add_input('stroke', val=0.2)
self.add_input('n_gear', val=3.0)
self.add_input('total_weight', val=26000)
self.add_output('landing_gear_weight')
self.declare_partials('*', '*', method='fd')
def compute(self, inputs, outputs):
stroke = inputs['stroke']
n_gear = inputs['n_gear']
total_weight = inputs['total_weight']
outputs['landing_gear_weight'] = total_weight * 0.1 + 100*stroke * n_gear ** 2
class FunctionForTest2(om.ExplicitComponent):
def setup(self):
self.add_input('landing_gear_weight')
self.add_output('total_weight')
self.declare_partials('*', '*', method='fd')
def compute(self, inputs, outputs):
landing_gear_weight = inputs['landing_gear_weight']
outputs['total_weight'] = 26000 + landing_gear_weight
Он сообщает, что оптимизация успешно завершена,
Optimization terminated successfully. (Exit mode 0)
Current function value: 26000.0
Iterations: 1
Function evaluations: 1
Gradient evaluations: 1
Optimization Complete
-----------------------------------
[26000.]
[29088.88888889]
[0.2]
[3.]
, однако значение для функции оптимизации не изменилось.Кажется, что он сходится к петле, чтобы оценить вес, но не изменяет расчетные переменные, чтобы найти оптимальный.
Он достигает 29088,9, что правильно для значения n_gear = 3 и хода = 0,2, но если оба значения уменьшатся до границ n_gear = 2 и stroke = 0.0254, получится значение ~ 28900, меньше ~ 188.
Буду признателен за любые советы, ссылки на учебные пособия или решения..