Beispiel #1
0
def test_data_types():
    """
    Test that input of different data types consistently produces same output

    See: https://github.com/aarondettmann/ambiance/issues/1
    """

    # ------------------------------
    # ----- Single value input -----
    # ------------------------------
    height = 11000
    entry = table_data.property_dict[height]

    h_types = [
        int(height),
        float(height),
        [int(height)],
        np.array(height, dtype=int),
        np.array(height, dtype=float),
    ]

    for h in h_types:
        print(repr(h))
        for prop_name, value in entry.items():
            computed = getattr(Atmosphere(h), prop_name)
            assert computed == approx(value, 1e-3)

    # -----------------------------------
    # ----- Vector-like value input -----
    # -----------------------------------
    heights = [11000, 20000, 75895]
    entries = [table_data.property_dict[height] for height in heights]

    exp_values = defaultdict(list)
    for entry in entries:
        for prop_name in table_data.PROPERTY_NAMES:
            exp_values[prop_name].append(entry[prop_name])

    h_types = [
        list(int(height) for height in heights),
        tuple(int(height) for height in heights),
        list(float(height) for height in heights),
        tuple(float(height) for height in heights),
        np.array(heights, dtype=int),
        np.array(heights, dtype=float),
    ]

    for h in h_types:
        print(repr(h))
        for prop_name, value in exp_values.items():
            computed = getattr(Atmosphere(h), prop_name)
            assert computed == approx(value, 1e-3)
Beispiel #2
0
def estol(fc_s, W, S, h, CLmax):

    sigma = Atmosphere(h).density[0] / Atmosphere(0).density[0]
    omega_resp, V_resp = [], []

    for i in fc_s:
        V_s = (2 * i * (W / S) /
               (Atmosphere(0).density[0] * sigma * CLmax))**(0.5)
        omega_s = 9.81 / V_s * np.sqrt(i**2 - 1)

        V_resp.append(V_s)
        omega_resp.append(omega_s)

    return V_resp, omega_resp
def calculate_cl(ref_area, alt, mach, mass, load_fact=1.05):
    """Function to calculate the lif coefficient (cl)

    Function 'calculate_cl' return the lift coefficient value for the given
    input (Reference Area, Altitude, Mach Number, Mass and Load Factor)

    Source:
       * Demonstration can be found in:
         /CEASIOMpy/lib/CLCalculator/doc/Calculate_CL.pdf

    Args:
        ref_area (float): Reference area [m^2]
        alt (float): Altitude [m]
        mach (float): Mach number [-]
        mass (float): Aircraft mass [kg]
        load_fact (float): Load Factor [-] (1.05 by default)

    Returns:
        target_cl (float): Lift coefficient [unit]
    """

    # Get atmosphere values at this altitude
    Atm = Atmosphere(alt)

    GAMMA = 1.401  # Air heat capacity ratio [-]

    # Calculate lift coefficient
    weight = mass * Atm.grav_accel[0]
    dyn_pres = 0.5 * GAMMA * Atm.pressure[0] * mach**2
    target_cl = weight * load_fact / (dyn_pres * ref_area)
    log.info(f"A lift coefficient (CL) of {target_cl} has been calculated")

    return target_cl
def init():
    global seaLevelTemperature, seaLevelPressure
    from ambiance import Atmosphere

    seaLevelAtmosphere = Atmosphere(0)
    seaLevelPressure = seaLevelAtmosphere.pressure[0]
    seaLevelTemperature = seaLevelAtmosphere.temperature[0]
Beispiel #5
0
def test_sealevel():
    """Test sealevel conditions"""

    sealevel = Atmosphere(0)

    # Geopotential and geometric height are equal
    assert sealevel.H == sealevel.h == 0

    # Table 1
    assert sealevel.temperature == 288.15
    assert sealevel.temperature_in_celsius == 15
    assert sealevel.pressure == 1.01325e5
    assert sealevel.density == approx(1.225)
    assert sealevel.grav_accel == 9.80665

    # Table 2
    assert sealevel.speed_of_sound == approx(340.294)
    assert sealevel.dynamic_viscosity == approx(1.7894e-5, 1e-4)
    assert sealevel.kinematic_viscosity == approx(1.4607e-5, 1e-4)
    assert sealevel.thermal_conductivity == approx(2.5343e-2, 1e-4)

    # Table 3
    assert sealevel.pressure_scale_height == approx(8434.5, 1e-4)
    assert sealevel.specific_weight == approx(1.2013e1, 1e-4)
    assert sealevel.number_density == approx(2.5471e25, 1e-4)
    assert sealevel.mean_particle_speed == approx(458.94, 1e-4)
    assert sealevel.collision_frequency == approx(6.9193e9, 1e-4)
    assert sealevel.mean_free_path == approx(6.6328e-8, 1e-4)
