def _compute_s(self): """ compute normalized curve length """ s = calculate_length(self.points) self.length = s[-1] self.s = s / s[-1]
def _compute_s(self): """ compute normalized curve length """ s = calculate_length(self._to_array()) self.smax = s[-1] self.s = s/s[-1]
def _compute_s(self): """ compute normalized curve length """ s = calculate_length(self._to_array()) self.smax = s[-1] self.s = s / s[-1]
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]
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
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]
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
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]
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)
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 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
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)
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]
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;
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()
def execute(self): s = calculate_length(np.array([self.x, self.y, self.z]).T) self.smax = s[-1]
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]
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]