def cubic_interpolator():
    b = BlendAirfoilShapes()
    b.airfoil_list = afs
    b.ni = 20
    b.blend_var = [0.241, 0.301, 0.36]
    b.spline = 'cubic'
    b.initialize()
    return b
def cubic_interpolator():
    b = BlendAirfoilShapes()
    b.airfoil_list = afs
    b.ni = 20
    b.blend_var = [0.241, 0.301, 0.36]
    b.spline = "cubic"
    b.initialize()
    return b
    def execute(self):

        self.interpolator = BlendAirfoilShapes()
        self.interpolator.ni = self.chord_ni
        self.interpolator.spline = self.surface_spline
        self.interpolator.blend_var = self.blend_var
        self.interpolator.airfoil_list = self.base_airfoils
        self.interpolator.initialize()

        self.span_ni = self.pf.s.shape[0]
        x = np.zeros((self.chord_ni, self.span_ni, 3))

        for i in range(self.span_ni):

            s = self.pf.s[i]
            pos_x = self.pf.x[i]
            pos_y = self.pf.y[i]
            pos_z = self.pf.z[i]
            chord = self.pf.chord[i]
            p_le = self.pf.p_le[i]

            # generate the blended airfoil shape
            if self.interp_type == 'rthick':
                rthick = self.pf.rthick[i]
                points = self.interpolator(rthick)
            else:
                points = self.interpolator(s)

            points *= chord
            points[:, 0] += pos_x - chord * p_le

            # x-coordinate needs to be inverted for clockwise rotating blades
            x[:, i, :] = (np.array(
                [-points[:, 0], points[:, 1], x.shape[0] * [pos_z]]).T)

        # save non-rotated blade (only really applicable for straight blades)
        x_norm = x.copy()
        x[:, :, 1] += self.pf.y
        x = self.rotate(x)

        self.surfnorot.surface = x_norm
        self.surfout.surface = x
Exemple #4
0
    def execute(self):

        self.interpolator = BlendAirfoilShapes()
        self.interpolator.ni = self.chord_ni
        self.interpolator.spline = self.surface_spline
        self.interpolator.blend_var = self.blend_var
        self.interpolator.airfoil_list = self.base_airfoils
        self.interpolator.initialize()

        self.span_ni = self.pf.s.shape[0]
        x = np.zeros((self.chord_ni, self.span_ni, 3))

        for i in range(self.span_ni):

            s = self.pf.s[i]
            pos_x = self.pf.x[i]
            pos_y = self.pf.y[i]
            pos_z = self.pf.z[i]
            chord = self.pf.chord[i]
            p_le = self.pf.p_le[i]

            # generate the blended airfoil shape
            if self.interp_type == "rthick":
                rthick = self.pf.rthick[i]
                points = self.interpolator(rthick)
            else:
                points = self.interpolator(s)

            points = self.redistribute(points, pos_z)

            points *= chord
            points[:, 0] -= chord * p_le

            # x-coordinate needs to be inverted for clockwise rotating blades
            x[:, i, :] = np.array([-points[:, 0], points[:, 1], x.shape[0] * [pos_z]]).T

        # save blade without sweep and prebend
        x_norm = x.copy()

        # add translation and rotation
        x[:, :, 0] += self.pf.x
        x[:, :, 1] += self.pf.y
        x = self.rotate(x)

        self.surfnorot.surface = x_norm
        self.surfout.surface = x
Exemple #5
0
    def execute(self):

        self.interpolator = BlendAirfoilShapes()
        self.interpolator.ni = self.chord_ni
        self.interpolator.spline = self.surface_spline
        self.interpolator.blend_var = self.blend_var
        self.interpolator.airfoil_list = self.base_airfoils
        self.interpolator.initialize()

        self.span_ni = self.pf.s.shape[0]
        x = np.zeros((self.chord_ni, self.span_ni, 3))

        for i in range(self.span_ni):

            s = self.pf.s[i]
            pos_x = self.pf.x[i]
            pos_y = self.pf.y[i]
            pos_z = self.pf.z[i]
            chord = self.pf.chord[i]
            p_le = self.pf.p_le[i]

            # generate the blended airfoil shape
            if self.interp_type == 'rthick':
                rthick = self.pf.rthick[i]
                points = self.interpolator(rthick)
            else:
                points = self.interpolator(s)

            points *= chord
            points[:, 0] += pos_x - chord * p_le

            # x-coordinate needs to be inverted for clockwise rotating blades
            x[:, i, :] = (np.array([-points[:,0], points[:,1], x.shape[0] * [pos_z]]).T)

        # save non-rotated blade (only really applicable for straight blades)
        x_norm = x.copy()
        x[:, :, 1] += self.pf.y
        x = self.rotate(x)

        self.surfnorot.surface = x_norm
        self.surfout.surface = x
