def efforts_hydrostat(phi, theta, DELTA, workbook): """ Fonction qui renvoie le torseur résultant des efforts hydrostatiques, au point O et dans le repère lié au bateau. Les valeurs d'entrée utilisées sont issues du logiciel GHS. -------------------- ENTREES : Phi : angle de gîte du bateau, en radians Theta : angle d'assiette du bateau, en radians DELTA : déplacement du navire, en kg -------------------- SORTIES : torseur_stab_repBateau : Torseur résultant des efforts hydrostatiques, au point O et dans le repère lié au bateau. Type : numpy.ndarray de taille (3,2) """ if abs(theta) > np.deg2rad(15): raise ValueError("Theta is over 15 degrees") g = 9.81 sheet_T = workbook["Trans"] lignes_T = fctAnnexes.trouver_lignes_stab(workbook, "Trans", np.rad2deg(phi)) n1_T, n2_T = lignes_T[0], lignes_T[1] GZ_T_inf = sheet_T["B" + str(n1_T)].value GZ_T_sup = sheet_T["B"+str(n2_T)].value phi_inf = np.deg2rad(sheet_T["A" + str(n1_T)].value) phi_sup = np.deg2rad(sheet_T["A"+str(n2_T)].value) if phi>=0: GZ_T = fctAnnexes.interpol_lin(phi, phi_inf, phi_sup, GZ_T_inf, GZ_T_sup) else: GZ_T = -fctAnnexes.interpol_lin(-phi, phi_inf, phi_sup, GZ_T_inf, GZ_T_sup) RM_T = -GZ_T*DELTA*g # signe négatif car si phi>0, le couple est négatif (cf repères) sheet_L = workbook["Longi"] lignes_L = fctAnnexes.trouver_lignes_stab(workbook, "Longi", np.rad2deg(theta)) n1_L, n2_L = lignes_L[0], lignes_L[1] GZ_L_inf = sheet_L["B"+str(n1_L)].value GZ_L_sup = sheet_L["B"+str(n2_L)].value theta_inf = np.deg2rad(sheet_L["A" + str(n1_L)].value) theta_sup = np.deg2rad(sheet_L["A"+str(n2_L)].value) if theta>=0: GZ_L = fctAnnexes.interpol_lin(theta, theta_inf, theta_sup, GZ_L_inf, GZ_L_sup) else: GZ_L = -fctAnnexes.interpol_lin(-theta, theta_inf, theta_sup, GZ_L_inf, GZ_L_sup) RM_L = -GZ_L*DELTA*g torseur_stab_repBateau = np.concatenate((np.array([0, 0, 0]).reshape(-1, 1), np.array([RM_T, RM_L, 0]).reshape(-1, 1)), axis=1) return torseur_stab_repBateau
def testInterpol_lin(self): # Test cas standard, A et B donnés dans le bon ordre xA, yA = 3, 12 xB, yB = 5, 14 x1, x2, x3 = 3, 4, 5 self.assertEqual(fctAnnexes.interpol_lin(x1, xA, xB, yA, yB), 12.) self.assertEqual(fctAnnexes.interpol_lin(x3, xA, xB, yA, yB), 14.) self.assertEqual(fctAnnexes.interpol_lin(x2, xA, xB, yA, yB), 13.) # Test cas opposé, A et B donnés dans le désordre xB, yB = 3, 12 xA, yA = 5, 14 x1, x2, x3 = 3, 4, 5 self.assertEqual(fctAnnexes.interpol_lin(x1, xA, xB, yA, yB), 12.) self.assertEqual(fctAnnexes.interpol_lin(x3, xA, xB, yA, yB), 14.) self.assertEqual(fctAnnexes.interpol_lin(x2, xA, xB, yA, yB), 13.)
def polaire_safran(Vs, rho_eau, Lambda, phi, workbook): alpha = np.arctan( np.tan(Lambda) * np.cos(phi) ) # alpha = angle d'incidence entre le sqfrqn et le flux d'eau Vf = vitesse_fluide(Vs, Lambda, phi) Vf_nds = fctAnnexes.ms2nds(Vf) if Vf_nds < 0.1: #Moins de 0.1 noeud de vitesse du bateau CL = 0 CD = 0 S = 0 CP_repsafran = np.array([0, 0, 0]).reshape( -1, 1) #le centre de poussée n'a aucune importance else: # Vitesse du bateau supérieure à 0.1 noeud v_bateau = [0.1, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 10] if Vf_nds in v_bateau: sheet = workbook[ str(Vf_nds) + "kts"] # On ouvre la feuille de calcul correspondant à la vitesse du bateau Lignes = fctAnnexes.trouver_lignes(workbook, alpha, Vf_nds) n1, n2 = Lignes[0], Lignes[1] # Extraction données du fichier excel alpha_inf = sheet["B" + str(n1)].value alpha_sup = sheet["B" + str(n2)].value CL_inf = sheet["F" + str(n1)].value CL_sup = sheet["F" + str(n2)].value CD_inf = sheet["H" + str(n1)].value CD_sup = sheet["H" + str(n2)].value XCP_inf = sheet["J" + str(n1)].value XCP_sup = sheet["J" + str(n2)].value ZCP_inf = sheet["K" + str(n1)].value ZCP_sup = sheet["K" + str(n2)].value # Interpolation avec les données extraites CL = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, CL_inf, CL_sup) CD = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, CD_inf, CD_sup) XCP = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, XCP_inf, XCP_sup) ZCP = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, ZCP_inf, ZCP_sup) CP_repsafran = np.array([XCP, 0, ZCP]).reshape(-1, 1) else: i = 0 Vf_inf = v_bateau[i] Vf_sup = v_bateau[i + 1] while Vf_nds > Vf_sup: i += 1 Vf_inf = v_bateau[i] Vf_sup = v_bateau[i + 1] # Vf_inf et Vf_sup encadrent la valeur de la vitesse du bateau, par des valeurs où la polaire du safran est connue. if alpha > np.deg2rad(19.9): alpha = np.deg2rad(19.9) Lignes1, Lignes2 = fctAnnexes.trouver_lignes( workbook, alpha, [Vf_inf, Vf_sup]) sheet_inf = workbook[ str(Vf_inf) + "kts"] # On ouvre la feuille de calcul correspondant a Vfinf sheet_sup = workbook[ str(Vf_sup) + "kts"] # On ouvre la feuille de calcul correspondant a Vfsup n1, n2 = Lignes1[0], Lignes1[1] #Pour la feuille de calcul Vf_inf m1, m2 = Lignes2[0], Lignes2[1] #Pour la feuille de calcul Vf_sup # Extraction données du fichier excel alpha_inf_Vfinf = sheet_inf["B" + str(n1)].value alpha_sup_Vfinf = sheet_inf["B" + str(n2)].value alpha_inf_Vfsup = sheet_sup["B" + str(m1)].value alpha_sup_Vfsup = sheet_sup["B" + str(m2)].value CL_inf_Vfinf = sheet_inf["F" + str(n1)].value CL_sup_Vfinf = sheet_inf["F" + str(n2)].value CL_inf_Vfsup = sheet_sup["F" + str(m1)].value CL_sup_Vfsup = sheet_sup["F" + str(m2)].value CD_inf_Vfinf = sheet_inf["H" + str(n1)].value CD_sup_Vfinf = sheet_inf["H" + str(n2)].value CD_inf_Vfsup = sheet_sup["H" + str(m1)].value CD_sup_Vfsup = sheet_sup["H" + str(m2)].value XCP_inf_Vfinf = sheet_inf["J" + str(n1)].value XCP_sup_Vfinf = sheet_inf["J" + str(n2)].value XCP_inf_Vfsup = sheet_sup["J" + str(m1)].value XCP_sup_Vfsup = sheet_sup["J" + str(m2)].value ZCP_inf_Vfinf = sheet_inf["K" + str(n1)].value ZCP_sup_Vfinf = sheet_inf["K" + str(n2)].value ZCP_inf_Vfsup = sheet_sup["K" + str(m1)].value ZCP_sup_Vfsup = sheet_sup["K" + str(m2)].value #NB : la surface est prise que pour une des valeurs de vitesse du bateau. # Première interpolation selon les angles, sur chaque feuille de calcul séparément CL_Vfinf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfinf, alpha_sup_Vfinf, CL_inf_Vfinf, CL_sup_Vfinf) CL_Vfsup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfsup, alpha_sup_Vfsup, CL_inf_Vfsup, CL_sup_Vfsup) CD_Vfinf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfinf, alpha_sup_Vfinf, CD_inf_Vfinf, CD_sup_Vfinf) CD_Vfsup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfsup, alpha_sup_Vfsup, CD_inf_Vfsup, CD_sup_Vfsup) XCP_Vfinf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfinf, alpha_sup_Vfinf, XCP_inf_Vfinf, XCP_sup_Vfinf) XCP_Vfsup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfsup, alpha_sup_Vfsup, XCP_inf_Vfsup, XCP_sup_Vfsup) ZCP_Vfinf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfinf, alpha_sup_Vfinf, ZCP_inf_Vfinf, ZCP_sup_Vfinf) ZCP_Vfsup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vfsup, alpha_sup_Vfsup, ZCP_inf_Vfsup, ZCP_sup_Vfsup) # Seconde interpolation, selon les vitesses CL = fctAnnexes.interpol_lin(Vf_nds, Vf_inf, Vf_sup, CL_Vfinf, CL_Vfsup) CD = fctAnnexes.interpol_lin(Vf_nds, Vf_inf, Vf_sup, CD_Vfinf, CD_Vfsup) XCP = fctAnnexes.interpol_lin(Vf_nds, Vf_inf, Vf_sup, XCP_Vfinf, XCP_Vfsup) ZCP = fctAnnexes.interpol_lin(Vf_nds, Vf_inf, Vf_sup, ZCP_Vfinf, ZCP_Vfsup) CP_repsafran = np.array([XCP, 0, ZCP]).reshape(-1, 1) S = 0.04 L = 0.5 * rho_eau * CL * S * Vs**2 D = 0.5 * rho_eau * CD * S * Vs**2 torseur_hydro_repFluide = np.concatenate((np.array([-D, L, 0]).reshape( -1, 1), np.array([0, 0, 0]).reshape(-1, 1)), axis=1) return torseur_hydro_repFluide, CP_repsafran
def polaire_voile(Vt, Vs, rho_air, Lambda, angle_allure, phi, workbook): """ Fonction qui renvoie le torseur dû aux forces aérodynamiques et les coordonnées du centre de poussée, dans le repère du fluide en écoulement et en l'origine de ce repère (le centre de poussée) -------------------- ENTREES : Vs : vitesse du bateau, en m/s Vt : vitesse du vent reel, en m/s rho_air : masse volumique de l'air, en kg/m3 Lambda : angle de dérive du bateau, en rad delta_v : angle de réglage de la voile, soit l'angle entre l'axe de la voile, et l'axe longitudinal du bateau, en rad angle_allure : true wind angle, angle que prend le vent avec l'axe longitudinal x du bateau, en rad phi : angle de gite, en rad -------------------- SORTIES : torseur_aero_repFluide : torseur des efforts aérodynamiques dans le repère lié à la voile, en son origine CP_repVoile : coordonnées dans le repère lié à la voile du centre de poussée """ Va = vent_apparent(Vt, Vs, Lambda, angle_allure, phi) Va_nds = fctAnnexes.ms2nds(Va) beta_t = Lambda + angle_allure # beta_t : page 33 de [2] - angle entre axe X d'avance du bateau et vent réel" betaMOINSlambda = np.pi / 2 - np.arctan( (Vt * np.cos(beta_t - Lambda) + Vs) / (Vt * np.sin(beta_t - Lambda) * np.cos(phi)) ) # beta : page 33 de [2] - angle entre axe X d'avance du bateau et vent apparent" # DETERMINATION DU L'INCIDENCE OPTIMALE alpha_opt A LA VITESSE DE VENT APPARENT CALCULEE v_bateau = [1, 5, 10, 15, 20, 25, 30, 35, 40] if int(Va_nds) in v_bateau: sheet = workbook[ str(int(Va_nds)) + "kts"] # On ouvre la feuille de calcul correspondant au vent alpha_opt = np.deg2rad(sheet["N2"].value) else: i = 0 Va_inf = v_bateau[i] Va_sup = v_bateau[i + 1] while Va_nds > Va_sup: i += 1 Va_inf = v_bateau[i] Va_sup = v_bateau[i + 1] sheet_inf = workbook[ str(Va_inf) + "kts"] # On ouvre la feuille de calcul correspondant a Vainf sheet_sup = workbook[ str(Va_sup) + "kts"] # On ouvre la feuille de calcul correspondant a Vasup alpha_opt_Vainf = np.deg2rad(sheet_inf["N2"].value) alpha_opt_Vasup = np.deg2rad(sheet_sup["N2"].value) alpha_opt = fctAnnexes.interpol_lin(Va_nds, Va_inf, Va_sup, alpha_opt_Vainf, alpha_opt_Vasup) # DETERMINATION DU L'INCIDENCE alpha ET DE L'ANGLE DE REGLAGE DE VOILE deltav REELS deltav_opt = betaMOINSlambda - alpha_opt # angle de réglage de voile pour avoir l'incidence optimale if abs(deltav_opt) <= np.deg2rad(90): # La voile est maintenue à incidence optimale par le flap deltav = deltav_opt alpha = alpha_opt elif deltav_opt < np.deg2rad(-90): # Au portant, la voile est en butée et on n'est plus à incidence optimale deltav = np.deg2rad(-90) alpha = betaMOINSlambda + deltav else: # Au portant, la voile est en butée et on n'est plus à incidence optimale deltav = np.deg2rad(90) alpha = betaMOINSlambda - deltav # print("alpha_opt = ", np.rad2deg(alpha_opt), "--", "deltaopt",np.rad2deg(deltav_opt)) # RECUPERATION DES COEFFICIENTS DE PORTANCE ET DE TRAINEE if Va_nds < 1: # Moins de 1 noeud de vent apparent. CL = 0 CD = 0 S = 0 CP_repVoile = np.array([0, 0, 0]).reshape( -1, 1) # le centre de poussée n'a aucune importance else: # Vent apparent supérieur à 1 noeud if int(Va_nds) in v_bateau: sheet = workbook[ str(int(Va_nds)) + "kts"] # On ouvre la feuille de calcul correspondant au vent Lignes = fctAnnexes.trouver_lignes(workbook, alpha, Va_nds) n1, n2 = Lignes[0], Lignes[1] # Extraction données du fichier excel alpha_inf = sheet["B" + str(n1)].value alpha_sup = sheet["B" + str(n2)].value CL_inf = sheet["F" + str(n1)].value CL_sup = sheet["F" + str(n2)].value CD_inf = sheet["H" + str(n1)].value CD_sup = sheet["H" + str(n2)].value XCP_inf = sheet["L" + str(n1)].value XCP_sup = sheet["L" + str(n2)].value ZCP_inf = sheet["K" + str(n1)].value ZCP_sup = sheet["K" + str(n2)].value # Interpolation avec les données extraites CL = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, CL_inf, CL_sup) CD = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, CD_inf, CD_sup) XCP = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, XCP_inf, XCP_sup) ZCP = fctAnnexes.interpol_lin(alpha, alpha_inf, alpha_sup, ZCP_inf, ZCP_sup) CP_repVoile = np.array([XCP, 0, ZCP]).reshape(-1, 1) else: i = 0 Va_inf = v_bateau[i] Va_sup = v_bateau[i + 1] while Va_nds > Va_sup: i += 1 Va_inf = v_bateau[i] Va_sup = v_bateau[i + 1] # Va_inf et Va_sup encadrent la valeur de vent apparent, par des valeurs où la polaire de voile est connue. Lignes1, Lignes2 = fctAnnexes.trouver_lignes( workbook, alpha, [Va_inf, Va_sup]) sheet_inf = workbook[ str(Va_inf) + "kts"] # On ouvre la feuille de calcul correspondant a Vainf sheet_sup = workbook[ str(Va_sup) + "kts"] # On ouvre la feuille de calcul correspondant a Vasup n1, n2 = Lignes1[0], Lignes1[1] # Pour la feuille de calcul Va_inf m1, m2 = Lignes2[0], Lignes2[1] # Pour la feuille de calcul Va_sup # print(n1, n2, m1, m2) # Extraction données du fichier excel alpha_inf_Vainf = sheet_inf["B" + str(n1)].value alpha_sup_Vainf = sheet_inf["B" + str(n2)].value alpha_inf_Vasup = sheet_sup["B" + str(m1)].value alpha_sup_Vasup = sheet_sup["B" + str(m2)].value CL_inf_Vainf = sheet_inf["F" + str(n1)].value CL_sup_Vainf = sheet_inf["F" + str(n2)].value CL_inf_Vasup = sheet_sup["F" + str(m1)].value CL_sup_Vasup = sheet_sup["F" + str(m2)].value CD_inf_Vainf = sheet_inf["H" + str(n1)].value CD_sup_Vainf = sheet_inf["H" + str(n2)].value CD_inf_Vasup = sheet_sup["H" + str(m1)].value CD_sup_Vasup = sheet_sup["H" + str(m2)].value XCP_inf_Vainf = sheet_inf["L" + str(n1)].value XCP_sup_Vainf = sheet_inf["L" + str(n2)].value XCP_inf_Vasup = sheet_sup["L" + str(m1)].value XCP_sup_Vasup = sheet_sup["L" + str(m2)].value ZCP_inf_Vainf = sheet_inf["K" + str(n1)].value ZCP_sup_Vainf = sheet_inf["K" + str(n2)].value ZCP_inf_Vasup = sheet_sup["K" + str(m1)].value ZCP_sup_Vasup = sheet_sup["K" + str(m2)].value # NB : la surface est prise que pour une des valeurs de vent, car elle est la même quelle que soit le Va. # Première interpolation selon les angles, sur chaque feuille de calcul séparément CL_Vainf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vainf, alpha_sup_Vainf, CL_inf_Vainf, CL_sup_Vainf) CL_Vasup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vasup, alpha_sup_Vasup, CL_inf_Vasup, CL_sup_Vasup) CD_Vainf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vainf, alpha_sup_Vainf, CD_inf_Vainf, CD_sup_Vainf) CD_Vasup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vasup, alpha_sup_Vasup, CD_inf_Vasup, CD_sup_Vasup) XCP_Vainf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vainf, alpha_sup_Vainf, XCP_inf_Vainf, XCP_sup_Vainf) XCP_Vasup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vasup, alpha_sup_Vasup, XCP_inf_Vasup, XCP_sup_Vasup) ZCP_Vainf = fctAnnexes.interpol_lin(alpha, alpha_inf_Vainf, alpha_sup_Vainf, ZCP_inf_Vainf, ZCP_sup_Vainf) ZCP_Vasup = fctAnnexes.interpol_lin(alpha, alpha_inf_Vasup, alpha_sup_Vasup, ZCP_inf_Vasup, ZCP_sup_Vasup) # Seconde interpolation, selon les vitesses CL = fctAnnexes.interpol_lin(Va_nds, Va_inf, Va_sup, CL_Vainf, CL_Vasup) CD = fctAnnexes.interpol_lin(Va_nds, Va_inf, Va_sup, CD_Vainf, CD_Vasup) XCP = fctAnnexes.interpol_lin(Va_nds, Va_inf, Va_sup, XCP_Vainf, XCP_Vasup) ZCP = fctAnnexes.interpol_lin(Va_nds, Va_inf, Va_sup, ZCP_Vainf, ZCP_Vasup) CP_repVoile = np.array([XCP, 0, ZCP]).reshape(-1, 1) S = 1.647 L = 0.5 * rho_air * CL * S * (Va**2) # print(alpha) # print("L=",L) # if L<0: # raise ValueError("Lift is negative !") D = 0.5 * rho_air * CD * S * (Va**2) torseur_aero_repFluide = np.concatenate((np.array([D, L, 0]).reshape( -1, 1), np.array([0, 0, 0]).reshape(-1, 1)), axis=1) return torseur_aero_repFluide, CP_repVoile, deltav