Skip to content
Merged
4 changes: 4 additions & 0 deletions bladex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
from .deform import Deformation
from .params import ParamFile
from .ndinterpolator import RBF, reconstruct_f, scipy_bspline
from .reversepropeller import ReversePropellerInterface
from .reversepropeller import BaseReversePropeller
from .reversepropeller import ReversePropeller
from .reversepropeller import ReversePropellerBladeX
from .reversepropeller.reversepropeller import ReversePropeller
from .shaft.cylinder_shaft import CylinderShaft
from .intepolatedface import InterpolatedFace
22 changes: 18 additions & 4 deletions bladex/blade.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ class Blade(object):
radial section of the blade.
:param array_like skew_angles: 1D array, contains the skew angles
(in degrees) for each radial section of the blade.
:param array_like thickness: 1D array, contains the value of the
thickness of each section, specified if sections have not the desired thickness.
:param array_like camber: 1D array, contains the value of the
camber of each section, specified if sections have note the desired camber.

Note that, each of the previous array_like parameters must be consistent
with the other parameters in terms of the radial ordering of the blade
Expand Down Expand Up @@ -149,7 +153,7 @@ class Blade(object):
"""

def __init__(self, sections, radii, chord_lengths, pitch, rake,
skew_angles):
skew_angles, thickness=None, camber=None):
# Data are given in absolute values
self.sections = sections
self.n_sections = len(sections)
Expand All @@ -158,6 +162,8 @@ def __init__(self, sections, radii, chord_lengths, pitch, rake,
self.pitch = pitch
self.rake = rake
self.skew_angles = skew_angles
self.thickness = thickness
self.camber = camber
self._check_params()

self.conversion_factor = 1000 # to convert units if necessary
Expand Down Expand Up @@ -328,12 +334,20 @@ def apply_transformations(self, reflect=True):
# Translate reference point into origin
self.sections[i].translate(-self.sections[i].reference_point)

if reflect:
self.sections[i].reflect()

# Scale the unit chord to actual length.
self.sections[i].scale(self.chord_lengths[i])

# Setting thickness max is required
if self.thickness is not None:
self.sections[i].set_thickness_max(self.thickness[i])

# Setting camber max is required
if self.camber is not None and i < self.n_sections-1:
self.sections[i].set_camber_line_max(self.camber[i])

if reflect:
self.sections[i].reflect()

# Rotate according to the pitch angle.
# Since the current orientation system is not standard (It is
# left-handed Cartesian orientation system, where Y-axis points
Expand Down
47 changes: 44 additions & 3 deletions bladex/profile/baseprofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,6 @@ def deform_camber_line(self, percent_change, n_interpolated_points=None):

:param float percent_change: percentage of change of the
maximum camber. Default value is None
:param bool interpolate: if True, the interpolated coordinates are
used to compute the camber line and foil's thickness, otherwise
the original discrete coordinates are used. Default value is False.
:param int n_interpolated_points: number of points to be used for the
equally-spaced sample computations. If None then there is no
interpolation, unless the arrays x_up != x_down elementwise which
Expand Down Expand Up @@ -415,6 +412,50 @@ def deform_camber_line(self, percent_change, n_interpolated_points=None):
self.yup_coordinates = self.camber_line[1] + half_thickness
self.ydown_coordinates = self.camber_line[1] - half_thickness

def set_camber_line_max(self, camber_max):
"""
Deform camber line according to a given maximum value.
The percentage of camber wrt to the x/c coordinate does not change, i.e.,
we rescale the camber value by a scalar
Also reconstructs the deformed airfoil's coordinates.

Thus, the percentage of change is defined as follows:

.. math::
\\frac{\\text{new magnitude of max camber - old magnitude of
maximum \
camber}}{\\text{old magnitude of maximum camber}} * 100

A positive percentage means the new camber is larger than the max
camber value, while a negative percentage indicates the new value
is smaller.

We note that the method works only for airfoils in the reference
position, i.e. chord line lies on the X-axis and the foil is not
rotated, since the measurements are based on the Y-values of the
airfoil coordinates, hence any measurements or scalings will be
inaccurate for the foils not in their reference position.

:param float camber_max: maximum camber to be set.
"""
old_camber_max = self.max_camber()
percent_scaling_factor = 100*(camber_max - old_camber_max) / (old_camber_max)
# print(percent_scaling_factor)
self.deform_camber_line(percent_scaling_factor)


def set_thickness_max(self, thickness_max):
"""
Deform y_up and y_down coordinates to have the desired thickness max value.
To do so, we compute the ratio between olt thickness and new one

:param float thickness_max: maximum thickness to be set.
"""
old_thickness = self.max_thickness()
ratio_thickness = thickness_max / old_thickness if old_thickness != 0. else 0.
self.yup_coordinates *= ratio_thickness
self.ydown_coordinates *= ratio_thickness

@property
def yup_curve(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions bladex/profile/customprofile.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ def __init__(self, **kwargs):
raise RuntimeError(
"""Input arguments should be the section coordinates
(xup, yup, xdown, ydown) or the section parameters
(camber_perc, thickness_perc,
camber_max, thickness_max, chord_perc).""")
(camber_perc, thickness_perc, camber_max,
thickness_max, chord_perc, chord_len).""")

def generate_parameters(self, convention='british'):
return super().generate_parameters(convention)
Expand Down
10 changes: 10 additions & 0 deletions bladex/reversepropeller/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""
Profile init
"""
__all__ = ['ReversePropellerInterface', 'BaseReversePropeller',
'ReversePropeller', 'ReversePropellerBladeX']

from .reversepropellerinterface import ReversePropellerInterface
from .basereversepropeller import BaseReversePropeller
from .reversepropeller import ReversePropeller
from .reversepropellerbladex import ReversePropellerBladeX
Loading
Loading