Skip to content

Commit

Permalink
fix broken connection in run.py; clean up other things a bit and veri…
Browse files Browse the repository at this point in the history
…fy with latest remote codes+beta
  • Loading branch information
Asthelen committed Dec 11, 2024
1 parent e7e0fb0 commit 53ce6c0
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 42 deletions.
28 changes: 28 additions & 0 deletions examples/aerostructural/supersonic_panel/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Summary of top-level codes:

run.py: most basic code that demonstrates a single scenario, doing a derivative check at the starting design
run_parallel.py: code that demonstrates two scenarios, evaluated in parallel with MultipointParallel, doing a derivative check at the starting design
as_opt_parallel.py: runs an optimization of the previous code's two scenarios (mass minimization subject to lift and stress constraints at the two flight conditions)
as_opt_remote_serial.py: runs the same optimization using one remote component that evaluates the MultipointParallel group in as_opt_parallel.py
as_opt_remote_parallel.py: runs the same optimization using two parallel remote components, which each evaluates the Multipoint analysis in run.py

The optimizations should complete with the following metrics; note that objective and constraint names can vary slightly based on the optimization script.

Nonlinear constraints
{'multipoint.aerostructural1.C_L': array([0.15]),
'multipoint.aerostructural1.func_struct': array([1.00000023]),
'multipoint.aerostructural2.C_L': array([0.45]),
'multipoint.aerostructural2.func_struct': array([1.00000051])}

Objectives
{'multipoint.aerostructural1.mass': array([8.73298752e-05])}

Optimization terminated successfully (Exit mode 0)
Current function value: 0.008732987524877025
Iterations: 22
Function evaluations: 24
Gradient evaluations: 22

Note that the remote scripts, which both use mphys_server.py, are set up to use the K4 queue of NASA Langley's K cluster.
To run this script on an HPC not supported by pbs4py, you will likely have to write your own pbs4py Launcher constructor.
Further details on remote components may be found on the document page: https://openmdao.github.io/mphys/basics/remote_components.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from piston_theory import PistonTheory

X_AERO0_MESH= MPhysVariables.Aerodynamics.Surface.Mesh.COORDINATES
X_AERO0_MESH = MPhysVariables.Aerodynamics.Surface.Mesh.COORDINATES
X_AERO = MPhysVariables.Aerodynamics.Surface.COORDINATES
F_AERO = MPhysVariables.Aerodynamics.Surface.LOADS

Expand Down
25 changes: 14 additions & 11 deletions examples/aerostructural/supersonic_panel/as_opt_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,25 @@ def initialize(self):
self.options.declare('scenario_names')

def setup(self):
for i in range(len(self.options['scenario_names'])):

for scenario_name in self.options['scenario_names']:

# create the run directory
if self.comm.rank==0:
if not os.path.isdir(self.options['scenario_names'][i]):
os.mkdir(self.options['scenario_names'][i])
if not os.path.isdir(scenario_name):
os.mkdir(scenario_name)
self.comm.Barrier()

nonlinear_solver = om.NonlinearBlockGS(maxiter=100, iprint=2, use_aitken=True, aitken_initial_factor=0.5)
linear_solver = om.LinearBlockGS(maxiter=40, iprint=2, use_aitken=True, aitken_initial_factor=0.5)
self.mphys_add_scenario(self.options['scenario_names'][i],
self.mphys_add_scenario(scenario_name,
ScenarioAeroStructural(
aero_builder=self.options['aero_builder'],
struct_builder=self.options['struct_builder'],
ldxfer_builder=self.options['xfer_builder'],
geometry_builder=self.options['geometry_builder'],
in_MultipointParallel=True,
run_directory=self.options['scenario_names'][i]),
run_directory=scenario_name),
coupling_nonlinear_solver=nonlinear_solver,
coupling_linear_solver=linear_solver)

Expand Down Expand Up @@ -98,12 +99,14 @@ def setup(self):
geometry_builder = GeometryBuilder(builders)

# add parallel multipoint group
self.add_subsystem('multipoint',AerostructParallel(
aero_builder=aero_builder,
struct_builder=struct_builder,
xfer_builder=xfer_builder,
geometry_builder=geometry_builder,
scenario_names=self.scenario_names))
self.add_subsystem('multipoint',
AerostructParallel(
aero_builder=aero_builder,
struct_builder=struct_builder,
xfer_builder=xfer_builder,
geometry_builder=geometry_builder,
scenario_names=self.scenario_names)
)

for i in range(len(self.scenario_names)):

Expand Down
1 change: 1 addition & 0 deletions examples/aerostructural/supersonic_panel/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def setup(self):

