diff --git a/pterasoftware/geometry.py b/pterasoftware/geometry.py index e475064f..f9f305fb 100644 --- a/pterasoftware/geometry.py +++ b/pterasoftware/geometry.py @@ -65,24 +65,27 @@ def __init__( :param name: str, optional A sensible name for your airplane. The default is "Untitled Airplane". :param x_ref: float, optional - This is the x coordinate of the moment reference point. It should be the - x coordinate of the center of gravity. The default is 0.0. + This is the x coordinate of the moment reference point in the body + frame. It should be the x coordinate of the center of gravity. The + default is 0.0. :param y_ref: float, optional - This is the y coordinate of the moment reference point. It should be the - y coordinate of the center of gravity. The default is 0.0. + This is the y coordinate of the moment reference point in the body + frame. It should be the y coordinate of the center of gravity. The + default is 0.0. :param z_ref: float, optional - This is the z coordinate of the moment reference point. It should be the - z coordinate of the center of gravity. The default is 0.0. + This is the z coordinate of the moment reference point in the body + frame. It should be the z coordinate of the center of gravity. The + default is 0.0. :param weight: float, optional This parameter holds the weight of the aircraft in Newtons. This is used by the trim functions. The default value is 0.0. - :param s_ref: float, optional if more than one wing is in the wings list. + :param s_ref: float, optional This is the reference wetted area. If not set, it populates from first wing object. - :param c_ref: float, optional if more than one wing is in the wings list. + :param c_ref: float, optional This is the reference chord length. If not set, it populates from first wing object. - :param b_ref: float, optional if more than one wing is in the wings list. + :param b_ref: float This is the reference calculate_span. If not set, it populates from first wing object. """ @@ -92,14 +95,16 @@ def __init__( else: raise Exception("An airplane's list of wings must have at least one entry.") - # Initialize the name, moment reference point coordinates, and weight. + # Initialize the name, moment reference point coordinates (in the body frame), + # and weight. self.name = name self.x_ref = x_ref self.y_ref = y_ref self.z_ref = z_ref self.weight = weight - # Create a (3,) array to hold the moment reference point coordinates. + # Create a (3,) array to hold the moment reference point coordinates in the + # body frame. self.xyz_ref = np.array([self.x_ref, self.y_ref, self.z_ref]) # Set the wing reference dimensions to be the main wing's reference dimensions. @@ -205,34 +210,33 @@ def __init__( :param name: str, optional This is a sensible name for the wing. The default is "Untitled Wing". :param x_le: float, optional - This is the x coordinate of the leading edge of the wing, relative to the - airplane's reference point. The default is 0.0. + This is the x coordinate of the leading edge of the wing in the body + frame. The default is 0.0. :param y_le: float, optional - This is the y coordinate of the leading edge of the wing, relative to the - airplane's reference point. The default is 0.0. + This is the y coordinate of the leading edge of the wing in the body + frame. The default is 0.0. :param z_le: float, optional - This is the z coordinate of the leading edge of the wing, relative to the - airplane's reference point. The default is 0.0. - :param unit_normal_vector: array, optional - This is an (3,) array of floats that represents the unit normal vector - of the wing's symmetry plane. It is also the direction vector that the - wing's span will be assessed relative to. Additionally, this vector - crossed with the "unit_chordwise_vector" defines the normal vector of the - plane that the wing's projected area will reference. It must be - equivalent to this wing's root wing cross section's "unit_normal_vector" - attribute. The default is np.array([0.0, 1.0, 0.0]), which is the XZ - plane's unit normal vector. + This is the z coordinate of the leading edge of the wing in the body + frame. The default is 0.0. + :param unit_normal_vector: (3,) array of floats, optional + This is an (3,) array of floats that represents the unit normal vector of + the wing's symmetry plane in the body frame. It is also the direction + vector that the wing's span will be assessed relative to. Additionally, + this vector crossed with the "unit_chordwise_vector" defines the normal + vector of the plane that the wing's projected area will reference. It + must be equivalent to this wing's root wing cross section's + "unit_normal_vector" attribute. The default is np.array([0.0, 1.0, 0.0]), + which is the XZ body frame's unit normal vector. :param symmetric: bool, optional - Set this to true if the wing is across the xz plane. Set it to false if - not. The default is false. - :param unit_chordwise_vector: array, optional + Set this to true if the wing is symmetric across the plane defined by its + unit normal vector. Set it to false if not. The default is false. + :param unit_chordwise_vector: (3,) array of floats, optional This is an (3,) array of floats that represents the unit vector that - defines the wing's chordwise direction. This vector crossed with the - "unit_normal_vector" defines the normal vector of the plane that - the wing's projected area will reference. This vector must be parallel to - the intersection of the wing's symmetry plane with each of its wing cross - section's planes. The default is np.array([1.0, 0.0, 0.0]), which is the - X unit vector. + defines the wing's chordwise direction in the body frame. This vector + crossed with the "unit_normal_vector" defines the normal vector of the + plane that the wing's projected area will reference. This vector must be + parallel to the intersection of the wing's symmetry plane with each of + its wing cross section's planes. The default is np.array([1.0, 0.0, 0.0]). :param num_chordwise_panels: int, optional This is the number of chordwise panels to be used on this wing. The default is 8. @@ -252,7 +256,8 @@ def __init__( "two entries." ) - # Initialize the name and the position of the wing's leading edge. + # Initialize the name and the position of the wing's leading edge in the body + # frame. self.name = name self.x_le = x_le self.y_le = y_le @@ -269,11 +274,14 @@ def __init__( else: raise Exception('The chordwise spacing must be "cosine" or "uniform".') - # Create a (3,) array to hold the leading edge's coordinates. + # Create a (3,) array to hold the wing's leading edge's coordinates in the + # body frame. self.leading_edge = np.array([self.x_le, self.y_le, self.z_le]) - # Check that the wing's symmetry plane is equal to its root wing cross - # section's plane. + # ToDo: Modify this check once the wing cross section vectors reference the + # wing's frame. + # Check that the wing's symmetry plane in the body frame is equal to its root + # wing cross section's plane. if not np.array_equal( self.unit_normal_vector, self.wing_cross_sections[0].unit_normal_vector, @@ -283,6 +291,8 @@ def __init__( "section's plane." ) + # ToDo: Modify this check once the wing cross section coordinates reference the + # wing's frame. # Check that the root wing cross section's leading edge isn't offset from the # wing's leading edge. if np.any( @@ -299,7 +309,8 @@ def __init__( "the wing's leading edge." ) - # Check that the wing's chordwise and normal directions are perpendicular. + # Check that the wing's body-frame chordwise and normal directions are + # perpendicular. if np.dot(self.unit_chordwise_vector, self.unit_normal_vector) != 0: raise Exception( "Every wing cross section's plane must intersect with the wing's " @@ -317,6 +328,8 @@ def __init__( if self.symmetric: self.num_spanwise_panels *= 2 + # ToDo: Modify this check once the wing cross section vectors reference the + # wing's frame. # Check that all the wing cross sections have valid unit normal vectors. for wing_cross_section in self.wing_cross_sections: @@ -338,6 +351,8 @@ def __init__( # Calculate the number of panels on this wing. self.num_panels = self.num_spanwise_panels * self.num_chordwise_panels + # ToDo: Determine if this is still necessary once the wing cross section + # vectors reference the wing's frame. for wing_cross_section in self.wing_cross_sections: wing_cross_section.wing_unit_chordwise_vector = self.unit_chordwise_vector @@ -353,19 +368,19 @@ def __init__( @property def unit_up_vector(self): - """This method sets a property for the wing's up orientation - vector, which is defined as the cross product of its unit chordwise and unit - normal vectors. + """This method sets a property for the wing's up orientation vector in the + body frame, which is defined as the cross product of its unit chordwise and + unit normal vectors. :return: (3,) array of floats - This is the wing's unit up vector. The units are meters. + This is the wing's unit up vector in the body frame. The units are meters. """ return np.cross(self.unit_chordwise_vector, self.unit_normal_vector) @property def projected_area(self): """This method defines a property for the area of the wing projected onto the - plane defined by the projected unit normal vector. + plane defined by its unit up vector. If the wing is symmetric, the area of the mirrored half is included. @@ -504,6 +519,7 @@ def mean_aerodynamic_chord(self): return integral / self.projected_area +# ToDo: Modify this object to make its parameters in the wing object's frame. class WingCrossSection: """This class is used to contain the cross sections of a Wing object. diff --git a/pterasoftware/meshing.py b/pterasoftware/meshing.py index fb35e473..d37c8d85 100644 --- a/pterasoftware/meshing.py +++ b/pterasoftware/meshing.py @@ -30,6 +30,8 @@ from . import panel +# ToDo: Make sure the panel locations are calculated correctly now that the wing +# cross section objects are defined in their parent wing frame. def mesh_wing(wing): """This function takes in an object of the Wing class and creates a quadrilateral mesh of its geometry, and then populates the object's panels with the mesh data. @@ -287,6 +289,8 @@ def mesh_wing(wing): wing.panels = wing_panels +# ToDo: Make sure the panel locations are calculated correctly now that the wing +# cross section objects are defined in their parent wing frame. def get_wing_section_panel_vertices( wing_leading_edge, inner_wing_cross_section, @@ -401,6 +405,8 @@ def get_wing_section_panel_vertices( ] +# ToDo: Make sure the panel locations are calculated correctly now that the wing +# cross section objects are defined in their parent wing frame. def get_transpose_mcl_vectors(inner_airfoil, outer_airfoil, chordwise_coordinates): """This function takes in the inner and outer airfoils of a wing cross section and its chordwise coordinates. It returns a list of four column vectors. They @@ -450,6 +456,8 @@ def get_transpose_mcl_vectors(inner_airfoil, outer_airfoil, chordwise_coordinate ] +# ToDo: Make sure the panel locations are calculated correctly now that the wing +# cross section objects are defined in their parent wing frame. def get_wing_section_panels( front_left_vertices, front_right_vertices,