Skip to content

Commit

Permalink
Updating Mphys wrapper for 2.0 update (#315)
Browse files Browse the repository at this point in the history
* Updating MPhys wrapper for 2.0

* Updating docs/examples

* Updating tests

* Updating distributed summer

* Update docstring

* Updating broken test

* Update setup.py

* Removing deprecated `mphys_connect_scenario_coordinate_source` method

---------

Co-authored-by: Alasdair Gray <alachris@umich.edu>
  • Loading branch information
timryanb and A-CGray authored Dec 12, 2024
1 parent f3c69ea commit e5e4d26
Show file tree
Hide file tree
Showing 20 changed files with 319 additions and 176 deletions.
14 changes: 9 additions & 5 deletions docs/source/examples/Example-Beam_Optimization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ First, we import required libraries, define the model bdf file, and define impor
import matplotlib.pyplot as plt
import numpy as np
import openmdao.api as om
from mphys import Multipoint
from mphys.scenario_structural import ScenarioStructural
from mphys.core import Multipoint, MPhysVariables
from mphys.scenarios import ScenarioStructural
from tacs import elements, constitutive, functions
from tacs.mphys import TacsBuilder
Expand Down Expand Up @@ -120,7 +120,6 @@ We use this builder to create an MPhys :class:`~mphys.StructuralScenario`.
mesh_file=bdf_file,
element_callback=element_callback,
problem_setup=problem_setup,
coupled=False,
write_solution=False,
)
struct_builder.initialize(self.comm)
Expand All @@ -135,7 +134,10 @@ We use this builder to create an MPhys :class:`~mphys.StructuralScenario`.
self.mphys_add_scenario(
"tip_shear", ScenarioStructural(struct_builder=struct_builder)
)
self.mphys_connect_scenario_coordinate_source("mesh", "tip_shear", "struct")
self.connect(
f"mesh.{MPhysVariables.Structures.Mesh.COORDINATES}",
f"tip_shear.{MPhysVariables.Structures.COORDINATES}",
)
# Connect dv component to input of structural scenario
self.connect("dv_struct", "tip_shear.dv_struct")
Expand Down Expand Up @@ -196,7 +198,9 @@ Finally, we can plot the optimized thickness distribution using matplotlib and c
.. code-block:: python
# Get optimized solution variables
x = prob.get_val("mesh.x_struct0", get_remote=True)[:-3:3]
x = prob.get_val(f"mesh.{MPhysVariables.Structures.Mesh.COORDINATES}", get_remote=True)[
:-3:3
]
t_opt = prob["dv_struct"]
m_opt = prob["tip_shear.mass"]
Expand Down
10 changes: 6 additions & 4 deletions docs/source/examples/Example-Composite_Optimization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ To begin we first import required libraries, define the model bdf file, and defi
import openmdao.api as om
import numpy as np
from mphys import Multipoint
from mphys.scenario_structural import ScenarioStructural
from mphys.core import Multipoint
from mphys.scenarios import ScenarioStructural

from tacs import elements, constitutive, functions
from tacs.mphys import TacsBuilder
Expand Down Expand Up @@ -168,7 +168,6 @@ We use this builder to create an MPhys :class:`~mphys.StructuralScenario`.
element_callback=element_callback,
problem_setup=problem_setup,
constraint_setup=constraint_setup,
coupled=False,
check_partials=True,
)
struct_builder.initialize(self.comm)
Expand All @@ -181,7 +180,10 @@ We use this builder to create an MPhys :class:`~mphys.StructuralScenario`.
self.mphys_add_scenario(
"pressure_load", ScenarioStructural(struct_builder=struct_builder)
)
self.mphys_connect_scenario_coordinate_source("mesh", "pressure_load", "struct")
self.connect(
f"mesh.{MPhysVariables.Structures.Mesh.COORDINATES}",
f"pressure_load.{MPhysVariables.Structures.COORDINATES}",
)
self.connect("dv_struct", "pressure_load.dv_struct")
Expand Down
14 changes: 9 additions & 5 deletions examples/beam/beam_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import matplotlib.pyplot as plt
import numpy as np
import openmdao.api as om
from mphys import Multipoint
from mphys.scenario_structural import ScenarioStructural
from mphys.core import Multipoint, MPhysVariables
from mphys.scenarios import ScenarioStructural

from tacs import elements, constitutive, functions
from tacs.mphys import TacsBuilder
Expand Down Expand Up @@ -88,7 +88,6 @@ def setup(self):
mesh_file=bdf_file,
element_callback=element_callback,
problem_setup=problem_setup,
coupled=False,
write_solution=False,
)
struct_builder.initialize(self.comm)
Expand All @@ -103,7 +102,10 @@ def setup(self):
self.mphys_add_scenario(
"tip_shear", ScenarioStructural(struct_builder=struct_builder)
)
self.mphys_connect_scenario_coordinate_source("mesh", "tip_shear", "struct")
self.connect(
f"mesh.{MPhysVariables.Structures.Mesh.COORDINATES}",
f"tip_shear.{MPhysVariables.Structures.COORDINATES}",
)

