From 6ac78b088e1b933a5dbd47264361a74f722c870d Mon Sep 17 00:00:00 2001 From: jkirk5 Date: Fri, 4 Sep 2026 17:55:44 -0400 Subject: [PATCH 1/4] fixed high linear scaling factor in models & tests --- .../advanced_single_aisle_FLOPS.csv | 2 +- .../propulsion/test/test_engine_scaling.py | 45 +-- .../test/test_propulsion_mission.py | 306 ++++++++++-------- .../propulsion/test/test_turboprop_model.py | 2 +- .../test_bench_throttle_allocation.py | 10 +- .../test_data/advanced_single_aisle_data.py | 2 +- .../multi_engine_single_aisle_data.py | 2 +- .../test_models/high_wing_single_aisle.csv | 2 +- aviary/variable_info/variable_meta_data.py | 4 +- 9 files changed, 201 insertions(+), 174 deletions(-) diff --git a/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_FLOPS.csv b/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_FLOPS.csv index 8d44e53820..acab7e611f 100644 --- a/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_FLOPS.csv +++ b/aviary/models/aircraft/advanced_single_aisle/advanced_single_aisle_FLOPS.csv @@ -44,7 +44,7 @@ aircraft:engine:flight_idle_max_fraction,1,unitless aircraft:engine:flight_idle_min_fraction,0.08,unitless aircraft:engine:flight_idle_thrust_fraction,0,unitless aircraft:engine:fuel_flow_scaler_constant_term,0,unitless -aircraft:engine:fuel_flow_scaler_linear_term,1,unitless +aircraft:engine:fuel_flow_scaler_linear_term,0,unitless aircraft:engine:generate_flight_idle,True,unitless aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless diff --git a/aviary/subsystems/propulsion/test/test_engine_scaling.py b/aviary/subsystems/propulsion/test/test_engine_scaling.py index 76faf205fa..52bf29b41c 100644 --- a/aviary/subsystems/propulsion/test/test_engine_scaling.py +++ b/aviary/subsystems/propulsion/test/test_engine_scaling.py @@ -3,6 +3,7 @@ import numpy as np import openmdao.api as om from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal +from openmdao.utils.testing_utils import use_tempdirs from aviary.subsystems.propulsion.engine_deck import EngineDeck from aviary.subsystems.propulsion.engine_scaling import EngineScaling @@ -16,14 +17,13 @@ class EngineScalingTest(unittest.TestCase): def setUp(self): - self.prob = om.Problem(model=om.Group()) + self.prob = om.Problem() def test_case(self): nn = 4 count = 1 - filename = 'models/engines/turbofan_28k.csv' - filename = get_path(filename) + filename = get_path('models/engines/turbofan_28k.csv') options = AviaryValues() options.set_val(Settings.VERBOSITY, 0) @@ -32,7 +32,7 @@ def test_case(self): # make supersonic scaling factor extremely high so it is obvious if it gets used options.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1000) 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.FUEL_FLOW_SCALER_LINEAR_TERM, 0.05) options.set_val(Aircraft.Engine.CONSTANT_FUEL_MASS_CONSUMPTION, 10.0, units='lbm/h') options.set_val(Aircraft.Engine.SCALE_FACTOR, 0.9) options.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, True) @@ -43,10 +43,8 @@ def test_case(self): options.set_val(Aircraft.Engine.GEOPOTENTIAL_ALT, False) options.set_val(Aircraft.Engine.INTERPOLATION_METHOD, 'slinear') - # engine1 uses all scaling factors - engine1 = EngineDeck(options=options) - - preprocess_propulsion(options, [engine1]) + engine = EngineDeck(options=options) + preprocess_propulsion(options, [engine]) engine_variables = { EngineModelVariables.THRUST: 'lbf', @@ -74,20 +72,25 @@ def test_case(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST) - fuel_flow = self.prob.get_val(Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE) - nox_rate = self.prob.get_val(Dynamic.Vehicle.Propulsion.NOX_RATE) - # exit_area = self.prob.get_val(Dynamic.Mission.EXIT_AREA) - - thrust_expected = np.array([900.0, 900.0, 900.0, 900]) - - fuel_flow_expected = np.array([-1836.55, -1836.55, -1836.55, -1836.55]) - - nox_rate_expected = np.array([9.0, 9.0, 9.0, 9]) + expected_values = { + Dynamic.Vehicle.Propulsion.THRUST: ( + np.array([900.0, 900.0, 900.0, 900.0]), + 'lbf', + ), + Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE: ( + np.array([-1755.55, -1755.55, -1755.55, -1755.55]), + 'lbm/h', + ), + Dynamic.Vehicle.Propulsion.NOX_RATE: ( + np.array([9.0, 9.0, 9.0, 9.0]), + 'lbm/h', + ), + } - assert_near_equal(thrust, thrust_expected, tolerance=1e-10) - assert_near_equal(fuel_flow, fuel_flow_expected, tolerance=1e-10) - assert_near_equal(nox_rate, nox_rate_expected, tolerance=1e-10) + for var_name, (expected, units) in expected_values.items(): + with self.subTest(var=var_name): + actual = self.prob.get_val(var_name, units=units) + assert_near_equal(actual, expected, tolerance=1e-10) partial_data = self.prob.check_partials(out_stream=None, method='cs') assert_check_partials(partial_data, atol=1e-11, rtol=1e-10) diff --git a/aviary/subsystems/propulsion/test/test_propulsion_mission.py b/aviary/subsystems/propulsion/test/test_propulsion_mission.py index c53336b6f4..6804228968 100644 --- a/aviary/subsystems/propulsion/test/test_propulsion_mission.py +++ b/aviary/subsystems/propulsion/test/test_propulsion_mission.py @@ -42,7 +42,7 @@ def test_case_1(self): options.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) options.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) 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.FUEL_FLOW_SCALER_LINEAR_TERM, 0.0) options.set_val(Aircraft.Engine.CONSTANT_FUEL_MASS_CONSUMPTION, 0.0, units='lbm/h') options.set_val(Aircraft.Engine.SCALE_FACTOR, 0.5) options.set_val(Aircraft.Engine.IGNORE_NEGATIVE_THRUST, False) @@ -78,63 +78,67 @@ def test_case_1(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') - fuel_flow = self.prob.get_val( - Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE_TOTAL, units='lbm/h' - ) - - expected_thrust = np.array( - [ - 26561.59369395, - 24186.86894359, - 21938.27488056, - 19715.05735655, - 17506.16718894, - 15460.34459449, - 13780.48894973, - 12280.8193203, - 10975.41682925, - 9457.56468145, - 7995.21902953, - 7398.69940308, - 7148.11078578, - 6431.41457704, - 5775.06520451, - 5165.40974506, - 4583.11663348, - 3991.15103423, - 3339.07858092, - 2733.73087418, - ] - ) - - expected_fuel_flow = np.array( - [ - -14708.13129181, - -14065.48817451, - -13382.86563425, - -12534.77028836, - -11523.83568308, - -10513.77300372, - -9696.27706444, - -8936.08244404, - -8203.69933068, - -8447.76373904, - -8705.57372767, - -7470.81543322, - -5980.73136927, - -5493.90702754, - -5072.25036487, - -4660.36809371, - -4260.86577106, - -3822.5941721, - -3344.49786121, - -2889.82801889, - ] - ) + expected_values = { + Dynamic.Vehicle.Propulsion.THRUST_TOTAL: ( + np.array( + [ + 26561.59369395, + 24186.86894359, + 21938.27488056, + 19715.05735655, + 17506.16718894, + 15460.34459449, + 13780.48894973, + 12280.8193203, + 10975.41682925, + 9457.56468145, + 7995.21902953, + 7398.69940308, + 7148.11078578, + 6431.41457704, + 5775.06520451, + 5165.40974506, + 4583.11663348, + 3991.15103423, + 3339.07858092, + 2733.73087418, + ] + ), + 'lbf', + ), + Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE_TOTAL: ( + np.array( + [ + -9805.42086121, + -9376.99211634, + -8921.91042284, + -8356.51352557, + -7682.55712206, + -7009.18200248, + -6464.18470963, + -5957.38829603, + -5469.13288712, + -5631.84249269, + -5803.71581845, + -4980.54362214, + -3987.15424618, + -3662.60468503, + -3381.50024325, + -3106.91206247, + -2840.57718071, + -2548.39611474, + -2229.66524081, + -1926.55201259, + ] + ), + 'lbm/h', + ), + } - assert_near_equal(thrust, expected_thrust, tolerance=1e-10) - assert_near_equal(fuel_flow, expected_fuel_flow, tolerance=1e-10) + for var_name, (expected, units) in expected_values.items(): + with self.subTest(var=var_name): + actual = self.prob.get_val(var_name, units=units) + assert_near_equal(actual, expected, tolerance=1e-10) partial_data = self.prob.check_partials(out_stream=None, method='cs') assert_check_partials(partial_data, atol=1e-10, rtol=1e-10) @@ -171,27 +175,24 @@ def test_propulsion_sum(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') - thrust_max = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, units='lbf') - fuel_flow = self.prob.get_val( - Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE_TOTAL, units='lb/h' - ) - electric_power_in = self.prob.get_val( - Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, units='kW' - ) - nox = self.prob.get_val(Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL, units='lb/h') - - expected_thrust = np.array([2347.202, 14535]) - expected_thrust_max = np.array([8914.33, 18300]) - expected_fuel_flow = np.array([-73.88, -2297.6]) - expected_electric_power_in = np.array([-14.97, 17698.6]) - expected_nox = np.array([10186, 10.308]) + expected_values = { + Dynamic.Vehicle.Propulsion.THRUST_TOTAL: (np.array([2347.202, 14535]), 'lbf'), + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL: (np.array([8914.33, 18300]), 'lbf'), + Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE_TOTAL: ( + np.array([-73.88, -2297.6]), + 'lb/h', + ), + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL: ( + np.array([-14.97, 17698.6]), + 'kW', + ), + Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL: (np.array([10186, 10.308]), 'lb/h'), + } - assert_near_equal(thrust, expected_thrust, tolerance=1e-12) - assert_near_equal(thrust_max, expected_thrust_max, tolerance=1e-12) - assert_near_equal(fuel_flow, expected_fuel_flow, tolerance=1e-12) - assert_near_equal(electric_power_in, expected_electric_power_in, tolerance=1e-12) - assert_near_equal(nox, expected_nox, tolerance=1e-12) + for var_name, (expected, units) in expected_values.items(): + with self.subTest(var=var_name): + actual = self.prob.get_val(var_name, units=units) + assert_near_equal(actual, expected, tolerance=1e-12) partial_data = self.prob.check_partials(out_stream=None, method='cs') assert_check_partials(partial_data, atol=1e-10, rtol=1e-10) @@ -249,44 +250,48 @@ def test_case_multiengine(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') - fuel_flow = self.prob.get_val( - Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE_TOTAL, units='lbm/h' - ) - nox_rate = self.prob.get_val(Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL, units='lbm/h') - # block auto-formatting of tables # fmt: off - expected_thrust = np.array( - [ - 103590.21540641, 92900.83040046, 82825.70799328, 73005.10411666, 63489.74235503, - 55210.75770546, 48313.84938232, 42275.86826606, 36870.28719096, 29717.82022574, - 26272.78176894, 24682.2638022, 22044.68474877, 19221.64939296, 16753.74585058, - 14404.83725986, 12273.31369208, 10143.03504195, 7869.72781898, 5794.48172967 - ] - ) - - expected_fuel_flow = np.array( - [ - -38241.14135872, -36079.34764117, -33777.26289895, -31056.78302442, -28036.07645153, - -25278.09940003, -22901.48613868, -20748.0936975, -19058.14550597, -19973.09349768, - -17702.71563899, -14371.77422339, -12584.74775338, -11320.39115751, -10191.86597545, - -9099.77210032, -8101.06611515, -7070.33673028, -5965.98165626, -4915.97493174 - ] - ) - - expected_nox_rate = np.array( - [ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - ] - ) - + expected_values = { + Dynamic.Vehicle.Propulsion.THRUST_TOTAL: ( + np.array( + [ + 103590.21540641, 92900.83040046, 82825.70799328, 73005.10411666, 63489.74235503, + 55210.75770546, 48313.84938232, 42275.86826606, 36870.28719096, 29717.82022574, + 26272.78176894, 24682.2638022, 22044.68474877, 19221.64939296, 16753.74585058, + 14404.83725986, 12273.31369208, 10143.03504195, 7869.72781898, 5794.48172967 + ] + ), + 'lbf', + ), + Dynamic.Vehicle.Propulsion.FUEL_MASS_FLOW_RATE_NEGATIVE_TOTAL: ( + np.array( + [ + -38241.14135872, -36079.34764117, -33777.26289895, -31056.78302442, -28036.07645153, + -25278.09940003, -22901.48613868, -20748.0936975, -19058.14550597, -19973.09349768, + -17702.71563899, -14371.77422339, -12584.74775338, -11320.39115751, -10191.86597545, + -9099.77210032, -8101.06611515, -7070.33673028, -5965.98165626, -4915.97493174 + ] + ), + 'lbm/h', + ), + Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL: ( + np.array( + [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + ] + ), + 'lbm/h', + ), + } # fmt: on - assert_near_equal(thrust, expected_thrust, tolerance=1e-10) - assert_near_equal(fuel_flow, expected_fuel_flow, tolerance=1e-10) - assert_near_equal(nox_rate, expected_nox_rate, tolerance=1e-9) + for var_name, (expected, units) in expected_values.items(): + with self.subTest(var=var_name): + actual = self.prob.get_val(var_name, units=units) + tol = 1e-9 if var_name == Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL else 1e-10 + assert_near_equal(actual, expected, tolerance=tol) partial_data = self.prob.check_partials(out_stream=None, method='cs') assert_check_partials(partial_data, atol=1e-10, rtol=1e-10) @@ -339,15 +344,21 @@ def test_case_no_max_thrust(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') - max_thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, units='lbf') - - expected_thrust = np.array([40000, 38000, 36000, 34000, 32000]) - - expected_max_thrust = np.array([40000, 40000, 40000, 40000, 40000]) + expected_values = { + Dynamic.Vehicle.Propulsion.THRUST_TOTAL: ( + np.array([40000, 38000, 36000, 34000, 32000]), + 'lbf', + ), + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL: ( + np.array([40000, 40000, 40000, 40000, 40000]), + 'lbf', + ), + } - assert_near_equal(thrust, expected_thrust, tolerance=1e-10) - assert_near_equal(max_thrust, expected_max_thrust, tolerance=1e-10) + for var_name, (expected, units) in expected_values.items(): + with self.subTest(var=var_name): + actual = self.prob.get_val(var_name, units=units) + assert_near_equal(actual, expected, tolerance=1e-10) def test_case_no_max_thrust_multiengine(self): # Takes the multiengine test case and replaces an engine with one that does not compute max @@ -404,18 +415,25 @@ def test_case_no_max_thrust_multiengine(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') - max_thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, units='lbf') - - expected_thrust = np.array( - [91795.1077032, 66538.67800773, 49882.20467434, 42078.10820403, 34897.24086484] - ) - expected_max_thrust = np.array( - [91795.1077032, 75448.88753979, 62863.25377679, 56217.19584678, 50659.15299758] - ) + expected_values = { + Dynamic.Vehicle.Propulsion.THRUST_TOTAL: ( + np.array( + [91795.1077032, 66538.67800773, 49882.20467434, 42078.10820403, 34897.24086484] + ), + 'lbf', + ), + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL: ( + np.array( + [91795.1077032, 75448.88753979, 62863.25377679, 56217.19584678, 50659.15299758] + ), + 'lbf', + ), + } - assert_near_equal(thrust, expected_thrust, tolerance=1e-10) - assert_near_equal(max_thrust, expected_max_thrust, tolerance=1e-10) + for var_name, (expected, units) in expected_values.items(): + with self.subTest(var=var_name): + actual = self.prob.get_val(var_name, units=units) + assert_near_equal(actual, expected, tolerance=1e-10) def test_case_no_max_thrust_turboprop(self): # replaces the engine with a turboprop @@ -487,19 +505,23 @@ def test_case_no_max_thrust_turboprop(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') - max_thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, units='lbf') - - expected_thrust = np.array( - [42629.8926234, 34593.95597499, 20003.65216215, 12039.90789131, 8385.527778477] - ) - - expected_max_thrust = np.array( - [42629.8926234, 41028.55584259, 29561.74, 22590.025, 20411.435] - ) + expected_values = { + Dynamic.Vehicle.Propulsion.THRUST_TOTAL: ( + np.array( + [42629.8926234, 34593.95597499, 20003.65216215, 12039.90789131, 8385.527778477] + ), + 'lbf', + ), + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL: ( + np.array([42629.8926234, 41028.55584259, 29561.74, 22590.025, 20411.435]), + 'lbf', + ), + } - assert_near_equal(thrust, expected_thrust, tolerance=1e-10) - assert_near_equal(max_thrust, expected_max_thrust, tolerance=1e-10) + for var_name, (expected, units) in expected_values.items(): + with self.subTest(var=var_name): + actual = self.prob.get_val(var_name, units=units) + assert_near_equal(actual, expected, tolerance=1e-10) if __name__ == '__main__': diff --git a/aviary/subsystems/propulsion/test/test_turboprop_model.py b/aviary/subsystems/propulsion/test/test_turboprop_model.py index a8ec487617..14e92a4be8 100644 --- a/aviary/subsystems/propulsion/test/test_turboprop_model.py +++ b/aviary/subsystems/propulsion/test/test_turboprop_model.py @@ -36,7 +36,7 @@ def prepare_model( options.set_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, 1.0) options.set_val(Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, 1.0) 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.FUEL_FLOW_SCALER_LINEAR_TERM, 0.0) options.set_val(Aircraft.Engine.CONSTANT_FUEL_MASS_CONSUMPTION, 0.0, units='lbm/h') options.set_val(Aircraft.Engine.SCALE_FACTOR, 1) options.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, False) diff --git a/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py b/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py index d76702ac9d..175a522bde 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py @@ -131,9 +131,9 @@ def test_multiengine_static(self): alloc_descent = prob.get_val('traj.descent.parameter_vals:throttle_allocations') with self.subTest('climb_allocation'): - assert_near_equal(alloc_climb[0], 0.5, tolerance=1e-2) + assert_near_equal(alloc_climb[0], 0.48777445, tolerance=1e-2) with self.subTest('cruise_allocation'): - assert_near_equal(alloc_cruise[0], 0.64523, tolerance=1e-2) + assert_near_equal(alloc_cruise[0], 0.34035731, tolerance=1e-2) @require_pyoptsparse(optimizer='SNOPT') def test_multiengine_dynamic(self): @@ -172,11 +172,11 @@ def test_multiengine_dynamic(self): with self.subTest('cruise_allocation'): # Cruise is pretty constant, check exact value. - assert_near_equal(alloc_cruise[0], 0.6452, tolerance=1e-2) + assert_near_equal(alloc_cruise[0], 0.33626162, tolerance=1e-2) with self.subTest('climb_allocation'): - # Check general trend: favors engine 1. - self.assertGreater(alloc_climb[2], 0.55) + # Check general trend: favors engine 2. + self.assertGreater(alloc_climb[2], 0.21) if __name__ == '__main__': diff --git a/aviary/validation_cases/validation_data/test_data/advanced_single_aisle_data.py b/aviary/validation_cases/validation_data/test_data/advanced_single_aisle_data.py index ed9c2ca9db..23c0673718 100644 --- a/aviary/validation_cases/validation_data/test_data/advanced_single_aisle_data.py +++ b/aviary/validation_cases/validation_data/test_data/advanced_single_aisle_data.py @@ -217,7 +217,7 @@ 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) -inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, 1.0) +inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, 0.0) inputs.set_val(Aircraft.Engine.CONSTANT_FUEL_MASS_CONSUMPTION, 0.0, units='lb/h') inputs.set_val(Aircraft.Engine.ADDITIONAL_MASS_FRACTION, 0.0) inputs.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, True) diff --git a/aviary/validation_cases/validation_data/test_data/multi_engine_single_aisle_data.py b/aviary/validation_cases/validation_data/test_data/multi_engine_single_aisle_data.py index 5321c2cbf9..d30417f0c2 100644 --- a/aviary/validation_cases/validation_data/test_data/multi_engine_single_aisle_data.py +++ b/aviary/validation_cases/validation_data/test_data/multi_engine_single_aisle_data.py @@ -199,7 +199,7 @@ 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) -engine_2_inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, 1.0) +engine_2_inputs.set_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, 0.0) engine_2_inputs.set_val(Aircraft.Engine.CONSTANT_FUEL_MASS_CONSUMPTION, 0.0, units='lb/h') engine_2_inputs.set_val(Aircraft.Engine.ADDITIONAL_MASS_FRACTION, 0.0) engine_2_inputs.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, True) diff --git a/aviary/validation_cases/validation_data/test_models/high_wing_single_aisle.csv b/aviary/validation_cases/validation_data/test_models/high_wing_single_aisle.csv index e392990898..c1d2ce1506 100644 --- a/aviary/validation_cases/validation_data/test_models/high_wing_single_aisle.csv +++ b/aviary/validation_cases/validation_data/test_models/high_wing_single_aisle.csv @@ -32,7 +32,7 @@ aircraft:engine:flight_idle_max_fraction,1.01,unitless #check aircraft:engine:flight_idle_min_fraction,0.08,unitless aircraft:engine:flight_idle_thrust_fraction,0.00001,unitless #check aircraft:engine:fuel_flow_scaler_constant_term,0.,unitless -aircraft:engine:fuel_flow_scaler_linear_term,1.,unitless +aircraft:engine:fuel_flow_scaler_linear_term,0.,unitless aircraft:engine:generate_flight_idle,True,unitless aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 76f32adfbe..a3d125f314 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -2097,7 +2097,9 @@ 'FLOPS': 'ENGDIN.FFFAC', }, units='unitless', - desc='Linear term in fuel flow scaling equation', + desc='Linear term in fuel flow scaling equation. Note that the slope of fuel flow with resepect ' + 'to this variable changes from positive to negative as Aircraft.Engine.SCALE_FACTOR crosses ' + 'above 1.', default_value=0.0, option=True, multivalue=True, From 2e81b3be29e3bfec547108f17fe986988751fb9e Mon Sep 17 00:00:00 2001 From: jkirk5 Date: Fri, 4 Sep 2026 17:59:10 -0400 Subject: [PATCH 2/4] added success requirement to throttle allocation bench --- .../benchmark_tests/test_bench_throttle_allocation.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py b/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py index 175a522bde..2c320d0a9c 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py @@ -126,6 +126,8 @@ def test_multiengine_static(self): prob.run_aviary_problem(suppress_solver_print=True) + self.assertTrue(prob.result.success) + alloc_climb = prob.get_val('traj.climb.parameter_vals:throttle_allocations') alloc_cruise = prob.get_val('traj.cruise.parameter_vals:throttle_allocations') alloc_descent = prob.get_val('traj.descent.parameter_vals:throttle_allocations') @@ -166,6 +168,8 @@ def test_multiengine_dynamic(self): prob.run_aviary_problem(suppress_solver_print=True) + self.assertTrue(prob.result.success) + alloc_climb = prob.get_val('traj.climb.controls:throttle_allocations') alloc_cruise = prob.get_val('traj.cruise.controls:throttle_allocations') alloc_descent = prob.get_val('traj.descent.controls:throttle_allocations') From b031161ace9ad6f1b9e810dd12bac935e4d34c1a Mon Sep 17 00:00:00 2001 From: Jason Kirk <110835404+jkirk5@users.noreply.github.com> Date: Fri, 4 Sep 2026 18:11:10 -0400 Subject: [PATCH 3/4] Apply suggestion from @jkirk5 --- .../benchmark_tests/test_bench_throttle_allocation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py b/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py index 2c320d0a9c..ab1f0b9777 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_throttle_allocation.py @@ -180,7 +180,7 @@ def test_multiengine_dynamic(self): with self.subTest('climb_allocation'): # Check general trend: favors engine 2. - self.assertGreater(alloc_climb[2], 0.21) + self.assertLesser(alloc_climb[2], 0.22) if __name__ == '__main__': From d7221ad6b6ccf112394743cb9f372f92122b4e22 Mon Sep 17 00:00:00 2001 From: jkirk5 Date: Fri, 11 Sep 2026 11:12:45 -0400 Subject: [PATCH 4/4] updated variable metadata --- aviary/variable_info/variable_meta_data.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 8f2d8a8c79..801adfdd16 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -2038,7 +2038,9 @@ }, units='unitless', option=True, - desc='Constant term in fuel flow scaling equation', + desc='Constant term in fuel flow scaling equation. Directly added to the overall fuel flow ' + 'scaling (so a constant term of 0.01 increases the overall fuel flow multiplier from 1.0 to ' + '1.01)', default_value=0.0, multivalue=True, ) @@ -2051,7 +2053,13 @@ 'FLOPS': 'ENGDIN.FFFAC', }, units='unitless', - desc='Linear term in fuel flow scaling equation', + desc='Linear term in fuel flow scaling equation. Accounts for how fuel flow changes ' + 'with engine size, penalizing smaller engines and benefiting larger ones. This term sets ' + 'the rate that fuel flow changes with Aircraft.Engine.SCALE_FACTOR - for every percent the ' + 'engine is scaled up or down, this sets how much of a percent is fuel flow adjusted. For ' + 'example, a linear term of 0.1 means for every percent the engine is scaled up (such as from ' + '1.0 to 1.01), the overall fuel flow multiplier is increased by 0.1, and similarly decreases ' + 'by 0.1 for every percent the engine is scaled down.', default_value=0.0, option=True, multivalue=True,