예제 #1
0
 def _compute_s(self):
     """
     compute normalized curve length
     """
     s = calculate_length(self.points)
     self.length = s[-1]
     self.s = s / s[-1]
예제 #2
0
 def _compute_s(self):
     """
     compute normalized curve length
     """
     s = calculate_length(self._to_array())
     self.smax = s[-1]
     self.s = s/s[-1]
예제 #3
0
 def _compute_s(self):
     """
     compute normalized curve length
     """
     s = calculate_length(self._to_array())
     self.smax = s[-1]
     self.s = s / s[-1]
예제 #4
0
 def _compute_s(self):
     """
     compute normalized curve length
     """
     s = calculate_length(self.points)
     self.length = s[-1]
     self.ds = np.diff(s)
     self.s = s/s[-1]
예제 #5
0
def read_blade_planform(filename):
    """
    read a planform file with columns:

    |  s: normalized running length of blade
    |  x: x-coordinates of blade axis
    |  y: y-coordinates of blade axis
    |  z: z-coordinates of blade axis
    |  rot_x: x-rotation of blade axis
    |  rot_y: y-rotation of blade axis
    |  rot_z: z-rotation of blade axis
    |  chord: chord distribution
    |  rthick: relative thickness distribution
    |  p_le: pitch axis aft leading edge distribution
    |  dy: vertical offset of cross-section

    parameters
    ----------
    filename: str
        path to file containing planform data

    returns
    -------
    pf: dict
        dictionary containing planform data normalized
        to a span of 1.
    """

    data = np.loadtxt(filename)
    s = calculate_length(data[:, [0, 1, 2]])

    pf = {}
    pf['blade_length'] = data[-1, 2]
    pf['s'] = s / s[-1]
    pf['smax'] = s[-1]
    pf['x'] = data[:, 0] / data[-1, 2]
    pf['y'] = data[:, 1] / data[-1, 2]
    pf['z'] = data[:, 2] / data[-1, 2]
    pf['rot_x'] = data[:, 3]
    pf['rot_y'] = data[:, 4]
    pf['rot_z'] = data[:, 5]
    pf['chord'] = data[:, 6] / data[-1, 2]
    pf['rthick'] = data[:, 7]
    pf['rthick'] /= pf['rthick'].max()
    pf['athick'] = pf['rthick'] * pf['chord']
    pf['p_le'] = data[:, 8]
    try:
        pf['dy'] = data[:, 9]
    except:
        pf['dy'] = np.zeros(data.shape[0])

    return pf
예제 #6
0
    def solve_nonlinear(self, params, unknowns, resids):
        """
        aggregate results and integrate mass and mass moment using np.trapz.
        """
        for i in range(self.nsec):
            cname = 'cs_props%03d' % i
            cs = params[cname]
            unknowns['blade_beam_structure'][i, :] = cs

        # offset chordwise position of x_cg, x_sh, and to half chord
        unknowns['blade_beam_structure'][:, 2] += (
            0.5 -
            params['p_le_st']) * params['chord_st'] * params['blade_length']
        unknowns['blade_beam_structure'][:, 6] += (
            0.5 -
            params['p_le_st']) * params['chord_st'] * params['blade_length']
        unknowns['blade_beam_structure'][:, 17] += (
            0.5 -
            params['p_le_st']) * params['chord_st'] * params['blade_length']

        # compute mass and mass moment
        x = params['x_st'] * params['blade_length']
        y = params['y_st'] * params['blade_length']
        z = params['z_st'] * params['blade_length']
        hub_radius = params['hub_radius']
        s = calculate_length(np.array([x, y, z]).T)

        unknowns['blade_beam_structure'][:, 0] = s

        dm = unknowns['blade_beam_structure'][:, 1]
        g = 9.81

        # mass
        m = np.trapz(dm, s)
        unknowns['blade_mass'] = m

        # mass moment
        mm = np.trapz(g * dm * (z + hub_radius), s)
        unknowns['blade_mass_moment'] = mm

        print('blade mass %10.3f' % m)

        for i in range(self.nsec):
            cname = 'csprops_ref%03d' % i
            cs = params[cname]
            unknowns['blade_beam_csprops_ref'][i, :] = cs

        for i in range(self.nsec):
            unknowns['KStruct'][:, :, i] = params['k_matrix%03d' % i]
            unknowns['MStruct'][:, :, i] = params['m_matrix%03d' % i]
