Skip to content

Commit

Permalink
Some updates to the serial run of the supersonic panel case for the
Browse files Browse the repository at this point in the history
variable naming convention class
  • Loading branch information
kejacobson committed Dec 11, 2024
1 parent 8cab854 commit 62484fd
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 129 deletions.
39 changes: 19 additions & 20 deletions examples/aerostructural/supersonic_panel/aerodynamics_mphys.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,27 @@

from piston_theory import PistonTheory

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

# IVC which returns a baseline mesh
class AeroMesh(om.IndepVarComp):
def initialize(self):
self.options.declare('x_aero0')
def setup(self):
self.x_aero0_name = MPhysVariables.Aerodynamics.Surface.COORDINATES_INITIAL
self.add_output(self.x_aero0_name, val=self.options['x_aero0'], distributed=True, tags=['mphys_coordinates'])
self.add_output(X_AERO0_MESH, val=self.options['x_aero0'], distributed=True, tags=['mphys_coordinates'])


# IC which computes aero pressures
class AeroSolver(om.ImplicitComponent):
def initialize(self):
self.options.declare('solver')

self.x_aero_name = MPhysVariables.Aerodynamics.Surface.COORDINATES

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

self.add_input(self.x_aero_name, shape_by_conn=True, distributed=True, tags=['mphys_coordinates'])
self.add_input(X_AERO, shape_by_conn=True, distributed=True, tags=['mphys_coordinates'])
self.add_input('aoa', 0., units = 'deg', tags=['mphys_input'])
self.add_input('qdyn', 0., tags=['mphys_input'])
self.add_input('mach', 0., tags=['mphys_input'])
Expand All @@ -38,15 +39,15 @@ def setup(self):

def solve_nonlinear(self,inputs,outputs):

self.solver.xyz = inputs[self.x_aero_name]
self.solver.xyz = inputs[X_AERO]
self.solver.aoa = inputs['aoa']
self.solver.qdyn = inputs['qdyn']
self.solver.mach = inputs['mach']

outputs['pressure'] = self.solver.compute_pressure()

def apply_nonlinear(self,inputs,outputs,residuals):
self.solver.xyz = inputs[self.x_aero_name]
self.solver.xyz = inputs[X_AERO]
self.solver.aoa = inputs['aoa']
self.solver.qdyn = inputs['qdyn']
self.solver.mach = inputs['mach']
Expand All @@ -69,8 +70,8 @@ def apply_linear(self,inputs,outputs,d_inputs,d_outputs,d_residuals,mode):
adjoint=d_residuals['pressure']
)

if self.x_aero_name in d_inputs:
d_inputs[self.x_aero_name] += d_xa
if X_AERO in d_inputs:
d_inputs[X_AERO] += d_xa
if 'aoa' in d_inputs:
d_inputs['aoa'] += d_aoa
if 'qdyn' in d_inputs:
Expand All @@ -85,30 +86,28 @@ def initialize(self):
self.options.declare('solver')

def setup(self):
self.x_aero_name = MPhysVariables.Aerodynamics.Surface.COORDINATES
self.f_aero_name = MPhysVariables.Aerodynamics.Surface.LOADS

self.solver = self.options['solver']

self.add_input(self.x_aero_name, shape_by_conn=True, distributed=True, tags=['mphys_coordinates'])
self.add_input(X_AERO, shape_by_conn=True, distributed=True, tags=['mphys_coordinates'])
self.add_input('pressure', shape_by_conn=True, distributed=True, tags=['mphys_coupling'])
self.add_output(self.f_aero_name, np.zeros(self.solver.n_nodes*self.solver.n_dof), distributed=True, tags=['mphys_coupling'])
self.add_output(F_AERO, np.zeros(self.solver.n_nodes*self.solver.n_dof), distributed=True, tags=['mphys_coupling'])