class LoftedBladeSurface(Component):

    pf = VarTree(BladePlanformVT(), iotype='in')
    base_airfoils = List(iotype='in')
    blend_var = Array(iotype='in')
    chord_ni = Int(300, iotype='in')
    span_ni = Int(300, iotype='in')

    interp_type = Enum('rthick', ('rthick', 's'), iotype='in')
    surface_spline = Str('akima', iotype='in', desc='Spline')

    rot_order = Array(np.array([2, 1, 0]),
                      iotype='in',
                      desc='rotation order of airfoil sections'
                      'default z,y,x (twist,sweep,dihedral)')

    surfout = VarTree(BladeSurfaceVT(), iotype='out')
    surfnorot = VarTree(BladeSurfaceVT(), iotype='out')

    def execute(self):

        self.interpolator = BlendAirfoilShapes()
        self.interpolator.ni = self.chord_ni
        self.interpolator.spline = self.surface_spline
        self.interpolator.blend_var = self.blend_var
        self.interpolator.airfoil_list = self.base_airfoils
        self.interpolator.initialize()

        self.span_ni = self.pf.s.shape[0]
        x = np.zeros((self.chord_ni, self.span_ni, 3))

        for i in range(self.span_ni):

            s = self.pf.s[i]
            pos_x = self.pf.x[i]
            pos_y = self.pf.y[i]
            pos_z = self.pf.z[i]
            chord = self.pf.chord[i]
            p_le = self.pf.p_le[i]

            # generate the blended airfoil shape
            if self.interp_type == 'rthick':
                rthick = self.pf.rthick[i]
                points = self.interpolator(rthick)
            else:
                points = self.interpolator(s)

            points *= chord
            points[:, 0] += pos_x - chord * p_le

            # x-coordinate needs to be inverted for clockwise rotating blades
            x[:, i, :] = (np.array(
                [-points[:, 0], points[:, 1], x.shape[0] * [pos_z]]).T)

        # save non-rotated blade (only really applicable for straight blades)
        x_norm = x.copy()
        x[:, :, 1] += self.pf.y
        x = self.rotate(x)

        self.surfnorot.surface = x_norm
        self.surfout.surface = x

    def rotate(self, x):
        """
        rotate blade sections accounting for twist and main axis orientation
        
        the blade will be built with a "sheared" layout, ie no rotation around y
        in the case of sweep.
        if the main axis includes a winglet, the blade sections will be
        rotated accordingly. ensure that an adequate point distribution is
        used in this case to avoid sections colliding in the winglet junction!
        """

        main_axis = Curve(points=np.array([self.pf.x, self.pf.y, self.pf.z]).T)

        rot_normals = np.zeros((3, 3))
        x_rot = np.zeros(x.shape)

        for i in range(x.shape[1]):
            points = x[:, i, :]
            rot_center = main_axis.points[i]
            # rotation angles read from file
            angles = np.array([
                self.pf.rot_x[i], self.pf.rot_y[i], self.pf.rot_z[i]
            ]) * np.pi / 180.

            # compute rotation angles of main_axis
            t = main_axis.dp[i]
            rot = np.zeros(3)
            rot[0] = -np.arctan(t[1] / (t[2] + 1.e-20))
            v = np.array([t[2], t[1]])
            vt = np.dot(v, v)**0.5
            rot[1] = (np.arcsin(t[0] / vt))
            angles[0] += rot[0]
            angles[1] += rot[1]

            # compute x-y-z normal vectors of rotation
            n_y = np.cross(t, [1, 0, 0])
            n_y = n_y / norm(n_y)
            rot_normals[0, :] = np.array([1, 0, 0])
            rot_normals[1, :] = n_y
            rot_normals[2, :] = t

            # compute final rotation matrix
            rotation_matrix = np.matrix([[1., 0., 0.], [0., 1., 0.],
                                         [0., 0., 1.]])
            for n, ii in enumerate(self.rot_order):
                mat = np.matrix(RotMat(rot_normals[ii], angles[ii]))
                rotation_matrix = mat * rotation_matrix

            # apply rotation
            x_rot[:, i, :] = dotXC(rotation_matrix, points, rot_center)

        return x_rot