예제 #7
0
def read_blade_planform(filename):
    """
    read a planform file with columns:

    |  s: normalized running length of blade
    |  x: x-coordinates of blade axis
    |  y: y-coordinates of blade axis
    |  z: z-coordinates of blade axis
    |  rot_x: x-rotation of blade axis
    |  rot_y: y-rotation of blade axis
    |  rot_z: z-rotation of blade axis
    |  chord: chord distribution
    |  rthick: relative thickness distribution
    |  p_le: pitch axis aft leading edge distribution

    parameters
    ----------
    filename: str
        path to file containing planform data

    returns
    -------
    pf: dict
        dictionary containing planform data normalized
        to a span of 1.
    """

    data = np.loadtxt(filename)
    s = calculate_length(data[:, [0, 1, 2]])

    pf = {}
    pf['blade_length'] = data[-1, 2]
    pf['s'] = s / s[-1]
    pf['smax'] = s[-1]
    pf['x'] = data[:, 0] / data[-1, 2]
    pf['y'] = data[:, 1] / data[-1, 2]
    pf['z'] = data[:, 2] / data[-1, 2]
    pf['rot_x'] = data[:, 3]
    pf['rot_y'] = data[:, 4]
    pf['rot_z'] = data[:, 5]
    pf['chord'] = data[:, 6] / data[-1, 2]
    pf['rthick'] = data[:, 7]
    pf['rthick'] /= pf['rthick'].max()
    pf['athick'] = pf['rthick'] * pf['chord']
    pf['p_le'] = data[:, 8]

    return pf
예제 #8
0
def write_blade_planform(pf, filename):
    """
    write a planform file with columns:

    |  s: normalized running length of blade
    |  x: x-coordinates of blade axis
    |  y: y-coordinates of blade axis
    |  z: z-coordinates of blade axis
    |  rot_x: x-rotation of blade axis
    |  rot_y: y-rotation of blade axis
    |  rot_z: z-rotation of blade axis
    |  chord: chord distribution
    |  rthick: relative thickness distribution
    |  p_le: pitch axis aft leading edge distribution
    |  dy: vertical offset of cross-section

    parameters
    ----------
    pf: dict
        planform dictionary
    filename: str
        path to file containing planform data
    """

    data = np.zeros((pf['x'].shape[0], 10))
    s = calculate_length(data[:, [0, 1, 2]])

    names = [
        'x', 'y', 'z', 'rot_x', 'rot_y', 'rot_z', 'chord', 'rthick', 'p_le',
        'dy'
    ]
    for i, name in enumerate(names):
        try:
            data[:, i] = pf[name]
        except:
            print 'failed writing %s - assuming zeros' % name
            data[:, i] = np.zeros(s.shape[0])
    fid = open(filename, 'w')
    exp_prec = 15  # exponential precesion
    col_width = exp_prec + 10  # column width required for exp precision
    header_full = '#'
    header_full += ''.join([(hh + ' [%i]').center(col_width + 1) % i
                            for i, hh in enumerate(names)]) + '\n'
    fid.write(header_full)
    np.savetxt(fid, data)
    def solve_nonlinear(self, params, unknowns, resids):
        """
        aggregate results and integrate mass and mass moment using np.trapz.
        """
        for i in range(self.nsec):
            cname = 'cs_props%03d' % i
            cs = params[cname]
            unknowns['blade_beam_structure'][i, :] = cs

        # offset chordwise position of x_cg, x_sh, and to half chord
        unknowns['blade_beam_structure'][:, 2]  += (0.5 - params['p_le_st']) * params['chord_st'] * params['blade_length']
        unknowns['blade_beam_structure'][:, 6]  += (0.5 - params['p_le_st']) * params['chord_st'] * params['blade_length']
        unknowns['blade_beam_structure'][:, 17] += (0.5 - params['p_le_st']) * params['chord_st'] * params['blade_length']

        # compute mass and mass moment
        x = params['x_st'] * params['blade_length']
        y = params['y_st'] * params['blade_length']
        z = params['z_st'] * params['blade_length']
        hub_radius = params['hub_radius']
        s = calculate_length(np.array([x, y, z]).T)

        unknowns['blade_beam_structure'][:, 0] = s

        dm = unknowns['blade_beam_structure'][:, 1]
        g = 9.81

        # mass
        m = np.trapz(dm, s)
        unknowns['blade_mass'] = m

        # mass moment
        mm = np.trapz(g * dm * (z + hub_radius), s)
        unknowns['blade_mass_moment'] = mm

        print('blade mass %10.3f' % m)

        for i in range(self.nsec):
            cname = 'csprops_ref%03d' % i
            cs = params[cname]
            unknowns['blade_beam_csprops_ref'][i, :] = cs

        for i in range(self.nsec):
            unknowns['KStruct'][:,:,i] = params['k_matrix%03d' % i]
            unknowns['MStruct'][:,:,i] = params['m_matrix%03d' % i]
