''' Created on 24/04/2014 @author: MMPE ''' from __future__ import print_function from __future__ import unicode_literals from __future__ import division from __future__ import absolute_import from io import open from builtins import range from builtins import int from future import standard_library standard_library.install_aliases() import numpy as np class StFile(object): """Read HAWC2 St (beam element structural data) file Methods are autogenerated for: - r : curved length distance from main_body node 1 [m] - m : mass per unit length [kg/m] - x_cg : xc2-coordinate from C1/2 to mass center [m] - y_cg : yc2-coordinate from C1/2 to mass center [m] - ri_x : radius of gyration related to elastic center. Corresponds to rotation about principal bending xe axis [m] - ri_y : radius of gyration related to elastic center. Corresponds to rotation about principal bending ye axis [m] - xs : xc2-coordinate from C1/2 to shear center [m]. The shear center is the point where external forces only contributes to pure bending and no torsion. - ys : yc2-coordinate from C1/2 to shear center [m]. The shear center is the point where external forces only contributes to pure bending and no torsion. - E : modulus of elasticity [N/m2] - G : shear modulus of elasticity [N/m2] - Ix : area moment of inertia with respect to principal bending xe axis [m4]. This is the principal bending axis most parallel to the xc2 axis - Iy : area moment of inertia with respect to principal bending ye axis [m4] - K : torsional stiffness constant with respect to ze axis at the shear center [m4/rad]. For a circular section only this is identical to the polar moment of inertia. - kx : shear factor for force in principal bending xe direction [-] - ky : shear factor for force in principal bending ye direction [-] - A : cross sectional area [m2] - pitch : structural pitch about z_c2 axis. This is the angle between the xc2 -axis defined with the c2_def command and the main principal bending axis xe. - xe : xc2-coordinate from C1/2 to center of elasticity [m]. The elastic center is the point where radial force (in the z-direction) does not contribute to bending around the x or y directions. - ye : yc2-coordinate from C1/2 to center of elasticity [m]. The elastic center is the point where radial force (in the The autogenerated methods have the following structure def xxx(radius=None, mset=1, set=1): Parameters: ----------- radius : int, float, array_like or None, optional Radius/radii of interest\n If int, float or array_like: values are interpolated to requested radius/radii If None (default): Values of all radii specified in st file returned mset : int, optional Main set number set : int, optional Sub set number Examples -------- >>> stfile = StFile(r"tests/test_files/DTU_10MW_RWT_Blade_st.dat") >>> print (stfile.m()) # Interpolated mass at radius 36 [ 1189.51054664 1191.64291781 1202.76694262 ... 15.42438683] >>> print (st.E(radius=36, mset=1, set=1)) # Elasticity interpolated to radius 36m 8722924514.652649 >>> print (st.E(radius=36, mset=1, set=2)) # Same for stiff blade set 8.722924514652648e+17 """ def __init__(self, filename): with open (filename) as fid: txt = fid.read() # Some files starts with first set ("#1...") with out specifying number of sets # no_maindata_sets = int(txt.strip()[0]) # assert no_maindata_sets == txt.count("#") self.main_data_sets = {} for mset in txt.split("#")[1:]: mset_nr = int(mset.strip().split()[0]) set_data_dict = {} for set_txt in mset.split("$")[1:]: set_lines = set_txt.split("\n") set_nr, no_rows = map(int, set_lines[0].split()[:2]) assert set_nr not in set_data_dict set_data_dict[set_nr] = np.array([set_lines[i].split() for i in range(1, no_rows + 1)], dtype=np.float) self.main_data_sets[mset_nr] = set_data_dict for i, name in enumerate("r m x_cg y_cg ri_x ri_y x_sh y_sh E G I_x I_y I_p k_x k_y A pitch x_e y_e".split()): setattr(self, name, lambda radius=None, mset=1, set=1, column=i: self._value(radius, column, mset, set)) def _value(self, radius, column, mset_nr=1, set_nr=1): st_data = self.main_data_sets[mset_nr][set_nr] if radius is None: radius = self.radius_st(None, mset_nr, set_nr) return np.interp(radius, st_data[:, 0], st_data[:, column]) def radius_st(self, radius=None, mset=1, set=1): r = self.main_data_sets[mset][set][:, 0] if radius is None: return r return r[np.argmin(np.abs(r - radius))] def to_str(self, mset=1, set=1): d = self.main_data_sets[mset][set] return "\n".join([("%12.5e "*d.shape[1]) % tuple(row) for row in d]) if __name__ == "__main__": import os st = StFile(os.path.dirname(__file__) + r"/tests/test_files/DTU_10MW_RWT_Blade_st.dat") print (st.m()) print (st.E(radius=36, mset=1, set=1)) # Elastic blade print (st.E(radius=36, mset=1, set=2)) # stiff blade #print (st.radius()) xyz = np.array([st.x_e(), st.y_e(), st.r()]).T[:40] n = 2 xyz = np.array([st.x_e(None, 1, n), st.y_e(None, 1, n), st.r(None, 1, n)]).T[:40] #print (xyz) print (np.sqrt(np.sum((xyz[1:] - xyz[:-1]) ** 2, 1)).sum()) print (xyz[-1, 2]) print (np.sqrt(np.sum((xyz[1:] - xyz[:-1]) ** 2, 1)).sum() - xyz[-1, 2]) print (st.x_e(67.8883), st.y_e(67.8883)) #print (np.sqrt(np.sum(np.diff(xyz, 0) ** 2, 1))) print (st.pitch(67.8883 - 0.01687)) print (st.pitch(23.2446)) #print (st.) #print (st.)