pytornado.objects package¶
Submodules¶
pytornado.objects.aircraft module¶
Aircraft data model. The aircraft hierarchy is defined as follows:
| AIRCRAFT
| |
| WING
| |
| / \
| / \
| / \
| SEGMENT CONTROL
| |
| STRIP
| |
| SUBDIVISION
Developed for Airinnova AB, Stockholm, Sweden.
-
class
pytornado.objects.aircraft.Aircraft¶ Bases:
object-
REF_SCHEMA= schemadict({'$required_keys': ['gcenter', 'rcenter', 'area', 'chord', 'span'], 'gcenter': {'type': <class 'list'>, 'min_len': 3, 'max_len': 3, 'item_types': (<class 'int'>, <class 'float'>)}, 'rcenter': {'type': <class 'list'>, 'min_len': 3, 'max_len': 3, 'item_types': (<class 'int'>, <class 'float'>)}, 'area': {'type': <class 'float'>, '>': 0}, 'chord': {'type': <class 'float'>, '>': 0}, 'span': {'type': <class 'float'>, '>': 0}, 'comment': {'type': <class 'str'>}})¶
-
add_wing(wing_uid)¶ Add a new wing object
- Args:
wing_uid: (string) Unique identifier for the wing - Returns:
wing: (obj) Created wing object
-
area¶ Aircraft area as sum of wing areas
-
generate()¶ Generate the aircraft model
-
has_deformed_wings¶ True if any wing are deformed
-
size¶ Approximate characteristic size of aircraft (diagonal of a bounding box)
-
state¶
-
uid¶
-
-
exception
pytornado.objects.aircraft.ComponentDefinitionError¶ Bases:
ExceptionRaised if when a component is ill-defined
-
class
pytornado.objects.aircraft.SegmentStrip(segment, rel_vertices)¶ Bases:
objectSegmentStrip is a “child class” of WingSegment.
This object further divides each WingSegment into chordwise strips. This simplifies the meshing of the wing surface when there are leading and trailing edge devices. Subdivisions can also be geometrically transformed (translation and rotation). This makes it possible to perform a analyses on a deformed surface mesh, which is of particular interest for aeroelastic analyses.
SegmentStrip are quadrilateral segments.
- Attributes:
segment: (obj) reference to the parent segment object rel_vertices: (dict) relative coordinates of the subdivision defined by eta coordinates subarea: (dict) dictionary containing subareas of a subdivision
-
abs_vertices(mirror)¶ Get absolute coordinates of the subdivision
Absolute coordinates are only computed upon request based on the parent geometry (segment) and transformation directives if defined.
Wing deformations are taken into account.
- Args:
mirror: (bool) flag to whether to return the mirrored or non-mirrored side - Returns:
abs_vertices: (dict) absolute subdivision vertices
-
symmetry¶ Symmetry inherited from parent wing
-
class
pytornado.objects.aircraft.StripSubdivision(subdivision, rel_vertices, subarea_type)¶ Bases:
objectStripSubdivision is a “child class” of SegmentStrip.
This object provides the basic geometric definition of subareas within a segment subdivision. Subareas are defined by their xsi coordinates within the subdivision. Absolute coordinates can be computed by calling the parent objects.
- Attributes:
_subdivision: (obj) reference to the parent subdivision object rel_vertices: (dict) relative coordinates of the subarea defined by xsi coordinates rel_hinge: (dict) relative coordinates of the hinge line (only for subarea of type {‘flap’, ‘slat’}) parent_control: (obj) reference to the parent control object (only for subarea of type {‘flap’, ‘slat’})
-
abs_camber_line_rot_axis(mirror)¶ Get the axis vector for camber line rotations in the global coordinate system.
Wing deformations are taken into account.
- Args:
mirror: (bool) optional flag, if true mirror axis is returned - Returns:
abs_axis: absolute axis in global system
-
abs_camber_line_rot_axis_vertices(mirror)¶ Get the rotation axis for the camber line.
- Note:
- The rotation axis is defined by two points.
- Args:
mirror: (bool) optional flag, if true mirror axis is returned - Returns:
abs_vertices: absolute axis vertices in global system
-
abs_hinge_axis(mirror)¶ Get the hinge axis vector in the global coordinate system.
Wing deformations are taken into account.
- Args:
mirror: (bool) optional flag, if true mirror axis is returned - Returns:
abs_hinge_axis: absolute hinge axis in global system
-
abs_hinge_vertices(mirror)¶ Get absolute coordinates of subarea hinge points.
Wing deformations are taken into account.
- Args:
mirror: (bool) optional flag, if true mirror is returned - Returns:
abs_hinge_vertices: (dict) dictionary with absolute hinge coordinates of subarea vertices
-
abs_vertices(mirror)¶ Get absolute coordinates of subarea vertices
Wing deformations are taken into account.
- Args:
mirror: (bool) optional flag, if true mirror is returned - Returns:
abs_vertices: (dict) dictionary with absolute coordinates of subarea vertices
-
get_xsi_for_collocation_points(num_panels)¶ Return the relative xsi coordinates of a panel collocation points
- Note:
- This functions assumes that all panels are linearly spaced!
- Work for mirrored/non-mirrored subareas
- Args:
num_panels: number of panels on a segment subdivision - Returns:
segment_xsi: list with xsi values of the collocation points
-
rel_length¶ Return the average ‘xsi length’ of the subarea
- Returns:
xsi_avg: (float) average xsi length
-
segment_vertices¶ Get segments coordinates of the parent segment.
- Returns:
vertices: (dict) dictionary segment vertices
-
symmetry¶ Get symmetry property of subarea (inherited from parent wing).
- Returns:
symmetry: (int) symmetry property
-
class
pytornado.objects.aircraft.Wing(wing_uid)¶ Bases:
object-
add_control(control_uid)¶ Add a new control surface
- Args:
control_uid: (string) Control identifier - Returns:
control: (obj) New segment object
-
add_segment(segment_uid)¶ Add a new segment
- Args:
segment_uid: (string) Segment identifier - Returns:
segment: (obj) New segment object
-
area¶ Return the wing area
-
check_deformation_continuity()¶ Check the continuity of the wing deformation
The deformation at the border of two neighbouring segments must be the same. Otherwise, there will be “gaps” in the wing which we will refuse to model.
-
generate()¶ Generate a wing and components
-
is_deformed¶
-
span¶ Return the wing span
-
state¶
-
symmetry¶
-
uid¶
-
-
class
pytornado.objects.aircraft.WingControl(parent_wing, control_uid)¶ Bases:
object-
DEVICE_TYPES= ('slat', 'flap')¶
-
PANELS_SCHEMA= schemadict({'num_c': {'type': <class 'int'>, '>': 0}})¶
-
REL_HINGE_VERTICES_SCHEMA= schemadict({'$required_keys': ['xsi_inner', 'xsi_outer'], 'xsi_inner': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}, 'xsi_outer': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}})¶
-
REL_VERTICES_SCHEMA= schemadict({'$required_keys': ['eta_inner', 'eta_outer', 'xsi_inner', 'xsi_outer'], 'eta_inner': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}, 'eta_outer': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}, 'xsi_inner': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}, 'xsi_outer': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}})¶
-
SEGMENT_UID_SCHEMA= schemadict({'$required_keys': ['inner', 'outer'], 'inner': {'type': <class 'str'>}, 'outer': {'type': <class 'str'>}})¶
-
abs_hinge_vertices¶ Get absolute hinge coordinates of the control
-
abs_vertices¶ Get absolute coordinates of the control
-
check()¶ Check definition of WINGCONTROL properties and data
-
device_type¶
-
symmetry¶ Symmetry inherited from parent wing
-
uid¶
-
-
class
pytornado.objects.aircraft.WingSegment(wing, uid)¶ Bases:
object-
AIRFOIL_SCHEMA= schemadict({'$required_keys': ['inner', 'outer'], 'inner': {'type': <class 'str'>}, 'outer': {'type': <class 'str'>}})¶
-
GEOMETRY_SCHEMA= schemadict({'$required_keys': ['inner_axis', 'outer_axis'], 'inner_chord': {'type': <class 'float'>}, 'outer_chord': {'type': <class 'float'>}, 'inner_alpha': {'type': <class 'float'>, '>=': -90, '<=': 90}, 'outer_alpha': {'type': <class 'float'>, '>=': -90, '<=': 90}, 'inner_beta': {'type': <class 'float'>, '>=': -90, '<=': 90}, 'outer_beta': {'type': <class 'float'>, '>=': -90, '<=': 90}, 'inner_axis': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}, 'outer_axis': {'type': <class 'float'>, '>=': 0.0, '<=': 1.0}, 'span': {'type': <class 'float'>}, 'sweep': {'type': <class 'float'>, '>=': -90, '<=': 90}, 'dihedral': {'type': <class 'float'>, '>=': -180, '<=': 180}})¶
-
PANELS_SCHEMA= schemadict({'num_c': {'type': <class 'int'>, '>': 0}, 'num_s': {'type': <class 'int'>, '>': 0}})¶
-
VERTICES_SCHEMA= schemadict({'a': {'type': <class 'list'>, 'min_len': 3, 'max_len': 3, 'item_types': (<class 'int'>, <class 'float'>)}, 'b': {'type': <class 'list'>, 'min_len': 3, 'max_len': 3, 'item_types': (<class 'int'>, <class 'float'>)}, 'c': {'type': <class 'list'>, 'min_len': 3, 'max_len': 3, 'item_types': (<class 'int'>, <class 'float'>)}, 'd': {'type': <class 'list'>, 'min_len': 3, 'max_len': 3, 'item_types': (<class 'int'>, <class 'float'>)}})¶
-
add_subdivision(eta_a, eta_d, ignore_inval_eta=False)¶ Add a subdivision for the current segment
- Note:
- A new division will not be created if:
- a division already exists at same position
- a division line is very close to an existing division
- In both cases the cases a handle to the already existing division will be returned.
- Args:
eta_a: (float) upper relative position of the division line eta_d: (float) upper relative position of the division line ignore_inval_eta: (bool) optional parameter to ignore invalid eta values - Returns:
subvivision: (obj) newly created subdivision object
-
add_subdivision_for_control(eta_a, eta_b, parent_control, xsi1, xsi2, xsi_h1=None, xsi_h2=None)¶ Add a subdivision for with a control device for a specified range
- Args:
eta_a: (float) inner eta position of control surface eta_b: (float) outer eta position of control surface parent_control: (obj) reference to the parent control surface xsi1: (float) inner xsi position of control surface xsi2: (float) outer xsi position of control surface xsi_h1: (float) [optional] inner position of the hinge line (=xsi1 if not specified) xsi_h2: (float) [optional] outer position of the hinge line (=xsi2 if not specified) - Returns:
sd_list: (obj-list) list of subdivision objects
-
area¶
-
check_airfoils()¶ Check type and value of airfoil dictionary
-
check_geometry()¶ Check type and value of geometry dictionary
-
check_panels()¶ Check type and value of properties in WINGSEGMENT.PANELS.
-
check_vertices()¶ Check types and values of properties in vertices dictionary
-
generate()¶ Compute wingsegment vertices and geometry from provided data
Procedure is as follows:
- Check if wing segment properties are correctly defined
- Check if wing segment definition is complete
- Generate wing segment vertices, geometry if possible
Note:
- Points are computed from geometric properties specified in geometry
- At least one of A, B, C, D must be defined as reference point
- Will compute corresponding properties in GEOMETRY given points A, D
- Will compute corresponding properties in GEOMETRY given points B, C
- Will compute all properties in GEOMETRY given points A, B, C, D
No other combination of properties and coordinates is accepted
Correct ordering of the vertices A, B, C, D is enforced:
- A = (x_min, y_min, z_a) or A = (x_min, y_a, z_min) if vertical
- B = (x_min, y_max, z_b) or B = (x_min, y_a, z_max) if vertical
- C = (x_max, y_max, z_c) or C = (x_max, y_a, z_max) if vertical
- D = (x_max, y_min, z_d) or D = (x_max, y_a, z_min) if vertical
-
get_deformed_segment_point(eta, xsi, mirror=False)¶ Return a point of the deformed segment based on relative coordinates of the undeformed segment.
- Args:
eta: (float) eta coordinate xsi: (float) xsi coordinate - Returns:
point: segment point in the deformed mesh
-
main_direction¶ Direction of segment
- Perpendicular to line AD (not normalised)
- Points roughly from AD to BC
-
normal_vector¶ Segment normal vector (not normalised)
-
symmetry¶ Symmetry inherited from parent wing
-
uid¶
-
-
pytornado.objects.aircraft.get_abs_segment_point_coords(segment_vertices, eta, xsi)¶ Compute the absolute coordinates for a point on a segment
- Warning:
- The function does only work for UNDEFORMED segments!
- Args:
segment_vertices: (dict) segment vertices rel_coords: (dict) relative coordinates (eta, xsi) - Returns:
p: (ndarray) absolute coordinates
-
pytornado.objects.aircraft.mirror_point(point, plane)¶ Mirror a point in 3D space about a symmetry plane.
- Args:
point: point plane: (str) plane (‘xy’, ‘xz’ or ‘yz’)
-
pytornado.objects.aircraft.mirror_vertices(vertices, plane)¶ Mirror vertices and keep vertex points consistently ordered.
This is a wrapper combining the mirroring and ordering.
- Args:
vertices: (tuple) vertices like (a, b, c, d) plane: (str) plane (‘xy’, ‘xz’ or ‘yz’) - Returns:
ordered_vertices: (tuple) ordered vertices
-
pytornado.objects.aircraft.order_mirrored_vertex_points(vertices, plane)¶ Order mirrored vertex points to keep consistent global system
- Args:
vertices: (tuple) vertices like (a, b, c, d) plane: (str) plane (‘xy’, ‘xz’ or ‘yz’) - Returns:
ordered_vertices: (tuple) ordered vertices
-
pytornado.objects.aircraft.xsi_interpol(segment_vertices, rel_inner, rel_outer, eta)¶ Return the linear interpolation of xsi value based on relative segment coordinates
- Args:
segment_vertices: (dict) segment vertices rel_inner: (tuple) eta and xsi coordinates of the inner position rel_outer: (tuple) eta and xsi coordinates of the outer position eta: (float) eta position at which xsi is to be interpolated - Return:
xsi_interpol: (float) interpolated value for xsi
pytornado.objects.objecttools module¶
Generators to facilitate looping over aircraft objects
Developed for Airinnova AB, Stockholm, Sweden.
-
pytornado.objects.objecttools.all_controls(aircraft)¶ Yield each control surface of the aircraft.
- Args:
aircraft: aircraft object - Yields:
this_control: tuple containing the control surface number, name and object this_wing: tuple containing the wing number, name and object
-
pytornado.objects.objecttools.all_segments(aircraft)¶ Yield each segment of the aircraft.
- Args:
aircraft: aircraft object - Yields:
this_segment: tuple containing the segment number, name and object this_wing: tuple containing the wing number, name and object
-
pytornado.objects.objecttools.all_subareas(aircraft)¶ Yield each subarea of the aircraft.
- Args:
aircraft: aircraft object - Yields:
this_subarea: tuple containing the subarea number, name and object this_subdivision: tuple containing the subdivision number, name and object this_segment: tuple containing the segment number, name and object this_wing: tuple containing the wing number, name and object
-
pytornado.objects.objecttools.all_subareas_of_control(aircraft, control_uid)¶ Yield each subarea belonging to a control of specified name.
- Args:
aircraft: aircraft object control_uid: name (UID) of the control - Yields:
this_subarea: tuple containing the subarea number, name and object
-
pytornado.objects.objecttools.all_subdivisions(aircraft)¶ Yield each subdivision of the aircraft.
- Args:
aircraft: aircraft object - Yields:
this_subdivision: tuple containing the subdivision number, name and object this_segment: tuple containing the segment number, name and object this_wing: tuple containing the wing number, name and object
-
pytornado.objects.objecttools.all_wings(aircraft)¶ Yield each wing of the aircraft.
- Args:
aircraft: aircraft object - Yields:
this_wing: tuple containing the wing number, name and object
-
pytornado.objects.objecttools.count_all_controls(aircraft)¶ Returns the number of control surfaces of the aircraft.
- Args:
aircraft: aircraft object - Returns:
n: number of control surfaces
-
pytornado.objects.objecttools.count_all_segments(aircraft)¶ Returns the number of segments of the aircraft.
- Args:
aircraft: aircraft object - Returns:
n: number of segments
-
pytornado.objects.objecttools.count_all_subareas(aircraft)¶ Returns the number of subareas of the aircraft.
- Args:
aircraft: aircraft object - Returns:
n: number of subareas
-
pytornado.objects.objecttools.count_all_wings(aircraft)¶ Returns the number of wings of the aircraft.
- Args:
aircraft: aircraft object - Returns:
n: number of wings
pytornado.objects.settings module¶
Data structures for execution settings.
Developed for Airinnova AB, Stockholm, Sweden.
-
class
pytornado.objects.settings.PATHS¶ Bases:
objectNamespace for project paths
-
class
pytornado.objects.settings.Settings(settings_filename, project_dir, *, settings_dict=None, make_dirs=True, check_ac_file_type=True)¶ Bases:
object-
clean()¶ Remove old files in project directory
-
generate_paths()¶ Initialise the file structure
-
state_is_cpacs¶ Flag indicating if state is to be read from CPACS
-
update_from_dict(settings_dict)¶ Update settings from dictionary structures
- Args:
settings: Dictionary with general settings plot: Dictionary with plot settings
-
pytornado.objects.state module¶
Data structure for aircraft flight state.
Developed for Airinnova AB, Stockholm, Sweden.
-
class
pytornado.objects.state.CurrentState¶ Bases:
object
-
class
pytornado.objects.state.FlightState¶ Bases:
object-
check_values()¶ Make sure input values have correct format
-
free_stream_velocity_vector¶ Return the free stream velocity vector (incoming flow)
-
iter_states()¶ Iterator which yields a dictionary for each flight state
-
update_from_dict(aero)¶ Update state using a dictionary
-
pytornado.objects.utils module¶
Miscellaneous data structures for PyTornado.
Developed for Airinnova AB, Stockholm, Sweden.
-
pytornado.objects.utils.check_dict(template_dict, test_dict)¶ Check that a test dictionary looks like a template dictionary
- Args:
template_dict: Template dictionary test_dict: Test dictionary
The template dictionary must have a specific structure as outlined below:
template_dict = { 'test_key1': ('default_value1', str), 'test_key2': (1792, (int, float)), }
The values have to be tuples with some default value and the expected types of the values. The follwing dictionary would pass the test:
test_dict = { 'test_key1': 'some_string', 'test_key2': 1111, }
However, the follwing dictionary does not have the correct form and an error will be raised.
test_dict = { 'test_key1': 'this is okay...', 'test_key2': '... but a string is now allowed here', }
- Raises:
TypeError: If types of test and template dictionary don’t match
-
pytornado.objects.utils.get_default_dict(template_dict)¶ Return a default dict from a template dictionary
- Args:
template_dict: Template dictionary - Returns:
default_dict: New dictionary with defaults generated from ‘template_dict’
The template dictionary must have a specific structure as outlined below:
template_dict = { 'test_key1': ('default_value1', str), 'test_key2': (1792, (int, float)), }
The ‘default_dict’ will look like this:
default_dict = { 'test_key1': 'default_value1', 'test_key2': 1792, }
pytornado.objects.vlm_struct module¶
Data structures for VLM-related data: grid and results
Developed for Airinnova AB, Stockholm, Sweden.
-
class
pytornado.objects.vlm_struct.BookKeepingEntry(subarea, pan_idx, num_chordwise_panels, mirror)¶ Bases:
tuple-
mirror¶ Alias for field number 3
-
num_chordwise_panels¶ Alias for field number 2
-
pan_idx¶ Alias for field number 1
-
subarea¶ Alias for field number 0
-
-
class
pytornado.objects.vlm_struct.VLMData¶ Bases:
object
Module contents¶
The objects package contains the definitions of the data structures. Each data structure is equipped with properties, called attributes, and functions that operate on these attributes, called methods.