Skip to content

Commit

Permalink
Merge branch 'supersonic_panel_update' into network_remote_dvs
Browse files Browse the repository at this point in the history
  • Loading branch information
Asthelen committed Dec 11, 2024
2 parents 2c96a51 + 62484fd commit e7e0fb0
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 131 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/host_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:

- uses: actions/setup-python@v2
with:
python-version: 3.8
python-version: 3.9

- name: Run unit test
run: |
Expand All @@ -34,7 +34,7 @@ jobs:
echo "=============================================================";
source $CONDA/etc/profile.d/conda.sh;
echo $CONDA/bin >> $GITHUB_PATH;
conda create -n OpenMDAO python=3.8 numpy=1 scipy=1 -q -y;
conda create -n OpenMDAO python=3.9 numpy=1 scipy=1 -q -y;
conda activate OpenMDAO;
pip install --upgrade pip
echo "=============================================================";
Expand Down
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 e7e0fb0

Please sign in to comment.