예제 #10
0
def get_recorded_planform(db, coordinate):

    data = db[coordinate]['Unknowns']
    pf = {}
    names = ['x', 'y', 'z', 'rot_x', 'rot_y', 'rot_z',
             'chord', 'rthick', 'p_le']
    for name in names:
        try:
            pf[name] = data[name]
        except:
            print '%s not found in database' % name
            pf[name] = np.zeros(data['x'].shape[0])

    s = calculate_length(np.array([pf['x'], pf['y'], pf['z']]).T)

    pf['blade_length'] = pf['z'][-1]
    pf['s'] = s / s[-1]
    pf['smax'] = s[-1]

    return pf
    def solve_nonlinear(self, params, unknowns, resids):
        """
        aggregate results and integrate mass and mass moment using np.trapz.
        """
        for i in range(self.nsec):
            cname = "cs_props%03d" % i
            cs = params[cname]
            unknowns["blade_beam_structure"][i, :] = cs

        # offset chordwise position of x_cg, x_sh, and to half chord
        unknowns["blade_beam_structure"][:, 2] += (
            (0.5 - params["p_le_st"]) * params["chord_st"] * params["blade_length"]
        )
        unknowns["blade_beam_structure"][:, 6] += (
            (0.5 - params["p_le_st"]) * params["chord_st"] * params["blade_length"]
        )
        unknowns["blade_beam_structure"][:, 17] += (
            (0.5 - params["p_le_st"]) * params["chord_st"] * params["blade_length"]
        )

        # compute mass and mass moment
        x = params["x_st"] * params["blade_length"]
        y = params["y_st"] * params["blade_length"]
        z = params["z_st"] * params["blade_length"]
        hub_radius = params["hub_radius"]
        s = calculate_length(np.array([x, y, z]).T)

        unknowns["blade_beam_structure"][:, 0] = s

        dm = unknowns["blade_beam_structure"][:, 1]
        g = 9.81

        # mass
        m = np.trapz(dm, s)
        unknowns["blade_mass"] = m

        # mass moment
        mm = np.trapz(g * dm * (z + hub_radius), s)
        unknowns["blade_mass_moment"] = mm

        print ("blade mass %10.3f" % m)
예제 #12
0
def get_recorded_planform(db, coordinate):

    data = db[coordinate]['Unknowns']
    pf = {}
    names = [
        'x', 'y', 'z', 'rot_x', 'rot_y', 'rot_z', 'chord', 'rthick', 'p_le'
    ]
    for name in names:
        try:
            pf[name] = data[name]
        except:
            print '%s not found in database' % name
            pf[name] = np.zeros(data['x'].shape[0])

    s = calculate_length(np.array([pf['x'], pf['y'], pf['z']]).T)

    pf['blade_length'] = pf['z'][-1]
    pf['s'] = s / s[-1]
    pf['smax'] = s[-1]

    return pf
예제 #13
0
def read_blade_planform(filename):

    data = np.loadtxt(filename)
    s = calculate_length(data[:, [0, 1, 2]])

    pf = BladePlanformVT()
    pf.blade_length = data[-1, 2]
    pf.s = s / s[-1]
    pf.x = data[:, 0] / data[-1, 2]
    pf.y = data[:, 1] / data[-1, 2]
    pf.z = data[:, 2] / data[-1, 2]
    pf.rot_x = data[:, 3]
    pf.rot_y = data[:, 4]
    pf.rot_z = data[:, 5]
    pf.chord = data[:, 6] / data[-1, 2]
    pf.rthick = data[:, 7]
    pf.rthick /= pf.rthick.max()
    pf.athick = pf.rthick * pf.chord
    pf.p_le = data[:, 8]

    return pf
예제 #14
0
def read_blade_planform(filename):

    data = np.loadtxt(filename)
    s = calculate_length(data[:, [0, 1, 2]])

    pf = BladePlanformVT()
    pf.blade_length = data[-1, 2]
    pf.s = s / s[-1]
    pf.x = data[:, 0] / data[-1, 2]
    pf.y = data[:, 1] / data[-1, 2]
    pf.z = data[:, 2] / data[-1, 2]
    pf.rot_x = data[:, 3]
    pf.rot_y = data[:, 4]
    pf.rot_z = data[:, 5]
    pf.chord = data[:, 6] / data[-1, 2]
    pf.rthick = data[:, 7]
    pf.rthick /= pf.rthick.max()
    pf.athick = pf.rthick * pf.chord
    pf.p_le = data[:, 8]

    return pf