def compute(self,inputs,outputs):
self.solver.xyz = inputs[self.x_aero_name]
self.solver.xyz = inputs[X_AERO]
self.solver.pressure = inputs['pressure']

outputs[self.f_aero_name] = self.solver.compute_force()
outputs[F_AERO] = self.solver.compute_force()

def compute_jacvec_product(self, inputs, d_inputs, d_outputs, mode):
if mode == 'rev':
if self.f_aero_name in d_outputs:
if F_AERO in d_outputs:
d_xa, d_p = self.solver.compute_force_derivatives(
adjoint=d_outputs[self.f_aero_name]
adjoint=d_outputs[F_AERO]
)

if self.x_aero_name in d_inputs:
d_inputs[self.x_aero_name] += d_xa
if X_AERO in d_inputs:
d_inputs[X_AERO] += d_xa
if 'pressure' in d_inputs:
d_inputs['pressure'] += d_p

Expand Down Expand Up @@ -205,4 +204,4 @@ def get_number_of_nodes(self):
return self.solver.n_nodes

def get_ndof(self):
return self.soler.n_dof
return self.solver.n_dof
26 changes: 18 additions & 8 deletions examples/aerostructural/supersonic_panel/geometry_morph.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
import numpy as np
import openmdao.api as om
from mpi4py import MPI
from mphys import Builder
from mphys import Builder, MPhysVariables


X_AERO0_GEOM_INPUT = MPhysVariables.Aerodynamics.Surface.Geometry.COORDINATES_INPUT
X_AERO0_GEOM_OUTPUT = MPhysVariables.Aerodynamics.Surface.Geometry.COORDINATES_OUTPUT

X_STRUCT_GEOM_INPUT = MPhysVariables.Structures.Geometry.COORDINATES_INPUT
X_STRUCT_GEOM_OUTPUT = MPhysVariables.Structures.Geometry.COORDINATES_OUTPUT

# EC which morphs the geometry
class GeometryMorph(om.ExplicitComponent):
def initialize(self):
self.options.declare('names')
self.options.declare('n_nodes')

self.input_names = {'aero': X_AERO0_GEOM_INPUT, 'struct': X_STRUCT_GEOM_INPUT}
self.output_names = {'aero': X_AERO0_GEOM_OUTPUT, 'struct': X_STRUCT_GEOM_OUTPUT}

def setup(self):
self.add_input('geometry_morph_param')

for name, n_nodes in zip(self.options['names'], self.options['n_nodes']):
self.add_input(f'x_{name}_in', distributed=True, shape_by_conn=True)
self.add_output(f'x_{name}0', shape=n_nodes*3, distributed=True, tags=['mphys_coordinates'])
self.add_input(self.input_names[name], distributed=True, shape_by_conn=True, tags=['mphys_coordinates'])
self.add_output(self.output_names[name], shape=n_nodes*3, distributed=True, tags=['mphys_coordinates'])

def compute(self,inputs,outputs):
for name in self.options['names']:
outputs[f'x_{name}0'] = inputs['geometry_morph_param']*inputs[f'x_{name}_in']
outputs[self.output_names[name]] = inputs['geometry_morph_param']*inputs[self.input_names[name]]

def compute_jacvec_product(self, inputs, d_inputs, d_outputs, mode):
if mode == 'rev':
for name in self.options['names']:
if f'x_{name}0' in d_outputs:
if self.output_names[name] in d_outputs:
if 'geometry_morph_param' in d_inputs:
d_inputs['geometry_morph_param'] += self.comm.allreduce(np.sum(d_outputs[f'x_{name}0']*inputs[f'x_{name}_in']), op=MPI.SUM)
d_inputs['geometry_morph_param'] += self.comm.allreduce(np.sum(d_outputs[self.output_names[name]]*inputs[self.input_names[name]]), op=MPI.SUM)

