Exemple #1
0
def filament(seg_data, epsilon=1.e-2):

    try:
        point_obs = seg_data[:3]
        point_1 = seg_data[3:6]
        point_2 = seg_data[6:9]
        Gamma = seg_data[9]

        vec_1 = point_obs - point_1
        vec_2 = point_obs - point_2
        vec_0 = point_2 - point_1

        r1 = vect_op.smooth_norm(vec_1)
        r2 = vect_op.smooth_norm(vec_2)
        r0 = vect_op.smooth_norm(vec_0)

        factor = Gamma / (4. * np.pi)

        num = (r1 + r2)

        den_ori = (r1 * r2) * (r1 * r2 + cas.mtimes(vec_1.T, vec_2))
        den_reg = (epsilon * r0)**2.
        den = den_ori + den_reg

        dir = vect_op.cross(vec_1, vec_2)
        scale = factor * num / den

        sol = dir * scale
    except:
        message = 'something went wrong while computing the filament biot-savart induction. proceed with zero induced velocity from this filament.'
        awelogger.logger.error(message)
        raise Exception(message)

    return sol
Exemple #2
0
def get_f_val(model_options, wind, parent, variables, architecture):
    dl_t = variables['xd']['dl_t']
    u_infty = get_actuator_freestream_velocity(model_options, wind, parent,
                                               variables, architecture)
    f_val = dl_t / vect_op.smooth_norm(u_infty)

    return f_val
Exemple #3
0
def get_segment_force(diam, q_upper, q_lower, dq_upper, dq_lower, atmos, wind, cd_tether_fun):

    q_average = (q_upper + q_lower) / 2.
    zz = q_average[2]

    uw_average = wind.get_velocity(zz)
    density = atmos.get_density(zz)

    dq_average = (dq_upper + dq_lower) / 2.
    ua = uw_average - dq_average

    ua_norm = vect_op.smooth_norm(ua, 1e-6)
    ehat_ua = vect_op.smooth_normalize(ua, 1e-6)

    tether = q_upper - q_lower

    length = vect_op.norm(tether)
    length_parallel_to_wind = cas.mtimes(tether.T, ehat_ua)
    length_perp_to_wind = (length**2. - length_parallel_to_wind**2.)**0.5

    reynolds = get_reynolds_number(atmos, ua, diam, q_upper, q_lower)
    cd = cd_tether_fun(reynolds)

    drag = cd * 0.5 * density * ua_norm * diam * length_perp_to_wind * ua

    return drag
Exemple #4
0
def get_radius_of_curvature(variables, kite, parent):

    dq = variables['xd']['dq' + str(kite) + str(parent)]
    ddq = variables['xddot']['ddq' + str(kite) + str(parent)]

    gamma_dot = dq
    gamma_ddot = ddq

    # from frenet vectors + curvature definition
    # r = || gamma' || / (e1' cdot e2)
    # e1 = gamma' / || gamma' ||
    # e1' = ( gamma" || gamma' ||^2  - gamma' (gamma' cdot gamma") ) / || gamma' ||^3
    # e2 = ebar2 / || ebar2 ||
    # ebar2 = gamma" - (gamma' cdot gamma") gamma' / || gamma' ||^2
    # ....
    # r = || gamma' ||^4 // || gamma" || gamma' ||^2 - gamma' (gamma' cdot gamma") ||

    num = cas.mtimes(gamma_dot.T, gamma_dot)**2. + 1.0e-8

    den_vec = gamma_ddot * cas.mtimes(gamma_dot.T,
                                      gamma_dot) - gamma_dot * cas.mtimes(
                                          gamma_dot.T, gamma_ddot)
    den = vect_op.smooth_norm(den_vec)

    radius = num / den
    return radius
Exemple #5
0
def get_local_induced_velocity(model_options, variables, wind, parent, architecture):

    u_app = get_rotor_apparent_velocity(model_options, wind, parent, variables, architecture)
    nhat = geom.get_nhat_var(variables, parent)

    a_val = get_local_induction_factor(model_options, variables, parent)
    u_ind = -1. * a_val * vect_op.smooth_norm(u_app) * nhat

    return u_ind