# Connect dv component to input of structural scenario
self.connect("dv_struct", "tip_shear.dv_struct")
Expand Down Expand Up @@ -137,7 +139,9 @@ def setup(self):
prob.model.tip_shear.coupling.write_bdf(bdf_out)

# Get optimized solution variables
x = prob.get_val("mesh.x_struct0", get_remote=True)[:-3:3]
x = prob.get_val(f"mesh.{MPhysVariables.Structures.Mesh.COORDINATES}", get_remote=True)[
:-3:3
]
t_opt = prob["dv_struct"]
m_opt = prob["tip_shear.mass"]

Expand Down
10 changes: 6 additions & 4 deletions examples/plate/optimize_composite_plate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

import openmdao.api as om
import numpy as np
from mphys import Multipoint
from mphys.scenario_structural import ScenarioStructural
from mphys.core import Multipoint, MPhysVariables
from mphys.scenarios import ScenarioStructural

from tacs import elements, constitutive, functions
from tacs.mphys import TacsBuilder
Expand Down Expand Up @@ -124,7 +124,6 @@ def setup(self):
element_callback=element_callback,
problem_setup=problem_setup,
constraint_setup=constraint_setup,
coupled=False,
check_partials=True,
)
struct_builder.initialize(self.comm)
Expand All @@ -137,7 +136,10 @@ def setup(self):
self.mphys_add_scenario(
"pressure_load", ScenarioStructural(struct_builder=struct_builder)
)
self.mphys_connect_scenario_coordinate_source("mesh", "pressure_load", "struct")
self.connect(
f"mesh.{MPhysVariables.Structures.Mesh.COORDINATES}",
f"pressure_load.{MPhysVariables.Structures.COORDINATES}",
)

self.connect("dv_struct", "pressure_load.dv_struct")

Expand Down
10 changes: 5 additions & 5 deletions examples/stiffened_plate/optimize_stiffened_plate.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ class uses T stiffeners.
# ==============================================================================
import numpy as np
import openmdao.api as om
from mphys import Multipoint
from mphys.scenario_structural import ScenarioStructural
from mphys.core import Multipoint, MPhysVariables
from mphys.scenarios import ScenarioStructural
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

Expand Down Expand Up @@ -510,7 +510,6 @@ def setup(self):
element_callback=element_callback,
problem_setup=problem_setup,
constraint_setup=constraint_setup,
coupled=False,
check_partials=True,
)
struct_builder.initialize(self.comm)
Expand All @@ -533,8 +532,9 @@ def setup(self):
self.mphys_add_scenario(
scenarioName, ScenarioStructural(struct_builder=struct_builder)
)
self.mphys_connect_scenario_coordinate_source(
"mesh", scenarioName, "struct"
self.connect(
f"mesh.{MPhysVariables.Structures.Mesh.COORDINATES}",
f"{scenarioName}.{MPhysVariables.Structures.COORDINATES}",
)

self.connect("dv_struct", f"{scenarioName}.dv_struct")
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def get_mpi_flags():
optional_dependencies = {
"testing": ["testflo>=1.4.7"],
"docs": ["sphinx", "breathe", "sphinxcontrib-programoutput"],
"mphys": ["mphys>=1.1.0,<2.0.0", "openmdao>=3.25.0"],
"mphys": ["mphys>=2.0.0", "openmdao>=3.25.0"],
"caps2tacs": ["imageio>=2.16.1"],
}

Expand Down
18 changes: 8 additions & 10 deletions tacs/mphys/buckling.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import numpy as np
from mphys.core import MPhysVariables

StructVars = MPhysVariables.Structures

import openmdao.api as om

Expand All @@ -10,7 +13,6 @@ class TacsBuckling(om.ExplicitComponent):

def initialize(self):
self.options.declare("fea_assembler", recordable=False)
self.options.declare("conduction", default=False)
self.options.declare("check_partials")
self.options.declare("write_solution")

Expand All @@ -22,13 +24,9 @@ def setup(self):
self.fea_assembler = self.options["fea_assembler"]
self.check_partials = self.options["check_partials"]
self.write_solution = self.options["write_solution"]
self.conduction = self.options["conduction"]
self.solution_counter = 0

if self.conduction:
self.states_name = "T_conduct"
else:
self.states_name = "u_struct"
self.states_name = StructVars.DISPLACEMENTS

# TACS part of setup
local_ndvs = self.fea_assembler.getNumDesignVars()
Expand All @@ -42,7 +40,7 @@ def setup(self):
tags=["mphys_coupling"],
)
self.add_input(
"x_struct0",
StructVars.COORDINATES,
distributed=True,
shape_by_conn=True,
desc="structural node coordinates",
Expand All @@ -69,7 +67,7 @@ def mphys_set_bp(self, bp):

def _update_internal(self, inputs):
self.bp.setDesignVars(inputs["tacs_dvs"])
self.bp.setNodes(inputs["x_struct0"])
self.bp.setNodes(inputs[StructVars.COORDINATES])

def compute(self, inputs, outputs):
self._update_internal(inputs)
Expand Down Expand Up @@ -111,9 +109,9 @@ def compute_jacvec_product(self, inputs, d_inputs, d_outputs, mode):
[mode_i], [d_inputs["tacs_dvs"]], scale=d_func
)

