예제 #1
0
파일: frames.py 프로젝트: mg-meth/awebox
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
예제 #2
0
파일: frames.py 프로젝트: mg-meth/awebox
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
예제 #3
0
파일: tools.py 프로젝트: wuyou33/awebox
def draw_kite_fuselage(ax, q, r, length, kite_color, side, num_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 * num_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

        basic_shell = get_naca_shell(length, naca) * (1 - (2. * y)**2.)

        horizontal_shell = []
        for idx in range(basic_shell[:, 0].shape[0]):

            new_point = q + yloc + np.array(cas.mtimes(r_dcm, basic_shell[idx, :].T))

            horizontal_shell = cas.vertcat(horizontal_shell, new_point.T)
        horizontal_shell = np.array(horizontal_shell)

        make_side_plot(ax, horizontal_shell, side, kite_color)
예제 #4
0
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
예제 #5
0
파일: tools.py 프로젝트: mg-meth/awebox
def draw_lifting_surface(ax,
                         q,
                         r,
                         b_ref,
                         c_tipn,
                         c_root,
                         c_tipp,
                         kite_color,
                         side,
                         body_cross_sections_per_meter,
                         naca="0012"):

    r_dcm = np.array(cas.reshape(r, (3, 3)))

    num_spanwise = np.ceil(b_ref * body_cross_sections_per_meter / 2.)

    ypos = np.arange(-1. * num_spanwise, num_spanwise + 1.) / num_spanwise / 2.

    leading_edges = []
    trailing_edges = []

    for y in ypos:

        yloc = cas.mtimes(r_dcm, vect_op.yhat_np()) * y * b_ref

        s = np.abs(y) / 0.5  # 1 at tips and 0 at root
        if y < 0:
            c_local = c_root * (1. - s) + c_tipn * s
        else:
            c_local = c_root * (1. - s) + c_tipp * s

        basic_shell = get_naca_shell(c_local, naca)

        basic_leading_ege = basic_shell[np.argmin(basic_shell[:, 0]), :]
        basic_trailing_ege = basic_shell[np.argmax(basic_shell[:, 0]), :]

        new_leading_edge = q + yloc + np.array(
            cas.mtimes(r_dcm, basic_leading_ege.T))
        new_trailing_edge = q + yloc + np.array(
            cas.mtimes(r_dcm, basic_trailing_ege.T))

        leading_edges = cas.vertcat(leading_edges, new_leading_edge.T)
        trailing_edges = cas.vertcat(trailing_edges, new_trailing_edge.T)

        horizontal_shell = []
        for idx in range(basic_shell[:, 0].shape[0]):

            new_point = q + yloc + np.array(
                cas.mtimes(r_dcm, basic_shell[idx, :].T))

            horizontal_shell = cas.vertcat(horizontal_shell, new_point.T)
        horizontal_shell = np.array(horizontal_shell)

        make_side_plot(ax, horizontal_shell, side, kite_color)

    make_side_plot(ax, leading_edges, side, kite_color)
    make_side_plot(ax, trailing_edges, side, kite_color)

    return None
예제 #6
0
파일: frames.py 프로젝트: mg-meth/awebox
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
예제 #7
0
파일: tools.py 프로젝트: mg-meth/awebox
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
예제 #8
0
파일: tools.py 프로젝트: mg-meth/awebox
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
예제 #9
0
def get_windings(nlp_options, model, V, outputs={}):

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

    nk = nlp_options['n_k']

    parent_map = model.architecture.parent_map
    kite_nodes = model.architecture.kite_nodes

    ehat_tether_x = 0.
    ehat_tether_y = 0.
    ehat_tether_z = 0.
    total_steps = float(nk)

    # TODO: in case of collocation, include collocation node info weighted with quad_weights
    # TODO: weight with time constant in case of phase fixing!
    for kdx in range(nk):
        local_ehat = vect_op.normalize(V['xd', kdx, 'q10'])
        ehat_tether_x += local_ehat[0] / total_steps
        ehat_tether_y += local_ehat[1] / total_steps
        ehat_tether_z += local_ehat[2] / total_steps

    ehat_tether = vect_op.normalize(
        cas.vertcat(ehat_tether_x, ehat_tether_y, ehat_tether_z))

    outputs['winding']['ehat_tether'] = ehat_tether

    ehat_side_a = vect_op.normed_cross(vect_op.yhat_np(), ehat_tether)
    # right handed coordinate system -> x/re: _a, y/im: _b, z/out: _tether
    ehat_side_b = vect_op.normed_cross(ehat_tether, ehat_side_a)

    # now project the path onto this plane
    for n in kite_nodes:
        parent = parent_map[n]

        theta_start = 0.
        theta_end = 0.

        # find the origin of the plane
        origin = np.zeros((3, 1))
        for kdx in range(nk):
            q = V['xd', kdx, 'q' + str(n) + str(parent)]
            q_in_plane = q - vect_op.dot(q, ehat_tether) * ehat_tether

            origin = origin + q_in_plane / total_steps

        # recenter the plane about origin
        for kdx in range(nk):
            q = V['xd', kdx, 'q' + str(n) + str(parent)]
            q_in_plane = q - vect_op.dot(q, ehat_tether) * ehat_tether
            q_recentered = q_in_plane - origin

            q_next = V['xd', kdx + 1, 'q' + str(n) + str(parent)]
            q_next_in_plane = q_next - vect_op.dot(q_next,
                                                   ehat_tether) * ehat_tether
            q_next_recentered = q_next_in_plane - origin

            delta_q = q_next_recentered - q_recentered

            x = vect_op.dot(q_recentered, ehat_side_a)
            y = vect_op.dot(q_recentered, ehat_side_b)
            r_squared = x**2. + y**2.

            dx = vect_op.dot(delta_q, ehat_side_a)
            dy = vect_op.dot(delta_q, ehat_side_b)

            # dx = vect_op.dot(dq_in_plane, ehat_side_a)
            # dy = vect_op.dot(dq_in_plane, ehat_side_b)

            dtheta = (x * dy - y * dx) / (r_squared + 1.0e-4)
            theta_end += dtheta

        winding = (theta_end - theta_start) / 2. / np.pi
        outputs['winding']['winding' + str(n)] = winding

    return outputs
예제 #10
0
파일: frames.py 프로젝트: mg-meth/awebox
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
예제 #11
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
예제 #12
0
def test(gamma_scale=1.):

    architecture = archi.Architecture({1: 0})

    options = {}
    options['induction'] = {}
    options['induction']['vortex_gamma_scale'] = gamma_scale
    options['induction']['vortex_wake_nodes'] = 2
    options['induction']['vortex_far_convection_time'] = 1.
    options['induction']['vortex_u_ref'] = 1.
    options['induction']['vortex_position_scale'] = 1.

    kite = architecture.kite_nodes[0]

    xd_struct = cas.struct([
        cas.entry("wx_" + str(kite) + "_ext_0", shape=(3, 1)),
        cas.entry("wx_" + str(kite) + "_ext_1", shape=(3, 1)),
        cas.entry("wx_" + str(kite) + "_int_0", shape=(3, 1)),
        cas.entry("wx_" + str(kite) + "_int_1", shape=(3, 1))
    ])
    xl_struct = cas.struct([cas.entry("wg_" + str(kite) + "_0")])
    var_struct = cas.struct_symSX(
        [cas.entry('xd', struct=xd_struct),
         cas.entry('xl', struct=xl_struct)])

    variables = var_struct(0.)
    variables['xd', 'wx_' + str(kite) + '_ext_0'] = 0.5 * vect_op.yhat_np()
    variables['xd', 'wx_' + str(kite) + '_int_0'] = -0.5 * vect_op.yhat_np()
    variables['xd', 'wx_' + str(kite) +
              '_ext_1'] = variables['xd', 'wx_' + str(kite) +
                                    '_ext_0'] + vect_op.xhat_np()
    variables['xd', 'wx_' + str(kite) +
              '_int_1'] = variables['xd', 'wx_' + str(kite) +
                                    '_int_0'] + vect_op.xhat_np()
    variables['xl', 'wg_' + str(kite) + '_0'] = 1. / gamma_scale

    test_list = get_list(options, variables, architecture)

    filaments = test_list.shape[1]

    filament_count_test = filaments - 6
    if not (filament_count_test == 0):
        message = 'filament list does not work as expected. difference in number of filaments in test_list = ' + str(
            filament_count_test)
        awelogger.logger.error(message)
        raise Exception(message)

    LE_expected = cas.DM(np.array([0., -0.5, 0., 0., 0.5, 0., 1.]))
    PE_expected = cas.DM(np.array([0., 0.5, 0., 1., 0.5, 0., 1.]))
    TE_expected = cas.DM(np.array([1., -0.5, 0., 0., -0.5, 0., 1.]))

    expected_filaments = {
        'leading edge': LE_expected,
        'positive edge': PE_expected,
        'trailing edge': TE_expected
    }

    for type in expected_filaments.keys():
        expected_filament = expected_filaments[type]
        expected_in_list = expected_filament_in_list(test_list,
                                                     expected_filament)
        if not expected_in_list:
            message = 'filament list does not work as expected. ' + type + \
                      ' test filament not in test_list.'
            awelogger.logger.error(message)

            with np.printoptions(precision=3, suppress=True):
                print('test_list:')
                print(np.array(test_list))

            raise Exception(message)

    NE_not_expected = cas.DM(np.array([1., -0.5, 0., 1., 0.5, 0., -1.]))
    not_expected_filaments = {'negative edge': NE_not_expected}

    for type in not_expected_filaments.keys():
        not_expected_filament = not_expected_filaments[type]
        is_reasonable = not (expected_filament_in_list(test_list,
                                                       not_expected_filament))
        if not is_reasonable:
            message = 'filament list does not work as expected. ' + type + \
                      ' test filament in test_list.'
            awelogger.logger.error(message)

            with np.printoptions(precision=3, suppress=True):
                print('test_list:')
                print(np.array(test_list))

            raise Exception(message)

    return test_list