Skip to content

Commit cdc592b

Browse files
committed
Fixed skew and rake computations
1 parent d37f926 commit cdc592b

File tree

3 files changed

+30
-104
lines changed

3 files changed

+30
-104
lines changed

bladex/reversepropeller/basereversepropeller.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import os, errno
2-
import os.path
3-
import time
1+
import sys
42
import numpy as np
53
import csv
64
from bladex import CustomProfile, Blade, Propeller, Shaft
@@ -13,7 +11,7 @@
1311
import OCC.Core.TopoDS
1412
from OCC.Core.TopTools import TopTools_ListOfShape
1513
from OCC.Core.TopExp import TopExp_Explorer
16-
from OCC.Core.TopAbs import TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_WIRE
14+
from OCC.Core.TopAbs import TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_WIRE, TopAbs_SHELL
1715
from OCC.Core.gp import gp_Pnt, gp_Dir, gp_Ax2, gp_Vec, gp_Pln
1816
from OCC.Core.TColgp import TColgp_Array1OfPnt
1917
from OCC.Core.BRepAdaptor import BRepAdaptor_Curve
@@ -128,7 +126,14 @@ def _extract_solid_from_file(self):
128126
sewer.Perform()
129127
result_sewed_blade = sewer.SewedShape()
130128
blade_solid_maker = BRepBuilderAPI_MakeSolid()
131-
blade_solid_maker.Add(OCC.Core.TopoDS.topods.Shell(result_sewed_blade))
129+
if result_sewed_blade.ShapeType() == 0:
130+
exp = TopExp_Explorer(result_sewed_blade, TopAbs_SHELL)
131+
while exp.More():
132+
shell = topods.Shell(exp.Current())
133+
blade_solid_maker.Add(shell)
134+
exp.Next()
135+
else:
136+
blade_solid_maker.Add(OCC.Core.TopoDS.topods.Shell(result_sewed_blade))
132137
if (blade_solid_maker.IsDone()):
133138
self.blade_solid = blade_solid_maker.Solid()
134139
else:
@@ -265,18 +270,6 @@ def _extract_parameters_and_transform_profile(self, radius):
265270
self.camber_points_on_plane[0, 0] = 0.0
266271
self.camber_points_on_plane[-1, 0] = 1.0
267272

