Как использовать внешний компонент кода в рамках оптимизации

Привет, я пытаюсь использовать компонент внешнего кода параболоида, чтобы получить те же результаты, что и в задаче оптимизации параболоида (openmdao v 2.2.0).

Поэтому, на мой взгляд, независимые переменные x,y должны быть обновлены и, таким образом, изменены входной файл внешнего компонента, чтобы минимизировать вывод f.
Не то чтобы у меня это работало, но я в основном добавляю выходные данные внешнего компонента в качестве цели и независимые переменные в качестве переменных проекта и т. Д. (См. Код ниже). Но что более важно, у меня есть проблема, чтобы концептуально понять, как оптимизатор узнает производные в таких внешних кодах. Я попробовал "COBYLA", думая, что это может быть подходом без градиента, но, похоже, в заявлении iprint есть ошибка, так как я не могу запустить примерную оптимизацию параболоида.

Я думаю, что у меня похожая проблема с суррогатами. Например, я использую метамодельноструктурированный компонент, чтобы найти мой суррогат, который хорошо работает, если я запрашиваю известное значение. Но я не вижу, как связать вывод этого компонента с целью оптимизатора. Я думаю, что делаю правильные вещи, задавая цель модели. но не уверен...

Ответ может быть таким, что я совершенно не согласен с логикой оптимизации, если это так, пожалуйста, отошлите меня к соответствующим статьям для алгоритмов.

заранее спасибо

from openmdao.api import Problem, Group, IndepVarComp
from openmdao.api import  ScipyOptimizeDriver
from openmdao.components.tests.test_external_code import ParaboloidExternalCode

top = Problem()
top.model = model = Group()

# create and connect inputs
model.add_subsystem('p1', IndepVarComp('x', 3.0))
model.add_subsystem('p2', IndepVarComp('y', -4.0))
model.add_subsystem('p', ParaboloidExternalCode())

model.connect('p1.x', 'p.x')
model.connect('p2.y', 'p.y')

top.driver = ScipyOptimizeDriver()
top.driver.options['optimizer'] = 'SLSQP'

top.model.add_design_var('p1.x', lower=-50, upper=50)
top.model.add_design_var('p2.y', lower=-50, upper=50)
top.model.add_objective('p.f_xy')
top.driver.options['tol'] = 1e-9
top.driver.options['disp'] = True
top.setup()
top.run_driver()
# minimum value
# location of the minimum
print(top['p1.x'])
print(top['p2.y'])

1 ответ

Решение

Итак, я думаю, что главное, что вы спрашиваете, - как предоставить производные для внешних кодов. Я думаю, что для этого есть два варианта.

  1. Конечная разница по всему внешнему компоненту.

В тестовом примере не показано, как это сделать, что очень печально, но вы делаете это так же, как объявляете производные fd для чистого компонента python, а именно добавляя эту строку в метод установки внешнего компонента:

self.declare_partials(of='*', wrt='*', method='fd')
  1. Предоставьте другой внешний метод для вычисления производных и поместите его в метод "compute_partials".

Мы делаем это с кодами CFD, которые предоставляют сопряженное решение. Возможно, вы также можете использовать автоматическое дифференцирование во внешнем исходном коде для создания вызываемой функции таким образом. Тем не менее, я думаю, что метод 1 - это то, что вы просите здесь.

Другие вопросы по тегам