Beispiel #6
0
def drag(V, h, fc):
    ''' 
    Arrasto em curva coordenada.
    '''

    D_list = []
    rho = Atmosphere(h).density[0]
    drag_manobra.Mp = V / Atmosphere(h).speed_of_sound[0]

    for i in fc:
        drag_manobra.CLp = CL(i, V, h)
        CD = drag_manobra.polar()
        D = (1 / 2) * rho * (V**2) * jet.S * CD
        D_list.append(D)

    return D_list
Beispiel #7
0
def standard_atm(h):
    """Compute quantities from International Civil Aviation Organization (ICAO)
    which extends the US 1976 Standard Atmospheric Model to 80 km.

    :h: altitude
    :returns: h_geop, T_inf, p_inf, rho_inf, a_inf, nu_inf

    """
    h_meters = h.to('m').magnitude

    atm = Atmosphere(h_meters)  # output units in SI
    arr_len = len(atm.H)
    if arr_len == 1:
        h_geop = atm.H[0] * unit('m')
        T_inf = atm.temperature[0] * unit('K')
        p_inf = atm.pressure[0] * unit('Pa')
        rho_inf = atm.density[0] * unit('kg/m^3')
        a_inf = atm.speed_of_sound[0] * unit('m/s')
        nu_inf = atm.kinematic_viscosity[0] * unit('m^2/s')
    else:
        h_geop = atm.H * unit('m')
        T_inf = atm.temperature * unit('K')
        p_inf = atm.pressure * unit('Pa')
        rho_inf = atm.density * unit('kg/m^3')
        a_inf = atm.speed_of_sound * unit('m/s')
        nu_inf = atm.kinematic_viscosity * unit('m^2/s')

    return h_geop, T_inf, p_inf, rho_inf, a_inf, nu_inf
def cruise_range(cond, V1, h, c, zeta, W):
    '''
    OBS: Inutilizado! (remover antes de entregar)
    Parâmetros
    ----------
    cond : Tipo de voo de cruzeiro, especificando qual variável
    se manterá constante: Velocidade (V), h (altitude) ou CL;
    
    V1 : Velocidade de início; 
    
    h : Altitude de cruzeiro;
    
    c : Coeficiente de consumo;
    
    zeta : Razão W1/W2 dos pesos inicial e final. 

    Returns
    -------
    x : Alcance, em metros.

    '''
    drag_cru = DragPolar()
    rho = Atmosphere(h).density[0]

    CL_cru = (2 * W) / (rho * V1**2 * jet.S)
    drag_cru.CLp = CL_cru
    drag_cru.Mp = V1 / Atmosphere(h).speed_of_sound[0]
    CD1 = drag_cru.polar()

    E1 = CL_cru / CD1
    Em = 4 * drag_cru.K / drag_cru.CD0

    if (cond == 'h_CL'):

        x = (2 * V1 * E1) / c * (1 - np.sqrt(1 - zeta))

    elif (cond == 'V_CL'):

        x = E1 * V1 / c * np.log(1 / (1 - zeta))

    elif (cond == 'V_h'):

        x = (2 * V1 * Em) / c * np.arctan(
            E1 * zeta / (2 * Em * (1 - drag_cru.K * E1 * CL_cru * zeta)))

    return x
Beispiel #9
0
def test_set_height_after_instantiating():
    """Do not allow to set heights (h, H) after instantiating"""

    atmos = Atmosphere(0)

    attr_errors = [
        0,
        1.2,
        np.array([1, 2, 3]),
    ]

    for invalid_input in attr_errors:
        with pytest.raises(AttributeError):
            atmos.h = invalid_input

        with pytest.raises(AttributeError):
            atmos.H = invalid_input
