Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added dict key validation & updated documentation #417

Merged
merged 10 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ python:
path: .
extra_requirements:
- docs
system_packages: true
50 changes: 49 additions & 1 deletion openaerostruct/docs/user_reference/mesh_surface_dict.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,42 @@ The surface dict will be provided to Groups, including ``Geometry``, ``AeroPoint
- 3D ndarray
- m
- ``x, y, z`` coordinates of the mesh vertices, can be created by ``generate_mesh``.
* - span
- 10.0
- m
- Wing span.
* - taper
- 0.5
-
- Wing taper ratio.
* - sweep
- 10.0
- deg
- Wing sweep angle.
* - dihedral
- 5.0
- deg
- Wing dihedral.
* - twist_cp
- np.array([0, 5])
- deg
- B-spline control points for twist distribution. Array convention is ``[wing tip, ..., root]`` in symmetry cases, and ``[tip, ..., root, ... tip]`` when ``symmetry = False``.
* - chord_cp
- np.array([0.1, 5])
-
- B-spline control points for chord distribution. This is a chord scaler applied to the initial mesh, not the chord value [m] itself. Array convention is the same as ``twist_cp``.
* - xshear_cp
- np.array([0.1, 0.2])
- m
- B-spline control points for the x-wise shear deformation of the wing.
* - yshear_cp
- np.array([0.1, 0.2])
- m
- B-spline control points for the y-wise shear deformation of the wing.
* - zshear_cp
- np.array([0.1, 0.2])
- m
- B-spline control points for chord distribution. Array convention is the same than ``twist_cp``.
- B-spline control points for the z-wise shear deformation of the wing.
* - ref_axis_pos
- 0.25
-
Expand Down Expand Up @@ -240,6 +268,10 @@ The surface dict will be provided to Groups, including ``Geometry``, ``AeroPoint
- 0.12
-
- Thickness-over-chord ratio of airfoil provided for the wingbox cross-section.
* - strength_factor _for_upper_skin
- 1.0
-
- A factor to adjust the yield strength of the upper skin relative to the lower skin.
* - data_x_upper
- 1D ndarray
-
Expand All @@ -257,5 +289,21 @@ The surface dict will be provided to Groups, including ``Geometry``, ``AeroPoint
-
- ``y`` coordinates of the wingbox cross-section's lower surface

.. list-table:: FFD parameters
:widths: 20 20 5 55
:header-rows: 1

* - Key
- Example value
- Units
- Description
* - mx
- 2
-
- Number of the FFD control points in the x direction.
* - my
- 2
-
- Number of the FFD control points in the y direction.
..
TODO: list default values (if any), and whethre each key is required or optional.
2 changes: 1 addition & 1 deletion openaerostruct/examples/drag_polar_ground_effect.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def compute_drag_polar_ground_effect(Mach, alphas, heights, surfaces, trimmed=Fa
"wing_type": "rect",
"symmetry": True,
"span": 12.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 1.0,
"chord_cos_spacing": 0.0,
}
Expand Down
2 changes: 1 addition & 1 deletion openaerostruct/examples/rectangular_wing/drag_polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"wing_type": "rect",
"symmetry": True,
"span": 10.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 1.0,
"chord_cos_spacing": 1.0,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def setup(self):
"wing_type": "rect",
"symmetry": True,
"span": 10.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 1.0,
"chord_cos_spacing": 1.0,
}
Expand Down
5 changes: 3 additions & 2 deletions openaerostruct/examples/rectangular_wing/opt_chord.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"wing_type": "rect",
"symmetry": True,
"span": 10.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 1.0,
"chord_cos_spacing": 1.0,
}
Expand Down Expand Up @@ -105,8 +105,9 @@
prob.driver.options["debug_print"] = ["nl_cons", "objs", "desvars"]

# Setup problem and add design variables, constraint, and objective
# wing.chord_cp is the chord scaling applied to the initial mesh
prob.model.add_design_var("alpha", lower=-10.0, upper=15.0)
prob.model.add_design_var("wing.chord_cp", lower=1e-3, upper=5.0)
prob.model.add_design_var("wing.chord_cp", lower=1e-3, upper=5.0, units=None)
prob.model.add_constraint(point_name + ".wing_perf.CL", equals=0.5)
prob.model.add_constraint(point_name + ".wing.S_ref", equals=10.0)
prob.model.add_objective(point_name + ".wing_perf.CD", scaler=1e4)
Expand Down
2 changes: 1 addition & 1 deletion openaerostruct/examples/rectangular_wing/opt_twist.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"wing_type": "rect",
"symmetry": True,
"span": 10.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 1.0,
"chord_cos_spacing": 1.0,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"wing_type": "rect",
"symmetry": True,
"span": 10.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 1.0,
"chord_cos_spacing": 1.0,
}
Expand Down
2 changes: 1 addition & 1 deletion openaerostruct/examples/rectangular_wing/run_roll.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"wing_type": "rect",
"symmetry": False,
"span": 9.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 1.0,
"chord_cos_spacing": 1.0,
}
Expand Down
8 changes: 6 additions & 2 deletions openaerostruct/geometry/geometry_group.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import numpy as np

