From 26625667141194e26fa324985184f6d0ac53019a Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:01:54 -0400 Subject: [PATCH 01/14] rename Useful_Load to Operating_Items --- aviary/docs/theory_guide/gasp_based_bwb.ipynb | 20 +++++++-------- .../subsystems/fuel.ipynb | 2 +- .../subsystems/mass.ipynb | 8 +++--- .../advanced_single_aisle_data.py | 2 +- .../bwb300_baseline_FLOPS_data.py | 2 +- .../bwb_detailed_FLOPS_data.py | 2 +- .../bwb_simple_FLOPS_data.py | 2 +- .../large_single_aisle_1_FLOPS_data.py | 2 +- .../large_single_aisle_2_FLOPS_data.py | 2 +- .../large_single_aisle_2_altwt_FLOPS_data.py | 2 +- ...ge_single_aisle_2_detailwing_FLOPS_data.py | 2 +- .../mass/flops_based/mass_summation.py | 19 ++++++++------ .../flops_based/test/test_mass_summation.py | 4 +-- .../gasp_based/equipment_and_useful_load.py | 6 ++--- .../mass/gasp_based/mass_premission.py | 6 +++-- .../mass/gasp_based/mass_summation.py | 19 ++++++++------ .../test/test_equipment_and_useful_load.py | 25 +++++++++++-------- .../mass/gasp_based/test/test_fuel.py | 2 +- .../mass/gasp_based/test/test_furnishings.py | 4 +-- .../gasp_based/test/test_mass_premission.py | 6 ++--- aviary/subsystems/mass/mass_builder.py | 4 ++- .../test/test_gasp_based_premission.py | 10 ++++---- aviary/variable_info/variable_meta_data.py | 2 +- aviary/variable_info/variables.py | 2 +- 24 files changed, 85 insertions(+), 70 deletions(-) diff --git a/aviary/docs/theory_guide/gasp_based_bwb.ipynb b/aviary/docs/theory_guide/gasp_based_bwb.ipynb index e8c602aa9..dc55e9478 100644 --- a/aviary/docs/theory_guide/gasp_based_bwb.ipynb +++ b/aviary/docs/theory_guide/gasp_based_bwb.ipynb @@ -123,16 +123,16 @@ "# Testing Cell\n", "\n", "from aviary.api import Aircraft\n", - "from aviary.subsystems.mass.gasp_based.equipment_and_useful_load import (\n", + "from aviary.subsystems.mass.gasp_based.equipment_and_operating_items import (\n", " BWBACMass,\n", " BWBFurnishingMass,\n", - " EquipAndUsefulLoadMassGroup,\n", - " UsefulLoadMassGroup,\n", + " EquipAndOperatingItemsMassGroup,\n", + " OperatingItemsMassGroup,\n", ")\n", "from aviary.utils.doctape import get_variable_name, glue_variable\n", "\n", - "glue_variable(get_variable_name(EquipAndUsefulLoadMassGroup), md_code=True)\n", - "glue_variable(get_variable_name(UsefulLoadMassGroup), md_code=True)\n", + "glue_variable(get_variable_name(EquipAndOperatingItemsMassGroup), md_code=True)\n", + "glue_variable(get_variable_name(OperatingItemsMassGroup), md_code=True)\n", "glue_variable(get_variable_name(BWBACMass), md_code=True)\n", "glue_variable(get_variable_name(BWBFurnishingMass), md_code=True)\n", "\n", @@ -150,11 +150,11 @@ "id": "8d5ec109", "metadata": {}, "source": [ - "### Equip And Useful Load\n", + "### Equip And Operating Items\n", "\n", - " - {glue:md}`EquipAndUsefulLoadMassGroup` includes the computations of 19 items. Ideally, each of them should be done in its own component and one group has them all. This is a long time goal. For now, it is separated to two components `EquipMass` and {glue:md}`UsefulLoadMassGroup`. The air conditioning and furnishing masses are already singled out because they need to be modified for BWB.\n", + " - {glue:md}`EquipAndOperatingItemsMassGroup` includes the computations of 19 items. Ideally, each of them should be done in its own component and one group has them all. This is a long time goal. For now, it is separated to two components `EquipMass` and {glue:md}`OperatingItemsMassGroup`. The air conditioning and furnishing masses are already singled out because they need to be modified for BWB.\n", " - A new variable {glue:md}`Aircraft.Electrical.SYSTEM_MASS_PER_PASSENGER` is added which corresponds to `CW(15)` in GASP. Its value is different for conventional aircraft and BWB.\n", - " - Two new components {glue:md}`BWBACMass` and {glue:md}`BWBFurnishingMass` are added to `equipment_and_useful_load.py`.\n", + " - Two new components {glue:md}`BWBACMass` and {glue:md}`BWBFurnishingMass` are added to `equipment_and_operating_items.py`.\n", " - **Note:** GASP Fortran code has new updates that are not included in Aviary. We've updated Aviary for furnishing mass but other masses need to be checked.\n", " - **Note:** `EquipMassPartialSum` has implementation errors for the computations of {glue:md}`Aircraft.APU.MASS`, {glue:md}`Aircraft.Avionics.MASS`, {glue:md}`Aircraft.AntiIcing.MASS`, {glue:md}`Aircraft.Furnishings.MASS`, and {glue:md}`Aircraft.Design.EMERGENCY_EQUIPMENT_MASS`. As a result, Aviary always uses user provided masses (not empirical formulas). We should use Aviary's feature of `overriding` to override those variables." ] @@ -249,7 +249,7 @@ "\n", "glue_variable(get_variable_name(Mission.TOTAL_FUEL), md_code=True)\n", "\n", - "glue_variable(get_variable_name(Mission.USEFUL_LOAD), md_code=True)\n", + "glue_variable(get_variable_name(Mission.OPERATING_ITEMS_MASS), md_code=True)\n", "glue_variable(get_variable_name(Aircraft.Wing.HIGH_LIFT_MASS), md_code=True)\n", "glue_variable(get_variable_name(Aircraft.Fuel.FUEL_SYSTEM_MASS), md_code=True)\n", "glue_variable(get_variable_name(Aircraft.Design.STRUCTURE_MASS), md_code=True)\n", @@ -275,7 +275,7 @@ "\n", "| Aviary |     | GASP |     | Observation |\n", "| ------- | ------- | ------- | -------- | ------------- |\n", - "| {glue:md}`Mission.USEFUL_LOAD` | 5972 | WFUL | 5775 | different unit weight of pilots and attendents |\n", + "| {glue:md}`Mission.OPERATING_ITEMS` | 5972 | WFUL | 5775 | different unit weight of pilots and attendents |\n", "| {glue:md}`Aircraft.Wing.HIGH_LIFT_MASS` | 972 | WHLDEV | 974 | In GASP, wing loading is a variable, but in Aviary, it is a constant |\n", "| {glue:md}`Aircraft.Fuel.FUEL_SYSTEM_MASS` | 1316 | WFSS | 1281 | the mass in GASP is computed after engine sizing. |\n", "| {glue:md}`Aircraft.Design.STRUCTURE_MASS` | 44471 | WST | 45623 | the mass in GASP is computed after engine sizing. |\n", diff --git a/aviary/docs/user_guide_unreviewed/subsystems/fuel.ipynb b/aviary/docs/user_guide_unreviewed/subsystems/fuel.ipynb index e221aa96b..b22fd4b94 100644 --- a/aviary/docs/user_guide_unreviewed/subsystems/fuel.ipynb +++ b/aviary/docs/user_guide_unreviewed/subsystems/fuel.ipynb @@ -16,7 +16,7 @@ "\n", "\n", "## Fuel Mass\n", - "The Fuel Mass breakdown is shown below. Note that UNUSABLE_FUEL_MASS is not accounted for in this mass and is instead book kept under USEFUL_LOAD which contributes to OPERATING_MASS see [mass subsystem for details](mass.ipynb).\n", + "The Fuel Mass breakdown is shown below. Note that UNUSABLE_FUEL_MASS is not accounted for in this mass and is instead book kept under OPERATING_ITEMS_MASS which contributes to OPERATING_MASS see [mass subsystem for details](mass.ipynb).\n", "\n", "- TOTAL_FUEL (mass)\n", " - FUEL (mass)\n", diff --git a/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb b/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb index 9c3adfc12..321354f17 100644 --- a/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb +++ b/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb @@ -25,7 +25,9 @@ " ZeroFuelMass,\n", ")\n", "from aviary.subsystems.mass.gasp_based.design_load import DesignLoadGroup\n", - "from aviary.subsystems.mass.gasp_based.equipment_and_useful_load import EquipAndUsefulLoadMassGroup\n", + "from aviary.subsystems.mass.gasp_based.equipment_and_operating_items import (\n", + " EquipAndOperatingItemsMassGroup,\n", + ")\n", "from aviary.subsystems.mass.gasp_based.fixed import FixedMassGroup\n", "from aviary.subsystems.mass.gasp_based.wing import WingMassGroup\n", "from aviary.utils.doctape import get_variable_name, glue_variable\n", @@ -74,9 +76,9 @@ "st = split_by_capitals_and_underscores(get_variable_name(FixedMassGroup))\n", "glue_variable(st, md_code=False)\n", "glue_variable(get_variable_name(FixedMassGroup), md_code=False)\n", - "st = split_by_capitals_and_underscores(get_variable_name(EquipAndUsefulLoadMassGroup))\n", + "st = split_by_capitals_and_underscores(get_variable_name(EquipAndOperatingItemsMassGroup))\n", "glue_variable(st, md_code=False)\n", - "glue_variable(get_variable_name(EquipAndUsefulLoadMassGroup), md_code=False)\n", + "glue_variable(get_variable_name(EquipAndOperatingItemsMassGroup), md_code=False)\n", "st = split_by_capitals_and_underscores(get_variable_name(WingMassGroup))\n", "glue_variable(st, md_code=False)\n", "glue_variable(get_variable_name(WingMassGroup), md_code=False)" 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 56e6a0061..b34daad82 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 @@ -337,7 +337,7 @@ outputs.set_val(Aircraft.Propulsion.MASS, 13105.0, 'lbm') outputs.set_val(Aircraft.Design.STRUCTURE_MASS, 29336.0, 'lbm') outputs.set_val(Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, 24105.0, 'lbm') -outputs.set_val(Mission.USEFUL_LOAD, 5100, 'lbm') +outputs.set_val(Mission.OPERATING_ITEMS_MASS, 5100, 'lbm') outputs.set_val(Aircraft.Design.TOTAL_WETTED_AREA, 7956.515738, 'ft**2') outputs.set_val(Mission.ZERO_FUEL_MASS, 103442.0, 'lbm') diff --git a/aviary/models/aircraft/blended_wing_body/bwb300_baseline_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb300_baseline_FLOPS_data.py index 90d203709..405ff41f0 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb300_baseline_FLOPS_data.py +++ b/aviary/models/aircraft/blended_wing_body/bwb300_baseline_FLOPS_data.py @@ -423,7 +423,7 @@ outputs.set_val(Aircraft.Wing.AREA, 8421.7146805052689, 'ft**2') # SW outputs.set_val(Aircraft.Wing.WETTED_AREA, 17302.04910213, 'ft**2') # SWET(1) -outputs.set_val(Mission.Summary.USEFUL_LOAD, 20996.3933862, 'lbm') +outputs.set_val(Mission.Summary.OPERATING_ITEMS_MASS, 20996.3933862, 'lbm') # outputs.set_val(Aircraft.Design.MACH, 0.800) # FMDES outputs.set_val(Mission.Summary.OPERATING_MASS, 321171.82272983, 'lbm') # DOWE 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 bf1332f14..65db21814 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 @@ -423,7 +423,7 @@ outputs.set_val(Aircraft.Wing.WETTED_AREA, 24713.661297561481, 'ft**2') # SWET(1) outputs.set_val(Aircraft.Wing.SPAN, 253.720756, 'ft') # SPAN = WF+OSSPAN*2 -outputs.set_val(Mission.USEFUL_LOAD, 20996.3933862, 'lbm') +outputs.set_val(Mission.OPERATING_ITEMS_MASS, 20996.3933862, 'lbm') outputs.set_val(Aircraft.Design.MACH, 0.800) outputs.set_val(Mission.OPERATING_MASS, 411552.29917206, 'lbm') # WOWE 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 6561c97d7..949526a03 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 @@ -370,7 +370,7 @@ outputs.set_val(Aircraft.Wing.WETTED_AREA, 33816.732336575638, 'ft**2') # SWET(1) outputs.set_val(Aircraft.Wing.SPAN, 238.08, 'ft') # SPAN = WF+OSSPAN*2 -outputs.set_val(Mission.USEFUL_LOAD, 21427.61093929, 'lbm') +outputs.set_val(Mission.OPERATING_ITEMS_MASS, 21427.61093929, 'lbm') outputs.set_val(Aircraft.Design.MACH, 0.800) outputs.set_val(Mission.OPERATING_MASS, 455464.65969526308, 'lbm') # WOWE 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 4503a5c46..387cebff0 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 @@ -262,7 +262,7 @@ outputs.set_val(Aircraft.Design.EMPENNAGE_MASS, 3052.8, 'lbm') outputs.set_val(Aircraft.Design.STRUCTURE_MASS, 50736.0, 'lbm') outputs.set_val(Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, 25169.0, 'lbm') -outputs.set_val(Mission.USEFUL_LOAD, 5969.278, 'lbm') +outputs.set_val(Mission.OPERATING_ITEMS_MASS, 5969.278, 'lbm') outputs.set_val(Aircraft.Design.TOTAL_WETTED_AREA, 8275.86, 'ft**2') outputs.set_val(Mission.ZERO_FUEL_MASS, 135848.0, 'lbm') 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 ae3a470f3..218e67966 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 @@ -261,7 +261,7 @@ outputs.set_val(Aircraft.Design.TOUCHDOWN_MASS_MAX, 146328.0, 'lbm') outputs.set_val(Mission.OPERATING_MASS, 95007.0, 'lbm') outputs.set_val(Aircraft.Design.EMPENNAGE_MASS, 2967.4, 'lbm') -outputs.set_val(Mission.USEFUL_LOAD, 6760.42285438, 'lbm') +outputs.set_val(Mission.OPERATING_ITEMS_MASS, 6760.42285438, 'lbm') outputs.set_val(Aircraft.Propulsion.MASS, 19232.0, 'lbm') outputs.set_val(Aircraft.Design.STRUCTURE_MASS, 44389.0, 'lbm') outputs.set_val(Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, 24174.0, 'lbm') 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 d6b2f4066..3e2989e38 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 @@ -271,7 +271,7 @@ sys_equip_mass = 32232.0 sys_equip_mass_units = 'lbm' outputs.set_val(Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, sys_equip_mass, sys_equip_mass_units) -outputs.set_val(Mission.USEFUL_LOAD, 10071.93, 'lbm') +outputs.set_val(Mission.OPERATING_ITEMS_MASS, 10071.93, 'lbm') outputs.set_val(Aircraft.Design.TOTAL_WETTED_AREA, 8319.07, 'ft**2') outputs.set_val(Mission.ZERO_FUEL_MASS, 142837.0, 'lbm') 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 a1d5085d3..6454f54a3 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 @@ -260,7 +260,7 @@ outputs.set_val(Aircraft.Propulsion.MASS, 19232.0, 'lbm') outputs.set_val(Aircraft.Design.STRUCTURE_MASS, 44648.0, 'lbm') outputs.set_val(Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, 24174.0, 'lbm') -outputs.set_val(Mission.USEFUL_LOAD, 6760.42285438, 'lbm') +outputs.set_val(Mission.OPERATING_ITEMS_MASS, 6760.42285438, 'lbm') outputs.set_val(Aircraft.Design.TOTAL_WETTED_AREA, 8319.07, 'ft**2') outputs.set_val(Mission.ZERO_FUEL_MASS, 131744.0, 'lbm') diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index 49c7c7c01..eabe32211 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -60,7 +60,10 @@ def setup(self): ) self.add_subsystem( - 'useful_load_mass', UsefulLoadMass(), promotes_inputs=['*'], promotes_outputs=['*'] + 'operating_items_mass', + OperatingItemsMass(), + promotes_inputs=['*'], + promotes_outputs=['*'], ) self.add_subsystem( @@ -361,7 +364,7 @@ def compute(self, inputs, outputs): ) -class UsefulLoadMass(om.ExplicitComponent): +class OperatingItemsMass(om.ExplicitComponent): def setup(self): add_aviary_input(self, Aircraft.CrewPayload.CARGO_CONTAINER_MASS, units='lbm') add_aviary_input(self, Aircraft.CrewPayload.CABIN_CREW_MASS, units='lbm') @@ -370,10 +373,10 @@ def setup(self): add_aviary_input(self, Aircraft.Fuel.UNUSABLE_FUEL_MASS, units='lbm') add_aviary_input(self, Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, units='lbm') - add_aviary_output(self, Mission.USEFUL_LOAD, units='lbm') + add_aviary_output(self, Mission.OPERATING_ITEMS_MASS, units='lbm') def setup_partials(self): - self.declare_partials(Mission.USEFUL_LOAD, '*', val=1) + self.declare_partials(Mission.OPERATING_ITEMS_MASS, '*', val=1) def compute(self, inputs, outputs): cargo_container_mass = inputs[Aircraft.CrewPayload.CARGO_CONTAINER_MASS] @@ -383,7 +386,7 @@ def compute(self, inputs, outputs): pass_service_mass = inputs[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS] unusable_fuel_mass = inputs[Aircraft.Fuel.UNUSABLE_FUEL_MASS] - outputs[Mission.USEFUL_LOAD] = ( + outputs[Mission.OPERATING_ITEMS_MASS] = ( cabin_crew_mass + flight_crew_mass + unusable_fuel_mass @@ -396,7 +399,7 @@ def compute(self, inputs, outputs): class OperatingMass(om.ExplicitComponent): def setup(self): add_aviary_input(self, Aircraft.Design.EMPTY_MASS, units='lbm') - add_aviary_input(self, Mission.USEFUL_LOAD, units='lbm') + add_aviary_input(self, Mission.OPERATING_ITEMS_MASS, units='lbm') add_aviary_output(self, Mission.OPERATING_MASS, units='lbm') @@ -404,10 +407,10 @@ def setup_partials(self): self.declare_partials(Mission.OPERATING_MASS, '*', val=1) def compute(self, inputs, outputs): - useful_load = inputs[Mission.USEFUL_LOAD] + operating_items_mass = inputs[Mission.OPERATING_ITEMS_MASS] empty_mass = inputs[Aircraft.Design.EMPTY_MASS] - outputs[Mission.OPERATING_MASS] = empty_mass + useful_load + outputs[Mission.OPERATING_MASS] = empty_mass + operating_items_mass class ZeroFuelMass(om.ExplicitComponent): diff --git a/aviary/subsystems/mass/flops_based/test/test_mass_summation.py b/aviary/subsystems/mass/flops_based/test/test_mass_summation.py index e60511ec7..4cbf6de14 100644 --- a/aviary/subsystems/mass/flops_based/test/test_mass_summation.py +++ b/aviary/subsystems/mass/flops_based/test/test_mass_summation.py @@ -100,7 +100,7 @@ def test_case( Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, Aircraft.Design.EMPENNAGE_MASS, Aircraft.Design.EMPTY_MASS, - Mission.USEFUL_LOAD, + Mission.OPERATING_ITEMS_MASS, Mission.OPERATING_MASS, Mission.ZERO_FUEL_MASS, ], @@ -185,7 +185,7 @@ def test_case(self, case_name): Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, Aircraft.Design.EMPENNAGE_MASS, Aircraft.Design.EMPTY_MASS, - Mission.USEFUL_LOAD, + Mission.OPERATING_ITEMS_MASS, Mission.OPERATING_MASS, Mission.ZERO_FUEL_MASS, ], diff --git a/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py b/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py index 4c9f40f71..5d3caf8aa 100644 --- a/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py +++ b/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py @@ -78,7 +78,7 @@ def setup(self): ) -class UsefulLoadMassGroup(om.Group): +class OperatingItemsMassGroup(om.Group): def setup(self): self.add_subsystem( 'cargo_containers', @@ -182,7 +182,7 @@ def setup(self): ) -class EquipAndUsefulLoadMassGroup(om.Group): +class EquipAndOperatingItemsMassGroup(om.Group): def initialize(self): add_aviary_option(self, Aircraft.Design.TYPE) @@ -206,7 +206,7 @@ def setup(self): self.add_subsystem( 'useful', - UsefulLoadMassGroup(), + OperatingItemsMassGroup(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/gasp_based/mass_premission.py b/aviary/subsystems/mass/gasp_based/mass_premission.py index d29739738..0a47d04c8 100644 --- a/aviary/subsystems/mass/gasp_based/mass_premission.py +++ b/aviary/subsystems/mass/gasp_based/mass_premission.py @@ -1,7 +1,9 @@ import openmdao.api as om from aviary.subsystems.mass.gasp_based.design_load import BWBDesignLoadGroup, DesignLoadGroup -from aviary.subsystems.mass.gasp_based.equipment_and_useful_load import EquipAndUsefulLoadMassGroup +from aviary.subsystems.mass.gasp_based.equipment_and_operating_items import ( + EquipAndOperatingItemsMassGroup, +) from aviary.subsystems.mass.gasp_based.fixed import FixedMassGroup from aviary.subsystems.mass.gasp_based.fuel import ( BodyTankCalculations, @@ -52,7 +54,7 @@ def setup(self): self.add_subsystem( 'equip_and_useful_mass', - EquipAndUsefulLoadMassGroup(), + EquipAndOperatingItemsMassGroup(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/gasp_based/mass_summation.py b/aviary/subsystems/mass/gasp_based/mass_summation.py index 29cf8832a..8d957d1a2 100644 --- a/aviary/subsystems/mass/gasp_based/mass_summation.py +++ b/aviary/subsystems/mass/gasp_based/mass_summation.py @@ -36,7 +36,10 @@ def setup(self): ) self.add_subsystem( - 'useful_load_mass', UsefulLoadMass(), promotes_inputs=['*'], promotes_outputs=['*'] + 'operating_items_mass', + OperatingItemsMass(), + promotes_inputs=['*'], + promotes_outputs=['*'], ) self.add_subsystem( @@ -190,7 +193,7 @@ def compute(self, inputs, outputs): ) -class UsefulLoadMass(om.ExplicitComponent): +class OperatingItemsMass(om.ExplicitComponent): def setup(self): add_aviary_input(self, Aircraft.CrewPayload.CARGO_CONTAINER_MASS, units='lbm') add_aviary_input(self, Aircraft.CrewPayload.CABIN_CREW_MASS, units='lbm') @@ -200,10 +203,10 @@ def setup(self): add_aviary_input(self, Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, units='lbm') add_aviary_input(self, Aircraft.Design.EMERGENCY_EQUIPMENT_MASS) - add_aviary_output(self, Mission.USEFUL_LOAD, units='lbm') + add_aviary_output(self, Mission.OPERATING_ITEMS_MASS, units='lbm') def setup_partials(self): - self.declare_partials(Mission.USEFUL_LOAD, '*', val=1) + self.declare_partials(Mission.OPERATING_ITEMS_MASS, '*', val=1) def compute(self, inputs, outputs): cargo_container_mass = inputs[Aircraft.CrewPayload.CARGO_CONTAINER_MASS] @@ -214,7 +217,7 @@ def compute(self, inputs, outputs): unusable_fuel_mass = inputs[Aircraft.Fuel.UNUSABLE_FUEL_MASS] emergency_equip_mass = inputs[Aircraft.Design.EMERGENCY_EQUIPMENT_MASS] - outputs[Mission.USEFUL_LOAD] = ( + outputs[Mission.OPERATING_ITEMS_MASS] = ( cabin_crew_mass + flight_crew_mass + unusable_fuel_mass @@ -228,7 +231,7 @@ def compute(self, inputs, outputs): class OperatingMass(om.ExplicitComponent): def setup(self): add_aviary_input(self, Aircraft.Design.EMPTY_MASS, units='lbm') - add_aviary_input(self, Mission.USEFUL_LOAD, units='lbm') + add_aviary_input(self, Mission.OPERATING_ITEMS_MASS, units='lbm') add_aviary_output(self, Mission.OPERATING_MASS, units='lbm') @@ -236,10 +239,10 @@ def setup_partials(self): self.declare_partials(Mission.OPERATING_MASS, '*', val=1) def compute(self, inputs, outputs): - useful_load = inputs[Mission.USEFUL_LOAD] + operating_items_mass = inputs[Mission.OPERATING_ITEMS_MASS] empty_mass = inputs[Aircraft.Design.EMPTY_MASS] - outputs[Mission.OPERATING_MASS] = empty_mass + useful_load + outputs[Mission.OPERATING_MASS] = empty_mass + operating_items_mass class ZeroFuelMass(om.ExplicitComponent): diff --git a/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py b/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py index 753f28743..394a89976 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py +++ b/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py @@ -4,13 +4,16 @@ from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal from openmdao.utils.testing_utils import use_tempdirs -from aviary.subsystems.mass.gasp_based.equipment_and_useful_load import ( +from aviary.subsystems.mass.gasp_based.equipment_and_operating_items import ( BWBEquipMassGroup, - EquipAndUsefulLoadMassGroup, + EquipAndOperatingItemsMassGroup, EquipMassGroup, - UsefulLoadMassGroup, + OperatingItemsMassGroup, +) +from aviary.subsystems.mass.gasp_based.mass_summation import ( + SystemsEquipmentMass, + OperatingItemsMass, ) -from aviary.subsystems.mass.gasp_based.mass_summation import SystemsEquipmentMass, UsefulLoadMass from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Mission, Settings @@ -135,7 +138,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( 'useful', - UsefulLoadMass(), + OperatingItemsMass(), promotes=['*'], ) @@ -169,7 +172,7 @@ def test_case1(self): self.prob.run_model() tol = 1e-7 - assert_near_equal(self.prob[Mission.USEFUL_LOAD], 5341.36, tol) + assert_near_equal(self.prob[Mission.OPERATING_ITEMS_MASS], 5341.36, tol) partial_data = self.prob.check_partials(out_stream=None, method='cs') assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) @@ -186,7 +189,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( 'useful_group', - UsefulLoadMassGroup(), + OperatingItemsMassGroup(), promotes=['*'], ) @@ -241,7 +244,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( 'group', - EquipAndUsefulLoadMassGroup(), + EquipAndOperatingItemsMassGroup(), promotes=['*'], ) @@ -399,7 +402,7 @@ def setUp(self): prob = self.prob = om.Problem() prob.model.add_subsystem( 'useful', - UsefulLoadMass(), + OperatingItemsMass(), promotes=['*'], ) @@ -431,7 +434,7 @@ def test_case1(self): self.prob.run_model() tol = 1e-7 - assert_near_equal(self.prob[Mission.USEFUL_LOAD], 4321.8, tol) + assert_near_equal(self.prob[Mission.OPERATING_ITEMS_MASS], 4321.8, tol) partial_data = self.prob.check_partials(out_stream=None, method='cs') assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) @@ -450,7 +453,7 @@ def setUp(self): prob = self.prob = om.Problem() prob.model.add_subsystem( 'group', - EquipAndUsefulLoadMassGroup(), + EquipAndOperatingItemsMassGroup(), promotes=['*'], ) diff --git a/aviary/subsystems/mass/gasp_based/test/test_fuel.py b/aviary/subsystems/mass/gasp_based/test/test_fuel.py index c3bdc9b52..76151a449 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_fuel.py +++ b/aviary/subsystems/mass/gasp_based/test/test_fuel.py @@ -754,7 +754,7 @@ def setUp(self): # prob.model.set_input_defaults( # Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS, 20876.477, units='lbm' # ) - # prob.model.set_input_defaults(Mission.USEFUL_LOAD, 5736.3, units='lbm') + # prob.model.set_input_defaults(Mission.OPERATING_ITEMS_MASS, 5736.3, units='lbm') prob.model.set_input_defaults(Mission.OPERATING_MASS, 88282.366, units='lbm') prob.model.set_input_defaults('fuel_mass_required', 26652.3, units='lbm') prob.model.set_input_defaults( diff --git a/aviary/subsystems/mass/gasp_based/test/test_furnishings.py b/aviary/subsystems/mass/gasp_based/test/test_furnishings.py index 35941c206..868fe66c2 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_furnishings.py +++ b/aviary/subsystems/mass/gasp_based/test/test_furnishings.py @@ -58,12 +58,12 @@ class FurnishingMassTestCase2(unittest.TestCase): """Test mass-weight conversion""" def setUp(self): - import aviary.subsystems.mass.gasp_based.equipment_and_useful_load as equip + import aviary.subsystems.mass.gasp_based.equipment_and_operating_items as equip equip.GRAV_ENGLISH_LBM = 1.1 def tearDown(self): - import aviary.subsystems.mass.gasp_based.equipment_and_useful_load as equip + import aviary.subsystems.mass.gasp_based.equipment_and_operating_items as equip equip.GRAV_ENGLISH_LBM = 1.0 diff --git a/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py b/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py index 507b4f80f..3b9bd49f1 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py +++ b/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py @@ -3236,7 +3236,7 @@ def setUp(self): Aircraft.Electrical.SYSTEM_MASS_PER_PASSENGER, 11.45, units='lbm' ) - # inputs to UsefulLoadMass + # inputs to OperatingItemsMass prob.model.set_input_defaults( Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, 12.0, units='unitless' ) @@ -3279,7 +3279,7 @@ def test_case1(self): Aircraft.Engine.POSITION_FACTOR -- SKEPOS = 1.05 Aircraft.CrewPayload.PASSENGER_PAYLOAD_MASS -- WPL = 33750 Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS - WFE = 20876. - Mission.USEFUL_LOAD -- WFUL = 5775. + Mission.OPERATING_ITEMS_MASS -- WFUL = 5775. Aircraft.Wing.MASS -- WW = 7645. Aircraft.Strut.MASS -- WSTRUT = 0 Aircraft.Wing.FOLD_MASS -- WWFOLD = 107.9 @@ -3358,7 +3358,7 @@ def test_case1(self): assert_near_equal(prob[Aircraft.Engine.ADDITIONAL_MASS], 153.16770871, tol) assert_near_equal(prob[Aircraft.Engine.POSITION_FACTOR], 1.05, tol) assert_near_equal(prob[Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS], 21885.38086961, tol) - assert_near_equal(prob[Mission.USEFUL_LOAD], 5961.79463002, tol) + assert_near_equal(prob[Mission.OPERATING_ITEMS_MASS], 5961.79463002, tol) assert_near_equal(prob[Aircraft.Wing.SURFACE_CONTROL_MASS], 1986.25111783, tol) # BWBWingMassGroup diff --git a/aviary/subsystems/mass/mass_builder.py b/aviary/subsystems/mass/mass_builder.py index 9e776250b..4c56d3da4 100644 --- a/aviary/subsystems/mass/mass_builder.py +++ b/aviary/subsystems/mass/mass_builder.py @@ -274,7 +274,9 @@ def report(self, prob, reports_folder, **kwargs): f.write(f'|####**MISSION SPECIFIC DETAILS:**####|||\n') f.write('||||\n') - val, units = find_variable_in_problem(Mission.USEFUL_LOAD, prob, self.meta_data) + val, units = find_variable_in_problem( + Mission.OPERATING_ITEMS_MASS, prob, self.meta_data + ) f.write(f'|Useful Load|{val}|{units}|\n') val1, units = find_variable_in_problem( diff --git a/aviary/subsystems/test/test_gasp_based_premission.py b/aviary/subsystems/test/test_gasp_based_premission.py index b3887b29f..440472280 100644 --- a/aviary/subsystems/test/test_gasp_based_premission.py +++ b/aviary/subsystems/test/test_gasp_based_premission.py @@ -97,7 +97,7 @@ def test_case1(self): Aircraft.LandingGear.MAIN_GEAR_MASS: 6366.3591, # GASP original 21078.3911, added controls mass Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS: 24_897.7475, - Mission.USEFUL_LOAD: 5341.4317956, + Mission.OPERATING_ITEMS_MASS: 5341.4317956, Aircraft.Engine.ADDITIONAL_MASS: 850.90095, Aircraft.Wing.MASS: 16206.8122, Aircraft.Fuel.FUEL_SYSTEM_MASS: 1740.2606, @@ -184,7 +184,7 @@ def test_case2(self): Aircraft.LandingGear.MAIN_GEAR_MASS: 6366.3591, # GASP original 21078.3911, added controls mass Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS: 24_897.7475, - Mission.USEFUL_LOAD: 5332.684, + Mission.OPERATING_ITEMS_MASS: 5332.684, Aircraft.Engine.ADDITIONAL_MASS: 827.5372, Aircraft.Wing.MASS: 15651.64198957, Aircraft.Fuel.FUEL_SYSTEM_MASS: 1779.06667944, @@ -235,7 +235,7 @@ def test_case1(self): Aircraft.AirConditioning.MASS -- WAC = 1301.57 Aircraft.Furnishings.MASS -- 11269.88 Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS -- WFE = 20876. - Mission.USEFUL_LOAD -- WFUL = 5775. + Mission.OPERATING_ITEMS_MASS -- WFUL = 5775. Aircraft.Engine.ADDITIONAL_MASS -- not in GASP Aircraft.Wing.FOLD_MASS -- WWFOLD = 107.9 Aircraft.Wing.MASS -- WW = 7645. @@ -322,7 +322,7 @@ def test_case1(self): Aircraft.Furnishings.MASS: 11269.876, # GASP original 20876.453, added controls mass Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS: 22_991.435, - Mission.USEFUL_LOAD: 5971.7946, + Mission.OPERATING_ITEMS_MASS: 5971.7946, Aircraft.Engine.ADDITIONAL_MASS: 153.1677, Aircraft.Wing.FOLD_MASS: 107.8736151, Aircraft.Wing.MASS: 6962.31442344, @@ -476,7 +476,7 @@ def test_case_geom_mass(self): Aircraft.Furnishings.MASS: 11269.876, # GASP original 20876.453, added controls mass Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS: 22_991.435, - Mission.USEFUL_LOAD: 5971.7946, + Mission.OPERATING_ITEMS_MASS: 5971.7946, Aircraft.Engine.ADDITIONAL_MASS: 153.1677, Aircraft.Wing.FOLD_MASS: 107.8335, Aircraft.Wing.MASS: 6959.7262, diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 4ef9a792b..3509cf67e 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -6934,7 +6934,7 @@ ) add_meta_data( - Mission.USEFUL_LOAD, + Mission.OPERATING_ITEMS_MASS, meta_data=_MetaData, historical_name={'GASP': 'INGASP.WFUL', 'FLOPS': None}, units='lbm', diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 1a2bc48df..7a3da5310 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -679,7 +679,7 @@ class Mission: RESERVE_FUEL_MARGIN = 'mission:reserve_fuel_margin' TOTAL_FUEL = 'mission:total_fuel' TOTAL_RESERVE_FUEL = 'mission:total_reserve_fuel' - USEFUL_LOAD = 'mission:useful_load' + OPERATING_ITEMS_MASS = 'mission:operating_items_mass' ZERO_FUEL_MASS = 'mission:zero_fuel_mass' class Constraints: From c2561419366146d4ef65ae6b608cd2eb906084cb Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:05:06 -0400 Subject: [PATCH 02/14] rename equipment_and_udeful_load.py file --- ...ipment_and_useful_load.py => equipment_and_operating_items.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename aviary/subsystems/mass/gasp_based/{equipment_and_useful_load.py => equipment_and_operating_items.py} (100%) diff --git a/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py b/aviary/subsystems/mass/gasp_based/equipment_and_operating_items.py similarity index 100% rename from aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py rename to aviary/subsystems/mass/gasp_based/equipment_and_operating_items.py From 42cfe82b6951763abd85eef18d38146e52cfd1f9 Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:12:07 -0400 Subject: [PATCH 03/14] fix ordering of variable names --- aviary/variable_info/variable_meta_data.py | 18 +++++++++--------- aviary/variable_info/variables.py | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 3509cf67e..f7612a1ca 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -6859,6 +6859,15 @@ 'May differ from Aircraft.Design.GROSS_MASS for off-design missions.', ) +add_meta_data( + Mission.OPERATING_ITEMS_MASS, + meta_data=_MetaData, + historical_name={'GASP': 'INGASP.WFUL', 'FLOPS': None}, + units='lbm', + desc='Useful load group. Includes crew, unusable fuel, and oil mass.', + default_value=0.0, +) + add_meta_data( Mission.OPERATING_MASS, meta_data=_MetaData, @@ -6933,15 +6942,6 @@ default_value=0, ) -add_meta_data( - Mission.OPERATING_ITEMS_MASS, - meta_data=_MetaData, - historical_name={'GASP': 'INGASP.WFUL', 'FLOPS': None}, - units='lbm', - desc='Useful load group. Includes crew, unusable fuel, and oil mass.', - default_value=0.0, -) - add_meta_data( Mission.ZERO_FUEL_MASS, meta_data=_MetaData, diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 7a3da5310..df97e5e92 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -672,6 +672,7 @@ class Mission: FINAL_TIME = 'mission:final_time' FUEL = 'mission:fuel' GROSS_MASS = 'mission:gross_mass' + OPERATING_ITEMS_MASS = 'mission:operating_items_mass' OPERATING_MASS = 'mission:operating_mass' RANGE = 'mission:range' RESERVE_FUEL = 'mission:reserve_fuel' @@ -679,7 +680,6 @@ class Mission: RESERVE_FUEL_MARGIN = 'mission:reserve_fuel_margin' TOTAL_FUEL = 'mission:total_fuel' TOTAL_RESERVE_FUEL = 'mission:total_reserve_fuel' - OPERATING_ITEMS_MASS = 'mission:operating_items_mass' ZERO_FUEL_MASS = 'mission:zero_fuel_mass' class Constraints: From a248901994c0c6aa4b248661a912f4a1b6b44e33 Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:27:31 -0400 Subject: [PATCH 04/14] add UsefulLoadMass subsystem to FLOPS mass summation and variable hierarchy --- .../mass/flops_based/mass_summation.py | 21 +++++++++++++++++++ aviary/variable_info/variable_meta_data.py | 10 +++++++++ aviary/variable_info/variables.py | 1 + 3 files changed, 32 insertions(+) diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index eabe32211..e520f5608 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -74,6 +74,10 @@ def setup(self): 'zero_fuel_mass', ZeroFuelMass(), promotes_inputs=['*'], promotes_outputs=['*'] ) + self.add_subsystem( + 'useful_load_mass', UsefulLoadMass(), promotes_inputs=['*'], promotes_outputs=['*'] + ) + class EmpennageMass(om.ExplicitComponent): def setup(self): @@ -432,3 +436,20 @@ def compute(self, inputs, outputs): operating_mass = inputs[Mission.OPERATING_MASS] outputs[Mission.ZERO_FUEL_MASS] = operating_mass + pass_mass + bag_mass + cargo_mass + + +class UsefulLoadMass(om.ExplicitComponent): + def setup(self): + self.add_input(Aircraft.Design.GROSS_MASS, units='lbm') + self.add_input(Aircraft.Design.EMPTY_MASS, units='lbm') + + self.add_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') + + self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, '**', val=1) + + def compute(self, inputs, outputs): + gross_mass = inputs[Aircraft.Design.GROSS_MASS] + empty_mass = inputs[Aircraft.Design.EMPTY_MASS] + + # True Useful Load + outputs[Aircraft.Design.USEFUL_LOAD_MASS] = gross_mass - empty_mass diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index f7612a1ca..8b67460e3 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -1784,6 +1784,16 @@ default_value=False, ) +add_meta_data( + Aircraft.Design.USEFUL_LOAD_MASS, + meta_data=MetaData, + historical_name={'GASP': None, 'FLOPS': None}, + units='lbm', + desc='Useful load of the aircraft calculated as ' + 'Aircraft.Design.GROSS_MASS - Aircraft.Design.EMPTY_MASS', +) + + add_meta_data( Aircraft.Design.WETTED_AREAS, meta_data=_MetaData, diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index df97e5e92..8d82233cd 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -176,6 +176,7 @@ class Design: TYPE = 'aircraft:design:type' ULF_CALCULATED_FROM_MANEUVER = 'aircraft:design:ulf_calculated_from_maneuver' USE_ALT_MASS = 'aircraft:design:use_alt_mass' + USEFUL_LOAD_MASS = 'aircraft:design:useful_load_mass' WETTED_AREAS = 'aircraft:design:wetted_areas' WING_LOADING = 'aircraft:design:wing_loading' ZERO_LIFT_DRAG_COEFF_FACTOR = 'aircraft:design:zero_lift_drag_coeff_factor' From 883e3efec386f93804e5059c850afb109f975876 Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:28:05 -0400 Subject: [PATCH 05/14] add UsefulLoadMass subsystem to FLOPS mass summation and variable hierarchy --- aviary/variable_info/variable_meta_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 8b67460e3..8fff5d984 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -1786,7 +1786,7 @@ add_meta_data( Aircraft.Design.USEFUL_LOAD_MASS, - meta_data=MetaData, + meta_data=_MetaData, historical_name={'GASP': None, 'FLOPS': None}, units='lbm', desc='Useful load of the aircraft calculated as ' From 8e3cf1da62ef504f9febcb26564821e951c18bfd Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:38:59 -0400 Subject: [PATCH 06/14] fix glue in doc and add setup_partials method to useful_load class --- aviary/docs/theory_guide/gasp_based_bwb.ipynb | 2 +- aviary/subsystems/mass/flops_based/mass_summation.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/aviary/docs/theory_guide/gasp_based_bwb.ipynb b/aviary/docs/theory_guide/gasp_based_bwb.ipynb index dc55e9478..98ea6d3df 100644 --- a/aviary/docs/theory_guide/gasp_based_bwb.ipynb +++ b/aviary/docs/theory_guide/gasp_based_bwb.ipynb @@ -275,7 +275,7 @@ "\n", "| Aviary |     | GASP |     | Observation |\n", "| ------- | ------- | ------- | -------- | ------------- |\n", - "| {glue:md}`Mission.OPERATING_ITEMS` | 5972 | WFUL | 5775 | different unit weight of pilots and attendents |\n", + "| {glue:md}`Mission.OPERATING_ITEMS_MASS` | 5972 | WFUL | 5775 | different unit weight of pilots and attendents |\n", "| {glue:md}`Aircraft.Wing.HIGH_LIFT_MASS` | 972 | WHLDEV | 974 | In GASP, wing loading is a variable, but in Aviary, it is a constant |\n", "| {glue:md}`Aircraft.Fuel.FUEL_SYSTEM_MASS` | 1316 | WFSS | 1281 | the mass in GASP is computed after engine sizing. |\n", "| {glue:md}`Aircraft.Design.STRUCTURE_MASS` | 44471 | WST | 45623 | the mass in GASP is computed after engine sizing. |\n", diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index e520f5608..5f6a512b0 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -445,6 +445,7 @@ def setup(self): self.add_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') + def setup_partials(self): self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, '**', val=1) def compute(self, inputs, outputs): From e551968fad81e4112403dfd6339917b8f19b0aff Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:48:15 -0400 Subject: [PATCH 07/14] doc updates and comment corrections --- aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb | 2 +- aviary/subsystems/mass/mass_builder.py | 2 +- aviary/variable_info/variable_meta_data.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb b/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb index 321354f17..3149aa4a5 100644 --- a/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb +++ b/aviary/docs/user_guide_unreviewed/subsystems/mass.ipynb @@ -138,7 +138,7 @@ "\n", "### Operating Mass\n", "Empty Mass, plus:\n", - "- **Useful Load**\n", + "- **Operating Items**\n", " - Flight Crew\n", " - Cabin Crew\n", " - Unusable Fuel\n", diff --git a/aviary/subsystems/mass/mass_builder.py b/aviary/subsystems/mass/mass_builder.py index 4c56d3da4..a734a7683 100644 --- a/aviary/subsystems/mass/mass_builder.py +++ b/aviary/subsystems/mass/mass_builder.py @@ -277,7 +277,7 @@ def report(self, prob, reports_folder, **kwargs): val, units = find_variable_in_problem( Mission.OPERATING_ITEMS_MASS, prob, self.meta_data ) - f.write(f'|Useful Load|{val}|{units}|\n') + f.write(f'|Operating Items|{val}|{units}|\n') val1, units = find_variable_in_problem( Aircraft.CrewPayload.CABIN_CREW_MASS, prob, self.meta_data diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 8fff5d984..5a81d359d 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -6874,7 +6874,7 @@ meta_data=_MetaData, historical_name={'GASP': 'INGASP.WFUL', 'FLOPS': None}, units='lbm', - desc='Useful load group. Includes crew, unusable fuel, and oil mass.', + desc='Operating Items group. Includes crew, unusable fuel, and oil mass.', default_value=0.0, ) From 6f9b0d6b31990a706b4b31223c317048be460db7 Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:53:45 -0400 Subject: [PATCH 08/14] add usefulload calculation group to gasp based mass summation --- .../mass/flops_based/mass_summation.py | 1 - .../mass/gasp_based/mass_summation.py | 21 + .../test/test_equipment_and_useful_load.py | 533 ------------------ 3 files changed, 21 insertions(+), 534 deletions(-) delete mode 100644 aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index 5f6a512b0..83c8cd370 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -452,5 +452,4 @@ def compute(self, inputs, outputs): gross_mass = inputs[Aircraft.Design.GROSS_MASS] empty_mass = inputs[Aircraft.Design.EMPTY_MASS] - # True Useful Load outputs[Aircraft.Design.USEFUL_LOAD_MASS] = gross_mass - empty_mass diff --git a/aviary/subsystems/mass/gasp_based/mass_summation.py b/aviary/subsystems/mass/gasp_based/mass_summation.py index 8d957d1a2..8929487a7 100644 --- a/aviary/subsystems/mass/gasp_based/mass_summation.py +++ b/aviary/subsystems/mass/gasp_based/mass_summation.py @@ -50,6 +50,10 @@ def setup(self): 'zero_fuel_mass', ZeroFuelMass(), promotes_inputs=['*'], promotes_outputs=['*'] ) + self.add_subsystem( + 'useful_load_mass', UsefulLoadMass(), promotes_inputs=['*'], promotes_outputs=['*'] + ) + class EmpennageMass(om.ExplicitComponent): def setup(self): @@ -260,3 +264,20 @@ def compute(self, inputs, outputs): operating_mass = inputs[Mission.OPERATING_MASS] outputs[Mission.ZERO_FUEL_MASS] = operating_mass + payload_mass + + +class UsefulLoadMass(om.ExplicitComponent): + def setup(self): + self.add_input(Aircraft.Design.GROSS_MASS, units='lbm') + self.add_input(Aircraft.Design.EMPTY_MASS, units='lbm') + + self.add_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') + + def setup_partials(self): + self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, '**', val=1) + + def compute(self, inputs, outputs): + gross_mass = inputs[Aircraft.Design.GROSS_MASS] + empty_mass = inputs[Aircraft.Design.EMPTY_MASS] + + outputs[Aircraft.Design.USEFUL_LOAD_MASS] = gross_mass - empty_mass diff --git a/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py b/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py deleted file mode 100644 index 394a89976..000000000 --- a/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py +++ /dev/null @@ -1,533 +0,0 @@ -import unittest - -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.mass.gasp_based.equipment_and_operating_items import ( - BWBEquipMassGroup, - EquipAndOperatingItemsMassGroup, - EquipMassGroup, - OperatingItemsMassGroup, -) -from aviary.subsystems.mass.gasp_based.mass_summation import ( - SystemsEquipmentMass, - OperatingItemsMass, -) -from aviary.variable_info.functions import setup_model_options -from aviary.variable_info.options import get_option_defaults -from aviary.variable_info.variables import Aircraft, Mission, Settings - - -class EquipmentMassSummationTest(unittest.TestCase): - """this is the large single aisle 1 V3 test case.""" - - def setUp(self): - options = get_option_defaults() - # options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') - # options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') - - self.prob = om.Problem() - self.prob.model.add_subsystem( - 'equip', - SystemsEquipmentMass(), - promotes=['*'], - ) - - self.prob.model.set_input_defaults( - Aircraft.AirConditioning.MASS, val=1324.0561, units='lbm' - ) - self.prob.model.set_input_defaults(Aircraft.APU.MASS, val=928.0, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Avionics.MASS, val=1959.0, units='lbm') - self.prob.model.set_input_defaults(Aircraft.AntiIcing.MASS, val=683.46852785, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Furnishings.MASS, val=13266.56, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Instruments.MASS, val=862.45194435, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Hydraulics.MASS, val=1487.78, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Electrical.MASS, val=2231.0, units='lbm') - self.prob.model.set_input_defaults(Aircraft.OxygenSystem.MASS, val=50, units='lbm') - - setup_model_options(self.prob, options) - - self.prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - assert_near_equal(self.prob[Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS], 22792.3165722, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -class EquipMassGroupTest(unittest.TestCase): - """this is the large single aisle 1 V3 test case.""" - - def setUp(self): - options = get_option_defaults() - options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') - options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') - - self.prob = om.Problem() - self.prob.model.add_subsystem( - 'group', - EquipMassGroup(), - promotes=['*'], - ) - - self.prob.model.set_input_defaults( - Aircraft.Instruments.MASS_COEFFICIENT, val=0.0736, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, val=0.112, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, val=0.14, units='unitless' - ) - self.prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, val=175400, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, val=129.4, units='ft') - self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=117.8, units='ft') - self.prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, val=7511, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Controls.MASS, val=3895.0, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Wing.AREA, val=1370.3, units='ft**2') - self.prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, val=375.9, units='ft**2') - self.prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, val=469.3, units='ft**2') - - self.prob.model.set_input_defaults( - Aircraft.AirConditioning.MASS_COEFFICIENT, val=1.65, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, val=7.5, units='psi' - ) - self.prob.model.set_input_defaults(Aircraft.Fuselage.AVG_DIAMETER, val=13.1, units='ft') - self.prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, val=1068.96, units='ft**2') - self.prob.model.set_input_defaults( - Aircraft.Furnishings.MASS_SCALER, val=40.0, units='unitless' - ) - - setup_model_options(self.prob, options) - - self.prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1324.05614369, tol) - assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 13266.53964608, tol) - assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 683.4685279, tol) - assert_near_equal(self.prob[Aircraft.APU.MASS], 1077.969377, tol) - assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1514.0, tol) - assert_near_equal(self.prob[Aircraft.Electrical.MASS], 170.0, tol) - assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1487.78, tol) - assert_near_equal(self.prob[Aircraft.Instruments.MASS], 547.41157631, tol) - assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -class UsefulMassSumTest(unittest.TestCase): - """this is the large single aisle 1 V3 test case.""" - - def setUp(self): - options = get_option_defaults() - # options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') - # options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') - - self.prob = om.Problem() - self.prob.model.add_subsystem( - 'useful', - OperatingItemsMass(), - promotes=['*'], - ) - - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.FLIGHT_CREW_MASS, val=492.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.CABIN_CREW_MASS, val=800.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, val=342.6, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.PASSENGER_SERVICE_MASS, val=2872.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Design.EMERGENCY_EQUIPMENT_MASS, val=50.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Fuel.UNUSABLE_FUEL_MASS, val=619.76, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.CARGO_CONTAINER_MASS, val=165, units='lbm' - ) - - setup_model_options(self.prob, options) - - self.prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - assert_near_equal(self.prob[Mission.OPERATING_ITEMS_MASS], 5341.36, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -class UsefulMassGroupTest(unittest.TestCase): - """this is the large single aisle 1 V3 test case.""" - - def setUp(self): - options = get_option_defaults() - options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') - options.set_val(Settings.VERBOSITY, val=0, units='unitless') - - self.prob = om.Problem() - self.prob.model.add_subsystem( - 'useful_group', - OperatingItemsMassGroup(), - promotes=['*'], - ) - - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.CATERING_ITEMS_MASS_PER_PASSENGER, val=7.6, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_PER_PASSENGER, val=5.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, val=12, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.WATER_MASS_PER_OCCUPANT, val=3.0, units='lbm' - ) - self.prob.model.set_input_defaults(Aircraft.Wing.AREA, val=1370.3, units='ft**2') - self.prob.model.set_input_defaults( - Aircraft.Engine.SCALED_SLS_THRUST, val=29500, units='lbf' - ) - self.prob.model.set_input_defaults( - Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units='unitless' - ) - - setup_model_options(self.prob, options) - - self.prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - assert_near_equal(self.prob[Aircraft.CrewPayload.CARGO_CONTAINER_MASS], 165.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.CABIN_CREW_MASS], 800.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.FLIGHT_CREW_MASS], 492.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS], 2872.0, tol) - assert_near_equal(self.prob[Aircraft.Design.EMERGENCY_EQUIPMENT_MASS], 115.0, tol) - assert_near_equal(self.prob[Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS], 342.6, tol) - assert_near_equal(self.prob[Aircraft.Fuel.UNUSABLE_FUEL_MASS], 619.82896954, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -class FixedEquipAndUsefulMassGroupTest(unittest.TestCase): - """this is the large single aisle 1 V3 test case.""" - - def setUp(self): - options = get_option_defaults() - options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') - options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') - - self.prob = om.Problem() - self.prob.model.add_subsystem( - 'group', - EquipAndOperatingItemsMassGroup(), - promotes=['*'], - ) - - self.prob.model.set_input_defaults( - Aircraft.Instruments.MASS_COEFFICIENT, val=0.0736, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, val=0.112, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, val=0.14, units='unitless' - ) - self.prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, val=175400, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, val=129.4, units='ft') - self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=117.8, units='ft') - self.prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, val=7511, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Controls.MASS, val=3895.0, units='lbm') - self.prob.model.set_input_defaults(Aircraft.Wing.AREA, val=1370.3, units='ft**2') - self.prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, val=375.9, units='ft**2') - self.prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, val=469.3, units='ft**2') - self.prob.model.set_input_defaults( - Aircraft.AirConditioning.MASS_COEFFICIENT, val=1.65, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, val=7.5, units='psi' - ) - self.prob.model.set_input_defaults(Aircraft.Fuselage.AVG_DIAMETER, val=13.1, units='ft') - self.prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, val=1068.96, units='ft**2') - self.prob.model.set_input_defaults( - Aircraft.Furnishings.MASS_SCALER, val=40.0, units='unitless' - ) - - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.CATERING_ITEMS_MASS_PER_PASSENGER, val=7.6, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_PER_PASSENGER, val=5.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, val=12, units='unitless' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.WATER_MASS_PER_OCCUPANT, val=3.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Engine.SCALED_SLS_THRUST, val=29500, units='lbf' - ) - self.prob.model.set_input_defaults( - Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units='unitless' - ) - - setup_model_options(self.prob, options) - - self.prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - - assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1324.05614369, tol) - assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 13266.53964608, tol) - assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 683.4685279, tol) - assert_near_equal(self.prob[Aircraft.APU.MASS], 1077.969377, tol) - assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1514.0, tol) - assert_near_equal(self.prob[Aircraft.Electrical.MASS], 170.0, tol) - assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1487.78, tol) - assert_near_equal(self.prob[Aircraft.Instruments.MASS], 547.41157631, tol) - assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.CARGO_CONTAINER_MASS], 165.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.CABIN_CREW_MASS], 800.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.FLIGHT_CREW_MASS], 492.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS], 2872.0, tol) - assert_near_equal(self.prob[Aircraft.Design.EMERGENCY_EQUIPMENT_MASS], 115.0, tol) - assert_near_equal(self.prob[Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS], 342.6, tol) - assert_near_equal(self.prob[Aircraft.Fuel.UNUSABLE_FUEL_MASS], 619.82896954, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -@use_tempdirs -class BWBFixedEquipMassGroupTest(unittest.TestCase): - """Created based on GASP BWB model.""" - - def setUp(self): - options = get_option_defaults() - options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=150, units='unitless') - options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') - - prob = self.prob = om.Problem() - prob.model.add_subsystem( - 'group', - BWBEquipMassGroup(), - promotes=['*'], - ) - prob.model.set_input_defaults( - Aircraft.Instruments.MASS_COEFFICIENT, 0.116, units='unitless' - ) - prob.model.set_input_defaults( - Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, 0.107, units='unitless' - ) - prob.model.set_input_defaults( - Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, 0.135, units='unitless' - ) - prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, 150000, units='lbm') - prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, 71.5245514, units='ft') - prob.model.set_input_defaults(Aircraft.Wing.SPAN, 146.38501, units='ft') - prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, 7800.0, units='lbm') - prob.model.set_input_defaults(Aircraft.Controls.MASS, 2115.19946, units='lbm') - prob.model.set_input_defaults(Aircraft.Wing.AREA, 2142.85718, units='ft**2') - prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, 0.00170628, units='ft**2') - prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, 169.119629, units='ft**2') - prob.model.set_input_defaults( - Aircraft.AirConditioning.MASS_COEFFICIENT, 1.155, units='unitless' - ) - prob.model.set_input_defaults(Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, 10.0, units='psi') - prob.model.set_input_defaults(Aircraft.Fuselage.HYDRAULIC_DIAMETER, 19.3650932, units='ft') - prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, 1283.5249, units='ft**2') - prob.model.set_input_defaults(Aircraft.Furnishings.MASS_SCALER, 40.0, units='unitless') - prob.model.set_input_defaults( - Aircraft.Electrical.SYSTEM_MASS_PER_PASSENGER, 11.45, units='lbm' - ) - - setup_model_options(self.prob, options) - - prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1301.5729093, tol) - assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 11269.87654648, tol) - assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 706.48495598, tol) - assert_near_equal(self.prob[Aircraft.APU.MASS], 928.46163145, tol) - assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1430.0, tol) - assert_near_equal(self.prob[Aircraft.Electrical.MASS], 1887.5, tol) - assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1279.32634222, tol) - assert_near_equal(self.prob[Aircraft.Instruments.MASS], 917.20099314, tol) - assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -class BWBUsefulMassSumTest(unittest.TestCase): - """Created based on GASP BWB model.""" - - def setUp(self): - options = get_option_defaults() - options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=150, units='unitless') - options.set_val(Settings.VERBOSITY, 0) - - prob = self.prob = om.Problem() - prob.model.add_subsystem( - 'useful', - OperatingItemsMass(), - promotes=['*'], - ) - - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.FLIGHT_CREW_MASS, val=446.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.CABIN_CREW_MASS, val=631.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, val=235.5, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.PASSENGER_SERVICE_MASS, val=2163.0, units='lbm' - ) - self.prob.model.set_input_defaults( - Aircraft.Design.EMERGENCY_EQUIPMENT_MASS, val=100.0, units='lbm' - ) - self.prob.model.set_input_defaults(Aircraft.Fuel.UNUSABLE_FUEL_MASS, val=581.3, units='lbm') - self.prob.model.set_input_defaults( - Aircraft.CrewPayload.CARGO_CONTAINER_MASS, val=165, units='lbm' - ) - - setup_model_options(self.prob, options) - - prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - assert_near_equal(self.prob[Mission.OPERATING_ITEMS_MASS], 4321.8, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -@use_tempdirs -class BWBFixedEquipAndUsefulMassGroupTest(unittest.TestCase): - """this is the large single aisle 1 V3 test case.""" - - def setUp(self): - options = get_option_defaults() - options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=150, units='unitless') - options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') - options.set_val(Aircraft.Design.TYPE, val='BWB', units='unitless') - - prob = self.prob = om.Problem() - prob.model.add_subsystem( - 'group', - EquipAndOperatingItemsMassGroup(), - promotes=['*'], - ) - - prob.model.set_input_defaults( - Aircraft.Instruments.MASS_COEFFICIENT, 0.116, units='unitless' - ) - prob.model.set_input_defaults( - Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, 0.107, units='unitless' - ) - prob.model.set_input_defaults( - Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, 0.135, units='unitless' - ) - prob.model.set_input_defaults( - Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_PER_PASSENGER, 6.0, units='lbm' - ) - prob.model.set_input_defaults( - Aircraft.CrewPayload.WATER_MASS_PER_OCCUPANT, 3.0, units='lbm' - ) - prob.model.set_input_defaults( - Aircraft.CrewPayload.CATERING_ITEMS_MASS_PER_PASSENGER, 5.0, units='lbm' - ) - prob.model.set_input_defaults( - Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, 12.0, units='unitless' - ) - prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, 150000, units='lbm') - prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, 71.5245514, units='ft') - prob.model.set_input_defaults(Aircraft.Wing.SPAN, 146.38501, units='ft') - prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, 7800.0, units='lbm') - prob.model.set_input_defaults(Aircraft.Controls.MASS, 2115.19946, units='lbm') - prob.model.set_input_defaults(Aircraft.Wing.AREA, 2142.85718, units='ft**2') - prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, 0.001706279, units='ft**2') - prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, 169.119629, units='ft**2') - prob.model.set_input_defaults( - Aircraft.AirConditioning.MASS_COEFFICIENT, 1.155, units='unitless' - ) - prob.model.set_input_defaults(Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, 10.0, units='psi') - prob.model.set_input_defaults(Aircraft.Fuselage.HYDRAULIC_DIAMETER, 19.3650932, units='ft') - prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, 1283.5249, units='ft**2') - prob.model.set_input_defaults(Aircraft.Furnishings.MASS_SCALER, 40.0, units='unitless') - prob.model.set_input_defaults( - Aircraft.Electrical.SYSTEM_MASS_PER_PASSENGER, 11.45, units='lbm' - ) - prob.model.set_input_defaults(Aircraft.Wing.AREA, 2142.85718, units='ft**2') - prob.model.set_input_defaults(Aircraft.Engine.SCALED_SLS_THRUST, [19580.1602], units='lbf') - prob.model.set_input_defaults(Aircraft.Fuel.WING_FUEL_FRACTION, 0.45, units='unitless') - - setup_model_options(self.prob, options) - - prob.setup(check=False, force_alloc_complex=True) - - def test_case1(self): - self.prob.run_model() - - tol = 1e-7 - assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1301.573, tol) - assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 11269.877, tol) - assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 706.48495598, tol) - assert_near_equal(self.prob[Aircraft.APU.MASS], 928.46163145, tol) - assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1430.0, tol) - assert_near_equal(self.prob[Aircraft.Electrical.MASS], 1887.5, tol) - assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1279.32634222, tol) - assert_near_equal(self.prob[Aircraft.Instruments.MASS], 917.20099314, tol) - assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.CARGO_CONTAINER_MASS], 165.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.CABIN_CREW_MASS], 600.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.FLIGHT_CREW_MASS], 492.0, tol) - assert_near_equal(self.prob[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS], 2148.0, tol) - assert_near_equal(self.prob[Aircraft.Design.EMERGENCY_EQUIPMENT_MASS], 90.0, tol) - assert_near_equal(self.prob[Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS], 235.46573016, tol) - assert_near_equal(self.prob[Aircraft.Fuel.UNUSABLE_FUEL_MASS], 581.3289049, tol) - - partial_data = self.prob.check_partials(out_stream=None, method='cs') - assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) - - -if __name__ == '__main__': - unittest.main() From cc407b6e83d522ba1e3816f72215cb46e03e6284 Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 14:54:55 -0400 Subject: [PATCH 09/14] renaming test_equipment_and_useful_load.py --- .../test_equipment_and_operating_items.py | 533 ++++++++++++++++++ 1 file changed, 533 insertions(+) create mode 100644 aviary/subsystems/mass/gasp_based/test/test_equipment_and_operating_items.py diff --git a/aviary/subsystems/mass/gasp_based/test/test_equipment_and_operating_items.py b/aviary/subsystems/mass/gasp_based/test/test_equipment_and_operating_items.py new file mode 100644 index 000000000..9d960707b --- /dev/null +++ b/aviary/subsystems/mass/gasp_based/test/test_equipment_and_operating_items.py @@ -0,0 +1,533 @@ +import unittest + +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.mass.gasp_based.equipment_and_operating_items import ( + BWBEquipMassGroup, + EquipAndOperatingItemsMassGroup, + EquipMassGroup, + OperatingItemsMassGroup, +) +from aviary.subsystems.mass.gasp_based.mass_summation import ( + SystemsEquipmentMass, + OperatingItemsMass, +) +from aviary.variable_info.functions import setup_model_options +from aviary.variable_info.options import get_option_defaults +from aviary.variable_info.variables import Aircraft, Mission, Settings + + +class EquipmentMassSummationTest(unittest.TestCase): + """this is the large single aisle 1 V3 test case.""" + + def setUp(self): + options = get_option_defaults() + # options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') + # options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') + + self.prob = om.Problem() + self.prob.model.add_subsystem( + 'equip', + SystemsEquipmentMass(), + promotes=['*'], + ) + + self.prob.model.set_input_defaults( + Aircraft.AirConditioning.MASS, val=1324.0561, units='lbm' + ) + self.prob.model.set_input_defaults(Aircraft.APU.MASS, val=928.0, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Avionics.MASS, val=1959.0, units='lbm') + self.prob.model.set_input_defaults(Aircraft.AntiIcing.MASS, val=683.46852785, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Furnishings.MASS, val=13266.56, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Instruments.MASS, val=862.45194435, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Hydraulics.MASS, val=1487.78, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Electrical.MASS, val=2231.0, units='lbm') + self.prob.model.set_input_defaults(Aircraft.OxygenSystem.MASS, val=50, units='lbm') + + setup_model_options(self.prob, options) + + self.prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + assert_near_equal(self.prob[Aircraft.Design.SYSTEMS_AND_EQUIPMENT_MASS], 22792.3165722, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +class EquipMassGroupTest(unittest.TestCase): + """this is the large single aisle 1 V3 test case.""" + + def setUp(self): + options = get_option_defaults() + options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') + options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') + + self.prob = om.Problem() + self.prob.model.add_subsystem( + 'group', + EquipMassGroup(), + promotes=['*'], + ) + + self.prob.model.set_input_defaults( + Aircraft.Instruments.MASS_COEFFICIENT, val=0.0736, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, val=0.112, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, val=0.14, units='unitless' + ) + self.prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, val=175400, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, val=129.4, units='ft') + self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=117.8, units='ft') + self.prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, val=7511, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Controls.MASS, val=3895.0, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Wing.AREA, val=1370.3, units='ft**2') + self.prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, val=375.9, units='ft**2') + self.prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, val=469.3, units='ft**2') + + self.prob.model.set_input_defaults( + Aircraft.AirConditioning.MASS_COEFFICIENT, val=1.65, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, val=7.5, units='psi' + ) + self.prob.model.set_input_defaults(Aircraft.Fuselage.AVG_DIAMETER, val=13.1, units='ft') + self.prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, val=1068.96, units='ft**2') + self.prob.model.set_input_defaults( + Aircraft.Furnishings.MASS_SCALER, val=40.0, units='unitless' + ) + + setup_model_options(self.prob, options) + + self.prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1324.05614369, tol) + assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 13266.53964608, tol) + assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 683.4685279, tol) + assert_near_equal(self.prob[Aircraft.APU.MASS], 1077.969377, tol) + assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1514.0, tol) + assert_near_equal(self.prob[Aircraft.Electrical.MASS], 170.0, tol) + assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1487.78, tol) + assert_near_equal(self.prob[Aircraft.Instruments.MASS], 547.41157631, tol) + assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +class OperatingItemsMassSumTest(unittest.TestCase): + """this is the large single aisle 1 V3 test case.""" + + def setUp(self): + options = get_option_defaults() + # options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') + # options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') + + self.prob = om.Problem() + self.prob.model.add_subsystem( + 'useful', + OperatingItemsMass(), + promotes=['*'], + ) + + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.FLIGHT_CREW_MASS, val=492.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.CABIN_CREW_MASS, val=800.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, val=342.6, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.PASSENGER_SERVICE_MASS, val=2872.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Design.EMERGENCY_EQUIPMENT_MASS, val=50.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Fuel.UNUSABLE_FUEL_MASS, val=619.76, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.CARGO_CONTAINER_MASS, val=165, units='lbm' + ) + + setup_model_options(self.prob, options) + + self.prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + assert_near_equal(self.prob[Mission.OPERATING_ITEMS_MASS], 5341.36, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +class UsefulMassGroupTest(unittest.TestCase): + """this is the large single aisle 1 V3 test case.""" + + def setUp(self): + options = get_option_defaults() + options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') + options.set_val(Settings.VERBOSITY, val=0, units='unitless') + + self.prob = om.Problem() + self.prob.model.add_subsystem( + 'useful_group', + OperatingItemsMassGroup(), + promotes=['*'], + ) + + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.CATERING_ITEMS_MASS_PER_PASSENGER, val=7.6, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_PER_PASSENGER, val=5.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, val=12, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.WATER_MASS_PER_OCCUPANT, val=3.0, units='lbm' + ) + self.prob.model.set_input_defaults(Aircraft.Wing.AREA, val=1370.3, units='ft**2') + self.prob.model.set_input_defaults( + Aircraft.Engine.SCALED_SLS_THRUST, val=29500, units='lbf' + ) + self.prob.model.set_input_defaults( + Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units='unitless' + ) + + setup_model_options(self.prob, options) + + self.prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + assert_near_equal(self.prob[Aircraft.CrewPayload.CARGO_CONTAINER_MASS], 165.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.CABIN_CREW_MASS], 800.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.FLIGHT_CREW_MASS], 492.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS], 2872.0, tol) + assert_near_equal(self.prob[Aircraft.Design.EMERGENCY_EQUIPMENT_MASS], 115.0, tol) + assert_near_equal(self.prob[Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS], 342.6, tol) + assert_near_equal(self.prob[Aircraft.Fuel.UNUSABLE_FUEL_MASS], 619.82896954, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +class FixedEquipAndUsefulMassGroupTest(unittest.TestCase): + """this is the large single aisle 1 V3 test case.""" + + def setUp(self): + options = get_option_defaults() + options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=180, units='unitless') + options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') + + self.prob = om.Problem() + self.prob.model.add_subsystem( + 'group', + EquipAndOperatingItemsMassGroup(), + promotes=['*'], + ) + + self.prob.model.set_input_defaults( + Aircraft.Instruments.MASS_COEFFICIENT, val=0.0736, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, val=0.112, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, val=0.14, units='unitless' + ) + self.prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, val=175400, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, val=129.4, units='ft') + self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=117.8, units='ft') + self.prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, val=7511, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Controls.MASS, val=3895.0, units='lbm') + self.prob.model.set_input_defaults(Aircraft.Wing.AREA, val=1370.3, units='ft**2') + self.prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, val=375.9, units='ft**2') + self.prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, val=469.3, units='ft**2') + self.prob.model.set_input_defaults( + Aircraft.AirConditioning.MASS_COEFFICIENT, val=1.65, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, val=7.5, units='psi' + ) + self.prob.model.set_input_defaults(Aircraft.Fuselage.AVG_DIAMETER, val=13.1, units='ft') + self.prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, val=1068.96, units='ft**2') + self.prob.model.set_input_defaults( + Aircraft.Furnishings.MASS_SCALER, val=40.0, units='unitless' + ) + + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.CATERING_ITEMS_MASS_PER_PASSENGER, val=7.6, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_PER_PASSENGER, val=5.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, val=12, units='unitless' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.WATER_MASS_PER_OCCUPANT, val=3.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Engine.SCALED_SLS_THRUST, val=29500, units='lbf' + ) + self.prob.model.set_input_defaults( + Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units='unitless' + ) + + setup_model_options(self.prob, options) + + self.prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + + assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1324.05614369, tol) + assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 13266.53964608, tol) + assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 683.4685279, tol) + assert_near_equal(self.prob[Aircraft.APU.MASS], 1077.969377, tol) + assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1514.0, tol) + assert_near_equal(self.prob[Aircraft.Electrical.MASS], 170.0, tol) + assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1487.78, tol) + assert_near_equal(self.prob[Aircraft.Instruments.MASS], 547.41157631, tol) + assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.CARGO_CONTAINER_MASS], 165.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.CABIN_CREW_MASS], 800.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.FLIGHT_CREW_MASS], 492.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS], 2872.0, tol) + assert_near_equal(self.prob[Aircraft.Design.EMERGENCY_EQUIPMENT_MASS], 115.0, tol) + assert_near_equal(self.prob[Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS], 342.6, tol) + assert_near_equal(self.prob[Aircraft.Fuel.UNUSABLE_FUEL_MASS], 619.82896954, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +@use_tempdirs +class BWBFixedEquipMassGroupTest(unittest.TestCase): + """Created based on GASP BWB model.""" + + def setUp(self): + options = get_option_defaults() + options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=150, units='unitless') + options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') + + prob = self.prob = om.Problem() + prob.model.add_subsystem( + 'group', + BWBEquipMassGroup(), + promotes=['*'], + ) + prob.model.set_input_defaults( + Aircraft.Instruments.MASS_COEFFICIENT, 0.116, units='unitless' + ) + prob.model.set_input_defaults( + Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, 0.107, units='unitless' + ) + prob.model.set_input_defaults( + Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, 0.135, units='unitless' + ) + prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, 150000, units='lbm') + prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, 71.5245514, units='ft') + prob.model.set_input_defaults(Aircraft.Wing.SPAN, 146.38501, units='ft') + prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, 7800.0, units='lbm') + prob.model.set_input_defaults(Aircraft.Controls.MASS, 2115.19946, units='lbm') + prob.model.set_input_defaults(Aircraft.Wing.AREA, 2142.85718, units='ft**2') + prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, 0.00170628, units='ft**2') + prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, 169.119629, units='ft**2') + prob.model.set_input_defaults( + Aircraft.AirConditioning.MASS_COEFFICIENT, 1.155, units='unitless' + ) + prob.model.set_input_defaults(Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, 10.0, units='psi') + prob.model.set_input_defaults(Aircraft.Fuselage.HYDRAULIC_DIAMETER, 19.3650932, units='ft') + prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, 1283.5249, units='ft**2') + prob.model.set_input_defaults(Aircraft.Furnishings.MASS_SCALER, 40.0, units='unitless') + prob.model.set_input_defaults( + Aircraft.Electrical.SYSTEM_MASS_PER_PASSENGER, 11.45, units='lbm' + ) + + setup_model_options(self.prob, options) + + prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1301.5729093, tol) + assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 11269.87654648, tol) + assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 706.48495598, tol) + assert_near_equal(self.prob[Aircraft.APU.MASS], 928.46163145, tol) + assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1430.0, tol) + assert_near_equal(self.prob[Aircraft.Electrical.MASS], 1887.5, tol) + assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1279.32634222, tol) + assert_near_equal(self.prob[Aircraft.Instruments.MASS], 917.20099314, tol) + assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +class BWBOperatingItemsMassSumTest(unittest.TestCase): + """Created based on GASP BWB model.""" + + def setUp(self): + options = get_option_defaults() + options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=150, units='unitless') + options.set_val(Settings.VERBOSITY, 0) + + prob = self.prob = om.Problem() + prob.model.add_subsystem( + 'useful', + OperatingItemsMass(), + promotes=['*'], + ) + + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.FLIGHT_CREW_MASS, val=446.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.CABIN_CREW_MASS, val=631.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, val=235.5, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.PASSENGER_SERVICE_MASS, val=2163.0, units='lbm' + ) + self.prob.model.set_input_defaults( + Aircraft.Design.EMERGENCY_EQUIPMENT_MASS, val=100.0, units='lbm' + ) + self.prob.model.set_input_defaults(Aircraft.Fuel.UNUSABLE_FUEL_MASS, val=581.3, units='lbm') + self.prob.model.set_input_defaults( + Aircraft.CrewPayload.CARGO_CONTAINER_MASS, val=165, units='lbm' + ) + + setup_model_options(self.prob, options) + + prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + assert_near_equal(self.prob[Mission.OPERATING_ITEMS_MASS], 4321.8, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +@use_tempdirs +class BWBFixedEquipAndUsefulMassGroupTest(unittest.TestCase): + """this is the large single aisle 1 V3 test case.""" + + def setUp(self): + options = get_option_defaults() + options.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, val=150, units='unitless') + options.set_val(Aircraft.LandingGear.FIXED_GEAR, val=False, units='unitless') + options.set_val(Aircraft.Design.TYPE, val='BWB', units='unitless') + + prob = self.prob = om.Problem() + prob.model.add_subsystem( + 'group', + EquipAndOperatingItemsMassGroup(), + promotes=['*'], + ) + + prob.model.set_input_defaults( + Aircraft.Instruments.MASS_COEFFICIENT, 0.116, units='unitless' + ) + prob.model.set_input_defaults( + Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, 0.107, units='unitless' + ) + prob.model.set_input_defaults( + Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, 0.135, units='unitless' + ) + prob.model.set_input_defaults( + Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_PER_PASSENGER, 6.0, units='lbm' + ) + prob.model.set_input_defaults( + Aircraft.CrewPayload.WATER_MASS_PER_OCCUPANT, 3.0, units='lbm' + ) + prob.model.set_input_defaults( + Aircraft.CrewPayload.CATERING_ITEMS_MASS_PER_PASSENGER, 5.0, units='lbm' + ) + prob.model.set_input_defaults( + Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, 12.0, units='unitless' + ) + prob.model.set_input_defaults(Aircraft.Design.GROSS_MASS, 150000, units='lbm') + prob.model.set_input_defaults(Aircraft.Fuselage.LENGTH, 71.5245514, units='ft') + prob.model.set_input_defaults(Aircraft.Wing.SPAN, 146.38501, units='ft') + prob.model.set_input_defaults(Aircraft.LandingGear.TOTAL_MASS, 7800.0, units='lbm') + prob.model.set_input_defaults(Aircraft.Controls.MASS, 2115.19946, units='lbm') + prob.model.set_input_defaults(Aircraft.Wing.AREA, 2142.85718, units='ft**2') + prob.model.set_input_defaults(Aircraft.HorizontalTail.AREA, 0.001706279, units='ft**2') + prob.model.set_input_defaults(Aircraft.VerticalTail.AREA, 169.119629, units='ft**2') + prob.model.set_input_defaults( + Aircraft.AirConditioning.MASS_COEFFICIENT, 1.155, units='unitless' + ) + prob.model.set_input_defaults(Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, 10.0, units='psi') + prob.model.set_input_defaults(Aircraft.Fuselage.HYDRAULIC_DIAMETER, 19.3650932, units='ft') + prob.model.set_input_defaults(Aircraft.Fuselage.CABIN_AREA, 1283.5249, units='ft**2') + prob.model.set_input_defaults(Aircraft.Furnishings.MASS_SCALER, 40.0, units='unitless') + prob.model.set_input_defaults( + Aircraft.Electrical.SYSTEM_MASS_PER_PASSENGER, 11.45, units='lbm' + ) + prob.model.set_input_defaults(Aircraft.Wing.AREA, 2142.85718, units='ft**2') + prob.model.set_input_defaults(Aircraft.Engine.SCALED_SLS_THRUST, [19580.1602], units='lbf') + prob.model.set_input_defaults(Aircraft.Fuel.WING_FUEL_FRACTION, 0.45, units='unitless') + + setup_model_options(self.prob, options) + + prob.setup(check=False, force_alloc_complex=True) + + def test_case1(self): + self.prob.run_model() + + tol = 1e-7 + assert_near_equal(self.prob[Aircraft.AirConditioning.MASS], 1301.573, tol) + assert_near_equal(self.prob[Aircraft.Furnishings.MASS], 11269.877, tol) + assert_near_equal(self.prob[Aircraft.AntiIcing.MASS], 706.48495598, tol) + assert_near_equal(self.prob[Aircraft.APU.MASS], 928.46163145, tol) + assert_near_equal(self.prob[Aircraft.Avionics.MASS], 1430.0, tol) + assert_near_equal(self.prob[Aircraft.Electrical.MASS], 1887.5, tol) + assert_near_equal(self.prob[Aircraft.Hydraulics.MASS], 1279.32634222, tol) + assert_near_equal(self.prob[Aircraft.Instruments.MASS], 917.20099314, tol) + assert_near_equal(self.prob[Aircraft.OxygenSystem.MASS], 50.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.CARGO_CONTAINER_MASS], 165.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.CABIN_CREW_MASS], 600.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.FLIGHT_CREW_MASS], 492.0, tol) + assert_near_equal(self.prob[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS], 2148.0, tol) + assert_near_equal(self.prob[Aircraft.Design.EMERGENCY_EQUIPMENT_MASS], 90.0, tol) + assert_near_equal(self.prob[Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS], 235.46573016, tol) + assert_near_equal(self.prob[Aircraft.Fuel.UNUSABLE_FUEL_MASS], 581.3289049, tol) + + partial_data = self.prob.check_partials(out_stream=None, method='cs') + assert_check_partials(partial_data, atol=8e-12, rtol=1e-12) + + +if __name__ == '__main__': + unittest.main() From 2214eced1715743e79c0318b2722ef4af0c4214c Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 15:26:13 -0400 Subject: [PATCH 10/14] fix flops mass summation test and include useful load calc for the bwb example test of total mass summation --- aviary/subsystems/mass/flops_based/mass_summation.py | 3 ++- .../subsystems/mass/flops_based/test/test_mass_summation.py | 5 ++--- .../validation_data/test_data/bwb_detailed_FLOPS_data.py | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index 83c8cd370..36ef984db 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -446,7 +446,8 @@ def setup(self): self.add_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') def setup_partials(self): - self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, '**', val=1) + self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.GROSS_MASS, val=1) + self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.EMPTY_MASS, val=-1) def compute(self, inputs, outputs): gross_mass = inputs[Aircraft.Design.GROSS_MASS] diff --git a/aviary/subsystems/mass/flops_based/test/test_mass_summation.py b/aviary/subsystems/mass/flops_based/test/test_mass_summation.py index 4cbf6de14..79b69c63e 100644 --- a/aviary/subsystems/mass/flops_based/test/test_mass_summation.py +++ b/aviary/subsystems/mass/flops_based/test/test_mass_summation.py @@ -7,10 +7,7 @@ from parameterized import parameterized from aviary.subsystems.mass.flops_based.mass_summation import ( - EmptyMass, MassSummation, - OperatingMass, - PropulsionMass, StructureMass, ) from aviary.subsystems.propulsion.engine_deck import EngineDeck @@ -92,6 +89,7 @@ def test_case( Aircraft.Wing.MASS, Aircraft.Propulsion.TOTAL_ENGINE_MASS, Aircraft.Propulsion.TOTAL_MISC_MASS, + Aircraft.Design.GROSS_MASS, ], output_keys=[ Aircraft.Design.EMPTY_MASS_MARGIN, @@ -103,6 +101,7 @@ def test_case( Mission.OPERATING_ITEMS_MASS, Mission.OPERATING_MASS, Mission.ZERO_FUEL_MASS, + Aircraft.Design.USEFUL_LOAD_MASS, ], version=Version.TRANSPORT_and_BWB, atol=1e-10, diff --git a/aviary/validation_cases/validation_data/test_data/bwb_detailed_FLOPS_data.py b/aviary/validation_cases/validation_data/test_data/bwb_detailed_FLOPS_data.py index 65db21814..1e7f09b29 100644 --- a/aviary/validation_cases/validation_data/test_data/bwb_detailed_FLOPS_data.py +++ b/aviary/validation_cases/validation_data/test_data/bwb_detailed_FLOPS_data.py @@ -428,3 +428,4 @@ outputs.set_val(Aircraft.Design.MACH, 0.800) outputs.set_val(Mission.OPERATING_MASS, 411552.29917206, 'lbm') # WOWE outputs.set_val(Mission.ZERO_FUEL_MASS, 509364.29917206, 'lbm') # WZF +outputs.set_val(Aircraft.Design.USEFUL_LOAD_MASS, 483543.0927945, 'lbm') From d01871df3b82215d75c6fa0b0f9da2c0aa5a55d5 Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 15:30:22 -0400 Subject: [PATCH 11/14] correct partials for computation of useful_load_mass for gasp based mass --- aviary/subsystems/mass/gasp_based/mass_summation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aviary/subsystems/mass/gasp_based/mass_summation.py b/aviary/subsystems/mass/gasp_based/mass_summation.py index 8929487a7..4c44e08fa 100644 --- a/aviary/subsystems/mass/gasp_based/mass_summation.py +++ b/aviary/subsystems/mass/gasp_based/mass_summation.py @@ -274,7 +274,8 @@ def setup(self): self.add_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') def setup_partials(self): - self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, '**', val=1) + self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.GROSS_MASS, val=1) + self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.EMPTY_MASS, val=-1) def compute(self, inputs, outputs): gross_mass = inputs[Aircraft.Design.GROSS_MASS] From b713acb73143728b7ba3bca14b24dd58c8e6e8fa Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 15:48:10 -0400 Subject: [PATCH 12/14] modify useful load to use aviary input and output functions --- aviary/subsystems/mass/flops_based/mass_summation.py | 6 +++--- aviary/subsystems/mass/gasp_based/mass_summation.py | 6 +++--- aviary/subsystems/test/test_flops_based_premission.py | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index 36ef984db..a35605ba1 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -440,10 +440,10 @@ def compute(self, inputs, outputs): class UsefulLoadMass(om.ExplicitComponent): def setup(self): - self.add_input(Aircraft.Design.GROSS_MASS, units='lbm') - self.add_input(Aircraft.Design.EMPTY_MASS, units='lbm') + self.add_aviary_input(Aircraft.Design.GROSS_MASS, units='lbm') + self.add_aviary_input(Aircraft.Design.EMPTY_MASS, units='lbm') - self.add_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') + self.add_aviary_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') def setup_partials(self): self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.GROSS_MASS, val=1) diff --git a/aviary/subsystems/mass/gasp_based/mass_summation.py b/aviary/subsystems/mass/gasp_based/mass_summation.py index 4c44e08fa..457e42bb2 100644 --- a/aviary/subsystems/mass/gasp_based/mass_summation.py +++ b/aviary/subsystems/mass/gasp_based/mass_summation.py @@ -268,10 +268,10 @@ def compute(self, inputs, outputs): class UsefulLoadMass(om.ExplicitComponent): def setup(self): - self.add_input(Aircraft.Design.GROSS_MASS, units='lbm') - self.add_input(Aircraft.Design.EMPTY_MASS, units='lbm') + self.add_aviary_input(Aircraft.Design.GROSS_MASS, units='lbm') + self.add_aviary_input(Aircraft.Design.EMPTY_MASS, units='lbm') - self.add_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') + self.add_aviary_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') def setup_partials(self): self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.GROSS_MASS, val=1) diff --git a/aviary/subsystems/test/test_flops_based_premission.py b/aviary/subsystems/test/test_flops_based_premission.py index bb14f4e2c..8a8f53147 100644 --- a/aviary/subsystems/test/test_flops_based_premission.py +++ b/aviary/subsystems/test/test_flops_based_premission.py @@ -1229,6 +1229,6 @@ def test_case_all_subsystems(self): if __name__ == '__main__': unittest.main() - test = BWBPreMissionGroupTest() - test.setUp() + # test = BWBPreMissionGroupTest() + # test.setUp() # test.test_case_all_subsystems() From 458ab966ae2e186f56f5be1e4aaee94588e2b2cc Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 15:49:59 -0400 Subject: [PATCH 13/14] modify useful load to use aviary input and output functions --- aviary/subsystems/mass/flops_based/mass_summation.py | 6 +++--- aviary/subsystems/mass/gasp_based/mass_summation.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index a35605ba1..e9e3950ca 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -440,10 +440,10 @@ def compute(self, inputs, outputs): class UsefulLoadMass(om.ExplicitComponent): def setup(self): - self.add_aviary_input(Aircraft.Design.GROSS_MASS, units='lbm') - self.add_aviary_input(Aircraft.Design.EMPTY_MASS, units='lbm') + add_aviary_input(self, Aircraft.Design.GROSS_MASS, units='lbm') + add_aviary_input(self, Aircraft.Design.EMPTY_MASS, units='lbm') - self.add_aviary_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') + add_aviary_output(self, Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') def setup_partials(self): self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.GROSS_MASS, val=1) diff --git a/aviary/subsystems/mass/gasp_based/mass_summation.py b/aviary/subsystems/mass/gasp_based/mass_summation.py index 457e42bb2..08c1be25f 100644 --- a/aviary/subsystems/mass/gasp_based/mass_summation.py +++ b/aviary/subsystems/mass/gasp_based/mass_summation.py @@ -268,10 +268,10 @@ def compute(self, inputs, outputs): class UsefulLoadMass(om.ExplicitComponent): def setup(self): - self.add_aviary_input(Aircraft.Design.GROSS_MASS, units='lbm') - self.add_aviary_input(Aircraft.Design.EMPTY_MASS, units='lbm') + add_aviary_input(self, Aircraft.Design.GROSS_MASS, units='lbm') + add_aviary_input(self, Aircraft.Design.EMPTY_MASS, units='lbm') - self.add_aviary_output(Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') + add_aviary_output(self, Aircraft.Design.USEFUL_LOAD_MASS, units='lbm') def setup_partials(self): self.declare_partials(Aircraft.Design.USEFUL_LOAD_MASS, Aircraft.Design.GROSS_MASS, val=1) From 08574e749e5c397c0d5d780e476b616fae5a62eb Mon Sep 17 00:00:00 2001 From: Bennett Date: Wed, 29 Apr 2026 16:12:32 -0400 Subject: [PATCH 14/14] add a useful load test case to gasp based mass premission --- aviary/subsystems/mass/gasp_based/test/test_mass_premission.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py b/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py index 4421fc57a..fa95239cf 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py +++ b/aviary/subsystems/mass/gasp_based/test/test_mass_premission.py @@ -79,8 +79,6 @@ def setUp(self): def test_case1(self): self.prob.run_model() - # print(f'wetted_area: {self.prob[Aircraft.Fuselage.WETTED_AREA]}') - tol = 5e-4 expected_values = { 'gasp_based_geom.cabin_height': 13.1, @@ -112,6 +110,7 @@ def test_case1(self): Aircraft.Fuel.AUXILIARY_FUEL_CAPACITY: 0, # always zero when no body tank 'extra_fuel_volume': 0, # always zero when no body tank 'max_extra_fuel_mass': 0, # always zero when no body tank + Aircraft.Design.USEFUL_LOAD_MASS: 85002.98039399, } for var_name, expected_val in expected_values.items():