Beispiel #10
0
def test_geom_geop_height_conversion():
    """Test conversion between geometric and geopotential height"""

    # Test different inputs
    inputs = [
        np.arange(-5e3, 80e3, 1e3),
        (-5e3, 80e3, 1e3),
        [-5e3, 80e3, 1e3],
        -5000,
    ]

    for in_data in inputs:
        geom_height_in = np.arange(-5e3, 80e3, 1e3)

        geop_height_out = Atmosphere.geom2geop_height(geom_height_in)
        geom_height_out = Atmosphere.geop2geom_height(geop_height_out)

        assert np.testing.assert_allclose(geom_height_out, geom_height_in) is None
Beispiel #11
0
    def check_phase(self, debug=False):
        """Check what phase of flight the rocket is in, e.g. on the rail, off the rail, or with the parachute open.
        Notes:
            - Since this only checks after each time step, there may be a very short period where the rocket is orientated as if it is still on the rail, when it shouldn't be.
            - For this reason, it may look like the rocket leaves the rail at an altitude greater than the rail length.
        Args:
            debug (bool, optional): If True, a message is printed when the rocket leaves the rail. Defaults to False.
        Returns:
            list: List of events that happened in this step, for the data log.
        """
        events = []

        # Rail check
        if self.on_rail == True:
            # Check how far we've travelled - remember that the 'l' coordinate system has its origin at alt=0.
            rocket_pos_l = pos_i2l(self.pos_i, self.launch_site, self.time)
            launch_site_pos_l = np.array([0.0, 0.0, self.launch_site.alt])

            flight_distance = np.linalg.norm(rocket_pos_l - launch_site_pos_l)

            # Check if we've left the rail yet
            if flight_distance >= self.launch_site.rail_length:
                self.on_rail = False
                events.append("Cleared rail")

                if debug == True:
                    alt = pos_i2alt(self.pos_i, self.time)
                    ambient_pressure = (Atmosphere(alt).pressure[0] *
                                        self.env_vars["pressure"])
                    thrust = (
                        self.motor.thrust(self.time) +
                        (self.motor.ambient_pressure - ambient_pressure) *
                        self.motor.exit_area)
                    weight = 9.81 * self.mass_model.mass(self.time)

                    print(
                        "Cleared rail at t={:.2f} s with alt={:.2f} m and TtW={:.2f}"
                        .format(self.time, alt, thrust / weight))

        # Parachute check
        if self.parachute_deployed == False:
            if self.alt_poll_watch < self.time - self.alt_poll_watch_interval:
                current_alt = pos_i2alt(self.pos_i, self.time)
                if self.alt_record > current_alt:
                    if debug == True:
                        print("Parachute deployed at {:.2f} km at {:.2f} s".
                              format(
                                  pos_i2alt(self.pos_i, self.time) / 1000,
                                  self.time))
                    events.append("Parachute deployed")
                    self.parachute_deployed = True
                    self.w_b = np.array([0, 0, 0])
                else:
                    self.alt_poll_watch = self.time
                    self.alt_record = current_alt
        return events
Beispiel #12
0
def test_table_data_single_value_input():
    """Test that data corresponds to tabularised data from 'Doc 7488/3'"""

    for h, entry in table_data.property_dict.items():
        print("="*80)
        print(f"Testing {h} m ...")
        for prop_name, value in entry.items():
            computed = float(getattr(Atmosphere(h), prop_name))
            # print(f"--> ({prop_name}) computed: {computed:.5e}")
            # print(f"--> ({prop_name}) expected: {value:.5e}")
            assert computed == approx(value, 1e-3)
Beispiel #13
0
def test_table_data_matrix_input():
    """
    Test that matrix can be passed as input (instead of single values)
    """

    # "Sorted" matrices
    heights, properties = table_data.get_matrices()
    atmos = Atmosphere(heights)

    for prop_name, exp_values in properties.items():
        computed_values = getattr(atmos, prop_name)
        assert np.testing.assert_allclose(
            computed_values, exp_values, rtol=1e-3) is None

    # Random matrices
    heights, properties = table_data.get_matrices(return_random=True)
    atmos = Atmosphere(heights)

    for prop_name, exp_values in properties.items():
        computed_values = getattr(atmos, prop_name)
        print(prop_name)
        print(computed_values)
        print()
        print(exp_values)
        print("--------------")
        assert np.testing.assert_allclose(
            computed_values, exp_values, rtol=1e-3) is None

    # "Differently shaped" matrices
    heights, properties = table_data.get_matrices(shape=(4, 5))
    atmos = Atmosphere(heights)

    for prop_name, exp_values in properties.items():
        computed_values = getattr(atmos, prop_name)
        print(prop_name)
        print(computed_values)
        print()
        print(exp_values)
        print("--------------")
        assert np.testing.assert_allclose(
            computed_values, exp_values, rtol=1e-3) is None
