Source code for settings

from dataclasses import dataclass
import numpy as np
import os
import pdb

[docs]class FrozenClass(object): __is_frozen = False def __setattr__(self, key, value): if self.__is_frozen and not hasattr(self, key): raise TypeError( "Invalid attribute specified for the %r class." % self ) object.__setattr__(self, key, value) def _freeze(self): self.__is_frozen = True
[docs]@dataclass() class Settings(FrozenClass): """ pyNA settings class """
[docs] def __init__(self, case_name, language = 'python', pyNA_directory = '.', engine_file_name = 'Engine_to.csv', trajectory_file_name = 'Trajectory_to.csv', output_file_name = 'Trajectory_stca.sql', ac_name = 'stca', ac_version = 'verification', save_results = False, fan_inlet = False, fan_discharge = False, core = False, jet_mixing = False, jet_shock = False, airframe = False, all_sources = True, fan_igv = False, fan_id = False, observer_lst = ('lateral', 'flyover'), method_core_turb ='GE', fan_BB_method ='geae', fan_RS_method = 'allied_signal', ge_flight_cleanup = 'takeoff', levels_int_metric = 'epnl', engine_mounting = 'underwing', direct_propagation = True, absorption = True, groundeffects = True, lateral_attenuation = False, suppression = True, fan_liner_suppression = True, shielding = True, hsr_calibration = True, validation = True, bandshare = False, TCF800 = True, combination_tones = False, N_shock = 8, dT = 10.0169, sigma = 291.0 * 515.379, a_coh = 0.01, N_f = 24, N_b = 5, n_altitude_absorption = 5, A_e = 10.334 * (0.3048 ** 2), dt_epnl = 0.5, n_harmonics = 10, r_0 = 0.3048, p_ref= 2e-5, x_observer_array = np.array([[12325.*0.3048, 450., 4*0.3048], [21325.*0.3048, 0., 4*0.3048]]), noise_optimization = False, PTCB = False, PHLD = False, TS_to = 1.0, TS_vnrs = 1.0, TS_cutback = None, z_cutback = 500., theta_flaps = 10., theta_slats = -6., n_segments_vnrs = 10, max_iter = 200): """ Initialize pyNA settings class :param case_name: Case name [-] :type case_name: str :param pyNA_directory: Directory where pyNA is installed :type pyNA_directory: str :param engine_file_name: File name of the take-off engine inputs [-] :type engine_file_name: str :param trajectory_file_name: File name of the take-off trajectory [-] :type trajectory_file_name: str :param output_file_name: Name of the output .sql file [-] :type output_file_name: str :param ac_name: Name of the aircraft [-] :type ac_name: str :param save_results: Flag to save results [-] :type save_results: bool :param fan_inlet: Enable fan inlet noise source [-] :type fan_inlet: bool :param fan_discharge: Enable fan discharge noise source [-] :type fan_discharge: bool :param core: Enable core noise source [-] :type core: bool :param jet_mixing: Enable jet mixing noise source [-] :type jet_mixing: bool :param jet_shock: Enable jet shock noise source [-] :type jet_shock: bool :param airframe: Enable airframe noise source [-] :type airframe: bool :param all_sources: Enable all noise sources [-] :type all_sources: bool :param trajectory_mode: mode for trajectory calculations [-] ('cutback', optimization') :type trajectory_mode: str :param observer_lst: List of observers to analyze [-] ('flyover','lateral','approach', 'contour') :type observer_lst: lst :param method_core_turb: Method to account for turbine transmission in the combustor ('GE', 'PW') [-] :type method_core_turb: str :param fan_BB_method: Method BB (original / allied_signal / geae / kresja) [-] :type fan_BB_method: str :param fan_RS_method: Method RS (original / allied_signal / geae / kresja) [-] :type fan_RS_method: str :param fan_igv: Enable fan inlet guide vanes :type fan_igv: bool :param fan_id: Enable fan inlet distortions :type fan_id: bool :param ge_flight_cleanup: GE flight cleanup switch (none/takeoff/approach) [-] :type ge_flight_cleanup: str :param levels_int_metric: Integrated noise metric [-] :type levels_int_metric: str :param engine_mounting: Engine mounting ('fuselage'/'underwing'/'none') [-] :type engine_mounting: str :param direct_propagation: Flag for direct propagation (including distance and characteristic impedance effects) [-] :type direct_propagation: bool :param absorption: Flag for atmospheric absorption [-] :type absorption: bool :param groundeffects: Flag for ground effects [-] :type groundeffects: bool :param lateral_attenuation: Flag for empirical lateral attenuation effects [-] :type lateral_attenuation: bool :param suppression: Flag for suppression of engine modules [-] :type suppression: bool :param fan_liner_suppression: Flag for fan liner suppression [-] :type fan_liner_suppression: bool :param shielding: Flag for shielding effects (not implemented yet) [-] :type shielding: bool :param hsr_calibration: Flag for HSR-era airframe calibration [-] :type hsr_calibration: bool :param validation: Flag for validation with NASA STCA noise model [-] :type validation: bool :param bandshare: Flag to plot PNLT [-] :type bandshare: bool :param TCF800: Flag for tone penalty addition to PNLT metric; allows any tone below 800Hz to be ignored [-] :type TCF800: bool :param combination_tones: Flag for combination tones int he fan noise model [-] :type combination_tones: bool :param N_shock: Number of shocks in supersonic jet [-] :type N_shock: int :param dT: dT standard atmosphere [K] :type dT: float :param sigma: Specific flow resistance of ground [kg/s m3] :type sigma: float :param a_coh: Incoherence constant [-] :type a_coh: float :param N_f: Number of discrete 1/3 octave frequency bands [-] :type N_f: int :param N_b: Number of bands (propagation) [-] :type N_b: int :param n_altitude_absorption: Number of integration steps in atmospheric propagation [-] :type n_altitude_absorption: int :param A_e: Engine reference area [m2] :type A_e: float :param dt_epnl: Time step of to calculate EPNL from interpolated PNLT data [s] :type dt_epnl: float :param n_harmonics: Number of harmonics to be considered in tones [-] :type n_harmonics: int :param r_0: Distance source observer in source mode [m] :type r_0: float :param p_ref: Reference pressure [Pa] :type p_ref: float :param noise_optimization: Flag to noise-optimize the trajectory [-] :type noise_optimization: bool :param PTCB: Enable PTCB [-] :type PTCB: bool :param PHLD: Enable PHLD [-] :type PHLD: bool :param TS_to: Engine TO thrust-setting (values < 1 denote APR) [-] :type TS_to: float :param TS_vnrs: Engine VNRS thrust-setting [-] :type TS_vnrs: float :param TS_cutback: Engine cutback thrust-setting [-] :type TS_cutback: float :param z_cutback: z-location of cutback [m] :type z_cutback: float :param theta_flaps: Flap deflection angles [deg] :type theta_flaps: float :param theta_slats: Slat deflection angles [deg] :type theta_slats: float :param n_segments_vnrs: List with phase number of segments [-] :type n_segments_vnrs: int :param max_iter: Maximum number of iterations for trajectory computations [-] :type max_iter: int """ self.case_name = case_name self.language = language self.pyNA_directory = pyNA_directory self.engine_file_name = engine_file_name self.trajectory_file_name = trajectory_file_name self.output_file_name = output_file_name self.ac_name = ac_name self.ac_version = ac_version self.save_results = save_results self.fan_inlet = fan_inlet self.fan_discharge = fan_discharge self.core = core self.jet_mixing = jet_mixing self.jet_shock = jet_shock self.airframe = airframe self.all_sources = all_sources self.observer_lst = observer_lst self.x_observer_array = x_observer_array self.method_core_turb = method_core_turb self.fan_BB_method = fan_BB_method self.fan_RS_method = fan_RS_method self.fan_igv = fan_igv self.fan_id = fan_id self.ge_flight_cleanup = ge_flight_cleanup self.levels_int_metric = levels_int_metric self.engine_mounting = engine_mounting self.direct_propagation = direct_propagation self.absorption = absorption self.groundeffects = groundeffects self.lateral_attenuation = lateral_attenuation self.suppression = suppression self.fan_liner_suppression = fan_liner_suppression self.shielding = shielding self.hsr_calibration = hsr_calibration self.validation = validation self.bandshare = bandshare self.TCF800 = TCF800 self.combination_tones = combination_tones self.N_shock = N_shock self.dT = dT self.sigma = sigma self.a_coh = a_coh self.N_f = N_f self.N_b = N_b self.n_altitude_absorption = n_altitude_absorption self.A_e = A_e self.dt_epnl = dt_epnl self.n_harmonics = n_harmonics self.r_0 = r_0 self.p_ref = p_ref self.noise_optimization = noise_optimization self.PTCB = PTCB self.PHLD = PHLD self.TS_to = TS_to self.TS_vnrs = TS_vnrs self.TS_cutback = TS_cutback self.z_cutback = z_cutback self.theta_flaps = theta_flaps self.theta_slats = theta_slats self.n_segments_vnrs = n_segments_vnrs self.max_iter = max_iter # Freeze self.settings self._freeze()
[docs] def check(self) -> None: """ Check the pyNA settings before a run. :return: None """ # pyNA directory if type(self.pyNA_directory) != str: raise TypeError(self.pyNA_directory, "is not a valid directory location. Specify the name (string).") # Folder and file names if type(self.case_name) != str: raise TypeError(self.case_name, "does not have the correct type for the engine file name. type(settings.case_name) must be str.") if type(self.engine_file_name) != str: raise TypeError(self.engine_file_name, "does not have the correct type for the engine file name. type(settings.output_file_name) must be str.") if type(self.trajectory_file_name) != str: raise TypeError(self.trajectory_file_name, "does not have the correct type for the trajectory file name. type(settings.trajectory_file_name) must be str.") if type(self.output_file_name) != str: raise TypeError(self.output_file_name, "does not have the correct type for the output file name. type(settings.output_file_name) must be str.") if self.ac_name not in ['stca', 'a10']: raise TypeError(self.ac_name, "is not a valid aircraft name. Specify: 'stca', 'stca_verification', 'a10'.") if type(self.ac_version) != str: raise TypeError(self.ac_version, "does not have the correct type for the aircraft version. type (self.ac_version) must be str.") # Flags if type(self.save_results) != bool: raise TypeError(self.save_results, "does not have the correct type. type(settings.save_results) must be bool.") if type(self.fan_inlet) != bool: raise TypeError(self.fan_inlet, "does not have the correct type. type(settings.fan_inlet) must be bool.") if type(self.fan_discharge) != bool: raise TypeError(self.fan_discharge, "does not have the correct type. type(settings.fan_discharge) must be bool.") if type(self.core) != bool: raise TypeError(self.core, "does not have the correct type. type(settings.core) must be bool.") if type(self.jet_mixing) != bool: raise TypeError(self.jet_mixing, "does not have the correct type. type(settings.jet_mixing) must be bool.") if type(self.jet_shock) != bool: raise TypeError(self.jet_shock, "does not have the correct type. type(settings.jet_shock) must be bool.") if type(self.airframe) != bool: raise TypeError(self.airframe, "does not have the correct type. type(settings.airframe) must be bool.") if type(self.all_sources) != bool: raise TypeError(self.all_sources, "does not have the correct type. type(settings.all_sources) must be bool.") if type(self.fan_igv) != bool: raise TypeError(self.fan_igv, "does not have the correct type. type(settings.fan_igv) must be bool.") if type(self.fan_id) != bool: raise TypeError(self.fan_id, "does not have the correct type. type(settings.fan_id) must be bool.") if type(self.direct_propagation) != bool: raise TypeError(self.direct_propagation, "does not have the correct type. type(settings.direct_propagation) must be bool.") if type(self.absorption) != bool: raise TypeError(self.absorption, "does not have the correct type. type(settings.absorption) must be bool.") if type(self.groundeffects) != bool: raise TypeError(self.groundeffects, "does not have the correct type. type(settings.groundeffects) must be bool.") if type(self.lateral_attenuation) != bool: raise TypeError(self.lateral_attenuation, "does not have the correct type. type(settingslateral_attenuation) must be bool.") if type(self.suppression) != bool: raise TypeError(self.suppression, "does not have the correct type. type(settings.suppression) must be bool.") if type(self.fan_liner_suppression) != bool: raise TypeError(self.fan_liner_suppression, "does not have the correct type. type(settings.fan_liner_suppression) must be bool.") if type(self.shielding) != bool: raise TypeError(self.shielding, "does not have the correct type. type(settings.shielding) must be bool.") if type(self.hsr_calibration) != bool: raise TypeError(self.hsr_calibration, "does not have the correct type. type(settings.hsr_calibration) must be bool.") if type(self.validation) != bool: raise TypeError(self.validation, "does not have the correct type. type(settings.validation) must be bool.") if type(self.bandshare) != bool: raise TypeError(self.bandshare, "does not have the correct type. type(settings.bandshare) must be bool.") if type(self.TCF800) != bool: raise TypeError(self.TCF800, "does not have the correct type. type(settings.TCF800) must be bool.") if type(self.combination_tones) != bool: raise TypeError(self.combination_tones, "does not have the correct type. type(settings.combination_tones) must be bool.") if type(self.PTCB) != bool: raise TypeError(self.PTCB, "does not have the correct type. type(settings.PTCB) must be bool.") if type(self.PHLD) != bool: raise TypeError(self.PHLD, "does not have the correct type. type(settings.PHLD) must be bool.") # Methods if self.method_core_turb not in ['GE', 'PW']: raise ValueError(self.method_core_turb, "is not a valid option for the core turbine attenuation method. Specify: 'GE'/'PW'.") if self.fan_BB_method not in ['original', 'allied_signal', 'geae', 'kresja']: raise ValueError(self.fan_BB_method, "is not a valid option for the fan broadband method. Specify: 'original'/'allied_signal'/'geae'/'kresja'.") if self.fan_RS_method not in ['original', 'allied_signal', 'geae', 'kresja']: raise ValueError(self.fan_RS_method, "is not a valid option for the fan rotor-stator interation method. Specify: 'original'/'allied_signal'/'geae'/'kresja'.") if self.ge_flight_cleanup not in ['none', 'takeoff', 'approach']: raise ValueError(self.ge_flight_cleanup, "is not a valid option for the GE flight clean-up effects method. Specify: 'none'/'takeoff'/'approach'.") if self.levels_int_metric not in ['epnl', 'ipnlt', 'ioaspl']: raise ValueError(self.levels_int_metric, "is not a valid option for the integrated noise levels metric. Specify: 'epnl'/'ipnlt'/'ioaspl'.") if self.engine_mounting not in ['fuselage', 'underwing', 'none']: raise ValueError(self.engine_mounting, "is not a valid option for the engine mounting description. Specify: 'fuselage', 'underwing', 'none'.") # Values if type(self.N_shock) not in [int, np.int32, np.int64]: raise TypeError(self.N_shock, "does not have the correct type. type(settings.N_shock) must be [int, np.int32, np.int64]") if type(self.dT) not in [float, np.float32, np.float64]: raise TypeError(self.dT, "does not have the correct type. type(settings.dT) must be [float, np.float32, np.float64]") if type(self.sigma) not in [float, np.float32, np.float64]: raise TypeError(self.sigma, "does not have the correct type. type(settings.sigma) must be [float, np.float32, np.float64]") if type(self.a_coh) not in [float, np.float32, np.float64]: raise TypeError(self.a_coh, "does not have the correct type. type(settings.a_coh) must be [float, np.float32, np.float64]") if type(self.N_f) not in [int, np.int32, np.int64]: raise TypeError(self.N_f, "does not have the correct type. type(settings.N_f) must be [int, np.int32, np.int64]") if type(self.N_b) not in [int, np.int32, np.int64]: raise TypeError(self.N_b, "does not have the correct type. type(settings.N_b) must be [int, np.int32, np.int64]") if np.remainder(self.N_b, 2) != 1: raise ValueError("The number of 1/3rd octave frequency sub-bands needs to be odd.") if type(self.n_altitude_absorption) not in [int, np.int32, np.int64]: raise TypeError(self.n_altitude_absorption, "does not have the correct type. type(settings.n_altitude_absorption) must be [int, np.int32, np.int64]") if type(self.n_harmonics) not in [int, np.int32, np.int64]: raise TypeError(self.n_harmonics, "does not have the correct type. type(settings.n_harmonics) must be [int, np.int32, np.int64]") if type(self.A_e) not in [float, np.float32, np.float64]: raise TypeError(self.A_e, "does not have the correct type. type(settings.A_e) must be [float, np.float32, np.float64]") if type(self.dt_epnl) not in [float, np.float32, np.float64]: raise TypeError(self.dt_epnl, "does not have the correct type. type(settings.dt_epnl) must be [float, np.float32, np.float64]") if type(self.r_0) not in [float, np.float32, np.float64]: raise TypeError(self.r_0, "does not have the correct type. type(settings.r_0) must be [float, np.float32, np.float64]") if type(self.p_ref) not in [float, np.float32, np.float64]: raise TypeError(self.p_ref, "does not have the correct type. type(settings.p_ref) must be [float, np.float32, np.float64]") if type(self.x_observer_array) != np.ndarray: raise TypeError(self.x_observer_array, "does not have the correct type. type(settings.x_observer_array) must be np.ndarray") if self.observer_lst in [('lateral', ), ('flyover', )] and np.shape(self.x_observer_array) != (1,3): raise ValueError("Shape of the x_observer_array must be (1, 3); instead shape is ", np.shape(self.x_observer_array)) elif self.observer_lst in [('lateral', 'flyover', ), ('flyover', 'lateral')] and np.shape(self.x_observer_array) != (2,3): raise ValueError("Shape of the x_observer_array must be (2, 3); instead shape is ", np.shape(self.x_observer_array)) # Trajectory options if type(self.TS_to) not in [float, np.float32, np.float64]: raise TypeError(self.TS_to, "does not have the correct type. type(settings.TS_to) must be in [float, np.float32, np.float64]") if type(self.TS_vnrs) not in [float, np.float32, np.float64]: raise TypeError(self.TS_vnrs, "does not have the correct type. type(settings.TS_vnrs) must be in [float, np.float32, np.float64]") NoneType = type(None) if type(self.TS_cutback) not in [NoneType, float, np.float32, np.float64]: raise TypeError(self.TS_cutback, "does not have the correct type. type(settings.TS_cutback) must be in [float, np.float32, np.float64]") if type(self.z_cutback) not in [float, np.float32, np.float64]: raise TypeError(self.z_cutback, "does not have the correct type. type(settings.z_cutback) must be in [float, np.float32, np.float64]") if type(self.theta_flaps) not in [float, np.float32, np.float64]: raise TypeError(self.theta_flaps, "does not have the correct type. type(settings.theta_flaps) must be np.ndarray") if type(self.theta_slats) not in [float, np.float32, np.float64]: raise TypeError(self.theta_slats, "does not have the correct type. type(settings.theta_slats) must be np.ndarray") if type(self.n_segments_vnrs) not in [int, np.int32, np.int64]: raise TypeError(self.n_segments_vnrs, "does not have the correct type. type(settings.n_segments_vnrs) must be in [int, np.int32, np.int64]") if type(self.max_iter) not in [int, np.int32, np.int64]: raise TypeError(self.max_iter, "does not have the correct type. type(settings.max_iter) must be in [int, np.int32, np.int64]") # Observer list for observer in self.observer_lst: if observer not in ['lateral','flyover', 'approach', 'contours']: raise ValueError(observer, "is not a valid option for the observer list. Specify any from 'lateral'/'flyover'/'approach'/'contours'") # Language to use to solve components (julia/python) if self.language not in ['python', 'julia']: raise ValueError("Invalid environment variable pyna_language. Specify 'python'/'julia'.") # Set all noise components equal to True if settings.all_sources == True if self.all_sources: self.fan_inlet = True self.fan_discharge = True self.core = True self.jet_mixing = True self.jet_shock = True self.airframe = True # Set lateral and flyover observer locations for nasa_stca_standard trajectory if self.case_name in ['nasa_stca_standard', 'stca_enginedesign_standard']: if self.observer_lst == 'lateral': self.x_observer_array = np.array([[3756.66, 450., 1.2192]]) elif self.observer_lst == 'flyover': self.x_observer_array = np.array([[6500., 0., 1.2192]]) elif self.observer_lst == ['lateral', 'flyover'] or self.observer_lst == ['flyover', 'lateral']: self.x_observer_array = np.array([[3756.66, 450., 1.2192], [6500., 0., 1.2192]]) # Disable validation if not nasa_stca_standard trajectory if not self.case_name == 'nasa_stca_standard': self.validation = False return