def indicial_gust_response( reduced_time: Union[float, np.ndarray], gust_velocity: float, plate_velocity: float, angle_of_attack: float = 0, # In degrees chord: float = 1): """ Computes the evolution of the lift coefficient of a flat plate entering a an infinitely long, sharp step gust (Heaveside function) at a constant angle of attack. Reduced_time = 0 corresponds to the instance the gust is entered (Leishman, Principles of Helicopter Aerodynamics, S8.10,S8.11) Args: reduced_time (float,np.ndarray) : Reduced time, equal to the number of semichords travelled. See function reduced_time gust_velocity (float) : velocity in m/s of the top hat gust velocity (float) : velocity of the thin airfoil entering the gust angle_of_attack (float) : The angle of attack, in degrees chord (float) : The chord of the plate in meters """ angle_of_attack_radians = np.deg2rad(angle_of_attack) offset = chord / 2 * (1 - np.cos(angle_of_attack_radians)) return (2 * np.pi * np.arctan(gust_velocity / plate_velocity) * np.cos(angle_of_attack_radians) * kussners_function(reduced_time - offset))
def indicial_pitch_response( reduced_time: Union[float, np.ndarray], angle_of_attack: float # In degrees ): """ Computes the evolution of the lift coefficient in Wagner's problem which can be interpreted as follows 1) An impulsively started flat plate at constant angle of attack 2) An impuslive change in the angle of attack of a flat plate at constant velocity The model predicts infinite added mass at the first instant due to the infinite acceleration The delta function term (and therefore added mass) has been ommited in this case. Reduced_time = 0 corresponds to the instance the airfoil pitches/accelerates Args: reduced_time (float,np.ndarray) : Reduced time, equal to the number of semichords travelled. See function reduced_time angle_of_attack (float) : The angle of attack, in degrees """ return 2 * np.pi * np.deg2rad(angle_of_attack) * wagners_function( reduced_time)
def added_mass_due_to_pitching( reduced_time: np.ndarray, angle_of_attack: Callable[[float], float] # In degrees ): """ This function calculate the lift coefficient due to the added mass of a flat plate pitching about its midchord while moving at constant velocity. Args: reduced_time (np.ndarray) : Reduced time, equal to the number of semichords travelled. See function reduced_time angle_of_attack (Callable[[float],float]) : The angle of attack as a function of reduced time of the flat plate Returns: lift_coefficient (np.ndarray) : The lift coefficient history of the flat plate """ AoA = np.array([np.deg2rad(angle_of_attack(s)) for s in reduced_time]) da_ds = np.gradient(AoA, reduced_time) # TODO: generalize to all unsteady motion return np.pi / 2 * np.cos(AoA)**2 * da_ds
def AoA_function(reduced_time): return np.deg2rad(angle_of_attack(reduced_time))
np.sum([da_ds[j] * wagner[i - j] * ds[j] for j in range(i)])) return lift_coefficient if __name__ == "__main__": n = 1000 n1 = int(n / 3) n2 = int(2 * n / 3) time = np.linspace(0, 100, n) velocity = 0.2 chord = 1 reduced_time = calculate_reduced_time(time, velocity, chord) gust_velocity = np.zeros_like(reduced_time) gust_velocity[n1:n2] = velocity angle_of_attack = 20 * np.deg2rad(np.sin(reduced_time)) #angle_of_attack[n1:n2] = np.deg2rad(-20) cl_k = duhamel_integral_kussner(reduced_time, gust_velocity, velocity) cl_w = duhamel_integral_wagner(reduced_time, angle_of_attack) plt.figure(dpi=300) plt.plot(reduced_time, cl_w, label="wagner") plt.plot(reduced_time, cl_k, label="kussner") plt.plot(reduced_time, cl_k + cl_w, label="total") plt.xlabel("Reduced time, t*") plt.ylabel("$C_\ell$") plt.legend()