def collect_aero_validity_outputs(options, base_aerodynamic_quantities, outputs): kite = base_aerodynamic_quantities['kite'] ua = base_aerodynamic_quantities['air_velocity'] kite_dcm = base_aerodynamic_quantities['kite_dcm'] if 'aero_validity' not in list(outputs.keys()): outputs['aero_validity'] = {} tightness = options['model_bounds']['aero_validity']['scaling'] airspeed_ref = options['model_bounds']['aero_validity']['airspeed_ref'] if 'aerodynamics' not in list(outputs.keys()): outputs['aerodynamics'] = {} ehat1 = kite_dcm[:, 0] # chordwise, from leading edge to trailing edge ehat2 = kite_dcm[:, 1] # spanwise, from positive edge to negative edge ehat3 = kite_dcm[:, 2] # up alpha = get_alpha(ua, kite_dcm) beta = get_beta(ua, kite_dcm) alpha_min = options['aero']['alpha_min_deg'] * np.pi / 180.0 alpha_max = options['aero']['alpha_max_deg'] * np.pi / 180.0 beta_min = options['aero']['beta_min_deg'] * np.pi / 180.0 beta_max = options['aero']['beta_max_deg'] * np.pi / 180.0 alpha_ub_unscaled = (cas.mtimes(ua.T, ehat3) - cas.mtimes(ua.T, ehat1) * alpha_max) alpha_lb_unscaled = (-cas.mtimes(ua.T, ehat3) + cas.mtimes(ua.T, ehat1) * alpha_min) beta_ub_unscaled = (cas.mtimes(ua.T, ehat2) - cas.mtimes(ua.T, ehat1) * beta_max) beta_lb_unscaled = (-cas.mtimes(ua.T, ehat2) + cas.mtimes(ua.T, ehat1) * beta_min) alpha_ub = alpha_ub_unscaled * tightness / airspeed_ref / vect_op.smooth_abs( alpha_max) alpha_lb = alpha_lb_unscaled * tightness / airspeed_ref / vect_op.smooth_abs( alpha_min) beta_ub = beta_ub_unscaled * tightness / airspeed_ref / vect_op.smooth_abs( beta_max) beta_lb = beta_lb_unscaled * tightness / airspeed_ref / vect_op.smooth_abs( beta_min) outputs['aero_validity']['alpha_ub' + str(kite)] = alpha_ub outputs['aero_validity']['alpha_lb' + str(kite)] = alpha_lb outputs['aero_validity']['beta_ub' + str(kite)] = beta_ub outputs['aero_validity']['beta_lb' + str(kite)] = beta_lb outputs['aerodynamics']['alpha' + str(kite)] = alpha outputs['aerodynamics']['beta' + str(kite)] = beta outputs['aerodynamics']['alpha_deg' + str(kite)] = alpha * 180. / np.pi outputs['aerodynamics']['beta_deg' + str(kite)] = beta * 180. / np.pi return outputs
def approximate_tip_radius(model_options, variables, kite, architecture, tip, parameters): b_ref = parameters['theta0', 'geometry', 'b_ref'] half_span_proj = b_ref / 2. parent = architecture.parent_map[kite] radial_vector = get_kite_radial_vector(model_options, kite, variables, architecture, parameters) if int(model_options['kite_dof']) == 6: r_column = variables['xd']['r' + str(kite) + str(parent)] r = cas.reshape(r_column, (3, 3)) ehat2 = r[:, 1] # spanwise, from pe to ne ehat2_proj_radial = vect_op.smooth_abs( cas.mtimes(radial_vector.T, ehat2)) half_span_proj = b_ref * ehat2_proj_radial / 2. radius = get_kite_radius(model_options, kite, variables, architecture, parameters) tip_radius = radius if ('int' in tip) or (tip == 0): tip_radius = tip_radius - half_span_proj elif ('ext' in tip) or (tip == 1): tip_radius = tip_radius + half_span_proj else: raise Exception('invalid tip designated') return tip_radius
def get_axi_new_residual(model_options, variables, parent, parameters, wind): a_var = flow.get_a_var(model_options, variables, parent) ct_var = coeff.get_ct_var(model_options, variables, parent) dbar_varrho_var = geom.get_dbar_varrho_var(variables, parent) df_var = flow.get_df_var(variables, parent) dct_var = coeff.get_dct_var(variables, parent) abs_dvarrho = vect_op.smooth_abs(dbar_varrho_var) t_star = geom.get_tstar_ref(parameters, wind) c1 = 4.837e-2 c2 = 5.582e-2 c3 = 8.730e-2 c4 = 7.255e-1 c5 = 1.065 c6 = 1.404e-1 c7 = 1.821e-1 p2 = df_var * t_star * c1 \ + abs_dvarrho * t_star * c2 \ + abs_dvarrho * df_var * t_star**2. * c3 \ + dct_var * t_star * c4 \ + dct_var * df_var * t_star**2. * c5\ + dct_var * abs_dvarrho * t_star**2. * c6 \ + dct_var * abs_dvarrho * df_var * t_star**3. * c7 resi = (2. * a_var + 1. + 2. * p2) ^ 2 - 1. + ct_var return resi
def get_speed(model, u_ref, z_ref, z0_air, exp_ref, zz): # approximates the maximum of (zz vs. 0) z_cropped = vect_op.smooth_abs(zz, epsilon=z0_air) if model == 'log_wind': # mathematically: it doesn't make a difference what the base of # these logarithms is, as long as they have the same base. # but, the values will be smaller in base 10 (since we're describing # altitude differences), which makes convergence nicer. # u = u_ref * np.log10(zz / z0_air) / np.log10(z_ref / z0_air) u = u_ref * np.log10(z_cropped / z0_air) / np.log10(z_ref / z0_air) elif model == 'power': # u = u_ref * (zz / z_ref) ** exp_ref u = u_ref * (z_cropped / z_ref) ** exp_ref elif model == 'uniform': u = u_ref else: raise ValueError('unsupported atmospheric option chosen: %s', model) return u
def get_trajectory_binormal(variables, kite, parent): tangent = get_trajectory_tangent(variables, kite, parent) normal = get_trajectory_normal(variables, kite, parent) binormal = vect_op.smooth_normed_cross(tangent, normal) forwards_orientation = binormal[0] / vect_op.smooth_abs(binormal[0]) forwards_binormal = forwards_orientation * binormal return forwards_binormal
def get_beta(ua, r): ehat1 = r[:, 0] # chordwise, from le to te ehat2 = r[:, 1] # spanwise, from pe to ne ehat3 = r[:, 2] # up y_component = cas.mtimes(ua.T, ehat2) x_component = vect_op.smooth_abs(cas.mtimes(ua.T, ehat1)) # x component had better be positive beta = y_component / x_component return beta
def get_beta(ua, r): ehat1 = r[:, 0] # chordwise, from le to te ehat2 = r[:, 1] # spanwise, from pe to ne ehat3 = r[:, 2] # up y_component = cas.mtimes(ua.T, ehat2) x_component = vect_op.smooth_abs(cas.mtimes(ua.T, ehat1)) # x component had better be positive # the small angle approximation of: # beta = cas.arctan(y_component / x_component) beta = y_component / x_component return beta