diff --git a/aviary/docs/examples_unreviewed/modified_aircraft.csv b/aviary/docs/examples_unreviewed/modified_aircraft.csv index bc2161b95..00aa09ca9 100644 --- a/aviary/docs/examples_unreviewed/modified_aircraft.csv +++ b/aviary/docs/examples_unreviewed/modified_aircraft.csv @@ -52,7 +52,6 @@ aircraft:engine:reference_mass,7400,lbm aircraft:engine:reference_sls_thrust,28928.1,lbf aircraft:engine:scale_factor,1.0,unitless aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,28928.1,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.,unitless diff --git a/aviary/docs/user_guide_unreviewed/subsystems/propulsion.ipynb b/aviary/docs/user_guide_unreviewed/subsystems/propulsion.ipynb index 2f1395202..93a12a746 100644 --- a/aviary/docs/user_guide_unreviewed/subsystems/propulsion.ipynb +++ b/aviary/docs/user_guide_unreviewed/subsystems/propulsion.ipynb @@ -158,7 +158,6 @@ "Aircraft.Engine = Aircraft.Engine\n", "check_contains(required_options, CoreMetaData)\n", "required = ( # f'{Aircraft.Engine.DATA_FILE=}'.split('=')[0],\n", - " get_variable_name(Aircraft.Engine.SCALE_PERFORMANCE),\n", " get_variable_name(Aircraft.Engine.IGNORE_NEGATIVE_THRUST),\n", " get_variable_name(Aircraft.Engine.GEOPOTENTIAL_ALT),\n", " get_variable_name(Aircraft.Engine.GENERATE_FLIGHT_IDLE),\n", @@ -213,7 +212,7 @@ "If you are missing any required variables, you may see a warning at runtime, depending on verbosity level. Aviary will try using the default value for the missing variable, which may affect analysis results.\n", "\n", "```\n", - "UserWarning: is a required option for EngineDecks, but has not been specified for EngineDeck . The default value will be used.\n", + "UserWarning: is a required option for EngineDecks, but has not been specified for EngineDeck . The default value will be used.\n", "```\n", "\n", "\n", diff --git a/aviary/interface/test/sizing_results_for_test.json b/aviary/interface/test/sizing_results_for_test.json index 601d951ee..1d29cbb26 100644 --- a/aviary/interface/test/sizing_results_for_test.json +++ b/aviary/interface/test/sizing_results_for_test.json @@ -407,14 +407,6 @@ "unitless", "" ], - [ - "aircraft:engine:scale_performance", - [ - true - ], - "unitless", - "" - ], [ "aircraft:engine:scaled_sls_thrust", [ diff --git a/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_data.py b/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_data.py index dc74b5080..2ee53ed07 100644 --- a/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_data.py +++ b/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_data.py @@ -213,7 +213,6 @@ inputs.set_val(Aircraft.Engine.WING_LOCATIONS, 0.289682918) inputs.set_val(Aircraft.Engine.SCALE_MASS, True) inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.15) -inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index 1599fb449..08cefd919 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -72,7 +72,6 @@ aircraft:engine:reference_mass,22017.0,lbm aircraft:engine:reference_sls_thrust,86459.2,lbf aircraft:engine:scale_factor,0.8096304384,unitless aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,70000,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.0,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.0,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py index 215494888..65797405f 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py @@ -167,7 +167,6 @@ inputs.set_val(Aircraft.Engine.SCALE_FACTOR, 0.8096304384) # THRUST/THRSO inputs.set_val(Aircraft.Engine.SCALE_MASS, True) inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.0) # EEXP -inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) # FFFSUB inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) # FFFSUP inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) # DFFAC diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index 52357c1ab..88442603e 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -72,7 +72,6 @@ aircraft:engine:reference_mass,22017.0,lbm aircraft:engine:reference_sls_thrust,86459.2,lbf aircraft:engine:scale_factor,0.8096304384,unitless aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,70000,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.0,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.0,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py index 6269b232a..9686b15ff 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py @@ -169,7 +169,6 @@ inputs.set_val(Aircraft.Engine.SCALE_FACTOR, 0.8096304384) # THRUST/THRSO inputs.set_val(Aircraft.Engine.SCALE_MASS, True) inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.0) # EEXP -inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) # FFFSUB inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) # FFFSUP inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) # DFFAC diff --git a/aviary/models/aircraft/large_single_aisle_1/large_single_aisle_1_FLOPS_data.py b/aviary/models/aircraft/large_single_aisle_1/large_single_aisle_1_FLOPS_data.py index 229376a8a..2feaa6e11 100644 --- a/aviary/models/aircraft/large_single_aisle_1/large_single_aisle_1_FLOPS_data.py +++ b/aviary/models/aircraft/large_single_aisle_1/large_single_aisle_1_FLOPS_data.py @@ -162,7 +162,6 @@ inputs.set_val(Aircraft.Engine.SCALE_FACTOR, 1.0) inputs.set_val(Aircraft.Engine.SCALE_MASS, True) inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.15) -inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) diff --git a/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_FLOPS_data.py b/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_FLOPS_data.py index 733480765..c489ffce9 100644 --- a/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_FLOPS_data.py +++ b/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_FLOPS_data.py @@ -168,7 +168,6 @@ inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SCALE_MASS, True) inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.15) -inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) inputs.set_val(Aircraft.Engine.SCALE_FACTOR, 1.0) inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) diff --git a/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_altwt_FLOPS_data.py b/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_altwt_FLOPS_data.py index 4b80e20a1..83abfdfde 100644 --- a/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_altwt_FLOPS_data.py +++ b/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_altwt_FLOPS_data.py @@ -167,7 +167,6 @@ inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SCALE_MASS, True) inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.15) -inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) diff --git a/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_detailwing_FLOPS_data.py b/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_detailwing_FLOPS_data.py index 677746351..d9d05694d 100644 --- a/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_detailwing_FLOPS_data.py +++ b/aviary/models/aircraft/large_single_aisle_2/large_single_aisle_2_detailwing_FLOPS_data.py @@ -158,7 +158,6 @@ inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SCALE_MASS, True) inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.15) -inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) diff --git a/aviary/models/aircraft/multi_engine_single_aisle/multi_engine_single_aisle_data.py b/aviary/models/aircraft/multi_engine_single_aisle/multi_engine_single_aisle_data.py index a6d98cbde..322bebf1b 100644 --- a/aviary/models/aircraft/multi_engine_single_aisle/multi_engine_single_aisle_data.py +++ b/aviary/models/aircraft/multi_engine_single_aisle/multi_engine_single_aisle_data.py @@ -164,7 +164,6 @@ engine_1_inputs.set_val(Aircraft.Engine.WING_LOCATIONS, 15.8300 / (117.83 / 2)) engine_1_inputs.set_val(Aircraft.Engine.SCALE_MASS, True) engine_1_inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.15) -engine_1_inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) engine_1_inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) engine_1_inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) engine_1_inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) @@ -197,7 +196,6 @@ engine_2_inputs.set_val(Aircraft.Engine.WING_LOCATIONS, 0.289682918) engine_2_inputs.set_val(Aircraft.Engine.SCALE_MASS, True) engine_2_inputs.set_val(Aircraft.Engine.MASS_SCALER, 1.15) -engine_2_inputs.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) engine_2_inputs.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) engine_2_inputs.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) engine_2_inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) diff --git a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv index 471385666..5a02c7f49 100644 --- a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv +++ b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv @@ -52,7 +52,6 @@ aircraft:engine:reference_mass,7400,lbm aircraft:engine:reference_sls_thrust,28928.1,lbf aircraft:engine:scale_factor,1.0,unitless aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,28928.1,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.,unitless diff --git a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm_with_electric.csv b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm_with_electric.csv index abce32f3b..28458237a 100644 --- a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm_with_electric.csv +++ b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwFm_with_electric.csv @@ -51,7 +51,6 @@ aircraft:engine:reference_mass,7400,lbm aircraft:engine:reference_sls_thrust,28928.1,lbf aircraft:engine:scale_factor,1.0,unitless aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,28928.1,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.,unitless diff --git a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwGm.csv b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwGm.csv index d9c6bcde7..acdda00af 100644 --- a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwGm.csv +++ b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_FwGm.csv @@ -17,7 +17,6 @@ aircraft:design:drag_divergence_shift,0.033,unitless aircraft:engine:constant_fuel_consumption,0.,lbm/h aircraft:engine:data_file,models/engines/turbofan_23k_1.csv,unitless aircraft:engine:global_throttle, True, unitless -aircraft:engine:scale_performance,False,unitless aircraft:engine:mass_specific,0.21366,lbm/lbf aircraft:engine:fuel_flow_scaler_constant_term,0.,unitless aircraft:engine:fuel_flow_scaler_linear_term,0.,unitless @@ -37,7 +36,6 @@ aircraft:engine:reference_mass,7400,lbm aircraft:engine:reference_sls_thrust,28928.1,lbf aircraft:engine:scale_factor,1.0,unitless aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,28928.1,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.,unitless diff --git a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_solved2dof.csv b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_solved2dof.csv index f9647bbd9..954301efb 100644 --- a/aviary/models/aircraft/test_aircraft/aircraft_for_bench_solved2dof.csv +++ b/aviary/models/aircraft/test_aircraft/aircraft_for_bench_solved2dof.csv @@ -51,7 +51,6 @@ aircraft:engine:reference_mass,7400,lbm aircraft:engine:reference_sls_thrust,28928.1,lbf aircraft:engine:scale_factor,1.0,unitless aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,28928.1,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.,unitless diff --git a/aviary/subsystems/aerodynamics/flops_based/test/data/high_wing_single_aisle.csv b/aviary/subsystems/aerodynamics/flops_based/test/data/high_wing_single_aisle.csv index cfd0e8037..a2ae07f94 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/data/high_wing_single_aisle.csv +++ b/aviary/subsystems/aerodynamics/flops_based/test/data/high_wing_single_aisle.csv @@ -44,7 +44,6 @@ aircraft:engine:num_wing_engines,2,unitless aircraft:engine:reference_mass,4600.0,lbm aircraft:engine:reference_sls_thrust,23000.0,lbf aircraft:engine:scale_mass,True,unitless -aircraft:engine:scale_performance,True,unitless aircraft:engine:scaled_sls_thrust,23000.0,lbf aircraft:engine:subsonic_fuel_flow_scaler,1.,unitless aircraft:engine:supersonic_fuel_flow_scaler,1.,unitless diff --git a/aviary/subsystems/propulsion/engine_deck.py b/aviary/subsystems/propulsion/engine_deck.py index 307a9a4ba..ecf765f1c 100644 --- a/aviary/subsystems/propulsion/engine_deck.py +++ b/aviary/subsystems/propulsion/engine_deck.py @@ -8,19 +8,18 @@ Aliases ------- aliases : dict - The strings that are accepted as valid header names after converted to all lowercase - with all whitespace removed, mapped to the enum EngineModelVariables. + The strings that are accepted as valid header names after converted to all lowercase with all + whitespace removed, mapped to the enum EngineModelVariables. default_required_variables : set - Variables that must be present in an EngineDeck's DATA_FILE (Mach, altitude, etc.). - Can be replaced by user-provided set. + Variables that must be present in an EngineDeck's DATA_FILE (Mach, altitude, etc.). Can be + replaced by user-provided set. required_options : tuple Options that must be present in an EngineDeck's options attribute. dependent_options : dict - Options that may or may not be required based on the presence or value of other - provided options. + Options that may or may not be required based on the presence or value of other provided options. """ import math @@ -67,8 +66,7 @@ # EngineDeck assumes all aliases point to an enum, these are used internally only aliases = { - # whitespaces are replaced with underscores converted to lowercase before - # comparison with keys + # whitespaces are replaced with underscores converted to lowercase before comparison with keys MACH: ['m', 'mn', 'mach', 'mach_number'], ALTITUDE: ['altitude', 'alt', 'h'], THROTTLE: ['throttle', 'power_code', 'pc'], @@ -94,18 +92,17 @@ # these variables must be present in engine performance data default_required_variables = {MACH, ALTITUDE, THROTTLE, THRUST} -# EngineDecks internally require these options to have values. Input checks will set -# these options to default values in self.options if they are not provided +# EngineDecks internally require these options to have values. Input checks will set these options +# to default values in self.options if they are not provided required_options = ( - Aircraft.Engine.SCALE_PERFORMANCE, Aircraft.Engine.IGNORE_NEGATIVE_THRUST, Aircraft.Engine.GEOPOTENTIAL_ALT, Aircraft.Engine.GENERATE_FLIGHT_IDLE, Aircraft.Engine.INTERPOLATION_METHOD, Aircraft.Engine.INTERPOLATION_SORT, - # TODO fuel flow scaler is required for the EngineScaling component but does not need - # to be defined on a per-engine basis, so it could exist only in the problem- - # level aviary_options without issue. Is this a propulsion_preprocessor task? + # TODO fuel flow scaler is required for the EngineScaling component but does not need to be + # defined on a per-engine basis, so it could exist only in the problem-level aviary_options + # without issue. Is this a propulsion_preprocessor task? Mission.FUEL_FLOW_SCALER, ) @@ -130,11 +127,10 @@ class EngineDeck(EngineModel): options : AviaryValues () Inputs and options related to engine model. data : NamedVaues (), optional - Engine performance data (optional). If provided, used instead of tabular data - file. + Engine performance data (optional). If provided, used instead of tabular data file. required_variables : set, optional - A set of required variables (from EngineModelVariables) for this EngineDeck. - Defaults to the required set {ALTITUDE, MACH, THROTTLE, THRUST}. + A set of required variables (from EngineModelVariables) for this EngineDeck. Defaults to the + required set {ALTITUDE, MACH, THROTTLE, THRUST}. Methods ------- @@ -174,8 +170,7 @@ def __init__( else: self.error_message = f'EngineDeck <{self.name}>' - # copy of raw data read from data_file or memory, never modified or used outside - # EngineDeck + # copy of raw data read from data_file or memory, never modified or used outside EngineDeck self._original_data = {key: np.array([]) for key in EngineModelVariables} # working copy of engine performance data, is modified during data pre-processing self.data = {key: np.array([]) for key in EngineModelVariables} @@ -219,9 +214,8 @@ def __init__( def _preprocess_inputs(self): """ - Checks that provided options are valid and logically consistent. Raises errors - for non-recoverable issues, issues warnings for minor problems that are fixed at - runtime. + Checks that provided options are valid and logically consistent. Raises errors for + non-recoverable issues, issues warnings for minor problems that are fixed at runtime. Raises ------ @@ -246,10 +240,9 @@ def _preprocess_inputs(self): if self.get_val(Settings.VERBOSITY) > Verbosity.BRIEF: warnings.warn( - f'<{key}> is a required option for EngineDecks, but has not been ' - f'specified for EngineDeck <{self.name}>. The default value ' - f'{val}{" " + units if units != "unitless" else ""} will ' - 'be used.' + f'<{key}> is a required option for EngineDecks, but has not been specified' + f'for EngineDeck <{self.name}>. The default value ' + f'{val}{" " + units if units != "unitless" else ""} will be used.' ) self.set_val(key, val, units) @@ -267,49 +260,17 @@ def _preprocess_inputs(self): if self.get_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE): idle_min = self.get_val(Aircraft.Engine.FLIGHT_IDLE_MIN_FRACTION) idle_max = self.get_val(Aircraft.Engine.FLIGHT_IDLE_MAX_FRACTION) - # Allowing idle fractions to be equal, i.e. fixing flight idle conditions - # instead of extrapolation + # Allowing idle fractions to be equal, i.e. fixing flight idle conditions instead of + # extrapolation if idle_min > idle_max: - if self.get_val(Settings.VERBOSITY).value >= 1: + if self.get_val(Settings.VERBOSITY).value >= Verbosity.BRIEF: warnings.warn( - f'EngineDeck <{self.name}>: Minimum flight idle fraction ' - 'exceeds maximum flight idle fraction. Values for min and max ' - 'fraction will be flipped.' + f'EngineDeck <{self.name}>: Minimum flight idle fraction exceeds maximum ' + 'flight idle fraction. Values for min and max fraction will be flipped.' ) self.set_val(Aircraft.Engine.FLIGHT_IDLE_MIN_FRACTION, val=idle_max) self.set_val(Aircraft.Engine.FLIGHT_IDLE_MAX_FRACTION, val=idle_min) - # check that sufficient information on engine scaling is provided - # default behavior is to calculate scale factor based on thrust target - engine_mapping = get_keys(self.options) - - # check if scale factor and thrust target are user defined and check consistency - scale_performance = self.get_val(Aircraft.Engine.SCALE_PERFORMANCE) - scale_factor_provided = False - thrust_provided = False - # was scale factor originally provided? (Not defaulted) - if Aircraft.Engine.SCALE_FACTOR in engine_mapping: - # if scale factor is 1, doesn't conflict with performance scaling turned off - if self.options.get_val(Aircraft.Engine.SCALE_FACTOR) == 1: - scale_factor_provided = False - else: - scale_factor_provided = True - # was scaled thrust originally provided? (Not defaulted) - if Aircraft.Engine.SCALED_SLS_THRUST in engine_mapping: - thrust_provided = True - - # user provided target thrust or scale factor, but performance scaling is off - if ( - not scale_performance - and (scale_factor_provided or thrust_provided) - and self.get_val(Settings.VERBOSITY).value >= 1 - ): - warnings.warn( - f'EngineDeck <{self.name}>: Scaling targets are provided, but will be ' - 'ignored because performance scaling is disabled. Set ' - 'aircraft:engine:scale_performance to True to enable scaling.' - ) - # Check validity of interp_sort. # TODO: support this as an enum instead. interp_sort = self.get_val(Aircraft.Engine.INTERPOLATION_SORT) @@ -321,13 +282,13 @@ def _preprocess_inputs(self): def _set_variable_flags(self): """ - Sets flags in EngineDeck to communicate which (non-required) variables are - available to greater propulsion module. + Sets flags in EngineDeck to communicate which (non-required) variables are available to + greater propulsion module. """ engine_variables = self.engine_variables - # these flags are shortcuts for common checks for the presence of specific - # variables in the engine deck + # these flags are shortcuts for common checks for the presence of specific variables in the + # engine deck self.use_thrust = ( THRUST in engine_variables or TAILPIPE_THRUST in engine_variables @@ -347,7 +308,7 @@ def _setup(self, data): - Sort and pack data - Determine reference thrust (optional) - Normalize throttles & hybrid throttles - - Fill flight idle points (optional) + - Fill flight idle points (optional). """ self._read_data(data) @@ -379,8 +340,8 @@ def _read_data(self, raw_data: NamedValues): Parameters ---------- raw_data : NamedValues (optional) - Data provided via a NamedValues object. Will be used as data source instead - of Aircraft.Engine.DATA_FILE if self.read_from_file is False + Data provided via a NamedValues object. Will be used as data source instead of + Aircraft.Engine.DATA_FILE if self.read_from_file is False Raises ------ @@ -414,13 +375,13 @@ def _read_data(self, raw_data: NamedValues): raw_data.delete(name) raw_data.set_val(alias_dict[name], val, units) - # Loop through all variables in provided data. Track which valid variables are - # included with the data and save raw data for reference + # Loop through all variables in provided data. Track which valid variables are included with + # the data and save raw data for reference for key in get_keys(raw_data): val, units = raw_data.get_item(key) if key in aliases: - # Convert data to expected units. Required so settings like tolerances - # that assume units work as expected + # Convert data to expected units. Required so settings like tolerances that assume + # units work as expected try: val = np.array([convert_units(i, units, default_units[key]) for i in val]) except TypeError: @@ -430,8 +391,8 @@ def _read_data(self, raw_data: NamedValues): f'units of {default_units[key]}' ) - # Engine_variables currently only used to store "valid" engine variables - # as defined in EngineModelVariables Enum + # Engine_variables currently only used to store "valid" engine variables as defined + # in EngineModelVariables Enum self.engine_variables[key] = default_units[key] else: @@ -446,22 +407,22 @@ def _read_data(self, raw_data: NamedValues): if not self.engine_variables: raise UserWarning(f'No valid engine variables found in data for {self.error_message}') - # Copy data from original data (never modified) to working data (changed through - # sorting, generating missing data, etc.) + # Copy data from original data (never modified) to working data (changed through sorting, + # generating missing data, etc.) for key in self.data: self.data[key] = self._original_data[key] def _check_data(self): """ - Checks for consistency of provided thrust and drag data, ensures no required - variables are missing, fills unused variables with a default value of zero, and - removes negative thrusts if requested. + Checks for consistency of provided thrust and drag data, ensures no required variables are + missing, fills unused variables with a default value of zero, and removes negative thrusts + if requested. Raises ------ UserWarning - If provided net thrust does not match difference between provided gross - thrust and ram drag within tolerance. + If provided net thrust does not match difference between provided gross thrust and ram + drag within tolerance. UserWarning If required variables are not present in the provided engine data. """ @@ -473,18 +434,19 @@ def _check_data(self): # Handle ram drag, net and gross thrust and potential conflicts in value or units # Warn user if they provide partial info for calculated thrust # Not a fail state if net thrust is still provided - # If both net thrust and components for calculated thrust both provided, a sanity - # check that they match is done after reading data + # If both net thrust and components for calculated thrust both provided, a sanity check that + # they match is done after reading data if THRUST in engine_variables: # if thrust is present, but gross thrust or ram drag also present raise warning if GROSS_THRUST in engine_variables and RAM_DRAG not in engine_variables: warnings.warn( - f'{self.error_message} contains both net and gross thrust. Only net thrust will be used.' + f'{self.error_message} contains both net and gross thrust. Only net thrust will ' + 'be used.' ) if GROSS_THRUST not in engine_variables and RAM_DRAG in engine_variables: warnings.warn( - f'{self.error_message} contains both net thrust ' - 'and ram drag. Only net thrust will be used.' + f'{self.error_message} contains both net thrust and ram drag. Only net thrust ' + 'will be used.' ) if RAM_DRAG in engine_variables and GROSS_THRUST in engine_variables: @@ -504,9 +466,8 @@ def _check_data(self): res = abs(net_thrust_calc - original_data[THRUST]) if np.any(self.thrust_tol > res): raise UserWarning( - 'Provided net thrust is not equal to difference ' - '(within tolerance) between gross thrust and ram ' - f'drag in {self.error_message}' + 'Provided net thrust is not equal to difference (within tolerance) between ' + f'gross thrust and ram drag in {self.error_message}' ) else: # store net thrust in THRUST key instead of gross thrust @@ -541,19 +502,19 @@ def _check_data(self): engine_variables.pop(TAILPIPE_THRUST) self.data.pop(TAILPIPE_THRUST) - # Handle shaft power (corrected and uncorrected). It is not possible to compare - # them for consistency, as that requires information not available during setup - # (freestream air temp and pressure). Instead, we must trust the source and - # assume either data set is valid and can be used. + # Handle shaft power (corrected and uncorrected). It is not possible to compare them for + # consistency, as that requires information not available during setup (freestream air temp + # and pressure). Instead, we must trust the source and assume either data set is valid and + # can be used. if ( SHAFT_POWER in engine_variables and SHAFT_POWER_CORRECTED in engine_variables and self.get_val(Settings.VERBOSITY) >= Verbosity.BRIEF ): warnings.warn( - 'Both corrected and uncorrected shaft horsepower are ' - f'present in {self.error_message}. The two cannot be validated for ' - 'consistency, and only uncorrected shaft power will be used.' + 'Both corrected and uncorrected shaft horsepower are present in ' + f'{self.error_message}. The two cannot be validated for consistency, and only ' + 'uncorrected shaft power will be used.' ) engine_variables.pop(SHAFT_POWER_CORRECTED) self.data.pop(SHAFT_POWER_CORRECTED) @@ -592,8 +553,8 @@ def _check_data(self): def _generate_flight_idle(self): """ - Generate flight idle data via extrapolation from lowest points in data set, - bound by upper and lower constraints set by user. + Generate flight idle data via extrapolation from lowest points in data set, bound by upper + and lower constraints set by user. Requires sorted, packed data with normalized throttles. @@ -644,11 +605,11 @@ def _extrapolate(array): alt_max_count = self.alt_max_count data_indices = self.data_indices - # Throttle is already normalized from 0 to 1. Set flight idle to -0.1, which will - # get re-normalized to 0 - # -0.1 is chosen to avoid stretching out the data range while at the same time - # avoiding "discontinuities" in engine data from very small negative throttles - # (e.g. a jump from -1e-6 to 0). Basically, this is an arbitrary number + # Throttle is already normalized from 0 to 1. Set flight idle to -0.1, which will get + # re-normalized to 0 + # -0.1 is chosen to avoid stretching out the data range while at the same time avoiding + # "discontinuities" in engine data from very small negative throttles (e.g. a jump from + # -1e-6 to 0). Basically, this is an arbitrary number throttle_idle = -0.1 # Hybrid throttle idle MUST be zero by definition. Any lower (negative) and generated power # is increased. Any higher (positive) and consumed power is increased. @@ -656,11 +617,10 @@ def _extrapolate(array): idle_points = {key: np.empty(0) for key in packed_data} - # Normally, only one idle point is needed - however, when hybrid throttle is - # present, there needs to be a sweep of points for a given Mach/alt/throttle - # to satisfy the interpolator's requirements for at least 3 points per dimension - # The data values at each point in the sweep are kept identical (e.g. same thrust, - # fuel flow, etc. as calculated by extrapolation) + # Normally, only one idle point is needed - however, when hybrid throttle is present, there + # needs to be a sweep of points for a given Mach/alt/throttle to satisfy the interpolator's + # requirements for at least 3 points per dimension The data values at each point in the + # sweep are kept identical (e.g. same thrust, fuel flow, etc. as calculated by extrapolation) num_points = 1 if self.use_hybrid_throttle: num_points = 3 @@ -675,10 +635,10 @@ def _extrapolate(array): if data_indices[M, A] == 0: skip = True - # don't generate flight idle points if thrust is already zero or negative - # at lowest index - # NOTE reusing thrust_tol to apply to shaft power, results in shaft power - # tol being much tighter if both in same unit system + # Don't generate flight idle points if thrust is already zero or negative at lowest + # index + # NOTE reusing thrust_tol to apply to shaft power, results in shaft power tol being + # much tighter if both in same unit system for var in direct_calc_vars: if packed_data[var][M, A, 0] <= self.thrust_tol: skip = True @@ -710,8 +670,8 @@ def _extrapolate(array): idle_points[HYBRID_THROTTLE], hybrid_throttle_idle ) - # if there is only one data point at this Mach, alt combination, use - # thrust fraction instead of extrapolation + # if there is only one data point at this Mach, alt combination, use thrust fraction + # instead of extrapolation if data_indices[M, A] == 1: # Find the point closest to hybrid throttle idle (0) if hybrid throttle is present if self.use_hybrid_throttle: @@ -757,11 +717,10 @@ def _extrapolate(array): # add this point to idle_points idle_points[var] = np.append(idle_points[var], [idle_calc_value] * num_points) - # Calculate term for linear extrapolation - shaft power has highest - # "preference" since it is last in the list, followed by corrected - # shaft power then finally thrust. This is designed for compatibility - # with turboshaft engine decks in TurbopropModels. - # Only one extrapolation term can be used for all dependent vars + # Calculate term for linear extrapolation - shaft power has highest "preference" + # since it is last in the list, followed by corrected shaft power then finally + # thrust. This is designed for compatibility with turboshaft engine decks in + # TurbopropModels. Only one extrapolation term can be used for all dependent vars extrap_term = (idle_calc_value - packed_data[var][M, A, 0]) / ( packed_data[var][M, A, 1] - packed_data[var][M, A, 0] ) @@ -795,8 +754,7 @@ def _extrapolate(array): # save idle points, in case they are wanted later self.idle_points = idle_points - # Re-sort and re-pack data with flight idle information to keep data - # structures consistent + # Re-sort and re-pack data with flight idle information to keep data structures consistent self._pack_data() # Re-normalize throttle since "dummy" idle values were used @@ -808,8 +766,8 @@ def build_pre_mission(self, aviary_inputs, subsystem_options=None) -> om.Explici Returns ------- - SizeEngine component specific to this EngineDeck, used for calculating engine - scaling factors. + SizeEngine component specific to this EngineDeck, used for calculating engine scaling + factors. """ return SizeEngine() @@ -888,8 +846,8 @@ def _build_engine_interpolator(self, num_nodes, aviary_inputs): def build_mission(self, num_nodes, aviary_inputs, user_options, subsystem_options) -> om.Group: """ Creates interpolator objects to be added to mission-level propulsion subsystem. - Interpolators must be re-generated for each ODE due to potentially different - num_nodes in each mission segment. + Interpolators must be re-generated for each ODE due to potentially different num_nodes in + each mission segment. Parameters ---------- @@ -905,9 +863,8 @@ def build_mission(self, num_nodes, aviary_inputs, user_options, subsystem_option Returns ------- engine_group : openmdao.core.Group - An OpenMDAO group containing engine data interpolators, an EngineScaling - component, and max throttle/max hybrid_throttle generating components as - needed for this EngineDeck. + An OpenMDAO group containing engine data interpolators, an EngineScaling component, and + max throttle/max hybrid_throttle generating components as needed for this EngineDeck. """ interp_method = self.get_val(Aircraft.Engine.INTERPOLATION_METHOD) interp_sort = self.get_val(Aircraft.Engine.INTERPOLATION_SORT) @@ -917,8 +874,8 @@ def build_mission(self, num_nodes, aviary_inputs, user_options, subsystem_option engine = self._build_engine_interpolator(num_nodes, aviary_inputs) units = self.engine_variable_units - # Create copy of interpolation component that computes max thrust/shp for current - # flight condition + # Create copy of interpolation component that computes max thrust/shp for current flight + # condition # NOTE max thrust is assumed to occur at maximum throttle and hybrid throttle # for each flight condition # TODO Use solver to find throttle/hybrid throttle for maximum thrust at given flight condition? @@ -1171,8 +1128,8 @@ def build_mission(self, num_nodes, aviary_inputs, user_options, subsystem_option promotes_outputs=['*'], ) - # manually connect unscaled variables, since we do not want them promoted - # skip variables that are not outputs of scaling component + # Manually connect unscaled variables, since we do not want them promoted + # Skip variables that are not outputs of scaling component skipped_variables = [ MACH, ALTITUDE, @@ -1347,7 +1304,6 @@ def _set_reference_thrust(self): ) # Update SCALED_SLS_THRUST if required based on scaling information provided - scale_performance = self.get_val(Aircraft.Engine.SCALE_PERFORMANCE) scale_factor_provided = False thrust_provided = False # was scale factor originally provided? (Not defaulted) @@ -1364,44 +1320,34 @@ def _set_reference_thrust(self): # both scale factor and target thrust provided: if thrust_provided: scaled_thrust = self.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') - if scale_performance: - # Check if target thrust and ref thrust * scale factor match using - # rough tolerance - # Tolerance is arbitrary, but designed to handle thrusts in the - # hundreds of thousands via rel_tol, and the hundreds via abs_tol - if not math.isclose( - scaled_thrust, - ref_thrust * scale_factor, - abs_tol=1e-1, - rel_tol=1e-4, - ): - # user wants scaling but provided conflicting inputs, - # cannot be resolved - raise AttributeError( - f'EngineDeck <{self.name}>: Conflicting values provided ' - 'for aircraft:engine:scale_factor and ' - 'aircraft:engine:scaled_sls_thrust when compared against ' - 'aircraft:engine:reference_sls_thrust' - ) - # get thrust target & scale factor matching exactly. Scale factor is - # design variable, so don't touch it!! Instead change output thrust - else: - target_thrust = ref_thrust * scale_factor - if self.get_val(Settings.VERBOSITY) >= Verbosity.VERBOSE: - warnings.warn( - f'EngineDeck <{self.name}>: ' - 'aircraft:engine:scaled_sls_thrust and ' - 'product of aircraft:engine_scale_factor and ' - 'aircraft:engine:reference_sls_thrust are not an exact ' - 'match but within tolerance. Setting scaled thrust ' - f'target to calculated value of {target_thrust} lbf.' - ) - self.set_val(Aircraft.Engine.SCALED_SLS_THRUST, target_thrust, 'lbf') + # Check if target thrust and ref thrust * scale factor match using rough tolerance + # Tolerance is arbitrary, but designed to handle thrusts in the hundreds of + # thousands via rel_tol, and the hundreds via abs_tol + if not math.isclose( + scaled_thrust, + ref_thrust * scale_factor, + abs_tol=1e-1, + rel_tol=1e-4, + ): + # user wants scaling but provided conflicting inputs, cannot be resolved + raise AttributeError( + f'EngineDeck <{self.name}>: Conflicting values provided for ' + 'aircraft:engine:scale_factor and aircraft:engine:scaled_sls_thrust when ' + 'compared against aircraft:engine:reference_sls_thrust' + ) + # get thrust target & scale factor matching exactly. Scale factor is design + # variable, so don't touch it!! Instead change output thrust else: - # engine is not scaled: make sure scaled thrust = ref thrust and - # scale factor = 1 - self.set_val(Aircraft.Engine.SCALED_SLS_THRUST, ref_thrust, 'lbf') - self.set_val(Aircraft.Engine.SCALE_FACTOR, 1.0) + target_thrust = ref_thrust * scale_factor + if self.get_val(Settings.VERBOSITY) >= Verbosity.VERBOSE: + warnings.warn( + f'EngineDeck <{self.name}>: aircraft:engine:scaled_sls_thrust and ' + 'product of aircraft:engine_scale_factor and ' + 'aircraft:engine:reference_sls_thrust are not an exact match but within ' + 'tolerance. Setting scaled thrust target to calculated value of ' + f'{target_thrust} lbf.' + ) + self.set_val(Aircraft.Engine.SCALED_SLS_THRUST, target_thrust, 'lbf') # scale factor provided, but not target thrust else: @@ -1412,44 +1358,35 @@ def _set_reference_thrust(self): # target thrust provided, but not scale factor elif thrust_provided: scaled_thrust = self.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') - if scale_performance: - scale_factor = scaled_thrust / ref_thrust - if self.get_val(Settings.VERBOSITY) >= Verbosity.VERBOSE: - warnings.warn( - f'EngineDeck <{self.name}>: aircraft:engine:scale_factor has ' - 'been indirectly set by the ratio of ' - 'aircraft:engine:scaled_sls_thrust and ' - f'aircraft:engine:reference_sls_thrust to {scale_factor}' - ) - self.set_val(Aircraft.Engine.SCALE_FACTOR, scale_factor) - else: - # engine is not scaled: just make sure scale_factor = 1 - self.set_val(Aircraft.Engine.SCALE_FACTOR, 1.0) + scale_factor = scaled_thrust / ref_thrust + if self.get_val(Settings.VERBOSITY) >= Verbosity.VERBOSE: + warnings.warn( + f'EngineDeck <{self.name}>: aircraft:engine:scale_factor has ' + 'been indirectly set by the ratio of ' + 'aircraft:engine:scaled_sls_thrust and ' + f'aircraft:engine:reference_sls_thrust to {scale_factor}' + ) + self.set_val(Aircraft.Engine.SCALE_FACTOR, scale_factor) # neither scale factor nor target thrust are provided elif not thrust_provided: - if scale_performance: - # user wants to scale, but provided no scaling info: default to - # scale factor of 1, set scaled thrust = ref thrust - scale_factor = 1 - self.set_val(Aircraft.Engine.SCALE_FACTOR, scale_factor) - self.set_val(Aircraft.Engine.SCALED_SLS_THRUST, ref_thrust, 'lbf') - else: - # engine is not scaled: just make sure scaled thrust = ref thrust - scaled_thrust = ref_thrust - self.set_val(Aircraft.Engine.SCALED_SLS_THRUST, scaled_thrust, 'lbf') + # user provided no scaling info: default to scale factor of 1, set scaled thrust = ref + # thrust + scale_factor = 1 + self.set_val(Aircraft.Engine.SCALE_FACTOR, scale_factor) + self.set_val(Aircraft.Engine.SCALED_SLS_THRUST, ref_thrust, 'lbf') def _normalize_throttle(self): """ Normalize throttle and hybrid throttle options. Requires packed data. - Throttle is normalized to [0, 1], while hybrid throttle is normalized to two - separate scales. Negative hybrid throttles are normalized to [-1, 0) and positive - hybrid throttles to (0, 1], with the zero point representing an assumed "idle" - condition based on the provided data. + Throttle is normalized to [0, 1], while hybrid throttle is normalized to two separate + scales. Negative hybrid throttles are normalized to [-1, 0) and positive hybrid throttles to + (0, 1], with the zero point representing an assumed "idle" condition based on the provided + data. - Normalization can be "global" (using max and min values from entire data set), or - "local" (using the max and min values from each individual flight condition). + Normalization can be "global" (using max and min values from entire data set), or "local" + (using the max and min values from each individual flight condition). """ def _hybrid_throttle_norm(hybrid_throttle_list): @@ -1461,9 +1398,9 @@ def _hybrid_throttle_norm(hybrid_throttle_list): <-> 0 (idle hybrid throttle) <-> 1 (max positive hybrid throttle)] - Negative normalized hybrid throttles only appear if negative hybrid throttle - values are provided in engine data. Positive normalized hybrid throttle values - only appear if positive hybrid throttle values are provided in engine data. + Negative normalized hybrid throttles only appear if negative hybrid throttle values are + provided in engine data. Positive normalized hybrid throttle values only appear if + positive hybrid throttle values are provided in engine data. Parameters ---------- @@ -1476,11 +1413,9 @@ def _hybrid_throttle_norm(hybrid_throttle_list): Normalized hybrid throttle data from hybrid_throttle_list. """ norm_hybrid_list = np.array(hybrid_throttle_list) - # Split throttle into positive and negative components - # (track index to preserve order) - # Throttle points at zero do not need to be tracked - they are already - # "normalized", and zero is always assumed to be in the normalization range - # (max or min) + # Split throttle into positive and negative components (track index to preserve order) + # Throttle points at zero do not need to be tracked - they are already "normalized", and + # zero is always assumed to be in the normalization range (max or min) hybrid_throttle_neg_idx = np.where(norm_hybrid_list < 0) if not hybrid_throttle_neg_idx[0].size == 0: hybrid_throttle_neg = norm_hybrid_list[hybrid_throttle_neg_idx] @@ -1578,8 +1513,8 @@ def _sort_data(self): interp_sort = self.get_val(Aircraft.Engine.INTERPOLATION_SORT) engine_data = self.data - # sort engine data to ensure independent variables are always in - # ascending order as required by metamodel interpolator + # sort engine data to ensure independent variables are always in ascending order as required + # by metamodel interpolator # convert engine_data from dict to list so it can be sorted sorted_values = np.array([engine_data[key] for key in engine_data]).transpose() @@ -1611,10 +1546,9 @@ def _sort_data(self): def _pack_data(self): """ - Reorganize data from a dictionary of flat 2d arrays to a dictionary of 3d arrays - organized by Mach, altitude, and data for each engine variable. - Data is an array with a length equal to the number of unique data points at - that Mach, alt point. + Reorganize data from a dictionary of flat 2d arrays to a dictionary of 3d arrays organized + by Mach, altitude, and data for each engine variable. Data is an array with a length equal + to the number of unique data points at that Mach, alt point. """ # method requires sorted data self._sort_data() @@ -1654,8 +1588,7 @@ def _count_data(self): Raises ------ UserWarning - If insufficient number of altitude points (<2) provided for a given Mach - number. + If insufficient number of altitude points (<2) provided for a given Mach number. """ interp_sort = self.get_val(Aircraft.Engine.INTERPOLATION_SORT) @@ -1675,10 +1608,9 @@ def _count_data(self): mach_numbers = self.data[MACH] altitudes = self.data[ALTITUDE] - # Loop through data. Keep track of last unique value (curr_*) to compare each new - # value with - # Count number of altitudes per mach, number of data points per - # mach/altitude combination, compare with max_count + # Loop through data. Keep track of last unique value (curr_*) to compare each new value with + # Count number of altitudes per mach, number of data points per mach/altitude combination, + # compare with max_count for idx in range(self.model_length): mach_num = mach_numbers[idx] alt = altitudes[idx] @@ -1754,18 +1686,19 @@ def _count_data(self): # UTILITY FUNCTIONS # ##################### """ -Functions that do not directly use attributes of EngineDeck (do not require self) are -located here. These functions are currently only used for EngineDecks and are not -applicable to other EngineModels. If any of these functions become useful to other -EngineModels besides EngineDeck, move them to propulsion utils. +Functions that do not directly use attributes of EngineDeck (do not require self) are located here. +These functions are currently only used for EngineDecks and are not applicable to other +EngineModels. If any of these functions become useful to other EngineModels besides EngineDeck, move +them to propulsion utils. """ def normalize(base_list, maximum=None, minimum=None): """ Normalize the given list from 0 to 1. - Maximum or minimum of data range can be overwritten, otherwise range of list - is assumed to contain full range of data that must be normalized. + + Maximum or minimum of data range can be overwritten, otherwise range of list is assumed to + contain full range of data that must be normalized. Parameters ---------- diff --git a/aviary/subsystems/propulsion/engine_scaling.py b/aviary/subsystems/propulsion/engine_scaling.py index d2cbb3fe7..2395c3874 100644 --- a/aviary/subsystems/propulsion/engine_scaling.py +++ b/aviary/subsystems/propulsion/engine_scaling.py @@ -46,7 +46,6 @@ def initialize(self): add_aviary_option(self, Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION, units='lbm/h') add_aviary_option(self, Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM) add_aviary_option(self, Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM) - add_aviary_option(self, Aircraft.Engine.SCALE_PERFORMANCE) add_aviary_option(self, Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER) add_aviary_option(self, Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER) add_aviary_option(self, Mission.FUEL_FLOW_SCALER) @@ -104,7 +103,6 @@ def compute(self, inputs, outputs): options = self.options nn = options['num_nodes'] engine_variables = options['engine_variables'] - scale_performance = options[Aircraft.Engine.SCALE_PERFORMANCE] subsonic_fuel_factor = options[Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER] supersonic_fuel_factor = options[Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER] @@ -120,32 +118,25 @@ def compute(self, inputs, outputs): scale_factor = 1 fuel_flow_scale_factor = np.ones(nn, dtype=engine_scale_factor.dtype) - # if len(scale_idx[0]) > 0: - if scale_performance: - # special factor to scale fuel flow based on thrust when scaling is permitted - # NOTE mission-specific fuel flow scaling factor is overwritten by - # scale_performance = False - - # Calculate fuel flow rate scaling factor using FLOPS-derived equation - fuel_flow_equation_scaling = ( - 1 + constant_fuel_term + linear_fuel_term * (1 - engine_scale_factor) - ) + # Special factor to scale fuel flow based on thrust: + # Calculate fuel flow rate scaling factor using FLOPS-derived equation + fuel_flow_equation_scaling = ( + 1 + constant_fuel_term + linear_fuel_term * (1 - engine_scale_factor) + ) - # use dtype to make complex safe - fuel_flow_mach_scaling = ( - np.ones(nn, dtype=engine_scale_factor.dtype) * subsonic_fuel_factor - ) - supersonic_idx = np.where(mach_number >= 1.0) - fuel_flow_mach_scaling[supersonic_idx] = supersonic_fuel_factor + # use dtype to make complex safe + fuel_flow_mach_scaling = np.ones(nn, dtype=engine_scale_factor.dtype) * subsonic_fuel_factor + supersonic_idx = np.where(mach_number >= 1.0) + fuel_flow_mach_scaling[supersonic_idx] = supersonic_fuel_factor - fuel_flow_scale_factor = ( - engine_scale_factor - * fuel_flow_mach_scaling - * fuel_flow_equation_scaling - * mission_fuel_scaler - ) + fuel_flow_scale_factor = ( + engine_scale_factor + * fuel_flow_mach_scaling + * fuel_flow_equation_scaling + * mission_fuel_scaler + ) - scale_factor = engine_scale_factor + scale_factor = engine_scale_factor # loop through all variables, singling out fuel flow to have special scaling # compute 'max' counterpart of variables that have them @@ -219,7 +210,6 @@ def compute_partials(self, inputs, J): options = self.options nn = options['num_nodes'] engine_variables = options['engine_variables'] - scale_performance = options[Aircraft.Engine.SCALE_PERFORMANCE] subsonic_fuel_factor = options[Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER] supersonic_fuel_factor = options[Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER] @@ -236,37 +226,31 @@ def compute_partials(self, inputs, J): fuel_flow_deriv = np.ones(nn, dtype=engine_scale_factor.dtype) fuel_flow_scale_deriv = np.zeros(nn, dtype=engine_scale_factor.dtype) - scale_factor = 1 - deriv_factor = 0 - if scale_performance: - if FUEL_FLOW in engine_variables: - # Calculate fuel flow rate scaling factor using FLOPS-derived equation - fuel_flow_equation_scaling = ( - 1 + constant_fuel_term + linear_fuel_term * (1 - engine_scale_factor) - ) + if FUEL_FLOW in engine_variables: + # Calculate fuel flow rate scaling factor using FLOPS-derived equation + fuel_flow_equation_scaling = ( + 1 + constant_fuel_term + linear_fuel_term * (1 - engine_scale_factor) + ) - fuel_flow_deriv = ( - -engine_scale_factor - * fuel_flow_mach_scaling - * fuel_flow_equation_scaling - * mission_fuel_scaler - ) + fuel_flow_deriv = ( + -engine_scale_factor + * fuel_flow_mach_scaling + * fuel_flow_equation_scaling + * mission_fuel_scaler + ) - fuel_flow_scale_deriv = ( - -fuel_flow_mach_scaling - * mission_fuel_scaler - * inputs['fuel_flow_rate_unscaled'] - * ( - 1 - + linear_fuel_term - + constant_fuel_term - - (2 * linear_fuel_term * engine_scale_factor) - ) + fuel_flow_scale_deriv = ( + -fuel_flow_mach_scaling + * mission_fuel_scaler + * inputs['fuel_flow_rate_unscaled'] + * ( + 1 + + linear_fuel_term + + constant_fuel_term + - (2 * linear_fuel_term * engine_scale_factor) ) - - scale_factor = engine_scale_factor - deriv_factor = 1.0 + ) for variable in engine_variables: if variable not in skip_variables: @@ -280,13 +264,15 @@ def compute_partials(self, inputs, J): Aircraft.Engine.SCALE_FACTOR, ] = fuel_flow_scale_deriv else: - J[variable.value, variable.value + '_unscaled'] = scale_factor - J[variable.value, Aircraft.Engine.SCALE_FACTOR] = ( - inputs[variable.value + '_unscaled'] * deriv_factor - ) + J[variable.value, variable.value + '_unscaled'] = engine_scale_factor + J[variable.value, Aircraft.Engine.SCALE_FACTOR] = inputs[ + variable.value + '_unscaled' + ] if variable in max_variables: - J[variable.value + '_max', variable.value + '_max_unscaled'] = scale_factor - J[variable.value + '_max', Aircraft.Engine.SCALE_FACTOR] = ( - inputs[variable.value + '_max_unscaled'] * deriv_factor + J[variable.value + '_max', variable.value + '_max_unscaled'] = ( + engine_scale_factor ) + J[variable.value + '_max', Aircraft.Engine.SCALE_FACTOR] = inputs[ + variable.value + '_max_unscaled' + ] diff --git a/aviary/subsystems/propulsion/engine_sizing.py b/aviary/subsystems/propulsion/engine_sizing.py index 84c43dbd6..c150c03f5 100644 --- a/aviary/subsystems/propulsion/engine_sizing.py +++ b/aviary/subsystems/propulsion/engine_sizing.py @@ -15,7 +15,6 @@ class SizeEngine(om.ExplicitComponent): def initialize(self): add_aviary_option(self, Aircraft.Engine.REFERENCE_SLS_THRUST, units='lbf') - add_aviary_option(self, Aircraft.Engine.SCALE_PERFORMANCE) def setup(self): add_aviary_input(self, Aircraft.Engine.SCALE_FACTOR, val=1.0) @@ -31,25 +30,17 @@ def setup(self): # TODO - nacelle_wetted_area: if length, diam get scaled - this should be covered by geom def compute(self, inputs, outputs): - scale_engine = self.options[Aircraft.Engine.SCALE_PERFORMANCE] reference_sls_thrust, _ = self.options[Aircraft.Engine.REFERENCE_SLS_THRUST] engine_scale_factor = inputs[Aircraft.Engine.SCALE_FACTOR] - # Engine is only scaled if required # engine scale factor is ratio of scaled thrust target and reference thrust - if scale_engine: - scaled_sls_thrust = engine_scale_factor * reference_sls_thrust - else: - scaled_sls_thrust = reference_sls_thrust + scaled_sls_thrust = engine_scale_factor * reference_sls_thrust outputs[Aircraft.Engine.SCALED_SLS_THRUST] = scaled_sls_thrust def setup_partials(self): - scale_engine = self.options[Aircraft.Engine.SCALE_PERFORMANCE] - - if scale_engine: - self.declare_partials(Aircraft.Engine.SCALED_SLS_THRUST, Aircraft.Engine.SCALE_FACTOR) + self.declare_partials(Aircraft.Engine.SCALED_SLS_THRUST, Aircraft.Engine.SCALE_FACTOR) def compute_partials(self, inputs, J): reference_sls_thrust, _ = self.options[Aircraft.Engine.REFERENCE_SLS_THRUST] diff --git a/aviary/subsystems/propulsion/test/test_engine_scaling.py b/aviary/subsystems/propulsion/test/test_engine_scaling.py index b820da74e..3cf949852 100644 --- a/aviary/subsystems/propulsion/test/test_engine_scaling.py +++ b/aviary/subsystems/propulsion/test/test_engine_scaling.py @@ -34,7 +34,6 @@ def test_case(self): options.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 1.15) options.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, 1.05) options.set_val(Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION, 10.0, units='lbm/h') - options.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) options.set_val(Aircraft.Engine.SCALE_FACTOR, 0.9) options.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, True) options.set_val(Aircraft.Engine.IGNORE_NEGATIVE_THRUST, False) diff --git a/aviary/subsystems/propulsion/test/test_engine_sizing.py b/aviary/subsystems/propulsion/test/test_engine_sizing.py index f7313f7f7..2dbcc375b 100644 --- a/aviary/subsystems/propulsion/test/test_engine_sizing.py +++ b/aviary/subsystems/propulsion/test/test_engine_sizing.py @@ -21,7 +21,6 @@ def test_case_multiengine(self): options = AviaryValues() options.set_val(Aircraft.Engine.DATA_FILE, filename) - options.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) options.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, True) options.set_val(Aircraft.Engine.IGNORE_NEGATIVE_THRUST, False) options.set_val(Aircraft.Engine.FLIGHT_IDLE_THRUST_FRACTION, 0.0) @@ -30,13 +29,11 @@ def test_case_multiengine(self): options.set_val(Aircraft.Engine.GEOPOTENTIAL_ALT, False) engine = EngineDeck(name='engine', options=options) - # options.set_val(Aircraft.Engine.SCALE_PERFORMANCE, False) # engine2 = EngineDeck(name='engine2', options=options) # preprocess_propulsion(options, [engine, engine2]) ref_thrust = engine.get_item(Aircraft.Engine.REFERENCE_SLS_THRUST) options = { - Aircraft.Engine.SCALE_PERFORMANCE: True, Aircraft.Engine.REFERENCE_SLS_THRUST: ref_thrust, } diff --git a/aviary/subsystems/propulsion/test/test_turboprop_model.py b/aviary/subsystems/propulsion/test/test_turboprop_model.py index 0fa1537f2..c65d05932 100644 --- a/aviary/subsystems/propulsion/test/test_turboprop_model.py +++ b/aviary/subsystems/propulsion/test/test_turboprop_model.py @@ -39,7 +39,6 @@ def prepare_model( options.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, 0.0) options.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, 1.0) options.set_val(Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION, 0.0, units='lbm/h') - options.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) options.set_val(Mission.FUEL_FLOW_SCALER, 1.0) options.set_val(Aircraft.Engine.SCALE_FACTOR, 1) options.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, False) diff --git a/aviary/utils/process_input_decks.py b/aviary/utils/process_input_decks.py index eeb67e4a3..35124c086 100644 --- a/aviary/utils/process_input_decks.py +++ b/aviary/utils/process_input_decks.py @@ -550,16 +550,6 @@ def initialization_guessing(aircraft_values: AviaryValues, initialization_guesse 'alternate': False, }, ], - [ - 'JENGSZ', - { - 'val': 4, - 'relation': '!=', - 'target': Aircraft.Engine.SCALE_PERFORMANCE, - 'result': True, - 'alternate': False, - }, - ], [ Aircraft.HorizontalTail.VOLUME_COEFFICIENT, { diff --git a/aviary/variable_info/functions.py b/aviary/variable_info/functions.py index 424a958ce..886b51d9a 100644 --- a/aviary/variable_info/functions.py +++ b/aviary/variable_info/functions.py @@ -600,7 +600,6 @@ def setup_model_options( # EngineDeck required options), so custom multiengine works opt_names = [ Aircraft.Engine.Motor.DATA_FILE, - Aircraft.Engine.SCALE_PERFORMANCE, Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 588ece73c..1abd21d31 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -2535,25 +2535,6 @@ default_value=True, ) -add_meta_data( - Aircraft.Engine.SCALE_PERFORMANCE, - meta_data=_MetaData, - historical_name={ - 'GASP': None, - 'FLOPS': None, - 'LEAPS1': [ - 'iengine.scale_mode', - '(types)EngineScaleModes.DEFAULT', - ], - }, - desc='Toggle for enabling scaling of engine performance including thrust, fuel flow, ' - 'and electric power using Aircraft.Engine.SCALE_FACTOR', - option=True, - types=bool, - multivalue=True, - default_value=True, -) - add_meta_data( Aircraft.Engine.SCALED_SLS_THRUST, meta_data=_MetaData, diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 7c7bcb6f9..f8679e7a4 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -216,7 +216,6 @@ class Engine: RPM_DESIGN = 'aircraft:engine:rpm_design' SCALE_FACTOR = 'aircraft:engine:scale_factor' SCALE_MASS = 'aircraft:engine:scale_mass' - SCALE_PERFORMANCE = 'aircraft:engine:scale_performance' SCALED_SLS_THRUST = 'aircraft:engine:scaled_sls_thrust' SUBSONIC_FUEL_FLOW_SCALER = 'aircraft:engine:subsonic_fuel_flow_scaler' SUPERSONIC_FUEL_FLOW_SCALER = 'aircraft:engine:supersonic_fuel_flow_scaler'