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: Exception

Raised if when a component is ill-defined

class pytornado.objects.aircraft.SegmentStrip(segment, rel_vertices)

Bases: object

SegmentStrip 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: object

StripSubdivision 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: object

Namespace for project paths

class DIR

Bases: object

AIRCRAFT = 'aircraft'
AIRFOILS = 'airfoils'
DEFORMATION = 'deformation'
PLOTS = '_plots'
RESULTS = '_results'
SETTINGS = 'settings'
STATE = 'state'
TEMPLATE_ROOT = 'pytornado'
class FILES

Bases: object

classmethod AIRFOIL(name_airfoil)

Return relative path to a ‘blade’ file

Notes:
  • Path is relative to the project root directory
  • Will return ‘airfoils/blade.NACA1234’ if ‘NACA1234’ is given
Args:
name_airfoil:String with the airfoil name
LOG = 'log.txt'
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

class pytornado.objects.vlm_struct.VLMLattice

Bases: object

clean_bookkeeping()

Remove all bookkeeping entries

update_bookkeeping(entry)

Add a ‘BookKeepingEntry()’ to the bookkeeping system

Args:
entry:(obj) Instance of ‘BookKeepingEntry()’

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.