Ошибка при вычислении векторного произведения Якоби - PullRequest
0 голосов
/ 13 апреля 2020

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

Когда я пытаюсь запустить модель со стандартным решателем «RunOnce», все в порядке, но как только я пытаюсь запустить оптимизацию, я получаю следующую ошибку от linear_block_gs.py:

Файл "... \ openmdao \ core \ group.py", строка 1790, в _apply_linear scope_out, scope_in)
Файл "... \ openmdao \ core \licitcomponent.py", строка 339, в _apply_linear self. compute_jacvec_product (* args)
Файл "... \ Thermal_Cycle.py", строка 51, в compute_jacvec_product d_inputs ['T'] = наклон * Файл deff_dT / alp_sc "... \ openmdao \ vectors \ vector.py" , строка 363, в setitem повышение KeyError (msg.format (name)) KeyError: «Имя переменной« T »не найдено».

Ниже приведена диаграмма N2 модель. Переменная «T», которая упоминается в ошибке, происходит из неявного компонента «temp» и возвращается в компонент «s c» (файл Thermal_Cycle.py в сообщении об ошибке) в качестве входных данных.

Диаграмма N2

Ошибка исчезает, когда я назначаю DirectSolver поверх всей модели. У меня сложилось впечатление, что «RunOnce» будет работать до тех пор, пока к группам с неявными компонентами будут применены соответствующие решатели, как предложено здесь , и это делается в моем случае. Почему это не работает при попытке вычислить суммарные производные модели, т.е. почему compute_jacvec_product не может найти связанную переменную "T"?

Причина, по которой я хочу использовать решатель "RunOnce", заключается в том, что оптимизация с DirecSolver сверху становится очень долго, пока мой переменный вектор "Т" увеличивается. Я подозреваю, что это должно быть намного быстрее с линейным «RunOnce»?

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Я думаю, этот пример метода compute_jacvec_product может быть полезным.

http://openmdao.org/twodocs/versions/latest/features/core_features/defining_components/explicitcomp.html#comp -type-2 -licitcomp

Проблема заключается в том, что в зависимости от конфигурации решателя или структуры модели OpenMDAO может потребоваться только некоторые Частицы, которые вы предоставляете в этом методе. Например, ваш компонент без матрицы может иметь два входа, но подключен только один, поэтому OpenMDAO не требуется производная по отношению к неподключенному входу и фактически не выделяет для него место в векторах d_inputs или d_outputs.

Итак, чтобы решить проблему, вам нужно просто поставить оператор if перед присвоением значения, как в примере.

0 голосов
/ 13 апреля 2020

Исходя из N2, я думаю , что я согласен с вашей стратегией установки прямого решателя только вокруг муфты. Это должно работать нормально, однако похоже, что вы реализуете линейный оператор в своем компоненте на основе:

File "...\Thermal_Cycle.py", line 51, in compute_jacvec_product d_inputs['T'] = slope * deff_dT / alp_sc 

Вы не должны использовать прямой решатель с частями без матрицы. Прямой решатель вычисляет обратное, что требует полной сборки матрицы. Единственная причина, по которой он работает, заключается в том, что OM обладает некоторой резервной функциональностью для ручной сборки якобиана, пропуская столбцы матрицы тождеств через метод compute_jacvec_product. Этот резервный механизм призван заставить все работать, но он очень медленный (в итоге вы вызываете compute_jacvec_product A LOT).

Ошибка, которую вы получаете, и почему она работает, когда вы поднимаете прямой решатель выше в модели, возможно, из-за отсутствия необходимых if условий в вашей реализации compute_jacvec_product. См. документы по явному компоненту для некоторых примеров , но ключевой момент заключается в том, чтобы понять, что не каждая отдельная переменная будет присутствовать при выполнении продукта jacve c (это зависит от того, какое решение делается --- то есть один для Ньютона против одного для полных производных всей модели). Таким образом, эти if-проверки необходимы для проверки релевантности переменных. Это сделано, потому что для дорогих кодов (например, CFD) некоторые из этих операций довольно дороги, и вы не хотите делать их без необходимости.

Ваши компоненты настолько велики, что вы не можете использовать функцию compute_partials? Вы пытались указать редкость в вашем якобиане ? Обычно безматричные методы с частными производными не нужны, пока вы не начнете работать с действительно большими решателями PDE с 1e6 или более неявными выходными переменными.

Не видя некоторого кода, трудно комментировать более подробно, но в итоге: вы не должны использовать compute_jacvec_product в сочетании с прямым решателем. Если вам действительно нужны безматричные матрицы, то вам нужно переключиться на итеративные линейные решатели liket PetscKrylov .

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

...