Skip to content

Commit e4468b3

Browse files
committed
Added possibility to specify thickness and camber max for each radius in the blade __init__ method. To do so, corresponding methods in baseprofile implemented. Added tests too
1 parent 4af7e24 commit e4468b3

3 files changed

Lines changed: 81 additions & 7 deletions

File tree

bladex/blade.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ class Blade(object):
8484
radial section of the blade.
8585
:param array_like skew_angles: 1D array, contains the skew angles
8686
(in degrees) for each radial section of the blade.
87+
:param array_like thickness: 1D array, contains the value of the
88+
thickness of each section, specified if sections have not the desired thickness.
89+
:param array_like camber: 1D array, contains the value of the
90+
camber of each section, specified if sections have note the desired camber.
8791
8892
Note that, each of the previous array_like parameters must be consistent
8993
with the other parameters in terms of the radial ordering of the blade
@@ -149,7 +153,7 @@ class Blade(object):
149153
"""
150154

151155
def __init__(self, sections, radii, chord_lengths, pitch, rake,
152-
skew_angles):
156+
skew_angles, thickness=None, camber=None):
153157
# Data are given in absolute values
154158
self.sections = sections
155159
self.n_sections = len(sections)
@@ -158,6 +162,8 @@ def __init__(self, sections, radii, chord_lengths, pitch, rake,
158162
self.pitch = pitch
159163
self.rake = rake
160164
self.skew_angles = skew_angles
165+
self.thickness = thickness
166+
self.camber = camber
161167
self._check_params()
162168

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

331-
if reflect:
332-
self.sections[i].reflect()
333-
334337
# Scale the unit chord to actual length.
335338
self.sections[i].scale(self.chord_lengths[i])
336339

340+
# Setting thickness max is required
341+
if self.thickness is not None:
342+
self.sections[i].set_thickness_max(self.thickness[i])
343+
344+
# Setting camber max is required
345+
if self.camber is not None and i < self.n_sections-1:
346+
self.sections[i].set_camber_line_max(self.camber[i])
347+
348+
if reflect:
349+
self.sections[i].reflect()
350+
337351
# Rotate according to the pitch angle.
338352
# Since the current orientation system is not standard (It is
339353
# left-handed Cartesian orientation system, where Y-axis points

bladex/profile/baseprofile.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,6 @@ def deform_camber_line(self, percent_change, n_interpolated_points=None):
379379
380380
:param float percent_change: percentage of change of the
381381
maximum camber. Default value is None
382-
:param bool interpolate: if True, the interpolated coordinates are
383-
used to compute the camber line and foil's thickness, otherwise
384-
the original discrete coordinates are used. Default value is False.
385382
:param int n_interpolated_points: number of points to be used for the
386383
equally-spaced sample computations. If None then there is no
387384
interpolation, unless the arrays x_up != x_down elementwise which
@@ -415,6 +412,50 @@ def deform_camber_line(self, percent_change, n_interpolated_points=None):
415412
self.yup_coordinates = self.camber_line[1] + half_thickness
416413
self.ydown_coordinates = self.camber_line[1] - half_thickness
417414

415+
def set_camber_line_max(self, camber_max):
416+
"""
417+
Deform camber line according to a given maximum value.
418+
The percentage of camber wrt to the x/c coordinate does not change, i.e.,
419+
we rescale the camber value by a scalar
420+
Also reconstructs the deformed airfoil's coordinates.
421+
422+
Thus, the percentage of change is defined as follows:
423+
424+
.. math::
425+
\\frac{\\text{new magnitude of max camber - old magnitude of
426+
maximum \
427+
camber}}{\\text{old magnitude of maximum camber}} * 100
428+
429+
A positive percentage means the new camber is larger than the max
430+
camber value, while a negative percentage indicates the new value
431+
is smaller.
432+
433+
We note that the method works only for airfoils in the reference
434+
position, i.e. chord line lies on the X-axis and the foil is not
435+
rotated, since the measurements are based on the Y-values of the
436+
airfoil coordinates, hence any measurements or scalings will be
437+
inaccurate for the foils not in their reference position.
438+
439+
:param float camber_max: maximum camber to be set.
440+
"""
441+
old_camber_max = self.max_camber()
442+
percent_scaling_factor = 100*(camber_max - old_camber_max) / (old_camber_max)
443+
# print(percent_scaling_factor)
444+
self.deform_camber_line(percent_scaling_factor)
445+
446+
447+
def set_thickness_max(self, thickness_max):
448+
"""
449+
Deform y_up and y_down coordinates to have the desired thickness max value.
450+
To do so, we compute the ratio between olt thickness and new one
451+
452+
:param float thickness_max: maximum thickness to be set.
453+
"""
454+
old_thickness = self.max_thickness()
455+
ratio_thickness = thickness_max / old_thickness if old_thickness != 0. else 0.
456+
self.yup_coordinates *= ratio_thickness
457+
self.ydown_coordinates *= ratio_thickness
458+
418459
@property
419460
def yup_curve(self):
420461
"""

tests/test_profiles.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@ def create_custom_profile():
1414
return CustomProfile(xup=xup, yup=yup, xdown=xdown, ydown=ydown)
1515

1616

17+
class TestBaseProfileMethods(TestCase):
18+
def test_max_thickness(self):
19+
profile = NacaProfile(digits='2412')
20+
self.assertAlmostEqual(profile.max_thickness(), .12, delta=1e-4)
21+
22+
def test_set_thickness_max(self):
23+
profile = NacaProfile(digits='2412')
24+
profile.set_thickness_max(.24)
25+
self.assertAlmostEqual(profile.max_thickness(), .24, delta=1e-4)
26+
27+
def test_max_camber(self):
28+
profile = NacaProfile(digits='3412')
29+
self.assertAlmostEqual(profile.max_camber(), .03, delta=1e-4)
30+
31+
def test_set_camber_max(self):
32+
profile = NacaProfile(digits='3412')
33+
profile.set_camber_line_max(.05)
34+
self.assertAlmostEqual(profile.max_camber(), .05, delta=1e-4)
35+
1736
class TestCustomProfile(TestCase):
1837
def test_inheritance_custom(self):
1938
self.assertTrue(issubclass(CustomProfile, ProfileInterface))

0 commit comments

Comments
 (0)