import openmdao.api as om
from openaerostruct.utils.check_surface_dict import check_surface_dict_keys


class Geometry(om.Group):
Expand All @@ -23,6 +24,9 @@ def initialize(self):
def setup(self):
surface = self.options["surface"]

# key validation of the surface dict
check_surface_dict_keys(surface)

# Get the surface name and create a group to contain components
# only for this surface
ny = surface["mesh"].shape[1]
Expand Down Expand Up @@ -91,10 +95,10 @@ def setup(self):
promotes_inputs=["chord_cp"],
promotes_outputs=["chord"],
)
comp.add_spline(y_cp_name="chord_cp", y_interp_name="chord", y_units="m")
comp.add_spline(y_cp_name="chord_cp", y_interp_name="chord", y_units=None)
bsp_inputs.append("chord")
if surface.get("chord_cp_dv", True):
self.set_input_defaults("chord_cp", val=surface["chord_cp"], units="m")
self.set_input_defaults("chord_cp", val=surface["chord_cp"], units=None)

if "t_over_c_cp" in surface.keys():
n_cp = len(surface["t_over_c_cp"])
Expand Down
2 changes: 1 addition & 1 deletion openaerostruct/geometry/geometry_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class GeometryMesh(om.Group):
twist[ny] : numpy array
1-D array of rotation angles for each wing slice in degrees.
chord_dist[ny] : numpy array
Chord length for each panel edge.
Spanwise distribution of the chord scaler.
taper : float
Taper ratio for the wing; 1 is untapered, 0 goes to a point at the tip.

Expand Down
4 changes: 2 additions & 2 deletions openaerostruct/geometry/geometry_mesh_transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class ScaleX(om.ExplicitComponent):
mesh[nx, ny, 3] : numpy array
Nodal mesh defining the initial aerodynamic surface.
chord[ny] : numpy array
Chord length for each panel edge.
Spanwise distribution of the chord scaler.

Returns
-------
Expand All @@ -147,7 +147,7 @@ def setup(self):
mesh_shape = self.options["mesh_shape"]
val = self.options["val"]
self.ref_axis_pos = self.options["ref_axis_pos"]
self.add_input("chord", units="m", val=val)
self.add_input("chord", units=None, val=val)
self.add_input("in_mesh", shape=mesh_shape, units="m")

self.add_output("mesh", shape=mesh_shape, units="m")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,40 @@ def test_scalex_ref_axis_trailing_edge(self):
# If chord_scaling_pos = 1, TE should not move
assert_near_equal(mesh[-1, :, :], prob["comp.mesh"][-1, :, :], tolerance=1e-10)

def test_scalex_chord_value(self):
# test actual chord value of a rectangular wing

mesh_dict = {
"num_y": 5,
"num_x": 3,
"wing_type": "rect",
"symmetry": True,
"span": 2.0,
"root_chord": 0.2,
}
mesh_in = generate_mesh(mesh_dict)

# initial chord
chord_in = mesh_in[-1, 0, 0] - mesh_in[0, 0, 0] # TE - LE

prob = om.Problem()
group = prob.model
comp = ScaleX(val=np.ones(3), mesh_shape=mesh_in.shape)
group.add_subsystem("comp", comp)

prob.setup()
chord_scaling = 1.3
prob.set_val("comp.chord", val=chord_scaling, units=None) # apply chord scaling factor
prob.set_val("comp.in_mesh", val=mesh_in, units="m")

prob.run_model()

# chord after manipulation
mesh_out = prob.get_val("comp.mesh", units="m")
chord_out = mesh_out[-1, 0, 0] - mesh_out[0, 0, 0] # TE - LE

assert_near_equal(chord_in * chord_scaling, chord_out, tolerance=1e-10)

def test_sweep(self):
symmetry = False
mesh = get_mesh(symmetry)
Expand Down
4 changes: 2 additions & 2 deletions openaerostruct/geometry/tests/test_vsp_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def test_full(self):
"wing_type": "rect",
"symmetry": False,
"span": 10.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 0.0,
}

Expand All @@ -44,7 +44,7 @@ def test_symm(self):
"wing_type": "rect",
"symmetry": True,
"span": 10.0,
"chord": 1,
"root_chord": 1,
"span_cos_spacing": 0.0,
}

Expand Down
36 changes: 33 additions & 3 deletions openaerostruct/geometry/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import numpy as np
from numpy import cos, sin, tan
import warnings

