我一直在OpenMDAO中运行航空MDO问题。该问题由4个耦合的学科组成,这些学科由明确的组件表示且没有约束。最近,我添加了并行处理以加速代码。以当前定义组件的方式,当我使用mpirun调用代码时,无法提高性能。相反,总运行时间增加了。我觉得这可能是因为我为学科定义了明确的组成部分的方式。我已附加了我正在调用的脚本以及其中一门学科的代码。在当前配置中,没有明确定义的派生或约束,因此我认为这些学科可能是罪魁祸首。还是可能是因为我混合使用了promise和connnct语句,如下所示?欢迎任何建议。
这是问题的脚本。
prob = Problem()
model = prob.model # = SsbjIdf2Mda(nx, ny, y12_initial, y23_initial, y32_initial, y21_initial, y31_initial)
parallel = model.add_subsystem('parallel', ParallelGroup())
model.add_subsystem('z_ini', IndepVarComp('z', .5 * np.ones(nx)))
model.add_subsystem('x1_ini', IndepVarComp('x1', .5 * np.ones(nx)))
model.add_subsystem('x2_ini', IndepVarComp('x2', .5 * np.ones(nx)))
model.add_subsystem('x3_ini', IndepVarComp('x3', .5 * np.ones(nx)))
model.add_subsystem('y31_ini', IndepVarComp('y31', .5 * np.ones(ny)))
model.add_subsystem('y12_ini', IndepVarComp('y12', .5 * np.ones(ny)))
model.add_subsystem('y32_ini', IndepVarComp('y32', .5 * np.ones(ny)))
model.add_subsystem('y23_ini', IndepVarComp('y23', .5 * np.ones(ny)))
model.add_subsystem('y21_ini', IndepVarComp('y21', .5 * np.ones(ny)))
parallel.add_subsystem('Structure', StructureDisc())
parallel.add_subsystem('Aerodynamics', AerodynamicsDisc())
parallel.add_subsystem('Propulsion', PropulsionDisc())
model.add_subsystem('Performance', PerformanceDisc())
# Shared variables z
model.connect('z_ini.z', 'parallel.Structure.z')
model.connect('z_ini.z', 'parallel.Aerodynamics.z')
model.connect('z_ini.z', 'parallel.Propulsion.z')
model.connect('z_ini.z', 'Performance.z')
# Local variables
model.connect('x1_ini.x1', 'parallel.Structure.x1')
model.connect('x2_ini.x2', 'parallel.Aerodynamics.x2')
model.connect('x3_ini.x3', 'parallel.Propulsion.x3')
model.connect('x1_ini.x1', 'Performance.x1')
model.connect('x2_ini.x2', 'Performance.x2')
model.connect('x3_ini.x3', 'Performance.x3')
# Coupling variables
model.connect('y21_ini.y21', 'parallel.Structure.y21')
model.connect('y31_ini.y31', 'parallel.Structure.y31')
model.connect('y32_ini.y32', 'parallel.Aerodynamics.y32')
model.connect('y12_ini.y12', 'parallel.Aerodynamics.y12')
model.connect('y23_ini.y23', 'parallel.Propulsion.y23')
model.add_subsystem('Obj', ExecComp('obj=range'), promotes=['obj'])
# Connections
model.connect('Performance.range', 'Obj.range')
model.connect('parallel.Aerodynamics.y21', 'Performance.y21')
model.connect('parallel.Propulsion.y31', 'Performance.y31')
model.connect('parallel.Propulsion.y32', 'Performance.y32')
model.connect('parallel.Structure.y12', 'Performance.y12')
model.connect('parallel.Aerodynamics.y23', 'Performance.y23')
# create the MDA
# Design variables
model.add_design_var('z_ini.z', lower=np.zeros(nx),
upper=np.ones(nx)) # shared variables
model.add_design_var('x1_ini.x1', lower=np.zeros(nx),
upper=np.ones(nx)) # local variable for structural discipline
model.add_design_var('x2_ini.x2', lower=np.zeros(nx),
upper=np.ones(nx)) # local variable for aerodyn. discipline
model.add_design_var('x3_ini.x3', lower=np.zeros(nx),
upper=np.ones(nx)) # local variable for propulsion discipline
# # coupling variables
model.add_design_var('y31_ini.y31', lower=np.zeros(ny),
upper=np.ones(ny))
model.add_design_var('y12_ini.y12', lower=np.zeros(ny),
upper=np.ones(ny))
model.add_design_var('y32_ini.y32', lower=np.zeros(ny),
upper=np.ones(ny))
model.add_design_var('y23_ini.y23', lower=np.zeros(ny),
upper=np.ones(ny))
model.add_design_var('y21_ini.y21', lower=np.zeros(ny),
upper=np.ones(ny))
# Objective function
model.add_objective('obj')
prob.driver = ScipyOptimizeDriver()
prob.set_solver_print(2)
prob.driver.options['optimizer'] = 'SLSQP'
for tol in [1e-3]:
prob.driver.options['maxiter'] = 50 # random.randint(40, 50)
prob.driver.options['tol'] = tol
prob.driver.add_recorder(SqliteRecorder("cases_idf.sql"))
# Run optimization
start_time = time.time()
prob.setup(mode='fwd')
# view_model(prob, outfile='n2_mdfgs.html', show_browser=True)
prob.run_driver()
prob.run_model()
# prob.check_partials()
prob.cleanup()
end_time = time.time()
total_time = end_time - start_time
print("total_time:", total_time, "seconds")
下面是定义这四个学科的方式。
class StructureDisc(ExplicitComponent):
def __init__(self):
super(StructureDisc, self).__init__()
with open("input_values.p", "rb") as f:
a = pickle.load(f)
self.nx = a[0]
self.ny = a[1]
@staticmethod
def structure():
structure = Structure()
return structure
def setup(self):
# Global Design Variable z
self.add_input('z', val=np.ones(self.nx) * 0.5)
# Local Design Variable
self.add_input('x1', val=np.ones(self.nx) * 0.5)
# Coupling parameters
self.add_input('y21', val=np.ones(self.ny) * 0.5)
self.add_input('y31', val=np.ones(self.ny) * 0.5)
# Coupling output
self.add_output('y12', val=np.ones(self.ny) * 0.5)
self.add_output('y14', val=np.ones(self.ny) * 0.5)
self.add_output('g1', val=np.ones(self.nx) * 0.5)
self.declare_partials('*', '*', method='fd')
def compute(self, inputs, outputs):
t1 = np.concatenate((inputs['x1'], inputs['y21'], inputs['y31'], np.ones(self.nx + 2 * self.ny),
np.ones(self.nx + self.ny), inputs['z']))
x_des = t1
output_list = ['y12', 'y14', 'g1']
for i in output_list:
outputs[i] = np.concatenate(getattr(self.structure(), i)(self.nx, self.ny, x_des), axis=0)