Exemple #6
0
def get_df_val(model_options, wind, parent, variables, architecture):

    if 'ddl_t' in variables['xd'].keys():
        ddl_t = variables['xd']['ddl_t']
    else:
        ddl_t = variables['u']['ddl_t']

    u_infty = get_actuator_freestream_velocity(model_options, wind, parent,
                                               variables, architecture)
    df_val = ddl_t / vect_op.smooth_norm(u_infty)

    return df_val
Exemple #7
0
def get_nhat_residual(model_options, parent, variables, parameters, architecture):

    nhat_val = get_normal_axis(model_options, parent, variables, parameters, architecture)
    nhat_var = get_nhat_var(variables, parent)

    nvec_resi = nhat_var - nhat_val

    factor_resi = vect_op.smooth_norm(nhat_var) - 1.

    resi = cas.vertcat(nvec_resi, factor_resi)

    return resi
Exemple #8
0
def get_trivial_forces(model_options, variables, atmos, wind, n, parameters, architecture):

    [diam, q_upper, q_lower, dq_upper, dq_lower, ua_upper, ua_lower] = get_upper_lower_q_and_dq(model_options,
                                                                                                  variables, wind, n,architecture)

    length = vect_op.norm(q_upper - q_lower)
    q_average = 0.5 * (q_upper + q_lower)
    dq_average = 0.5 * (dq_upper + dq_lower)
    rho = atmos.get_density(q_average[2])

    u_a = wind.get_velocity(q_average[2]) - dq_average

    cd = parameters['theta0','tether','cd']
    drag_force = cd * 0.5 * rho * vect_op.smooth_norm(u_a, 1e-6) * u_a * diam * length

    force_upper = drag_force / 2.
    force_lower = drag_force / 2.

    return [force_lower, force_upper]
Exemple #9
0
def get_element_drag_and_moment_fun(wind, atmos, cd_tether_fun):

    info_sym = cas.SX.sym('info_sym', (16, 1))

    q_upper = info_sym[:3]
    q_lower = info_sym[3:6]
    dq_upper = info_sym[6:9]
    dq_lower = info_sym[9:12]
    diam = info_sym[12]
    q_seg_avg = info_sym[13:16]

    q_average = (q_upper + q_lower) / 2.
    zz = q_average[2]

    ua = get_uapp(q_upper, q_lower, dq_upper, dq_lower, wind)

    epsilon = 1.e-6

    ua_norm = vect_op.smooth_norm(ua, epsilon)
    ehat_ua = vect_op.smooth_normalize(ua, epsilon)

    tether = q_upper - q_lower

    length_sq = cas.mtimes(tether.T, tether)
    length_parallel_to_wind = cas.mtimes(tether.T, ehat_ua)
    length_perp_to_wind = vect_op.smooth_sqrt(
        length_sq - length_parallel_to_wind**2., epsilon)

    re_number = reynolds.get_reynolds_number(atmos, ua, diam, q_upper, q_lower)
    cd = cd_tether_fun(re_number)

    density = atmos.get_density(zz)
    drag = cd * 0.5 * density * ua_norm * diam * length_perp_to_wind * ua

    moment_arm = q_average - q_seg_avg
    moment = vect_op.cross(moment_arm, drag)

    element_drag_fun = cas.Function('element_drag_fun', [info_sym], [drag])
    element_moment_fun = cas.Function('element_moment_fun', [info_sym],
                                      [moment])

    return element_drag_fun, element_moment_fun
Exemple #10
0
def get_induction_factor_at_kite(options,
                                 filament_list,
                                 wind,
                                 variables,
                                 parameters,
                                 architecture,
                                 kite_obs,
                                 n_hat=vect_op.xhat()):

    x_obs = variables['xd']['q' + str(kite_obs) +
                            str(architecture.parent_map[kite_obs])]

    parent = architecture.parent_map[kite_obs]
    u_zero_vec = actuator_flow.get_uzero_vec(options, wind, parent, variables,
                                             parameters, architecture)
    u_zero = vect_op.smooth_norm(u_zero_vec)

    a_calc = get_induction_factor_at_observer(options,
                                              filament_list,
                                              x_obs,
                                              u_zero,
                                              n_hat=n_hat)

    return a_calc