예제 #15
0
def write_blade_planform(pf, filename):
    """
    write a planform file with columns:

    |  s: normalized running length of blade
    |  x: x-coordinates of blade axis
    |  y: y-coordinates of blade axis
    |  z: z-coordinates of blade axis
    |  rot_x: x-rotation of blade axis
    |  rot_y: y-rotation of blade axis
    |  rot_z: z-rotation of blade axis
    |  chord: chord distribution
    |  rthick: relative thickness distribution
    |  p_le: pitch axis aft leading edge distribution

    parameters
    ----------
    pf: dict
        planform dictionary
    filename: str
        path to file containing planform data
    """

    data = np.zeros((pf['x'].shape[0], 9))
    s = calculate_length(data[:, [0, 1, 2]])

    names = ['x', 'y', 'z', 'rot_x', 'rot_y', 'rot_z',
             'chord', 'rthick', 'p_le']
    for i, name in enumerate(names):
        data[:, i] = pf[name]
    fid = open(filename, 'w')
    exp_prec = 15             # exponential precesion
    col_width = exp_prec + 10  # column width required for exp precision
    header_full = '#'
    header_full += ''.join([(hh + ' [%i]').center(col_width + 1) % i
                           for i, hh in enumerate(names)]) + '\n'
    fid.write(header_full)
    np.savetxt(fid, data)
예제 #16
0
    def solve_nonlinear(self, params, unknowns, resids):

        s = calculate_length(np.array([params['x'],
                                       params['y'],
                                       params['z']]).T)
        unknowns['blade_curve_length'] = s[-1]
예제 #17
0
from BISDEM.lib.vartrees import WingPlanformVT

from openmdao.main.api import Component
from openmdao.lib.datatypes.api import Float, List, Slot, File, FileRef
from fusedwind.turbine.geometry_vt import BeamGeometryVT, BladePlanformVT
from fusedwind.lib.geom_tools import calculate_length

from os.path import expanduser
home = expanduser("~")

surface = WingSurface()
beam = BeamGeometryVT()
beam.x = np.array([0, 0.0, -0.05]);
beam.y = np.array([0, -0.01, -0.02]);
beam.z = np.array([0, 0.1, 0.2]);
beam.s = calculate_length(np.array([beam.x, beam.y, beam.z]).T)
beam.rot_x = [0, 0, 0];
beam.rot_y = [0, 0, 0];
beam.rot_z = [0, 0, 0];
surface.eqspar_geom  = [beam]

planform = WingPlanformVT();
planform.blade_length = .2;
planform.chord = [1, 1, 0.5];
planform.rthick = np.array([0.05, 0.05, 0.05]);
planform.p_le = [0.0, 0.0, 0.0];
surface.planform_in = [planform];