Beispiel #14
0
def test_table_data_vector_input():
    """Test that vector can be passed as input (instead of single values)"""

    # "Sorted" vectors
    heights, properties = table_data.get_vectors()
    atmos = Atmosphere(heights)

    for prop_name, exp_values in properties.items():
        computed_values = getattr(atmos, prop_name)
        # print(computed_values)
        # print(exp_values)
        assert np.testing.assert_allclose(computed_values, exp_values, rtol=1e-3) is None

    # Random vectors
    heights, properties = table_data.get_vectors(return_random=True)
    atmos = Atmosphere(heights)
    print(heights)

    for prop_name, exp_values in properties.items():
        computed_values = getattr(atmos, prop_name)
        assert np.testing.assert_allclose(computed_values, exp_values, rtol=1e-3) is None
Beispiel #15
0
def test_invalid_inputs():
    """Do not allow strange input"""

    with pytest.raises(TypeError):
        Atmosphere()

    type_errors = [
        None,
        dict,
        str,
    ]

    value_errors = [[], (), [[]], [1, [2, 3]]]

    for invalid_input in type_errors:
        with pytest.raises(TypeError):
            Atmosphere(invalid_input)

    for invalid_input in value_errors:
        with pytest.raises(ValueError):
            Atmosphere(invalid_input)
def payload_vs_range(c,POV,MTOW,max_payload,max_fuel, V1, h1):
    
    Mach = V1/Atmosphere(h1).speed_of_sound[0] 
    
    # Ponto A:
    '''
    A aeronave não possui combustível nesse ponto, não havendo variação de peso.
    '''
    W1_A = POV + max_payload
    W2_A = W1_A
    zeta_A = (W1_A - W2_A)/W1_A
    x_A = cruise_range('V_h', W1_A, c, zeta_A, V1, h1)
    
    # Ponto B:
    '''
    Nesse ponto, adiciona-se combustível até atingir-se o MTOW da aeronave.
    '''
    W1_B = MTOW
    W2_B = W1_B - (MTOW - (max_payload + POV))
    zeta_B = (W1_B - W2_B)/W1_B
    x_B = cruise_range('V_h',W1_B, c, zeta_B, V1, h1)
    
    # Ponto C:
    '''
    Nesse ponto, partiu-se com o máximo combustível permitido.
    '''
    W1_C = MTOW
    W2_C = W1_C - max_fuel
    zeta_C = (W1_C - W2_C)/W1_C
    x_C = cruise_range('V_h', W1_C, c, zeta_C, V1, h1)

    # Ponto D:
    '''
    Nesse ponto, partiu-se sem carga paga, com o máximo de combustível.
    '''
    W1_D = POV + max_fuel
    W2_D = POV 
    zeta_D = (W1_D - W2_D)/W1_D
    x_D = cruise_range('V_h',W1_D, c, zeta_D, V1, h1)    
    
    plt.figure()
    plt.ylabel("Payload [kg]", fontsize = 12)
    plt.xlabel("x [km]", fontsize = 12)
    plt.grid(False)
    plt.plot([x_A/1000,x_B/1000],[max_payload/9.81,max_payload/9.81],'-ok', linewidth = 3)
    plt.plot([x_B/1000, x_C/1000],[max_payload/9.81, (MTOW - (POV + max_fuel))/9.81],'-ok', linewidth = 3)
    plt.plot([x_C/1000, x_D/1000],[(MTOW - (POV + max_fuel))/9.81, 0],'-ok', linewidth = 3)
    plt.text(2000, 600,'M = {:.1f}\nh = {:.1f} km'.format(Mach,h1/1000))
    plt.savefig("carga_paga.svg")
    plt.show()
    
    return
    def add_forces(self, state, t):
        # Weight
        weight = -9.80665 * state.mass
        self._forces.append(weight)

        # Thrust
        thrust = self._motor.thrust_at(t)
        self._forces.append(thrust)

        # (Very) rough approximation of drag
        air_density = float(Atmosphere(state.pos).density)
        drag = 0.5 * self._frontal_area * air_density * -(state.vel**2.0) * self._drag_coefficient
        self._forces.append(drag)
