Source code for openaerostruct.geometry.geometry_mesh

""" Group that manipulates geometry mesh based on high-level design parameters. """

import numpy as np

import openmdao.api as om

from openaerostruct.geometry.geometry_mesh_transformations import (
    Taper,
    ScaleX,
    Sweep,
    ShearX,
    Stretch,
    ShearY,
    Dihedral,
    ShearZ,
    Rotate,
)


[docs] class GeometryMesh(om.Group): """ OpenMDAO group that performs mesh manipulation functions. It reads in the initial mesh from the surface dictionary and outputs the altered mesh based on the geometric design variables. Depending on the design variables selected or the supplied geometry information, only some of the follow parameters will actually be given to this component. If parameters are not active (they do not deform the mesh), then they will not be given to this component. Parameters ---------- sweep : float Shearing sweep angle in degrees. dihedral : float Dihedral angle in degrees. twist[ny] : numpy array 1-D array of rotation angles for each wing slice in degrees. chord_dist[ny] : numpy array Spanwise distribution of the chord scaler. taper : float Taper ratio for the wing; 1 is untapered, 0 goes to a point at the tip. Returns ------- mesh[nx, ny, 3] : numpy array Modified mesh based on the initial mesh in the surface dictionary and the geometric design variables. """ def initialize(self): self.options.declare("surface", types=dict) def setup(self): surface = self.options["surface"] if "ref_axis_pos" in surface: ref_axis_pos = surface["ref_axis_pos"] else: ref_axis_pos = 0.25 # if no reference axis line is specified : it is the quarter-chord mesh = surface["mesh"] ny = mesh.shape[1] mesh_shape = mesh.shape symmetry = surface["symmetry"] # This flag determines whether or not changes in z (dihedral) add an # additional rotation matrix to modify the twist direction self.rotate_x = True # 1. Taper if "taper" in surface: val = surface["taper"] promotes = ["taper"] else: val = 1.0 promotes = [] self.add_subsystem( "taper", Taper(val=val, mesh=mesh, symmetry=symmetry, ref_axis_pos=ref_axis_pos), promotes_inputs=promotes ) # 2. Scale X val = np.ones(ny) if "chord_cp" in surface: promotes = ["chord"] else: promotes = [] self.add_subsystem( "scale_x", ScaleX(val=val, mesh_shape=mesh_shape, ref_axis_pos=ref_axis_pos), promotes_inputs=promotes, ) # 3. Sweep if "sweep" in surface: val = surface["sweep"] promotes = ["sweep"] else: val = 0.0 promotes = [] self.add_subsystem("sweep", Sweep(val=val, mesh_shape=mesh_shape, symmetry=symmetry), promotes_inputs=promotes) # 4. Shear X val = np.zeros(ny) if "xshear_cp" in surface: promotes = ["xshear"] else: promotes = [] self.add_subsystem("shear_x", ShearX(val=val, mesh_shape=mesh_shape), promotes_inputs=promotes) # 5. Stretch if "span" in surface: promotes = ["span"] val = surface["span"] else: # Compute span. We need .real to make span to avoid OpenMDAO warnings. ref_axis = ref_axis_pos * mesh[-1, :, :] + (1 - ref_axis_pos) * mesh[0, :, :] span = max(ref_axis[:, 1]).real - min(ref_axis[:, 1]).real if symmetry: span *= 2.0 val = span promotes = [] self.add_subsystem( "stretch", Stretch(val=val, mesh_shape=mesh_shape, symmetry=symmetry, ref_axis_pos=ref_axis_pos), promotes_inputs=promotes, ) # 6. Shear Y val = np.zeros(ny) if "yshear_cp" in surface: promotes = ["yshear"] else: promotes = [] self.add_subsystem("shear_y", ShearY(val=val, mesh_shape=mesh_shape), promotes_inputs=promotes) # 7. Dihedral if "dihedral" in surface: val = surface["dihedral"] promotes = ["dihedral"] else: val = 0.0 promotes = [] self.add_subsystem( "dihedral", Dihedral(val=val, mesh_shape=mesh_shape, symmetry=symmetry), promotes_inputs=promotes ) # 8. Shear Z val = np.zeros(ny) if "zshear_cp" in surface: promotes = ["zshear"] else: promotes = [] self.add_subsystem("shear_z", ShearZ(val=val, mesh_shape=mesh_shape), promotes_inputs=promotes) # 9. Rotate val = np.zeros(ny) if "twist_cp" in surface: promotes = ["twist"] else: val = np.zeros(ny) promotes = [] self.add_subsystem( "rotate", Rotate(val=val, mesh_shape=mesh_shape, symmetry=symmetry, ref_axis_pos=ref_axis_pos), promotes_inputs=promotes, promotes_outputs=["mesh"], ) names = ["taper", "scale_x", "sweep", "shear_x", "stretch", "shear_y", "dihedral", "shear_z", "rotate"] for j in np.arange(len(names) - 1): self.connect(names[j] + ".mesh", names[j + 1] + ".in_mesh")