Esempio n. 1
0
def make_terminal_battery_integrand(options, variables, parameters, model):

    nu = parameters['phi','nu']
    broken_kite = options['compromised_landing']['emergency_scenario'][1]
    broken_kite_parent = model.architecture.parent_map[broken_kite]
    surface = options['compromised_landing']['kite']['flap_length']*options['compromised_landing']['kite']['flap_width']
    moment_arm = options['compromised_landing']['kite']['flap_length']/2.
    q_z = variables['xd','q' + str(broken_kite) + str(broken_kite_parent),2]
    dq = variables['xd','dq' + str(broken_kite) + str(broken_kite_parent)]
    C_L = variables['xd','coeff' + str(broken_kite) + str(broken_kite_parent),0]
    Phi = variables['xd','coeff' + str(broken_kite) + str(broken_kite_parent),1]
    dC_L = variables['u','dcoeff' + str(broken_kite) + str(broken_kite_parent),0]
    dPhi = variables['u','dcoeff' + str(broken_kite) + str(broken_kite_parent),1]

    density = model.atmos.get_density(q_z)
    dynamic_pressure = 0.5*cas.mtimes(dq.T,dq)*density
    c_dl = options['compromised_landing']['aero']['c_dl']
    c_dphi = options['compromised_landing']['aero']['c_dphi']
    deflection_lift_0 = options['compromised_landing']['aero']['defl_lift_0']
    deflection_roll_0 = options['compromised_landing']['aero']['defl_roll_0']
    deflection_lift = deflection_lift_0 + c_dl*C_L
    deflection_roll = deflection_roll_0 + c_dphi*Phi
    ddeflection_lift = c_dl*dC_L
    ddeflection_roll = c_dphi*dPhi
    lift_moment = dynamic_pressure*surface*moment_arm*cas.sin(deflection_lift)
    roll_moment = dynamic_pressure*surface*moment_arm*cas.sin(deflection_roll)

    terminal_battery_integrand = -(lift_moment*ddeflection_lift + roll_moment*ddeflection_roll + options['compromised_landing']['battery']['power_controller'] + options['compromised_landing']['battery']['power_electronics'])*(1. - nu)

    return terminal_battery_integrand
Esempio n. 2
0
def get_kite_only_segment_forces(atmos, outputs, variables, upper_node,
                                 architecture, cd_tether_fun):

    force_lower = cas.DM.zeros((3, 1))
    force_upper = cas.DM.zeros((3, 1))

    if upper_node in architecture.kite_nodes:

        kite = upper_node

        ehat_1 = outputs['aerodynamics']['ehat_chord' + str(kite)]
        ehat_3 = outputs['aerodynamics']['ehat_span' + str(kite)]
        alpha = outputs['aerodynamics']['alpha' + str(kite)]
        d_hat = cas.cos(alpha) * ehat_1 + cas.sin(alpha) * ehat_3

        kite_dyn_pressure = outputs['aerodynamics']['dyn_pressure' + str(kite)]
        q_upper, q_lower, dq_upper, dq_lower = element.get_upper_and_lower_pos_and_vel(
            variables, upper_node, architecture)
        length = vect_op.norm(q_upper - q_lower)
        diam = element.get_element_diameter(variables, upper_node,
                                            architecture)

        air_velocity = outputs['aerodynamics']['air_velocity' + str(kite)]
        re_number = reynolds.get_reynolds_number(atmos, air_velocity, diam,
                                                 q_upper, q_lower)
        cd_tether = cd_tether_fun(re_number)

        d_mag = (1. / 4.) * cd_tether * kite_dyn_pressure * diam * length

        force_upper = d_mag * d_hat

    return force_lower, force_upper
Esempio n. 3
0
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
Esempio n. 4
0
def get_outputs(options, atmos, wind, variables, outputs, parameters,
                architecture):
    parent_map = architecture.parent_map
    kite_nodes = architecture.kite_nodes

    xd = variables['xd']

    elevation_angle = indicators.get_elevation_angle(xd)

    for n in kite_nodes:

        parent = parent_map[n]

        # get relevant variables for kite n
        q = xd['q' + str(n) + str(parent)]
        dq = xd['dq' + str(n) + str(parent)]
        coeff = xd['coeff' + str(n) + str(parent)]

        # wind parameters
        rho_infty = atmos.get_density(q[2])
        uw_infty = wind.get_velocity(q[2])

        # apparent air velocity
        if options['induction_model'] == 'actuator':
            ua = actuator_disk_flow.get_kite_effective_velocity(
                options, variables, wind, n, parent, architecture)
        else:
            ua = uw_infty - dq

        # relative air speed
        ua_norm = vect_op.smooth_norm(ua, epsilon=1e-8)
        # ua_norm = mtimes(ua.T, ua) ** 0.5

        # in kite body:
        if parent > 0:
            grandparent = parent_map[parent]
            qparent = xd['q' + str(parent) + str(grandparent)]
        else:
            qparent = np.array([0., 0., 0.])

        ehat_r = (q - qparent) / vect_op.norm(q - qparent)
        ehat_t = vect_op.normed_cross(ua, ehat_r)
        ehat_s = vect_op.normed_cross(ehat_t, ua)

        # roll angle
        psi = coeff[1]

        ehat_l = cas.cos(psi) * ehat_s + cas.sin(psi) * ehat_t
        ehat_span = cas.cos(psi) * ehat_t - cas.sin(psi) * ehat_s
        ehat_chord = ua / ua_norm

        # implicit direct cosine matrix (for plotting only)
        r = cas.horzcat(ehat_chord, ehat_span, ehat_l)

        # lift and drag coefficients
        CL = coeff[0]
        CD = parameters['theta0', 'aero', 'CD0'] + 0.02 * CL**2

        # lift and drag force
        f_lift = CL * 1. / 2. * rho_infty * cas.mtimes(
            ua.T, ua) * parameters['theta0', 'geometry', 's_ref'] * ehat_l
        f_drag = CD * 1. / 2. * rho_infty * ua_norm * parameters['theta0',
                                                                 'geometry',
                                                                 's_ref'] * ua
        f_side = cas.DM(np.zeros((3, 1)))

        f_aero = f_lift + f_drag
        m_aero = cas.DM(np.zeros((3, 1)))

        CA = CD
        CN = CL
        CY = cas.DM(0.)

        aero_coefficients = {}
        aero_coefficients['CD'] = CD
        aero_coefficients['CL'] = CL
        aero_coefficients['CA'] = CA
        aero_coefficients['CN'] = CN
        aero_coefficients['CY'] = CY

        outputs = indicators.collect_kite_aerodynamics_outputs(
            options, atmos, ua, ua_norm, aero_coefficients, f_aero, f_lift,
            f_drag, f_side, m_aero, ehat_chord, ehat_span, r, q, n, outputs,
            parameters)
        outputs = indicators.collect_environmental_outputs(
            atmos, wind, q, n, outputs)
        outputs = indicators.collect_aero_validity_outputs(
            options, xd, ua, n, parent, outputs, parameters)
        outputs = indicators.collect_local_performance_outputs(
            options, atmos, wind, variables, CL, CD, elevation_angle, ua, n,
            parent, outputs, parameters)
        outputs = indicators.collect_power_balance_outputs(
            variables, n, outputs, architecture)

    return outputs