# openvsp python interface
try:
Expand Down Expand Up @@ -94,7 +95,7 @@
mesh[nx, ny, 3] : numpy array
Nodal mesh defining the initial aerodynamic surface.
chord_dist[ny] : numpy array
Chord length for each panel edge.
Spanwise distribution of the chord scaler.

Returns
-------
Expand Down Expand Up @@ -636,12 +637,39 @@
def generate_mesh(input_dict):
# Get defaults and update surface with the user-provided input
surf_dict = get_default_geo_dict()

# Warn if a user provided a key that is not implemented
user_defined_keys = input_dict.keys()
for key in user_defined_keys:
if key not in surf_dict:
warnings.warn(
"Key `{}` in mesh_dict is not implemented and will be ignored".format(key),
category=RuntimeWarning,
stacklevel=2,
)
# Warn if a user did not define important keys
for key in ["num_x", "num_y", "wing_type", "symmetry"]:
if key not in user_defined_keys:
warnings.warn(
"Missing `{}` in mesh_dict. The default value of {} will be used.".format(key, surf_dict[key]),
category=RuntimeWarning,
stacklevel=2,
)

# Apply user-defined options
surf_dict.update(input_dict)

# Warn if a user defined span and root_chord for CRM
if surf_dict["wing_type"] == "CRM":
if "span" in user_defined_keys or "root_chord" in user_defined_keys:
warnings.warn(

Check warning on line 665 in openaerostruct/geometry/utils.py

View check run for this annotation

Codecov / codecov/patch

openaerostruct/geometry/utils.py#L665

Added line #L665 was not covered by tests
"`span` and `root_chord` in mesh_dict will be ignored for the CRM wing.",
category=RuntimeWarning,
stacklevel=2,
)

num_x = surf_dict["num_x"]
num_y = surf_dict["num_y"]
span = surf_dict["span"]
chord = surf_dict["root_chord"]
span_cos_spacing = surf_dict["span_cos_spacing"]
chord_cos_spacing = surf_dict["chord_cos_spacing"]

Expand All @@ -655,6 +683,8 @@

# Generate rectangular mesh
if surf_dict["wing_type"] == "rect":
span = surf_dict["span"]
chord = surf_dict["root_chord"]
mesh = gen_rect_mesh(num_x, num_y, span, chord, span_cos_spacing, chord_cos_spacing)

# Generate CRM mesh. Note that this outputs twist information
Expand Down
4 changes: 4 additions & 0 deletions openaerostruct/integration/aerostruct_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from openaerostruct.aerodynamics.compressible_states import CompressibleVLMStates
from openaerostruct.structures.tube_group import TubeGroup
from openaerostruct.structures.wingbox_group import WingboxGroup
from openaerostruct.utils.check_surface_dict import check_surface_dict_keys

import openmdao.api as om

Expand All @@ -26,6 +27,9 @@ def setup(self):
DVGeo = self.options["DVGeo"]
connect_geom_DVs = self.options["connect_geom_DVs"]

# key validation of the surface dict
check_surface_dict_keys(surface)

geom_promotes_in = []
geom_promotes_out = ["mesh"]

Expand Down
2 changes: 0 additions & 2 deletions openaerostruct/tests/test_aero_atmos.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ def test(self):
"fem_model_type": "tube",
"twist_cp": twist_cp,
"mesh": mesh,
"num_x": mesh.shape[0],
"num_y": mesh.shape[1],
# Aerodynamic performance of the lifting surface at
# an angle of attack of 0 (alpha=0).
# These CL0 and CD0 values are added to the CL and CD
Expand Down
1 change: 0 additions & 1 deletion openaerostruct/tests/test_simple_rect_aero.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ def test(self):
surf_dict = {
# Wing definition
"name": "wing", # name of the surface
"type": "aero",
"symmetry": True, # if true, model one half of wing
# reflected across the plane y = 0
"S_ref_type": "wetted", # how we compute the wing area,
Expand Down
1 change: 0 additions & 1 deletion openaerostruct/tests/test_simple_rect_aero_roll.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ def test(self):
surf_dict = {
# Wing definition
"name": "wing", # name of the surface
"type": "aero",
"symmetry": False, # if true, model one half of wing
# reflected across the plane y = 0
"S_ref_type": "wetted", # how we compute the wing area,
Expand Down
1 change: 0 additions & 1 deletion openaerostruct/tests/test_simple_rect_aero_sideslip.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ def test(self):
surf_dict = {
# Wing definition
"name": "wing", # name of the surface
"type": "aero",
"symmetry": False, # if true, model one half of wing
# reflected across the plane y = 0
"S_ref_type": "wetted", # how we compute the wing area,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ def test(self):
surf_dict = {
# Wing definition
"name": "wing", # name of the surface
"type": "aero",
"symmetry": False, # if true, model one half of wing
# reflected across the plane y = 0
"S_ref_type": "wetted", # how we compute the wing area,
Expand Down
Loading
Loading