Beispiel #18
0
def T(h, T0, n, fc):
    '''
    Empuxo em curva coordenada.
    '''

    T = []

    for i in fc:
        sigma = Atmosphere(h).density[0] / rho0
        Ti = T0 * (sigma**n)
        T.append(Ti)

    return T
Beispiel #19
0
def CL(fc, V, h):
    '''
    Coeficiente de sustentação em curva coordenada.

    Entradas:

    h: Altitude (inteiro)
    V: Velocidade (lista)
    
    '''
    rho = Atmosphere(h).density[0]
    CL = 2 * fc * jet.W / (rho * (V**2) * jet.S)
    return CL
Beispiel #20
0
def max_CL_cte(x, h1, h2, cond):

    rho = (Atmosphere(h1).density[0] + Atmosphere(h2).density[0]) / 2
    velo_som = (Atmosphere(h1).speed_of_sound[0] +
                Atmosphere(h2).speed_of_sound[0]) / 2

    # Variáveis desconhecidas:
    CD0 = x[0]
    k = x[1]
    V = x[2]

    drag_CL.Mp = V / velo_som
    drag_polar_CL = drag_CL.polar()

    if (cond.get('condicao') == 'max_range'):

        # CL de otimização do alcance:
        CL = np.sqrt(CD0 / k)

        # Equações do sistema:
        eq1 = (jet.W / (0.5 * CL * rho * jet.S))**.5 - V
        eq2 = drag_CL.CD0 - CD0
        eq3 = drag_CL.K - k

        return [eq1, eq2, eq3]

    elif (cond.get('condicao') == 'max_endurance'):

        # CL de otimização da autonomia:
        CL = np.sqrt(3 * CD0 / k)

        # Equações do sistema:
        eq1 = (jet.W / (0.5 * CL * rho * jet.S))**.5 - V
        eq2 = drag_CL.CD0 - CD0
        eq3 = drag_CL.K - k

        return [eq1, eq2, eq3]
Beispiel #21
0
        def compute_other_aero_quantities(self):

            # Compute cruise speed, based on altitude and Mach during cruise
            V_sound = Atmosphere(int(self.h_cruise)).speed_of_sound[0]
            # h_cruise must be in meters
            self.V_cruise = round(self.M_cruise * V_sound, 1)
            # m/s

            # Compute (L/D)_max
            self.L_D_max = round(
                0.5 * m.sqrt(m.pi * self.AR / (self.k * self.CD_0)), 2)

            # Compute load factor during loiter
            self.n_loiter = round(1 / m.cos(self.phi_loiter * 2 * m.pi / 360),
                                  4)
def total_drag(V, h):
    '''
    
    Parâmetros
    ----------
    V : Lista de velocidades definida em "MAIN".
    h : Lista de altitudes definida em "MAIN".

    Returns
    -------
    D_resp : Arrasto total em cruzeiro (lista)
    Dmin_resp : Arrasto mínimo em cruzeiro (lista)

    '''

    D_resp, Dmin_resp = [], []

    for i in h:
        sigma = Atmosphere(i).density[0] / rho0
        drag_object.Mp = V / Atmosphere(i).speed_of_sound[0]

        drag_polar = drag_object.polar()
        CD0 = drag_object.CD0
        K = drag_object.K

        Dp = (1 / 2) * sigma * rho0 * (V**2) * jet.S * CD0
        Di = (2 * K * (jet.W**2)) / (sigma * rho0 * jet.S * V**2)
        D_total = Dp + Di

        Emax = np.sqrt(CD0 / K) / (2 * CD0)
        Dmin = jet.W / Emax

        D_resp.append(D_total)
        Dmin_resp.append(Dmin)

    return D_resp, Dmin_resp