for var in ['modulus', 'yield_stress', 'density', 'mach', 'qdyn', 'aoa', 'dv_struct']:
self.connect(var, self.scenario_name+'.'+var)
self.connect('geometry_morph_param', 'geometry.geometry_morph_param')
self.connect(f'geometry.{X_AERO0_GEOM_OUTPUT}', f'{self.scenario_name}.{X_AERO0}')
self.connect(f'geometry.{X_STRUCT_GEOM_OUTPUT}', f'{self.scenario_name}.{X_STRUCT}')

Expand Down
61 changes: 31 additions & 30 deletions examples/aerostructural/supersonic_panel/run_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,36 @@
N_el_aero = 7

class AerostructParallel(MultipointParallel):
def __init__(self, aero_builder=None, struct_builder=None, xfer_builder=None, geometry_builder=None, scenario_names=None):
super().__init__()
self.aero_builder = aero_builder
self.struct_builder = struct_builder
self.xfer_builder = xfer_builder
self.geometry_builder = geometry_builder
self.scenario_names = scenario_names

def initialize(self):
self.options.declare('aero_builder')
self.options.declare('struct_builder')
self.options.declare('xfer_builder')
self.options.declare('geometry_builder')
self.options.declare('scenario_names')

def setup(self):
for i in range(len(self.scenario_names)):

for scenario_name in self.options['scenario_names']:
nonlinear_solver = om.NonlinearBlockGS(maxiter=100, iprint=2, use_aitken=True, aitken_initial_factor=0.5)
linear_solver = om.LinearBlockGS(maxiter=40, iprint=2, use_aitken=True, aitken_initial_factor=0.5)
self.mphys_add_scenario(self.scenario_names[i],
self.mphys_add_scenario(scenario_name,
ScenarioAeroStructural(
aero_builder=self.aero_builder,
struct_builder=self.struct_builder,
ldxfer_builder=self.xfer_builder,
geometry_builder=self.geometry_builder,
aero_builder=self.options['aero_builder'],
struct_builder=self.options['struct_builder'],
ldxfer_builder=self.options['xfer_builder'],
geometry_builder=self.options['geometry_builder'],
in_MultipointParallel=True),
coupling_nonlinear_solver=nonlinear_solver,
coupling_linear_solver=linear_solver)

# OM group
class Model(om.Group):
def initialize(self):
self.options.declare('scenario_names', default=['aerostructural1','aerostructural2'])

def setup(self):
self.scenario_names = self.options['scenario_names']

# ivc
self.add_subsystem('ivc', om.IndepVarComp(), promotes=['*'])
Expand Down Expand Up @@ -76,38 +81,34 @@ def setup(self):
aero_builder = AeroBuilder(aero_setup)

# xfer builder
xfer_builder = XferBuilder(
aero_builder=aero_builder,
struct_builder=struct_builder
)
xfer_builder = XferBuilder(aero_builder=aero_builder, struct_builder=struct_builder)

# geometry
builders = {'struct': struct_builder, 'aero': aero_builder}
geometry_builder = GeometryBuilder(builders)

# list of scenario names
scenario_names = ['aerostructural1','aerostructural2']

# add parallel multipoint group
self.add_subsystem('multipoint',AerostructParallel(
aero_builder=aero_builder,
struct_builder=struct_builder,
xfer_builder=xfer_builder,
geometry_builder=geometry_builder,
scenario_names=scenario_names))
self.add_subsystem('multipoint',
AerostructParallel(
aero_builder=aero_builder,
struct_builder=struct_builder,
xfer_builder=xfer_builder,
geometry_builder=geometry_builder,
scenario_names=self.scenario_names)
)

for i in range(len(scenario_names)):
for i in range(len(self.scenario_names)):

# connect scalar inputs to the scenario
for var in ['modulus', 'yield_stress', 'density', 'dv_struct']:
self.connect(var, 'multipoint.'+scenario_names[i]+'.'+var)
self.connect(var, 'multipoint.'+self.scenario_names[i]+'.'+var)

# connect vector inputs
for var in ['mach', 'qdyn', 'aoa']:
self.connect(var, 'multipoint.'+scenario_names[i]+'.'+var, src_indices=[i])
self.connect(var, 'multipoint.'+self.scenario_names[i]+'.'+var, src_indices=[i])

# connect top-level geom parameter
self.connect('geometry_morph_param', 'multipoint.'+scenario_names[i]+'.geometry.geometry_morph_param')
self.connect('geometry_morph_param', 'multipoint.'+self.scenario_names[i]+'.geometry.geometry_morph_param')

# run model and check derivatives
if __name__ == "__main__":
Expand Down

0 comments on commit 53ce6c0

Please sign in to comment.