def get_naca_shell(chord, naca="0012", center_at_quarter_chord = True): m = np.float(naca[0]) / 100. p = np.float(naca[1]) / 10. t = np.float(naca[2:]) / 100. s_list = np.arange(0., 101.) / 100. x_upper = [] x_lower = [] for s in s_list: [xu, xl, yu, yl] = get_naca_airfoil_coordinates(s, m, p, t) new_x_upper = xu * vect_op.xhat_np() + yu * vect_op.zhat_np() new_x_lower = xl * vect_op.xhat_np() + yl * vect_op.zhat_np() if center_at_quarter_chord: new_x_upper = new_x_upper - vect_op.xhat_np() / 4. new_x_lower = new_x_lower - vect_op.xhat_np() / 4. x_upper = cas.vertcat(x_upper, (chord * new_x_upper.T)) x_lower = cas.vertcat(x_lower, (chord * new_x_lower.T)) x_upper = np.array(x_upper) x_lower = np.array(x_lower)[::-1] x = np.array(cas.vertcat(x_lower, x_upper)) return x
def get_aero_test_values(t, options): h_0 = options['aero_test']['h_0'] phi_0 = options['aero_test']['phi_0'] omega = options['aero_test']['omega'] h = h_0 * np.sin(omega * t) dh = h_0 * np.cos(omega * t) * omega dh = -1. * h_0 * np.sin(omega * t) * omega**2. phi = phi_0 * np.cos(omega * t) dphi = -1. * phi_0 * np.sin(omega * t) * omega ddphi = -1. * phi_0 * np.cos(omega * t) * omega**2. l_t = h + 3. dl_t = dh q10 = l_t * vect_op.zhat_np() dq10 = dl_t * vect_op.zhat_np() ehat1 = np.cos(phi) * vect_op.xhat_np() - np.sin(phi) * vect_op.zhat_np() ehat2 = vect_op.yhat_np() ehat3 = np.cos(phi) * vect_op.zhat_np() + np.sin(phi) * vect_op.xhat_np() r_dcm = cas.horzcat(ehat1, ehat2, ehat3) r_dcm = cas.reshape(r_dcm, (9, 1)) omega = dphi * ehat2 return l_t, dl_t, q10, dq10, r_dcm, omega
def test_horizontal(): name = 'horizontal' xhat = vect_op.xhat_np() yhat = vect_op.yhat_np() zhat = vect_op.zhat_np() ehat_x = vect_op.xhat_np() ehat_y = vect_op.yhat_np() ehat_z = vect_op.zhat_np() q_upper = 5. * xhat q_lower = 2. * xhat dir = 'x' transformed = from_earth_to_body(xhat, q_upper, q_lower) reference = ehat_z diff = transformed - reference resi = cas.mtimes(diff.T, diff) epsilon = 1.e-12 if resi > epsilon: awelogger.logger.error('tether frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'y' transformed = from_earth_to_body(yhat, q_upper, q_lower) reference = ehat_y diff = transformed - reference resi = cas.mtimes(diff.T, diff) epsilon = 1.e-12 if resi > epsilon: awelogger.logger.error('tether frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'z' transformed = from_earth_to_body(zhat, q_upper, q_lower) reference = -1. * ehat_x diff = transformed - reference resi = cas.mtimes(diff.T, diff) epsilon = 1.e-12 if resi > epsilon: awelogger.logger.error('tether frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) return None
def test_transform_from_body(): xhat = vect_op.xhat_np() yhat = vect_op.yhat_np() zhat = vect_op.zhat_np() qx_test = np.random.random() * 1000. qy_test = np.random.random() * 1000. qz_test = np.random.random() * 1000. q_upper = qx_test * xhat + qy_test * yhat + qz_test * zhat q_lower = q_upper / 2. x_test = np.random.random() * 100. y_test = np.random.random() * 100. z_test = np.random.random() * 100. test_vec = x_test * xhat + y_test * yhat + z_test * zhat test_mag = vect_op.norm(test_vec) trans_vec = from_body_to_earth(test_vec, q_upper, q_lower) trans_mag = vect_op.norm(trans_vec) norm_error = vect_op.norm(trans_mag - test_mag) reformed_vec = from_earth_to_body(trans_vec, q_upper, q_lower) vector_diff = reformed_vec - test_vec vector_error = cas.mtimes(vector_diff.T, vector_diff) tot_error = norm_error + vector_error epsilon = 1.e-12 if tot_error > epsilon: awelogger.logger.error( 'tether frame transformation test gives error of size: ' + str(tot_error)) return None
def test_level_body_wind(epsilon): name = 'level wind' kite_dcm = cas.DM.eye(3) # CA = CD, CY = CS, CN = CL alpha = 0. beta = 0. u_test = get_test_wind(alpha, beta, kite_dcm) dir = 'x body->wind' test = vect_op.xhat_np() reference = vect_op.xhat_np() transformed = from_body_to_wind(u_test, kite_dcm, test) diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'y body->wind' test = vect_op.yhat_np() reference = vect_op.yhat_np() transformed = from_body_to_wind(u_test, kite_dcm, test) diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'z body->wind' test = vect_op.zhat_np() reference = vect_op.zhat_np() transformed = from_body_to_wind(u_test, kite_dcm, test) diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) return None
def get_rotor_reference_frame(init_options): n_rot_hat = get_ehat_tether(init_options) n_hat_is_x_hat = vect_op.abs( vect_op.norm(n_rot_hat - vect_op.xhat_np())) < 1.e-4 if n_hat_is_x_hat: y_rot_hat = vect_op.yhat_np() z_rot_hat = vect_op.zhat_np() else: u_hat = vect_op.xhat_np() z_rot_hat = vect_op.normed_cross(u_hat, n_rot_hat) y_rot_hat = vect_op.normed_cross(z_rot_hat, n_rot_hat) return n_rot_hat, y_rot_hat, z_rot_hat
def draw_kite_fuselage(ax, q, r, length, kite_color, side, body_cross_sections_per_meter, naca="0006"): r_dcm = np.array(cas.reshape(r, (3, 3))) total_width = np.float(naca[2:]) / 100. * length num_spanwise = np.ceil(total_width * body_cross_sections_per_meter / 2.) ypos = np.arange(-1. * num_spanwise, num_spanwise + 1.) / num_spanwise / 2. for y in ypos: yloc = cas.mtimes(r_dcm, vect_op.yhat_np()) * y * total_width zloc = cas.mtimes(r_dcm, vect_op.zhat_np()) * y * total_width basic_shell = get_naca_shell(length, naca) * (1 - (2. * y)**2.) span_direction_shell = [] up_direction_shell = [] for idx in range(basic_shell[:, 0].shape[0]): new_point_spanwise = q + yloc + np.array( cas.mtimes(r_dcm, basic_shell[idx, :].T)) span_direction_shell = cas.vertcat(span_direction_shell, new_point_spanwise.T) new_point_upwise = q + zloc + np.array( cas.mtimes(r_dcm, basic_shell[idx, :].T)) up_direction_shell = cas.vertcat(up_direction_shell, new_point_upwise.T) span_direction_shell = np.array(span_direction_shell) make_side_plot(ax, span_direction_shell, side, kite_color) up_direction_shell = np.array(up_direction_shell) make_side_plot(ax, up_direction_shell, side, kite_color) return None
def test_vertical_body_earth(epsilon): name = 'vertical' xhat = vect_op.xhat_np() yhat = vect_op.yhat_np() zhat = vect_op.zhat_np() ehat1_k = vect_op.xhat_np() ehat2_k = vect_op.yhat_np() ehat3_k = vect_op.zhat_np() ehat_chord = -1. * zhat ehat_span = -1. * xhat ehat_up = yhat kite_dcm = cas.horzcat(ehat_chord, ehat_span, ehat_up) dir = 'chord body->earth' transformed = from_body_to_earth(kite_dcm, ehat1_k) reference = ehat_chord diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'span body->earth' transformed = from_body_to_earth(kite_dcm, ehat2_k) reference = ehat_span diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'up body->earth' transformed = from_body_to_earth(kite_dcm, ehat3_k) reference = ehat_up diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'chord earth->body' transformed = from_earth_to_body(kite_dcm, ehat_chord) reference = ehat1_k diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'span earth->body' transformed = from_earth_to_body(kite_dcm, ehat_span) reference = ehat2_k diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) dir = 'up earth->body' transformed = from_earth_to_body(kite_dcm, ehat_up) reference = ehat3_k diff = transformed - reference resi = cas.mtimes(diff.T, diff) if resi > epsilon: awelogger.logger.error( 'kite frame transformation test (' + name + ' ' + dir + ') gives error of size: ' + str(resi)) return None
def compute_vortex_verification_points(plot_dict, cosmetics, idx_at_eval, kdx): kite_plane_induction_params = get_kite_plane_induction_params( plot_dict, idx_at_eval) architecture = plot_dict['architecture'] filament_list = reconstruct_filament_list(plot_dict, idx_at_eval) number_of_kites = architecture.number_of_kites radius = kite_plane_induction_params['average_radius'] center = kite_plane_induction_params['center'] u_infty = kite_plane_induction_params['u_infty'] u_zero = u_infty verification_points = plot_dict['options']['model']['aero']['vortex'][ 'verification_points'] half_points = int(verification_points / 2.) + 1 psi0_base = plot_dict['options']['solver']['initialization']['psi0_rad'] mu_grid_min = kite_plane_induction_params['mu_start_by_path'] mu_grid_max = kite_plane_induction_params['mu_end_by_path'] psi_grid_min = psi0_base - np.pi / float(number_of_kites) + float( kdx) * 2. * np.pi / float(number_of_kites) psi_grid_max = psi0_base + np.pi / float(number_of_kites) + float( kdx) * 2. * np.pi / float(number_of_kites) # define mu with respect to kite mid-span radius mu_grid_points = np.linspace(mu_grid_min, mu_grid_max, verification_points, endpoint=True) length_mu = mu_grid_points.shape[0] beta = np.linspace(0., np.pi / 2, half_points) cos_front = 0.5 * (1. - np.cos(beta)) cos_back = -1. * cos_front[::-1] psi_grid_unscaled = cas.vertcat(cos_back, cos_front) + 0.5 psi_grid_points_cas = psi_grid_unscaled * (psi_grid_max - psi_grid_min) + psi_grid_min psi_grid_points_np = np.array(psi_grid_points_cas) psi_grid_points_recenter = np.deg2rad(np.rad2deg(psi_grid_points_np)) psi_grid_points = np.unique(psi_grid_points_recenter) length_psi = psi_grid_points.shape[0] # reserve mesh space y_matr = np.ones((length_psi, length_mu)) z_matr = np.ones((length_psi, length_mu)) a_matr = np.ones((length_psi, length_mu)) for mdx in range(length_mu): mu_val = mu_grid_points[mdx] for pdx in range(length_psi): psi_val = psi_grid_points[pdx] r_val = mu_val * radius ehat_radial = vect_op.zhat_np() * cas.cos( psi_val) - vect_op.yhat_np() * cas.sin(psi_val) added = r_val * ehat_radial x_obs = center + added unscaled = mu_val * ehat_radial a_ind = float( vortex_flow.get_induction_factor_at_observer( plot_dict['options']['model'], filament_list, x_obs, u_zero, n_hat=vect_op.xhat())) unscaled_y_val = float(cas.mtimes(unscaled.T, vect_op.yhat_np())) unscaled_z_val = float(cas.mtimes(unscaled.T, vect_op.zhat_np())) y_matr[pdx, mdx] = unscaled_y_val z_matr[pdx, mdx] = unscaled_z_val a_matr[pdx, mdx] = a_ind y_list = np.array(cas.reshape(y_matr, (length_psi * length_mu, 1))) z_list = np.array(cas.reshape(z_matr, (length_psi * length_mu, 1))) return y_matr, z_matr, a_matr, y_list, z_list