Exemple #7
0
class LoftedBladeSurface(Component):

    pf = VarTree(BladePlanformVT(), iotype="in")
    base_airfoils = List(iotype="in")
    blend_var = Array(iotype="in")
    chord_ni = Int(300, iotype="in")
    span_ni = Int(300, iotype="in")
    redistribute_flag = Bool(False, desc="redistribute points chordwise")
    x_chordwise = Array(iotype="in", desc="user specified chordwise distribution")

    interp_type = Enum("rthick", ("rthick", "s"), iotype="in")
    surface_spline = Str("akima", iotype="in", desc="Spline")

    rot_order = Array(
        np.array([2, 1, 0]),
        iotype="in",
        desc="rotation order of airfoil sections" "default z,y,x (twist,sweep,dihedral)",
    )

    surfout = VarTree(BladeSurfaceVT(), iotype="out")
    surfnorot = VarTree(BladeSurfaceVT(), iotype="out")

    def execute(self):

        self.interpolator = BlendAirfoilShapes()
        self.interpolator.ni = self.chord_ni
        self.interpolator.spline = self.surface_spline
        self.interpolator.blend_var = self.blend_var
        self.interpolator.airfoil_list = self.base_airfoils
        self.interpolator.initialize()

        self.span_ni = self.pf.s.shape[0]
        x = np.zeros((self.chord_ni, self.span_ni, 3))

        for i in range(self.span_ni):

            s = self.pf.s[i]
            pos_x = self.pf.x[i]
            pos_y = self.pf.y[i]
            pos_z = self.pf.z[i]
            chord = self.pf.chord[i]
            p_le = self.pf.p_le[i]

            # generate the blended airfoil shape
            if self.interp_type == "rthick":
                rthick = self.pf.rthick[i]
                points = self.interpolator(rthick)
            else:
                points = self.interpolator(s)

            points = self.redistribute(points, pos_z)

            points *= chord
            points[:, 0] -= chord * p_le

            # x-coordinate needs to be inverted for clockwise rotating blades
            x[:, i, :] = np.array([-points[:, 0], points[:, 1], x.shape[0] * [pos_z]]).T

        # save blade without sweep and prebend
        x_norm = x.copy()

        # add translation and rotation
        x[:, :, 0] += self.pf.x
        x[:, :, 1] += self.pf.y
        x = self.rotate(x)

        self.surfnorot.surface = x_norm
        self.surfout.surface = x

    def rotate(self, x):
        """
        rotate blade sections accounting for twist and main axis orientation
        
        the blade will be built with a "sheared" layout, ie no rotation around y
        in the case of sweep.
        if the main axis includes a winglet, the blade sections will be
        rotated accordingly. ensure that an adequate point distribution is
        used in this case to avoid sections colliding in the winglet junction!
        """

        main_axis = Curve(points=np.array([self.pf.x, self.pf.y, self.pf.z]).T)

        rot_normals = np.zeros((3, 3))
        x_rot = np.zeros(x.shape)

        for i in range(x.shape[1]):
            points = x[:, i, :]
            rot_center = main_axis.points[i]
            # rotation angles read from file
            angles = np.array([self.pf.rot_x[i], self.pf.rot_y[i], self.pf.rot_z[i]]) * np.pi / 180.0

            # compute rotation angles of main_axis
            t = main_axis.dp[i]
            rot = np.zeros(3)
            rot[0] = -np.arctan(t[1] / (t[2] + 1.0e-20))
            v = np.array([t[2], t[1]])
            vt = np.dot(v, v) ** 0.5
            rot[1] = np.arcsin(t[0] / vt)
            angles[0] += rot[0]
            angles[1] += rot[1]

            # compute x-y-z normal vectors of rotation
            n_y = np.cross(t, [1, 0, 0])
            n_y = n_y / norm(n_y)
            rot_normals[0, :] = np.array([1, 0, 0])
            rot_normals[1, :] = n_y
            rot_normals[2, :] = t

            # compute final rotation matrix
            rotation_matrix = np.matrix([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])
            for n, ii in enumerate(self.rot_order):
                mat = np.matrix(RotMat(rot_normals[ii], angles[ii]))
                rotation_matrix = mat * rotation_matrix

            # apply rotation
            x_rot[:, i, :] = dotXC(rotation_matrix, points, rot_center)

        return x_rot

    def redistribute(self, points, pos_z):

        if self.redistribute_flag == False:
            return points

        airfoil = AirfoilShape(points=points)
        try:
            dist_LE = np.interp(pos_z, self.dist_LE[:, 0], self.dist_LE[:, 1])
        except:
            dist_LE = None
        # pass airfoil to user defined routine to allow for additional configuration
        airfoil = self.set_airfoil(airfoil, pos_z)
        if self.x_chordwise.shape[0] > 0:
            airfoil = airfoil.redistribute_chordwise(self.x_chordwise)
        else:
            airfoil = airfoil.redistribute(ni=self.chord_ni, dLE=dist_LE)

        return airfoil.points

    def set_airfoil(self, airfoil, pos_z):

        if hasattr(self, "gf_height"):
            height = self.gf_height(pos_z)
            length_factor = self.gf_length_factor(pos_z)
            print "gf", pos_z, height, length_factor
            if height > 0.0:
                airfoil = airfoil.gurneyflap(height, length_factor)

        return airfoil

    def add_gurney_flap(self, s, gf_heights, gf_length_factor):
        """spline the gurney flap height and length factor curves"""

        self.gf_height = pchip(s, gf_heights)
        self.gf_length_factor = pchip(s, gf_length_factor)