if f'x_{name}_in' in d_inputs:
d_inputs[f'x_{name}_in'] += d_outputs[f'x_{name}0']*inputs['geometry_morph_param']
if self.input_names[name] in d_inputs:
d_inputs[self.input_names[name]] += d_outputs[self.output_names[name]]*inputs['geometry_morph_param']


# Builder
Expand Down
23 changes: 18 additions & 5 deletions examples/aerostructural/supersonic_panel/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import openmdao.api as om
import os

from mphys import Multipoint
from mphys import Multipoint, MPhysVariables
from mphys.scenarios.aerostructural import ScenarioAeroStructural

from structures_mphys import StructBuilder
Expand All @@ -23,6 +23,17 @@
N_el_struct = 20
N_el_aero = 7

X_AERO = MPhysVariables.Aerodynamics.Surface.COORDINATES
X_AERO0 = MPhysVariables.Aerodynamics.Surface.COORDINATES_INITIAL
X_AERO0_MESH = MPhysVariables.Aerodynamics.Surface.Mesh.COORDINATES
X_AERO0_GEOM_INPUT = MPhysVariables.Aerodynamics.Surface.Geometry.COORDINATES_INPUT
X_AERO0_GEOM_OUTPUT = MPhysVariables.Aerodynamics.Surface.Geometry.COORDINATES_OUTPUT

X_STRUCT = MPhysVariables.Structures.COORDINATES
X_STRUCT_MESH = MPhysVariables.Structures.Mesh.COORDINATES
X_STRUCT_GEOM_INPUT = MPhysVariables.Structures.Geometry.COORDINATES_INPUT
X_STRUCT_GEOM_OUTPUT = MPhysVariables.Structures.Geometry.COORDINATES_OUTPUT

# Mphys
class Model(Multipoint):
def initialize(self):
Expand Down Expand Up @@ -74,10 +85,10 @@ def setup(self):

self.add_subsystem('struct_mesh', struct_builder.get_mesh_coordinate_subsystem())
self.add_subsystem('aero_mesh', aero_builder.get_mesh_coordinate_subsystem())
self.add_subsystem('geometry', geometry_builder.get_mesh_coordinate_subsystem(), promotes=['*'])
self.add_subsystem('geometry', geometry_builder.get_mesh_coordinate_subsystem())

self.connect('struct_mesh.x_struct0', 'x_struct_in')
self.connect('aero_mesh.x_aero0', 'x_aero_in')
self.connect(f'struct_mesh.{X_STRUCT_MESH}', f'geometry.{X_STRUCT_GEOM_INPUT}')
self.connect(f'aero_mesh.{X_AERO0_MESH}', f'geometry.{X_AERO0_GEOM_INPUT}')

# create the run directory
if self.comm.rank==0:
Expand All @@ -97,8 +108,10 @@ def setup(self):
coupling_nonlinear_solver=nonlinear_solver,
coupling_linear_solver=linear_solver)

for var in ['modulus', 'yield_stress', 'density', 'mach', 'qdyn', 'aoa', 'dv_struct', 'x_struct0', 'x_aero0']:
for var in ['modulus', 'yield_stress', 'density', 'mach', 'qdyn', 'aoa', 'dv_struct']:
self.connect(var, self.scenario_name+'.'+var)
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}')

# add design variables, to simplify remote setup
self.add_design_var('geometry_morph_param', lower=0.1, upper=10.0)
Expand Down
4 changes: 1 addition & 3 deletions examples/aerostructural/supersonic_panel/run_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from mpi4py import MPI
import openmdao.api as om

from mphys import Multipoint, MultipointParallel
from mphys import MultipointParallel
from mphys.scenarios.aerostructural import ScenarioAeroStructural

from structures_mphys import StructBuilder
Expand All @@ -22,9 +22,7 @@
N_el_struct = 20
N_el_aero = 7

# Mphys parallel multipoint scenarios
class AerostructParallel(MultipointParallel):
#class AerostructParallel(Multipoint):
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
Expand Down
Loading

0 comments on commit 62484fd

Please sign in to comment.