Beispiel #23
0
def h_dot_max_eq(x, h, S, W, T0, n):
    '''
    Montagem do sistema para calcular a velocidade
    de maxima razao de subida, dada uma altitude 'h'.

    Entradas:
    ---------

    h: Altitude (float)
    S: Area de asa (float)
    W: Peso da aeronave (float)
    T0, n: Parametros propulsivos (float)

    Saidas:
    -------

    eq: Sistema de equacoes a serem resolvidas
    '''

    CD0 = x[0]
    K = x[1]
    V = x[2]

    T = cr.jet_buoyancy(h, T0, n)[0]
    drag_asc.Mp = V/Atmosphere(h).speed_of_sound[0]
    drag_polar = drag_asc.polar()
    
    rho = Atmosphere(h).density[0]

    eq1 = drag_asc.CD0 - CD0
    eq2 = drag_asc.K - K
    eq3 = ((T/S)/(3*rho*CD0)*(1 + np.sqrt(1 + 12*CD0*K*(W/T)**2)))**(1/2) - V

    eq = [eq1, eq2, eq3]

    return eq
def estol(W, S, h, CLmax):


    V_s_resp = []

    if(type(h) == np.ndarray or type(h) == list):
        for i in h:
            sigma = Atmosphere(i).density[0]/Atmosphere(0).density[0]
            V_s = (2*(W/S)/(Atmosphere(0).density[0]*sigma*CLmax))**(0.5)
            V_s_resp.append(V_s)
        return V_s_resp

    else:
        sigma = Atmosphere(h).density[0]/Atmosphere(0).density[0]
        V_s = (2*(W/S)/(Atmosphere(0).density[0]*sigma*CLmax))**(0.5)
        
        return V_s

    sigma = Atmosphere(h).density[0]/Atmosphere(0).density[0]
    V_s = (2*(W/S)/(Atmosphere(0).density[0]*sigma*CLmax))**(0.5)

    return V_s
Beispiel #25
0
    def get_drag(self, altitude, speed, engine_on):
        if altitude >= 81020:
            return (0)
        atmosphere = Atmosphere(altitude)
        mach = speed / atmosphere.speed_of_sound[0]
        density = atmosphere.density[0]

        if mach <= 0.01:
            mach = 0.01
        if engine_on:
            cd = self.cd_on(mach)
        else:
            cd = self.cd_off(mach)

        drag_force = 0.5 * cd * density * (np.pi * self.radius**2) * (speed**2)

        return (drag_force)
Beispiel #26
0
def estimate_skin_friction_coef(wetted_area, wing_area, wing_span, mach, alt):
    """Return an estimation of skin friction drag coefficient.

    Function 'estimate_skin_friction_coef' gives an estimation of the skin
    friction drag coefficient, based on an empirical formala (see source).

    Source:
        * Gerard W. H. van Es.  "Rapid Estimation of the Zero-Lift Drag
          Coefficient of Transport Aircraft", Journal of Aircraft, Vol. 39,
          No. 4 (2002), pp. 597-599. https://doi.org/10.2514/2.2997

    Args:
        wetted_area (float):  Wetted Area of the entire aircraft [m^2]
        wing_area (float):  Main wing area [m^2]
        wing_span (float):  Main wing span [m]
        mach (float):  Cruise Mach number [-]
        alt (float):  Aircraft altitude [m]

    Returns:
        cd0 (float): Drag coefficient due to skin friction [-]
    """

    # Get atmosphere values at this altitude
    Atm = Atmosphere(alt)

    # Get speed from Mach Number
    speed = mach * Atm.speed_of_sound[0]

    # Reynolds number based on the ratio Wetted Area / Wing Span
    reynolds_number = (wetted_area /
                       wing_span) * speed / Atm.kinematic_viscosity[0]
    log.info("Reynolds number:" + str(round(reynolds_number)))

    # Skin friction coefficient, formula from source (see function description)
    cfe = (0.00258 + 0.00102 * math.exp(-6.28 * 1e-9 * reynolds_number) +
           0.00295 * math.exp(-2.01 * 1e-8 * reynolds_number))
    log.info("Skin friction coefficient:" + str(round(cfe, 5)))

    # Drag coefficient due to skin friction
    cd0 = cfe * wetted_area / wing_area
    log.info("Skin friction drag coefficient: " + str(cd0))

    return cd0