Exemple #8
0
class LoftedBladeSurface(Component):

    pf = VarTree(BladePlanformVT(), iotype='in')
    base_airfoils = List(iotype='in')
    blend_var = Array(iotype='in')
    chord_ni = Int(300, iotype='in')
    span_ni = Int(300, iotype='in')

    interp_type = Enum('rthick', ('rthick', 's'), iotype='in')
    surface_spline = Str('akima', iotype='in', desc='Spline')

    rot_order = Array(np.array([2,1,0]),iotype='in',desc='rotation order of airfoil sections'
                                                         'default z,y,x (twist,sweep,dihedral)')

    surfout = VarTree(BladeSurfaceVT(), iotype='out')
    surfnorot = VarTree(BladeSurfaceVT(), iotype='out')

    def execute(self):

        self.interpolator = BlendAirfoilShapes()
        self.interpolator.ni = self.chord_ni
        self.interpolator.spline = self.surface_spline
        self.interpolator.blend_var = self.blend_var
        self.interpolator.airfoil_list = self.base_airfoils
        self.interpolator.initialize()

        self.span_ni = self.pf.s.shape[0]
        x = np.zeros((self.chord_ni, self.span_ni, 3))

        for i in range(self.span_ni):

            s = self.pf.s[i]
            pos_x = self.pf.x[i]
            pos_y = self.pf.y[i]
            pos_z = self.pf.z[i]
            chord = self.pf.chord[i]
            p_le = self.pf.p_le[i]

            # generate the blended airfoil shape
            if self.interp_type == 'rthick':
                rthick = self.pf.rthick[i]
                points = self.interpolator(rthick)
            else:
                points = self.interpolator(s)

            points *= chord
            points[:, 0] += pos_x - chord * p_le

            # x-coordinate needs to be inverted for clockwise rotating blades
            x[:, i, :] = (np.array([-points[:,0], points[:,1], x.shape[0] * [pos_z]]).T)

        # save non-rotated blade (only really applicable for straight blades)
        x_norm = x.copy()
        x[:, :, 1] += self.pf.y
        x = self.rotate(x)

        self.surfnorot.surface = x_norm
        self.surfout.surface = x

    def rotate(self, x):
        """
        rotate blade sections accounting for twist and main axis orientation
        
        the blade will be built with a "sheared" layout, ie no rotation around y
        in the case of sweep.
        if the main axis includes a winglet, the blade sections will be
        rotated accordingly. ensure that an adequate point distribution is
        used in this case to avoid sections colliding in the winglet junction!
        """

        main_axis = Curve(points=np.array([self.pf.x, self.pf.y, self.pf.z]).T)

        rot_normals = np.zeros((3,3))
        x_rot = np.zeros(x.shape)

        for i in range(x.shape[1]):
            points = x[:, i, :]
            rot_center = main_axis.points[i]
            # rotation angles read from file
            angles = np.array([self.pf.rot_x[i],
                               self.pf.rot_y[i], 
                               self.pf.rot_z[i]]) * np.pi / 180.

            # compute rotation angles of main_axis
            t = main_axis.dp[i]
            rot = np.zeros(3)
            rot[0] = -np.arctan(t[1]/(t[2]+1.e-20))
            v = np.array([t[2], t[1]])
            vt = np.dot(v, v)**0.5
            rot[1] = (np.arcsin(t[0]/vt))
            angles[0] += rot[0]
            angles[1] += rot[1]

            # compute x-y-z normal vectors of rotation
            n_y = np.cross(t, [1,0,0])
            n_y = n_y/norm(n_y)
            rot_normals[0, :] = np.array([1,0,0])
            rot_normals[1, :] = n_y
            rot_normals[2, :] = t

            # compute final rotation matrix
            rotation_matrix = np.matrix([[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]])
            for n, ii in enumerate(self.rot_order):
                mat = np.matrix(RotMat(rot_normals[ii], angles[ii]))
                rotation_matrix = mat * rotation_matrix

            # apply rotation
            x_rot[:, i, :] = dotXC(rotation_matrix, points, rot_center)

        return x_rot