surface.airfoils = [home+'/git/BISDEM/data/ffaw3241.dat', home+'/git/BISDEM/data/ffaw3301.dat'];
surface.span_ni = 3;
예제 #18
0
파일: motion.py 프로젝트: sebasanper/BISDEM
    def createEquivalentBeam(self):
        """ 
        Takes the wing positions at every time step and creates an equivalent beam description 
        """
        
        # distance following the form of the wing
        r_OC = np.linspace(0.0, self.wdef.front.OC, np.round(self.n*self.wdef.front.OC/(self.wdef.front.OC+self.wdef.front.CD)))
        r_CD = np.linspace(0.0, self.wdef.front.CD, np.round(self.n*self.wdef.front.CD/(self.wdef.front.OC+self.wdef.front.CD))+1)
        
        # calculate vector from O to C and from C to D for angular step of the mechanism
        OCf_vec = (self.wpos.front.C-self.wpos.front.O).T
        CDf_vec = (self.wpos.front.D-self.wpos.front.C).T
        OCb_vec = (self.wpos.back.C-self.wpos.back.O).T
        CDb_vec = (self.wpos.back.D-self.wpos.back.C).T
        
        for ocf, cdf, ocb, cdb in zip(OCf_vec, CDf_vec, OCb_vec, CDb_vec):
            
            # make unit vectors
            ocf = ocf/np.linalg.norm(ocf)
            cdf = cdf/np.linalg.norm(cdf)
            
            ocb = ocb/np.linalg.norm(ocb)
            cdb = cdb/np.linalg.norm(cdb)
            
            # beam position
            beam_pos = np.array([[0.0, 0.0, 0.0]])
            for r in r_OC[1:]:
                beam_pos = np.vstack((beam_pos, [ocf*r]))
                # beam_pos[-1][2] = self.wpos.front.O[2][0]
            for r in r_CD[1:]:
                beam_pos = np.vstack((beam_pos, [beam_pos[len(r_OC)-1]+cdf*r]))
                # beam_pos[-1][2] = self.wpos.front.O[2][0]
            
            # put position into correct structure
            beam = BeamGeometryVT()
            beam.x = beam_pos.T[2]
            beam.y = beam_pos.T[1]
            beam.z = beam_pos.T[0]
            
            # print beam_pos.T[2]
            
            # beam twist
            beam_pos_back = np.array([[0.0, 0.0, self.wpos.back.O[2][0]]])
            
            z = np.array([0, 0, 1])
            x = np.array([ocf])
            for r in r_OC[1:]:
                beam_pos_back = np.vstack((beam_pos_back, [ocb*r]))
                # Assumption: no taper, no sweep
                beam_pos_back[-1][2] = self.wpos.back.O[2][0]
                #rot_x.append(np.rad2deg(np.arccos(np.dot(ocf, np.array([1, 0, 0]))/np.linalg.norm(ocf))))
                z = np.vstack((z, [0, 0, 1]))
                x = np.vstack((x, [ocf]))

            for r in r_CD[1:]:
                beam_pos_back = np.vstack((beam_pos_back, [beam_pos_back[len(r_OC)-1]+cdb*r]))
                # Assumption: no taper, no sweep
                # beam_pos_back[-1][2] = self.wpos.back.O[2][0]
                #rot_x.append(np.rad2deg(np.arccos(np.dot(cdf, np.array([1, 0, 0]))/np.linalg.norm(cdf))))
                z = np.vstack((z, [0, 0, 1]))
                x = np.vstack((x, [cdf]))

            y = np.cross(x, z)
            y = y/((y*y).sum(axis=1)**0.5)[:, np.newaxis]
            
            

            v = beam_pos-beam_pos_back
            v_y = (v*y).sum(axis=1)
            v_x = (v*x).sum(axis=1)
            v_z = (v*z).sum(axis=1)
            
            #v_z = beam_pos-beam_pos_back
            #v_z[:,1] = np.zeros(len(v_z))
            #v_z = v_z/((v_z*v_z).sum(axis=1)**0.5)[:,np.newaxis]
            
            beam.rot_x = np.zeros(len(beam_pos.T[0])) #np.array(rot_x)
            beam.rot_y = np.zeros(len(beam_pos.T[0])) #np.rad2deg(np.arctan((beam_pos.T[0]-beam_pos_back.T[0])/(beam_pos.T[2]-beam_pos_back.T[2])))
            beam.rot_z = -np.rad2deg(np.arctan(v_y/v_z)) #np.sign(v[:,1])*np.rad2deg(np.arccos((v*v_z).sum(axis=1)/(v*v).sum(axis=1)**0.5))   # np.rad2deg(np.arctan((beam_pos.T[1]-beam_pos_back.T[1])/(beam_pos.T[2]-beam_pos_back.T[2])))
            beam.s = calculate_length(np.array([beam.x, beam.y, beam.z]).T)
            
            if (len(self.wpos.eqspar_geom) == 0):
                print "v_y ", v_y
                print "v_z ", v_z
                print "rot_z ", beam.rot_z
            
            # beam speed
            if len(self.wpos.eqspar_geom)>0:
                beam_previous = self.wpos.eqspar_geom[-1]
                beam_previous.vel_x = (beam.x-beam_previous.x)/self.dt
                beam_previous.vel_y = (beam.y-beam_previous.y)/self.dt
                beam_previous.vel_z = (beam.z-beam_previous.z)/self.dt
                self.wpos.eqspar_geom[-1] = beam_previous
            
            self.wpos.eqspar_geom.append(beam)
        
        self.wpos.eqspar_geom.pop()
예제 #19
0
    def execute(self):

        s = calculate_length(np.array([self.x, self.y, self.z]).T)
        self.smax = s[-1]
예제 #20
0
    def solve_nonlinear(self, params, unknowns, resids):

        s = calculate_length(np.array([params["x"], params["y"], params["z"]]).T)
        unknowns["blade_curve_length"] = s[-1]
예제 #21
0
    def solve_nonlinear(self, params, unknowns, resids):

        s = calculate_length(
            np.array([params['x'], params['y'], params['z']]).T)
        unknowns['blade_curve_length'] = s[-1]