Exemple #11
0
def get_mach(options, atmos, ua, q):
    norm_ua = vect_op.smooth_norm(ua)
    a = atmos.get_speed_of_sound( q[2])
    mach = norm_ua / a
    return mach
Exemple #12
0
def get_aerodynamic_outputs(options, atmos, wind, variables, outputs,
                            parameters, architecture):

    xd = variables['xd']

    b_ref = parameters['theta0', 'geometry', 'b_ref']
    c_ref = parameters['theta0', 'geometry', 'c_ref']
    s_ref = parameters['theta0', 'geometry', 's_ref']
    reference_lengths = cas.diag(cas.vertcat(b_ref, c_ref, b_ref))

    kite_nodes = architecture.kite_nodes
    for kite in kite_nodes:
        parent = architecture.parent_map[kite]

        q = xd['q' + str(kite) + str(parent)]
        dq = xd['dq' + str(kite) + str(parent)]

        vec_u_eff = tools.get_u_eff_in_earth_frame(options, variables, wind,
                                                   kite, architecture)
        u_eff = vect_op.smooth_norm(vec_u_eff)
        rho = atmos.get_density(q[2])
        q_eff = 0.5 * rho * cas.mtimes(vec_u_eff.T, vec_u_eff)

        if int(options['kite_dof']) == 3:
            kite_dcm = three_dof_kite.get_kite_dcm(options, variables, wind,
                                                   kite, architecture)
        elif int(options['kite_dof']) == 6:
            kite_dcm = six_dof_kite.get_kite_dcm(kite, variables, architecture)
        else:
            message = 'unsupported kite_dof chosen in options: ' + str(
                options['kite_dof'])
            awelogger.logger.error(message)

        if int(options['kite_dof']) == 3:
            framed_forces = tools.get_framed_forces(vec_u_eff, kite_dcm,
                                                    variables, kite,
                                                    architecture)
            m_aero_body = cas.DM.zeros((3, 1))
        elif int(options['kite_dof']) == 6:
            framed_forces = tools.get_framed_forces(vec_u_eff, kite_dcm,
                                                    variables, kite,
                                                    architecture)
            framed_moments = tools.get_framed_moments(vec_u_eff, kite_dcm,
                                                      variables, kite,
                                                      architecture)
            m_aero_body = framed_moments['body']
        else:
            message = 'unsupported kite_dof chosen in options: ' + str(
                options['kite_dof'])
            awelogger.logger.error(message)

        f_aero_body = framed_forces['body']
        f_aero_wind = framed_forces['wind']
        f_aero_control = framed_forces['control']
        f_aero_earth = framed_forces['earth']

        coeff_body = f_aero_body / q_eff / s_ref
        CA = coeff_body[0]
        CY = coeff_body[1]
        CN = coeff_body[2]

        f_drag_wind = f_aero_wind[0] * vect_op.xhat()
        f_side_wind = f_aero_wind[1] * vect_op.yhat()
        f_lift_wind = f_aero_wind[2] * vect_op.zhat()

        f_drag_earth = frames.from_wind_to_earth(vec_u_eff, kite_dcm,
                                                 f_drag_wind)
        f_side_earth = frames.from_wind_to_earth(vec_u_eff, kite_dcm,
                                                 f_side_wind)
        f_lift_earth = frames.from_wind_to_earth(vec_u_eff, kite_dcm,
                                                 f_lift_wind)

        coeff_wind = f_aero_wind / q_eff / s_ref
        CD = coeff_wind[0]
        CS = coeff_wind[1]
        CL = coeff_wind[2]

        CM = cas.mtimes(cas.inv(reference_lengths),
                        m_aero_body) / q_eff / s_ref
        Cl = CM[0]
        Cm = CM[1]
        Cn = CM[2]

        aero_coefficients = {}
        aero_coefficients['CD'] = CD
        aero_coefficients['CS'] = CS
        aero_coefficients['CL'] = CL
        aero_coefficients['CA'] = CA
        aero_coefficients['CY'] = CY
        aero_coefficients['CN'] = CN
        aero_coefficients['Cl'] = Cl
        aero_coefficients['Cm'] = Cm
        aero_coefficients['Cn'] = Cn
        aero_coefficients['LoverD'] = CL / CD

        base_aerodynamic_quantities = {}
        base_aerodynamic_quantities['kite'] = kite
        base_aerodynamic_quantities['air_velocity'] = vec_u_eff
        base_aerodynamic_quantities['airspeed'] = u_eff
        base_aerodynamic_quantities['aero_coefficients'] = aero_coefficients
        base_aerodynamic_quantities['f_aero_earth'] = f_aero_earth
        base_aerodynamic_quantities['f_aero_body'] = f_aero_body
        base_aerodynamic_quantities['f_aero_control'] = f_aero_control
        base_aerodynamic_quantities['f_aero_wind'] = f_aero_wind
        base_aerodynamic_quantities['f_lift_earth'] = f_lift_earth
        base_aerodynamic_quantities['f_drag_earth'] = f_drag_earth
        base_aerodynamic_quantities['f_side_earth'] = f_side_earth
        base_aerodynamic_quantities['m_aero_body'] = m_aero_body
        base_aerodynamic_quantities['kite_dcm'] = kite_dcm
        base_aerodynamic_quantities['q'] = q
        base_aerodynamic_quantities['dq'] = dq

        outputs = indicators.collect_kite_aerodynamics_outputs(
            options, architecture, atmos, wind, variables, parameters,
            base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_environmental_outputs(
            atmos, wind, base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_aero_validity_outputs(
            options, base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_local_performance_outputs(
            architecture, atmos, wind, variables, parameters,
            base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_power_balance_outputs(
            options, architecture, variables, base_aerodynamic_quantities,
            outputs)

    return outputs
Exemple #13
0
def collect_kite_aerodynamics_outputs(options, architecture, atmos, wind,
                                      variables, parameters,
                                      base_aerodynamic_quantities, outputs):

    if 'aerodynamics' not in list(outputs.keys()):
        outputs['aerodynamics'] = {}

    # unpack
    kite = base_aerodynamic_quantities['kite']
    air_velocity = base_aerodynamic_quantities['air_velocity']
    aero_coefficients = base_aerodynamic_quantities['aero_coefficients']
    f_aero_earth = base_aerodynamic_quantities['f_aero_earth']
    f_aero_body = base_aerodynamic_quantities['f_aero_body']

    f_aero_control = base_aerodynamic_quantities['f_aero_control']
    f_aero_wind = base_aerodynamic_quantities['f_aero_wind']
    f_lift_earth = base_aerodynamic_quantities['f_lift_earth']
    f_drag_earth = base_aerodynamic_quantities['f_drag_earth']
    f_side_earth = base_aerodynamic_quantities['f_side_earth']
    m_aero_body = base_aerodynamic_quantities['m_aero_body']
    kite_dcm = base_aerodynamic_quantities['kite_dcm']
    q = base_aerodynamic_quantities['q']

    f_lift_earth_overwrite = options['aero']['overwrite']['f_lift_earth']
    if f_lift_earth_overwrite is not None:
        f_lift_earth = f_lift_earth_overwrite

    for name in set(base_aerodynamic_quantities['aero_coefficients'].keys()):
        outputs['aerodynamics'][
            name +
            str(kite)] = base_aerodynamic_quantities['aero_coefficients'][name]

    outputs['aerodynamics']['air_velocity' + str(kite)] = air_velocity
    airspeed = vect_op.norm(air_velocity)
    outputs['aerodynamics']['airspeed' + str(kite)] = airspeed
    outputs['aerodynamics']['u_infty' + str(kite)] = wind.get_velocity(q[2])

    rho = atmos.get_density(q[2])
    outputs['aerodynamics']['air_density' + str(kite)] = rho
    outputs['aerodynamics']['dyn_pressure' +
                            str(kite)] = 0.5 * rho * cas.mtimes(
                                air_velocity.T, air_velocity)

    ehat_chord = kite_dcm[:, 0]
    ehat_span = kite_dcm[:, 1]
    ehat_up = kite_dcm[:, 2]

    outputs['aerodynamics']['ehat_chord' + str(kite)] = ehat_chord
    outputs['aerodynamics']['ehat_span' + str(kite)] = ehat_span
    outputs['aerodynamics']['ehat_up' + str(kite)] = ehat_up

    outputs['aerodynamics']['f_aero_body' + str(kite)] = f_aero_body
    outputs['aerodynamics']['f_aero_control' + str(kite)] = f_aero_control
    outputs['aerodynamics']['f_aero_earth' + str(kite)] = f_aero_earth
    outputs['aerodynamics']['f_aero_wind' + str(kite)] = f_aero_wind

    ortho = cas.reshape(cas.mtimes(kite_dcm.T, kite_dcm) - np.eye(3), (9, 1))
    ortho_resi = cas.mtimes(ortho.T, ortho)
    outputs['aerodynamics']['ortho_resi' + str(kite)] = ortho_resi

    conversion_resis = []
    conversion_targets = {
        'control': f_aero_control,
        'earth': f_aero_earth,
        'wind': f_aero_wind
    }
    for f_aero_target in conversion_targets.values():
        resi = 1. - vect_op.norm(f_aero_target) / vect_op.norm(f_aero_body)
        conversion_resis = cas.vertcat(conversion_resis, resi)

    resi = vect_op.norm(f_aero_earth - f_lift_earth - f_drag_earth -
                        f_side_earth) / vect_op.norm(f_aero_body)
    conversion_resis = cas.vertcat(conversion_resis, resi)

    outputs['aerodynamics']['check_conversion' + str(kite)] = conversion_resis

    outputs['aerodynamics']['f_lift_earth' + str(kite)] = f_lift_earth
    outputs['aerodynamics']['f_drag_earth' + str(kite)] = f_drag_earth
    outputs['aerodynamics']['f_side_earth' + str(kite)] = f_side_earth

    b_ref = parameters['theta0', 'geometry', 'b_ref']
    c_ref = parameters['theta0', 'geometry', 'c_ref']

    circulation_cross = vect_op.smooth_norm(
        f_lift_earth) / b_ref / rho / vect_op.smooth_norm(
            vect_op.cross(air_velocity, ehat_span))
    circulation_cl = 0.5 * airspeed**2. * aero_coefficients[
        'CL'] * c_ref / vect_op.smooth_norm(
            vect_op.cross(air_velocity, ehat_span))

    outputs['aerodynamics']['circulation_cross' +
                            str(kite)] = circulation_cross
    outputs['aerodynamics']['circulation_cl' + str(kite)] = circulation_cl
    outputs['aerodynamics']['circulation' + str(kite)] = circulation_cross

    outputs['aerodynamics']['wingtip_ext' +
                            str(kite)] = q + ehat_span * b_ref / 2.
    outputs['aerodynamics']['wingtip_int' +
                            str(kite)] = q - ehat_span * b_ref / 2.

    outputs['aerodynamics']['fstar_aero' + str(kite)] = cas.mtimes(
        air_velocity.T, ehat_chord) / c_ref

    outputs['aerodynamics']['r' + str(kite)] = kite_dcm.reshape((9, 1))

    if int(options['kite_dof']) == 6:
        outputs['aerodynamics']['m_aero_body' + str(kite)] = m_aero_body

    outputs['aerodynamics']['mach' + str(kite)] = get_mach(
        options, atmos, air_velocity, q)
    outputs['aerodynamics']['reynolds' + str(kite)] = get_reynolds(
        options, atmos, air_velocity, q, parameters)

    return outputs
Exemple #14
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