Beispiel #27
0
def setupInitialConditions(workingPath, alfa, beta, mach, altitude, transient):

    #PATHS
    templatePath = os.path.join(workingPath, settings.templatePath)
    filePath = os.path.join(
        workingPath,
        settings.filePathTransient if transient else settings.filePathSteady)

    #ATMOSPHERIC MODEL
    atm = Atmosphere(altitude)
    temp = atm.temperature[0]
    press = atm.pressure[0]
    dens = atm.density[0]
    c = atm.speed_of_sound[0]
    vel = c * mach
    u = rotateVelocity(vel, alfa, beta)

    #TURBULENCE PARAMETERS
    Re, turbulentLengthScale, turbulentIntensity, k, w, epsilon, nut, nuTilda = turbulenceCalculator(
        0.15, vel)

    #OPEN TEMPLATE
    with open(templatePath, 'r') as f:
        dumpStr = f.read()

    #SUBSTITUTE PARAMETERS IN TEMPLATE
    dumpStr = dumpStr.replace("%ux%", str(round(u[0], 3)))
    dumpStr = dumpStr.replace("%uy%", str(round(u[1], 3)))
    dumpStr = dumpStr.replace("%uz%", str(round(u[2], 3)))
    dumpStr = dumpStr.replace("%pressure%", str(round(press, 3)))
    dumpStr = dumpStr.replace("%densityRef%", str(round(dens, 3)))
    dumpStr = dumpStr.replace("%temperature%", str(round(temp, 3)))
    dumpStr = dumpStr.replace("%nut%", str(round(nut, 5)))
    dumpStr = dumpStr.replace("%k%", str(round(k, 5)))
    dumpStr = dumpStr.replace("%w%", str(round(w, 5)))
    dumpStr = dumpStr.replace("%Uinf%", str(round(vel, 3)))
    dumpStr = dumpStr.replace("%nuTilda%", str(round(nuTilda, 5)))

    #DUMP FILE
    with open(filePath, 'w') as f:
        f.write(dumpStr)

    return True
def jet_buoyancy(h,T0,n):
    '''
    Parâmetros
    ----------
    h : Lista de altitudes definida em "MAIN".
    T0 : Empuxo dos quatro motores da aeronave ao nível do mar
    n: Coeficiente propulsivo
    Returns
    -------
    T : Lista de empuxo para cada altitude (h).
    '''
    
    T = []
    
    for i in h:
        sigma = Atmosphere(i).density[0]/rho0
        Ti = T0*(sigma**n) 
        T.append(Ti)
    
    return T
def h_vs_V(h,V1,V2,Vs):
    

    V_som = Atmosphere(h).speed_of_sound
  
    h_plot = [i*3.28084 for i in h]
    
    plt.style.use('tableau-colorblind10')
    
    plt.figure()
    plt.xlabel("Mach")
    plt.ylabel("h [ft]")
    plt.grid(True)
    plt.plot(V1/V_som,h_plot,'k')
    plt.plot(V2/V_som,h_plot,'k')
    plt.plot(Vs/V_som, h_plot, 'r', label = 'Stall')
    plt.legend(loc = 'best', framealpha = 1)
    plt.savefig('h_vs_V.svg')
    plt.show()

    return
Beispiel #30
0
def make_plots():
    h = np.linspace(CONST.h_min, CONST.h_max, num=1000)
    a = Atmosphere(h)
    hs = h/1000

    lw = 1.5
    cp1 = 'blue'
    cp2 = 'green'

    for p in props:
        fig, ax1 = plt.subplots()

        data = getattr(a, p.name)

        ax1.plot(data, hs, lw=lw, c=cp1)
        ax1.set_ylabel('Height [km]')
        ax1.tick_params(axis='x', labelcolor=cp1)
        ax1.grid()

        ax1.set_xlabel(f"{p.name_long} [{p.unit}]")

        if p.log:
            ax2 = ax1.twiny()
            ax2.plot(data, hs, '--', lw=lw, c=cp2)
            ax2.set_xscale('log')
            ax2.tick_params(axis='x', labelcolor=cp2)
            ax2.grid()

        fig.tight_layout()

        fname = p.name + '.png'
        print(fname)
        plt.savefig(os.path.join(HERE, fname))

        plt.cla()
        plt.close('all')
        plt.clf()