if "x_struct0" in d_inputs:
if StructVars.COORDINATES in d_inputs:
self.bp.addXptSens(
[mode_i], [d_inputs["x_struct0"]], scale=d_func
[mode_i], [d_inputs[StructVars.COORDINATES]], scale=d_func
)

if self.states_name in d_inputs:
Expand Down
40 changes: 27 additions & 13 deletions tacs/mphys/builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import copy
import warnings

from mphys.builder import Builder
from mphys.core import Builder, MPhysVariables
import numpy as np

from tacs.pytacs import pyTACS
Expand All @@ -23,7 +20,7 @@ def __init__(
pytacs_options=None,
check_partials=False,
conduction=False,
coupled=True,
coupling_loads=None,
write_solution=True,
separate_mass_dvs=False,
res_ref=None,
Expand Down Expand Up @@ -102,9 +99,10 @@ def buckling_setup(scenario_name, fea_assembler)
conduction : bool, optional
Flag to determine weather TACS component represents a thermal (True) or structural (False) analysis.
Defaults to False.
coupled : bool, optional
Flag to determine of if multidisciplinary coupling variables should be turned on
(used in aerostructural/thermostructural analyses). Defaults to True.
coupling_loads : list[str] or str or None, optional
List of coupling loads to add to right handside of FEA state equation. These loads correspond to the nodal
forces on the model. Multiple load sources can be specified, these will be added together before being
applied to the model. This is used in aerostructural/thermostructural analyses. Defaults to None.
write_solution : bool, optional
Flag to determine whether to write out TACS solutions to f5 file each design iteration. Defaults to True.
separate_mass_dvs : bool, optional
Expand Down Expand Up @@ -204,7 +202,12 @@ def buckling_setup(scenario_name, fea_assembler)
self.pytacs_options = pytacs_options
self.check_partials = check_partials
self.conduction = conduction
self.coupled = coupled
if isinstance(coupling_loads, str):
self.coupling_loads = [coupling_loads]
elif hasattr(coupling_loads, "__iter__"):
self.coupling_loads = coupling_loads
else:
self.coupling_loads = []
self.write_solution = write_solution
self.separate_mass_dvs = separate_mass_dvs
self.res_ref = res_ref
Expand Down Expand Up @@ -232,6 +235,13 @@ def initialize(self, comm):
# Set up elements and TACS assembler
self.fea_assembler.initialize(self.element_callback)

if self.conduction:
self.discipline_vars = MPhysVariables.Thermal
self.discipline_vars.STATES = self.discipline_vars.TEMPERATURE
else:
self.discipline_vars = MPhysVariables.Structures
self.discipline_vars.STATES = self.discipline_vars.DISPLACEMENTS

def get_coupling_group_subsystem(self, scenario_name=None):
"""
The subsystem that this builder will add to the CouplingGroup
Expand All @@ -249,9 +259,9 @@ def get_coupling_group_subsystem(self, scenario_name=None):
"""
return TacsCouplingGroup(
fea_assembler=self.fea_assembler,
conduction=self.conduction,
discipline_vars=self.discipline_vars,
check_partials=self.check_partials,
coupled=self.coupled,
coupling_loads=self.coupling_loads,
scenario_name=scenario_name,
problem_setup=self.problem_setup,
res_ref=self.res_ref,
Expand All @@ -272,7 +282,10 @@ def get_mesh_coordinate_subsystem(self, scenario_name=None):
mesh : :class:`~openmdao.api.Component` or :class:`~openmdao.api.Group`
The openmdao subsystem that has an output of coordinates.
"""
return TacsMeshGroup(fea_assembler=self.fea_assembler)
return TacsMeshGroup(
fea_assembler=self.fea_assembler,
discipline_vars=self.discipline_vars,
)

def get_pre_coupling_subsystem(self, scenario_name=None):
"""
Expand All @@ -292,6 +305,7 @@ def get_pre_coupling_subsystem(self, scenario_name=None):
fea_assembler=self.fea_assembler,
initial_dv_vals=initial_dvs,
separate_mass_dvs=self.separate_mass_dvs,
discipline_vars=self.discipline_vars,
)

def get_post_coupling_subsystem(self, scenario_name=None):
Expand All @@ -310,7 +324,7 @@ def get_post_coupling_subsystem(self, scenario_name=None):
return TacsPostcouplingGroup(
fea_assembler=self.fea_assembler,
check_partials=self.check_partials,
conduction=self.conduction,
discipline_vars=self.discipline_vars,
write_solution=self.write_solution,
scenario_name=scenario_name,
problem_setup=self.problem_setup,
Expand Down
Loading

0 comments on commit e5e4d26

Please sign in to comment.