268-
# Save the properties we wanted for each section
269-
self.pitch_angles_list.append(self.pitch_angle)
270-
self.pitch_list.append(
271-
abs(2 * np.pi * radius / np.tan(self.pitch_angle)) / 1000.0)
272-
self.skew_angles_list.append((self.skew / radius - np.pi) * 180 / np.pi)
273-
self.skew_list.append((self.skew - np.pi * radius) / 1000.0)
274-
total_rake = self.rake + self.rake_induced_by_skew
275-
rake = total_rake - (self.skew - np.pi * radius) / np.tan(
276-
self.pitch_angle)
277-
rake = -rake / 1000.0
278-
self.rake_list.append(rake)
279-
self.chord_length_list.append(self.chord_length / 1000.0)
280273
self.camber_points_on_plane = np.sort(
281274
self.camber_points_on_plane.view('float64,float64'),
282275
order=['f0'],
@@ -303,7 +296,7 @@ def save_global_parameters(self, filename_csv):
303296
writer.writerow(("Skew angles list: ", self.skew_angles_list))
304297
writer.writerow(("Rake list: ", self.rake_list))
305298
writer.writerow(("Chord length list: ", self.chord_length_list))
306-
for j in range(self.num_sections):
299+
for j in range(len(self.radii_list)):
307300
writer.writerow(("x section" + str(j) + " upper coordinates: ",
308301
self.xup[j, :]))
309302
writer.writerow(("x section" + str(j) + " lower coordinates: ",

bladex/reversepropeller/reversepropeller.py

Lines changed: 2 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ def __init__(self, filename, radii_list, num_points_top_bottom):
144144
self._initial_camber_points_plane(radius)
145145
self._initial_airfoil_points_plane(radius)
146146
self._extract_parameters_and_transform_profile(radius)
147+
self._store_properties(radius)
147148
self._airfoil_top_and_bottom_points()
148149
self.xup[ind_sec, :] = self.ascissa
149150
self.xdown[ind_sec, :] = self.ascissa
@@ -463,7 +464,7 @@ def _initial_airfoil_points_plane(self, radius):
463464
self.leading_edge_point_on_plane +
464465
self.trailing_edge_point_on_plane) / 2.0
465466

466-
def _extract_parameters_and_transform_profile(self, radius):
467+
def _store_properties(self, radius):
467468
"""
468469
Private method which extracts the parameters (pitch, rake, skew ,...) related
469470
to a specific section of the blade, and then transforms the camber points
@@ -475,78 +476,6 @@ def _extract_parameters_and_transform_profile(self, radius):
475476
Basically all points and edges of the profile section are transformed
476477
to fulfill the properties of the specific sectionwe are considering.
477478
"""
478-
self.pitch_angle = np.arctan2(
479-
self.leading_edge_point_on_plane[1] -
480-
self.trailing_edge_point_on_plane[1],
481-
self.leading_edge_point_on_plane[0] -
482-
self.trailing_edge_point_on_plane[0])
483-
self.skew = self.mid_chord_point_on_plane[1]
484-
self.rake_induced_by_skew = self.skew / np.tan(self.pitch_angle)
485-
486-
self.airfoil_points_on_plane[:, 1:2] -= self.skew
487-
self.camber_points_on_plane[:, 1:2] -= self.skew
488-
self.leading_edge_point_on_plane[1] -= self.skew
489-
self.trailing_edge_point_on_plane[1] -= self.skew
490-
self.mid_chord_point_on_plane[1] -= self.skew
491-
492-
self.airfoil_points_on_plane[:, 0:1] -= self.rake_induced_by_skew
493-
self.camber_points_on_plane[:, 0:1] -= self.rake_induced_by_skew
494-
self.leading_edge_point_on_plane[0] -= self.rake_induced_by_skew
495-
self.trailing_edge_point_on_plane[0] -= self.rake_induced_by_skew
496-
self.mid_chord_point_on_plane[0] -= self.rake_induced_by_skew
497-
498-
self.rake = self.mid_chord_point_on_plane[0]
499-
500-
self.airfoil_points_on_plane[:, 0:1] -= self.rake
501-
self.camber_points_on_plane[:, 0:1] -= self.rake
502-
self.leading_edge_point_on_plane[0] -= self.rake
503-
self.trailing_edge_point_on_plane[0] -= self.rake
504-
self.mid_chord_point_on_plane[0] -= self.rake
505-
506-
rotation_matrix = np.zeros((2, 2))
507-
rotation_matrix[0][0] = np.cos(-self.pitch_angle)
508-
rotation_matrix[0][1] = -np.sin(-self.pitch_angle)
509-
rotation_matrix[1][0] = np.sin(-self.pitch_angle)
510-
rotation_matrix[1][1] = np.cos(-self.pitch_angle)
511-
512-
self.airfoil_points_on_plane = self.airfoil_points_on_plane.dot(
513-
rotation_matrix.transpose())
514-
self.camber_points_on_plane = self.camber_points_on_plane.dot(
515-
rotation_matrix.transpose())
516-
self.leading_edge_point_on_plane = self.leading_edge_point_on_plane.dot(
517-
rotation_matrix.transpose())
518-
self.trailing_edge_point_on_plane = self.trailing_edge_point_on_plane.dot(
519-
rotation_matrix.transpose())
520-
self.mid_chord_point_on_plane = self.mid_chord_point_on_plane.dot(
521-
rotation_matrix.transpose())
522-
523-
self.chord_length = ((self.leading_edge_point_on_plane[0] -
524-
self.trailing_edge_point_on_plane[0])**2 +
525-
(self.leading_edge_point_on_plane[1] -
526-
self.trailing_edge_point_on_plane[1])**2)**.5
527-
528-
self.airfoil_points_on_plane[:, 0:2] /= self.chord_length
529-
self.camber_points_on_plane[:, 0:2] /= self.chord_length
530-
self.leading_edge_point_on_plane[0:1] /= self.chord_length
531-
self.trailing_edge_point_on_plane[0:1] /= self.chord_length
532-
self.mid_chord_point_on_plane[0:1] /= self.chord_length
533-
534-
self.airfoil_points_on_plane[:, 0:1] *= -1.0
535-
self.camber_points_on_plane[:, 0:1] *= -1.0
536-
self.leading_edge_point_on_plane[0] *= -1.0
537-
self.trailing_edge_point_on_plane[0] *= -1.0
538-
self.mid_chord_point_on_plane[0] *= -1.0
539-
540-
self.airfoil_points_on_plane[:, 0:1] += 0.5
541-
self.camber_points_on_plane[:, 0:1] += 0.5
542-
self.leading_edge_point_on_plane[0] += 0.5
543-
self.trailing_edge_point_on_plane[0] += 0.5
544-
self.mid_chord_point_on_plane[0] += 0.5
545-
546-
self.camber_points_on_plane = np.matrix(self.camber_points_on_plane)
547-
self.camber_points_on_plane[0, 0] = 0.0
548-
self.camber_points_on_plane[-1, 0] = 1.0
549-
550479
# Save the properties we wanted for each section
551480
self.pitch_angles_list.append(self.pitch_angle)
552481
self.pitch_list.append(
@@ -559,14 +488,6 @@ def _extract_parameters_and_transform_profile(self, radius):
559488
self.rake = -self.rake / 1000.0
560489
self.rake_list.append(self.rake)
561490
self.chord_length_list.append(self.chord_length / 1000.0)
562-
self.camber_points_on_plane = np.sort(
563-
self.camber_points_on_plane.view('float64,float64'),
564-
order=['f0'],
565-
axis=0).view(np.float64)
566-
self.f_camber = interp1d(
567-
np.squeeze(np.asarray(self.camber_points_on_plane[:, 0])),
568-
np.squeeze(np.asarray(self.camber_points_on_plane[:, 1])),
569-
kind='cubic')
570491

571492
def _airfoil_top_and_bottom_points(self):
572493
"""

bladex/reversepropeller/reversepropellerbladex.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def __init__(self, filename, radii_list, num_points_top_bottom):
100100
self._initial_airfoil_points_plane(radius)
101101
self._airfoil_top_and_bottom_points_before_transformations(radius)
102102
self._extract_parameters_and_transform_profile(radius)
103+
self._store_properties(radius)
103104
self._transform_top_and_bottom()
104105
self._airfoil_top_and_bottom_points_after_transformations()
105106
self.xup[ind_sec, :] = self.ascissa
@@ -122,7 +123,6 @@ def _build_intersection_cylinder_blade(self):
122123
section_builder.ComputePCurveOn2(True)
123124
section_builder.Build()
124125
self.section = section_builder.Shape()
125-
126126
wire_maker = BRepBuilderAPI_MakeWire()
127127
wire_maker_top = BRepBuilderAPI_MakeWire()
128128
wire_maker_bottom = BRepBuilderAPI_MakeWire()
@@ -171,10 +171,8 @@ def _camber_curve(self, radius):
171171
Computation of the camber points. We get the chord, move along it and fint the intersection
172172
of the othogonal plane to the chord-curvilinear absissa and the top-bottom wires
173173
"""
174-
# self.trailing_edge = self.curve_adaptor_top.Value(0.0)
175-
# self.leading_edge = self.curve_adaptor_top.Value(self.curve_adaptor_top.LastParameter())
176-
self.trailing_edge = self.curve_adaptor_bottom.Value(0.0)
177-
self.leading_edge = self.curve_adaptor_bottom.Value(self.curve_adaptor_bottom.LastParameter())
174+
self.trailing_edge = self.curve_adaptor_top.Value(0.0)
175+
self.leading_edge = self.curve_adaptor_top.Value(self.curve_adaptor_top.LastParameter())
178176
# Equation of generic geodesic from leading to trailing edge:
179177
# x = lambda*s + mu, y = R*sin(a*s+b), z = R*cos(a*s+b)
180178
# with s parametrization of curve and lambda, mu, a, b to be found
@@ -363,6 +361,20 @@ def _airfoil_top_and_bottom_points_before_transformations(self, radius):
363361
self.airfoil_top = np.array(self.airfoil_top)
364362
self.airfoil_bottom = np.array(self.airfoil_bottom)
365363

364+
def _store_properties(self, radius):
365+
# Save the properties we wanted for each section
366+
self.pitch_angles_list.append(self.pitch_angle)
367+
self.pitch_list.append(
368+
abs(2 * np.pi * radius / np.tan(self.pitch_angle)) / 1000.0)
369+
self.skew_angles_list.append(-(self.skew / radius) * 180 / np.pi)
370+
self.skew_list.append(self.skew / 1000.0)
371+
total_rake = self.rake + self.rake_induced_by_skew
372+
rake = total_rake - (self.skew) / np.tan(
373+
self.pitch_angle)
374+
rake = -rake / 1000.0
375+
self.rake_list.append(rake)
376+
self.chord_length_list.append(self.chord_length / 1000.0)
377+
366378
def _transform_top_and_bottom(self):
367379
"""
368380
Method that transforms the top and bottom coordinates from physical coordinates

0 commit comments

Comments
 (0)