Я выполняю статический аэроупругий анализ, используя скрипт на основе OpenMDAO. Я пытаюсь адаптировать свой скрипт для запуска на суперкомпьютере.
Цикл MDA включает в себя несколько компонентов, в том числе решатель CFD, который обычно запускается в терминале с помощью mpirun -np 24 python runScript.py
, и структурный решатель, который обычно запускается в терминале с помощью nast20212 nastran_static_alpha_c.bdf
.
Чтобы запустить CFD в параллельном режиме в моем основном скрипте, мне нужно запустить его с помощью mpirun -np 24 python aeroelastic_mda.py
.
Проблема в том, что когда я это делаю, скрипт пытается запустить все компоненты в параллельном режиме. Однако мне нужно было только запустить мой CFD-решатель для работы на нескольких узлах, в то время как другие компоненты работают в последовательном режиме.
Я просмотрел документацию OpenMDAO и другие сообщения, но не нашел информации по своей проблеме.
Ниже приведен краткий обзор моего сценария OpenMDAO, который я запускаю с
mpirun -np 24 python aeroelastic_mda.py
.
#Importing necessary modules
...
if __name__ == "__main__":
#Problem parameters
Sw = 383.689555/2 #Wing reference surface
V = 295.0 #Airspeed
rho_a = 1.17 #Air density
... #Some other parameters
root = Problem()
#Add independent variables
root.model.add_subsystem('wing_area', IndepVarComp('Sw', Sw), promotes=['*'])
root.model.add_subsystem('airspeed', IndepVarComp('V', V), promotes=['*'])
root.model.add_subsystem('air_density', IndepVarComp('rho_a', rho_a), promotes=['*'])
... #Some other independent variables
mda = Group()
#Add disciplines to the group
# Displacement transfer:
# Inputs -> Displacements at structural nodes
# Outputs -> Displacements to be applied to aerodynamic nodes
# Simple matrix product
mda.add_subsystem('displacement_transfer', DisplacementTransfer(), promotes=['*'])
# Aerodynamic solver
mda.add_subsystem('aerodynamics', Dafoam(), promotes=['*'])
# Load transfer
# Inputs -> Forces at aerodynamic nodes
# Outputs -> Forces to be applied to structural nodes
# Simple matrix product
mda.add_subsystem('load_transfer', LoadTransfer(), promotes=['*'])
# Structural solver
mda.add_subsystem('structures', NastranStatic(), promotes=['*'])
root.model.add_subsystem('mda_group', mda, promotes=['*'])
mda.nonlinear_solver = NonlinearBlockGS()
mda.nonlinear_solver.options['rtol'] = 1.e-3
mda.nonlinear_solver.options['use_aitken'] = True
mda.linear_solver = ScipyKrylov()
root.linear_solver = ScipyKrylov()
root.setup()
root.run_model()
Также вот упрощенный вид моего аэродинамического компонента:
#Importing necessary modules
...
class Dafoam(ExplicitComponent):
... #Some constants
def initialize(self):
... #Declaring options
def setup(self):
... #Declaring inputs
... #Declaring outputs
def compute(self, inputs, outputs):
#Generate current deformed shape
self.create_current_geom(inputs, outputs)
#Generate the input file for Dafoam from current geometry and flow conditions
self.create_input_file(inputs, outputs)
# Run DAFoam
p = Popen(['python', 'runScript.py'])
p.wait()
# Parse the output file from the external code
...
def create_current_geom(self, inputs, outputs):
...
#Method that creates the Dafoam input file runScript.py
def create_input_file(self, inputs, outputs):
...
def get_forces(self, inputs, outputs):
...
def get_aero_coeff(self, inputs, outputs):
...
Также вот упрощенный вид моего структурного компонента:
#Importing necessary modules
...
class NastranStatic(ExplicitComponent):
... #Some constants
def initialize(self):
... #Declaring options
def setup(self):
... #Declaring inputs
... #Declaring outputs
def compute(self, inputs, outputs):
# Generate the input file for Nastran
self.create_input_file(inputs, outputs)
# Run MSC Nastran
p = Popen(['nast20212', 'nastran_static_alpha_c.bdf'])
p.wait()
# Parse the output file from the external code and set output values
...
def create_input_file(self, inputs, outputs):
...
def get_output_data(self, inputs, outputs):
...
Заранее большое спасибо за вашу помощь!
@JustinGray спасибо за ответ. Я добавил упрощенные виды моего основного скрипта OpenMDAO, аэродинамических и конструктивных компонентов. Когда я запускаю основной скрипт в MPI, CFD-решатель успешно работает в MPI, но основной скрипт также пытается запустить структурный решатель в MPI, даже если, как я знаю, он не поддерживает MPI. Пожалуйста, сообщите мне, если вам нужна дополнительная информация.
Без подробностей сложно дать точный ответ. Тем не менее, похоже, что у вас есть компонент, выполняющий вызов подпроцесса, чтобы попытаться запустить CFD под MPI, в то время как сама модель OpenMDAO запускается последовательно сверху.
Вообще говоря, это неправильный подход к OpenMDAO. Сама структура поддерживает MPI, и компоненты могут объявлять распределенные входы/выходы. Документы по распределенному вводу-выводу дают несколько достойных примеров, на которые стоит обратить внимание.
Я также рекомендую вам ознакомиться с библиотекой Mphys, которая построена на основе OpenMDAO и содержит множество примеров аэроструктур для работы.
Вы можете рассмотреть возможность последовательного запуска скрипта верхнего уровня только с помощью python aeroelastic_mda.py
и изменить вызовы Popen для запуска подпроцессов с помощью mpirun, например Popen(['mpirun', '-np', '24', 'nast20212', 'nastran_static_alpha_c.bdf'])
. Вы также можете изменить свой сценарий верхнего уровня, чтобы он принимал аргументы командной строки, чтобы указать количество процессов, которые вы хотите использовать с вашими вызовами nastran и Dafoam.
@BretNeylor спасибо за ответ. Это была моя первая идея, но по какой-то причине Popen(['mpirun', '-np', '24', 'python','runScript.py']) не работает в моей среде OpenMDAO. Код компонента просто не запускается и сразу завершается.
Вы получили сообщение об ошибке, когда пытались это сделать? Если да, то не могли бы вы опубликовать это? Я только что попробовал это с помощью простого скрипта Python и нижнего скрипта, и он работал нормально.
Нет, к сожалению, я не получаю конкретного сообщения. Я пытался сделать это с помощью простого скрипта, как и вы, он работал нормально, пока я не импортировал API OpenMDAO. Может быть, вы можете попробовать добавить его в свой сценарий, чтобы посмотреть, сможете ли вы воспроизвести проблему?
В конце концов я решил свою проблему, заменив Popen функцией ShellProc (openmdao.utils.shell_proc). По какой-то причине Popen не работал должным образом при использовании с командой mpirun.
Из вашего вопроса не ясно на 100%, но похоже, что вы пытаетесь использовать компонент OpenMDAO, который вызывает вызов подпроцесса для запуска вашего aero_analysis.py. Если это так, то это неправильный подход к использованию MPI. Чтобы дать вам реальный ответ, не могли бы вы привести игрушечный пример, который, по крайней мере, показывает структуру ваших компонентов и модели, а также любые соответствующие команды запуска, которые вы используете?