From f1b3f4a3a9621efb4a4f40a78b9569c3efdb153c Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 24 Dec 2025 18:51:51 -0500 Subject: [PATCH 01/68] work in progress: add Aircraft.HorizontalTail.NUM_TAILS --- aviary/variable_info/variable_meta_data.py | 10 ++++++++++ aviary/variable_info/variables.py | 1 + 2 files changed, 11 insertions(+) diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 316bde8e7..d36acdeb0 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -3931,6 +3931,16 @@ desc='Ratio of wing chord to horizontal tail moment arm', ) +add_meta_data( + Aircraft.HorizontalTail.NUM_TAILS, + meta_data=_MetaData, + historical_name={'GASP': None, 'FLOPS': None, 'LEAPS1': None}, + desc='number of horizontal tails', + types=int, + option=True, + default_value=1, +) + add_meta_data( Aircraft.HorizontalTail.ROOT_CHORD, meta_data=_MetaData, diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 7053a86a7..9a1c795d6 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -378,6 +378,7 @@ class HorizontalTail: MASS_SCALER = 'aircraft:horizontal_tail:mass_scaler' MOMENT_ARM = 'aircraft:horizontal_tail:moment_arm' MOMENT_RATIO = 'aircraft:horizontal_tail:moment_ratio' + NUM_TAILS = 'aircraft:horizontal_tail:num_tails' ROOT_CHORD = 'aircraft:horizontal_tail:root_chord' SPAN = 'aircraft:horizontal_tail:span' SWEEP = 'aircraft:horizontal_tail:sweep' From e129a6c2608c2fb4dbdf6d80dd32bea6df041aac Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 24 Dec 2025 18:54:37 -0500 Subject: [PATCH 02/68] add FLOPS model input deck --- .../blended_wing_body/bwb_detailed_FLOPS.in | 190 ++++++++++++++++++ .../blended_wing_body/bwb_simple_FLOPS.in | 186 +++++++++++++++++ 2 files changed, 376 insertions(+) create mode 100644 aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.in create mode 100644 aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.in diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.in b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.in new file mode 100644 index 000000000..e072d1681 --- /dev/null +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.in @@ -0,0 +1,190 @@ +468 passenger BWB - Based on Boeing BWB450-1U, Karl Geiselhart + + $OPTION +MPRINT=1, +IOPT=1, +IANAL=3, +INENG=1, +ICOST=0, +ITAKOF=0, +ILAND=0, +NOPRO=0, +NOISE=0, +IFITE=3, +IXFL=1, +IPOLP=0, +IPLTTH=0, + $END + + $WTIN +DGW=874099, +VMMO=0.85, +DIH=3, +FLAPR=0.333, +GLOV=121.05, +VARSWP=0, +FCOMP=1, +FAERT=0, +FSTRT=0, +NETAW=14, +ETAW=0.35,0.4,0.45,0.5,0.55,0.6,0.6499,0.7,0.75,0.8,0.85,0.8999,0.95,1, +CHD=58.03,0.4491,0.3884,0.3317,0.2886,0.2537,0.2269,0.2121,0.1983,0.1843,0.1704,0.1565,0.1426,0.1287, +TOC=0.15,0.1132,0.0928,0.0822,0.0764,0.0742,0.0746,0.0758,0.0758,0.0756,0.0756,0.0758,0.076,0.076, +SWL=0,0,0,0,0,0,0,42.9,42.9,42.9,42.9,42.9,42.9,42.9,0,0,0,0,0,0, +SHT=0, +SWPHT=0, +ARHT=0, +TRHT=0, +TCHT=0, +NVERT=0, +NFIN=2, +SFIN=184.89, +ARFIN=1.952, +TRFIN=0.464, +SWPFIN=39.42, +TCFIN=0.08, +NFUSE=1, +XL=0, ! XL=137.5 for fixed geom. +WF=0, ! WF=64.58 +DF=0, ! DF=17 +XLP=0, ! XLP=40 +XMLG=85, +XNLG=87, +CARBAS=0, +NEW=0, +NEF=3, +THRSO=86459.2, +WENG=22017, +EEXP=1, +WINL=0, +XNAC=17.433, +DNAC=12.608, +NPF=28, +NPB=100, +NPT=340, +NSTU=22, +NFLCR=2, +CARGF=0, +FRWI=1, +FRHT=1, +FRVT=1, +FRFU=1, +FRNA=0, +WTHR=0, +WPMSC=0, +WHYD=1, +WAVONC=1, +WFURN=1, +ISPOWE=0, + $END + + $FUSEIN +ACABIN=0, +FPITCH=61, +NFABR=4, +BPITCH=39, +NBABR=4, +TPITCH=32, +NTABR=6, +OSSPAN=86.75, + $END + $CONFIN +DESRNG=7750, +OFG=1, +OFF=0, +GW=874099, +AR=7.557,0, +THRUST=70000,1,0,0,0,0, +SW=7621.66,1, +TR=0.311, +SWEEP=35.7, +TCA=0.11, +VCMN=0.85, +CH=39000, + $END + + $AERIN +MYAERO=0, +ITPAER=2, +CAM=2, +AITEK=2, +XLLAM=0, +E=0, +WRATIO=0.8, +VAPPR=140, +FLTO=11000, +FLLDG=11000, +THROFF=0.25, + $END + + $ENGDIN +IGENEN=-1, +EIFILE='ENGDEK', +IDLE=1, +MAXCR=1, +NOX=1, + $END + + $MISSIN +FCDO=1, +FCDI=1, +ISKAL=1, +IFLAG=2, +MSUMPT=1, +IRW=2, +IATA=0, +NPCON=1, +TAKOTM=2, +TAXOTM=9, +APPRTM=4, +TAXITM=5, +ITTFF=1, +NCLIMB=1, +CLAMIN=0, +FWF=-0.001, +NCRUSE=3, +IOC=1,4,4, +CRMACH=0.85,0.6,0, +CRALT=45000,25000,1500, +RCIN=300, +IVS=1, +DEAMIN=0, +IRS=1, +RESTRP=0.05, +TIMMAP=2, +ALTRAN=200, +NCLRES=1, +NCRRES=2, +HOLDTM=30, +NCRHOL=3, +IHOPOS=1, +THOLD=0.1, +NCRTH=1, + $END +START +CLIMB +CRUISE +DESCENT +END + + $PCONIN +CONALT=35000, +CONMCH=0.85, +CONPC=1, +ICONSG=2, +CONLIM=300, +ICONTP=5, + $END + + $RERUN + $END + + $MISSIN +IRW=1, +NPCON=0, + $END +START +CLIMB +CRUISE +DESCENT +END diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.in b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.in new file mode 100644 index 000000000..53d81a10a --- /dev/null +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.in @@ -0,0 +1,186 @@ +468 passenger BWB - Based on Boeing BWB450-1U, Karl Geiselhart + + $OPTION +MPRINT=1, +IOPT=1, +IANAL=3, +INENG=1, +ICOST=0, +ITAKOF=0, +ILAND=0, +NOPRO=0, +NOISE=0, +IFITE=3, +IXFL=1, +IPOLP=0, +IPLTTH=0, + $END + + $WTIN +DGW=874099, +VMMO=0.85, +DIH=3, +FLAPR=0.333, +GLOV=121.05, +VARSWP=0, +FCOMP=1, +FAERT=0, +FSTRT=0, +NETAW=0, +SHT=0, +SWPHT=0, +ARHT=0, +TRHT=0, +TCHT=0, +NVERT=0, +NFIN=2, +SFIN=184.89, +ARFIN=1.952, +TRFIN=0.464, +SWPFIN=39.42, +TCFIN=0.08, +NFUSE=1, +XL=137.5, ! XL=137.5 for fixed geom. +WF=64.58 +DF=0, ! DL=17 +XLP=0, ! XLP=40 +XMLG=85, +XNLG=87, +CARBAS=0, +NEW=0, +NEF=3, +THRSO=86459.2, +WENG=22017, +EEXP=1, +WINL=0, +XNAC=17.433, +DNAC=12.608, +NPF=28, +NPB=100, +NPT=340, +NSTU=22, +NFLCR=2, +CARGF=0, +FRWI=1, +FRHT=1, +FRVT=1, +FRFU=1, +FRNA=0, +WTHR=0, +WPMSC=0, +WHYD=1, +WAVONC=1, +WFURN=1, +ISPOWE=0, + $END + + $FUSEIN +ACABIN=0, +FPITCH=61, +NFABR=4, +BPITCH=39, +NBABR=4, +TPITCH=32, +NTABR=6, +OSSPAN=86.75, + $END + $CONFIN +DESRNG=7750, +OFG=1, +OFF=0, +GW=874099, +AR=7.557,0, +THRUST=70000,1,0,0,0,0, +SW=7621.66,1, +TR=0.311, +SWEEP=35.7, +TCA=0.11, +VCMN=0.85, +CH=39000, + $END + + $AERIN +MYAERO=0, +ITPAER=2, +CAM=2, +AITEK=2, +XLLAM=0, +E=0, +WRATIO=0.8, +VAPPR=140, +FLTO=11000, +FLLDG=11000, +THROFF=0.25, + $END + + $ENGDIN +IGENEN=-1, +EIFILE='ENGDEK', +IDLE=1, +MAXCR=1, +NOX=1, + $END + + $MISSIN +FCDO=1, +FCDI=1, +ISKAL=1, +IFLAG=2, +MSUMPT=1, +IRW=2, +IATA=0, +NPCON=1, +TAKOTM=2, +TAXOTM=9, +APPRTM=4, +TAXITM=5, +ITTFF=1, +NCLIMB=1, +CLAMIN=0, +FWF=-0.001, +NCRUSE=3, +IOC=1,4,4, +CRMACH=0.85,0.6,0, +CRALT=45000,25000,1500, +RCIN=300, +IVS=1, +DEAMIN=0, +IRS=1, +RESTRP=0.05, +TIMMAP=2, +ALTRAN=200, +NCLRES=1, +NCRRES=2, +HOLDTM=30, +NCRHOL=3, +IHOPOS=1, +THOLD=0.1, +NCRTH=1, + $END +START +CLIMB +CRUISE +DESCENT +END + + $PCONIN +CONALT=35000, +CONMCH=0.85, +CONPC=1, +ICONSG=2, +CONLIM=300, +ICONTP=5, + $END + + $RERUN + $END + + $MISSIN +IRW=1, +NPCON=0, + $END +START +CLIMB +CRUISE +DESCENT +END From 2846139b039fba426cb3eb9ce115e2ac77cd5a5a Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 31 Dec 2025 11:44:18 -0500 Subject: [PATCH 03/68] work in progress --- .../models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 3 +-- .../aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py | 1 - aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 1 - .../models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index 24bedb619..a14698af6 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -6,7 +6,7 @@ aircraft:air_conditioning:mass_scaler,1.0,unitless aircraft:anti_icing:mass_scaler,1.0,unitless aircraft:apu:mass_scaler,1.0,unitless aircraft:avionics:mass_scaler,1.0,unitless -aircraft:blended_wing_body_design:detailed_wing_provided,False,unitless +aircraft:blended_wing_body_design:detailed_wing_provided,True,unitless aircraft:blended_wing_body_design:passenger_leading_edge_sweep,45,deg aircraft:canard:area,0.0,ft**2 aircraft:canard:aspect_ratio,0.0,unitless @@ -160,7 +160,6 @@ aircraft:wing:var_sweep_mass_penalty,0.0,unitless aircraft:wing:wetted_area_scaler,1.0,unitless mission:constraints:max_mach,0.85,unitless mission:design:gross_mass,874099,lbm -mission:design:lift_coefficient,-1.0,unitless mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s 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 5728d528b..7d567823d 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 @@ -20,7 +20,6 @@ inputs.set_val(Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, 1.0) # FCDSUP inputs.set_val(Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, 1.0) # FCDO inputs.set_val(Aircraft.Design.TYPE, AircraftTypes.BLENDED_WING_BODY) -inputs.set_val(Mission.Design.LIFT_COEFFICIENT, -1.0) # FCLDES inputs.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, False) inputs.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, True) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index d78d7176c..ca95241d4 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -156,7 +156,6 @@ aircraft:wing:var_sweep_mass_penalty,0.0,unitless aircraft:wing:wetted_area_scaler,1.0,unitless mission:constraints:max_mach,0.85,unitless mission:design:gross_mass,874099,lbm -mission:design:lift_coefficient,-1.0,unitless mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s 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 257012b54..01cf06b3b 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 @@ -20,7 +20,6 @@ inputs.set_val(Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, 1.0) # FCDSUP inputs.set_val(Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, 1.0) # FCDO inputs.set_val(Aircraft.Design.TYPE, AircraftTypes.BLENDED_WING_BODY) -inputs.set_val(Mission.Design.LIFT_COEFFICIENT, -1.0) # FCLDES inputs.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, True) inputs.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, False) From 1edb49a3432188adbf6df6e390a292dda63283e3 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 5 Jan 2026 13:04:18 -0500 Subject: [PATCH 04/68] work in progress --- .../aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 7 +------ .../blended_wing_body/bwb_detailed_FLOPS_data.py | 4 ---- .../aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 9 ++------- .../aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 4 ---- aviary/utils/legacy_code_data/flops_defaults.py | 4 ++++ 5 files changed, 7 insertions(+), 21 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index a14698af6..1824b6dec 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -27,13 +27,9 @@ aircraft:crew_and_payload:design:seat_pitch_tourist,32,inch aircraft:crew_and_payload:flight_crew_mass_scaler,1.0,unitless aircraft:crew_and_payload:misc_cargo,0.0,lbm aircraft:crew_and_payload:mass_per_passenger,165.0,lbm -aircraft:crew_and_payload:num_business_class,100,unitless -aircraft:crew_and_payload:num_first_class,28,unitless aircraft:crew_and_payload:num_flight_attendants,22,unitless aircraft:crew_and_payload:num_flight_crew,2,unitless aircraft:crew_and_payload:num_galley_crew,2,unitless -aircraft:crew_and_payload:num_passengers,468,unitless -aircraft:crew_and_payload:num_tourist_class,340,unitless aircraft:crew_and_payload:passenger_service_mass_scaler,1.0,unitless aircraft:crew_and_payload:wing_cargo,0.0,lbm aircraft:design:base_area,0.0,ft**2 @@ -104,8 +100,8 @@ aircraft:horizontal_tail:taper_ratio,0.0,unitless aircraft:horizontal_tail:thickness_to_chord,0.11,unitless aircraft:horizontal_tail:vertical_tail_fraction,0.0,unitless aircraft:horizontal_tail:wetted_area_scaler,1.0,unitless -aircraft:hydraulics:system_pressure,3000.0,psi aircraft:hydraulics:mass_scaler,1.0,unitless +aircraft:hydraulics:system_pressure,3000.0,psi aircraft:instruments:mass_scaler,1.0,unitless aircraft:landing_gear:main_gear_oleo_length,85.0,inch aircraft:landing_gear:main_gear_mass_scaler,1.0,unitless @@ -153,7 +149,6 @@ aircraft:wing:surface_control_mass_scaler,1.0,unitless aircraft:wing:sweep,35.7,deg aircraft:wing:taper_ratio,0.311,unitless aircraft:wing:thickness_to_chord,0.11,unitless -aircraft:wing:thickness_to_chord_reference,0.11,unitless aircraft:wing:thickness_to_chord_dist,0.15,0.1132,0.0928,0.0822,0.0764,0.0742,0.0746,0.0758,0.0758,0.0756,0.0756,0.0758,0.076,0.076,unitless aircraft:wing:ultimate_load_factor,3.75,unitless aircraft:wing:var_sweep_mass_penalty,0.0,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py index 7d567823d..754c80560 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 @@ -51,10 +51,6 @@ inputs.set_val(Aircraft.CrewPayload.Design.NUM_FIRST_CLASS, 28) # NPF inputs.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, 468, units='unitless') # NPB+NPF+NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS, 340) # NPT -inputs.set_val(Aircraft.CrewPayload.NUM_BUSINESS_CLASS, 100) # NPB -inputs.set_val(Aircraft.CrewPayload.NUM_FIRST_CLASS, 28) # NPF -inputs.set_val(Aircraft.CrewPayload.NUM_PASSENGERS, 468, units='unitless') # sum of three classes -inputs.set_val(Aircraft.CrewPayload.NUM_TOURIST_CLASS, 340) # NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BUSINESS, 4) # NBABR inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST, 4) # NFABR inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_TOURIST, 6) # NTABR diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index ca95241d4..bbc29319c 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -27,13 +27,9 @@ aircraft:crew_and_payload:design:seat_pitch_tourist,32,inch aircraft:crew_and_payload:flight_crew_mass_scaler,1.0,unitless aircraft:crew_and_payload:misc_cargo,0.0,lbm aircraft:crew_and_payload:mass_per_passenger,165.0,lbm -aircraft:crew_and_payload:num_business_class,100,unitless -aircraft:crew_and_payload:num_first_class,28,unitless aircraft:crew_and_payload:num_flight_attendants,22,unitless aircraft:crew_and_payload:num_flight_crew,2,unitless aircraft:crew_and_payload:num_galley_crew,2,unitless -aircraft:crew_and_payload:num_passengers,468,unitless -aircraft:crew_and_payload:num_tourist_class,340,unitless aircraft:crew_and_payload:passenger_service_mass_scaler,1.0,unitless aircraft:crew_and_payload:wing_cargo,0.0,lbm aircraft:design:base_area,0.0,ft**2 @@ -99,13 +95,13 @@ aircraft:fuselage:wetted_area_scaler,1.0,unitless aircraft:horizontal_tail:area,0.0,ft**2 aircraft:horizontal_tail:aspect_ratio,0.1,unitless aircraft:horizontal_tail:mass_scaler,1.0,unitless -# aircraft:horizontal_tail:sweep,0.0,deg +aircraft:horizontal_tail:sweep,0.0,deg aircraft:horizontal_tail:taper_ratio,0.0,unitless aircraft:horizontal_tail:thickness_to_chord,0.11,unitless aircraft:horizontal_tail:vertical_tail_fraction,0.0,unitless aircraft:horizontal_tail:wetted_area_scaler,1.0,unitless -aircraft:hydraulics:system_pressure,3000.0,psi aircraft:hydraulics:mass_scaler,1.0,unitless +aircraft:hydraulics:system_pressure,3000.0,psi aircraft:instruments:mass_scaler,1.0,unitless aircraft:landing_gear:main_gear_oleo_length,85.0,inch aircraft:landing_gear:main_gear_mass_scaler,1.0,unitless @@ -150,7 +146,6 @@ aircraft:wing:surface_control_mass_scaler,1.0,unitless aircraft:wing:sweep,35.7,deg aircraft:wing:taper_ratio,0.311,unitless aircraft:wing:thickness_to_chord,0.11,unitless -aircraft:wing:thickness_to_chord_reference,0.11,unitless aircraft:wing:ultimate_load_factor,3.75,unitless aircraft:wing:var_sweep_mass_penalty,0.0,unitless aircraft:wing:wetted_area_scaler,1.0,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py index 01cf06b3b..610ebd9d5 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 @@ -51,10 +51,6 @@ inputs.set_val(Aircraft.CrewPayload.Design.NUM_FIRST_CLASS, 28) # NPF inputs.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, 468, units='unitless') # NPB+NPF+NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS, 340) # NPT -inputs.set_val(Aircraft.CrewPayload.NUM_BUSINESS_CLASS, 100) # NPB -inputs.set_val(Aircraft.CrewPayload.NUM_FIRST_CLASS, 28) # NPF -inputs.set_val(Aircraft.CrewPayload.NUM_PASSENGERS, 468, units='unitless') # sum of three classes -inputs.set_val(Aircraft.CrewPayload.NUM_TOURIST_CLASS, 340) # NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BUSINESS, 4) # NBABR inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST, 4) # NFABR inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_TOURIST, 6) # NTABR diff --git a/aviary/utils/legacy_code_data/flops_defaults.py b/aviary/utils/legacy_code_data/flops_defaults.py index 98f796401..1bef060d1 100644 --- a/aviary/utils/legacy_code_data/flops_defaults.py +++ b/aviary/utils/legacy_code_data/flops_defaults.py @@ -7,12 +7,16 @@ 'WTIN.IALTWT': (False, 'unitless'), 'WTIN.CARGF': (False, 'unitless'), 'WTIN.IFUFU': (False, 'unitless'), + 'WTIN.HYDPR': (3000.0, 'psi'), + 'WTIN.ULF': (3.75, 'unitless'), + 'WTIN.WPPASS': (165.0, 'lbm'), 'ENGDIN.IDLE': (False, 'unitless'), 'ENGDIN.IGEO': (False, 'unitless'), 'ENGDIN.NONEG': (False, 'unitless'), 'AERIN.MIKE': (False, 'unitless'), 'AERIN.SWETF': (1, 'unitless'), 'AERIN.SWETV': (1, 'unitless'), + 'FUSEIN.SWPLE': (45.0, 'deg'), } ) From f7961579295263bf91743d8ddc8bdde358948490 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 16:58:23 -0500 Subject: [PATCH 05/68] add OPTION.IFITE to aviary variable Aircraft.Design.TYPE --- 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 316bde8e7..8844d0bd8 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -1740,7 +1740,7 @@ add_meta_data( Aircraft.Design.TYPE, meta_data=_MetaData, - historical_name={'GASP': ['INGASP.IHWB'], 'FLOPS': None, 'LEAPS1': None}, + historical_name={'GASP': ['INGASP.IHWB'], 'FLOPS': ['OPTION.IFITE'], 'LEAPS1': None}, units='unitless', types=AircraftTypes, option=True, From 1244ff8e64ffbd9930b7e7b99243a4da20e1e203 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 16:59:54 -0500 Subject: [PATCH 06/68] modify a docstring --- aviary/subsystems/geometry/flops_based/fuselage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/subsystems/geometry/flops_based/fuselage.py b/aviary/subsystems/geometry/flops_based/fuselage.py index 0fa9d61bf..5c6595531 100644 --- a/aviary/subsystems/geometry/flops_based/fuselage.py +++ b/aviary/subsystems/geometry/flops_based/fuselage.py @@ -135,7 +135,7 @@ def compute_partials(self, inputs, partials): class SimpleCabinLayout(om.ExplicitComponent): """ - Given fuselage length, height and width, compute passenger compartment length. + Given fuselage length, compute passenger compartment length. This is for transporter aircraft, not BWB. """ From bc53c1a185de3ac8645fec1820c651d773acfeba Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 17:01:33 -0500 Subject: [PATCH 07/68] modify BWB models --- .../aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 6 +----- .../models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index 1824b6dec..fd91a650b 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -73,7 +73,6 @@ aircraft:fins:num_fins,2,unitless aircraft:fins:taper_ratio,0.464,unitless aircraft:fins:mass_scaler,1.0,unitless aircraft:fuel:auxiliary_fuel_capacity,0.0,lbm -aircraft:fuel:density,6.7,lbm/galUS aircraft:fuel:ignore_fuel_capacity_constraint,False,unitless aircraft:fuel:num_tanks,7,unitless aircraft:fuel:fuel_system_mass_scaler,1.0,unitless @@ -123,9 +122,6 @@ aircraft:vertical_tail:thickness_to_chord,0.11,unitless aircraft:vertical_tail:wetted_area_scaler,1.0,unitless aircraft:wing:aeroelastic_tailoring_factor,0.0,unitless aircraft:wing:airfoil_technology,2.0,unitless -aircraft:wing:area,7621.66,1,ft**2 -aircraft:wing:aspect_ratio,7.557,0,unitless -# aircraft:wing:aspect_ratio_ref,7.557,0,unitless aircraft:wing:bending_material_mass_scaler,1.0,unitless aircraft:wing:chord_per_semispan_dist,58.03,0.4491,0.3884,0.3317,0.2886,0.2537,0.2269,0.2121,0.1983,0.1843,0.1704,0.1565,0.1426,0.1287,unitless aircraft:wing:composite_fraction,1,unitless @@ -158,7 +154,7 @@ mission:design:gross_mass,874099,lbm mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s -mission:landing:lift_coefficient_max,3.0,unitless +#mission:landing:lift_coefficient_max,3.0,unitless mission:landing:rolling_friction_coefficient,0.025,unitless mission:takeoff:lift_coefficient_max,2.0,unitless mission:summary:cruise_mach,0.85,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index bbc29319c..095dbe0e6 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -73,7 +73,6 @@ aircraft:fins:num_fins,2,unitless aircraft:fins:taper_ratio,0.464,unitless aircraft:fins:mass_scaler,1.0,unitless aircraft:fuel:auxiliary_fuel_capacity,0.0,lbm -aircraft:fuel:density,6.7,lbm/galUS aircraft:fuel:ignore_fuel_capacity_constraint,False,unitless aircraft:fuel:num_tanks,7,unitless aircraft:fuel:fuel_system_mass_scaler,1.0,unitless @@ -123,8 +122,6 @@ aircraft:vertical_tail:thickness_to_chord,0.11,unitless aircraft:vertical_tail:wetted_area_scaler,1.0,unitless aircraft:wing:aeroelastic_tailoring_factor,0.0,unitless aircraft:wing:airfoil_technology,2.0,unitless -# aircraft:wing:area,7621.66,1,ft**2 -# aircraft:wing:aspect_ratio,7.557,0,unitless aircraft:wing:bending_material_mass_scaler,1.0,unitless aircraft:wing:composite_fraction,1,unitless aircraft:wing:control_surface_area_ratio,0.333,unitless @@ -154,7 +151,7 @@ mission:design:gross_mass,874099,lbm mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s -mission:landing:lift_coefficient_max,3.0,unitless +#mission:landing:lift_coefficient_max,3.0,unitless mission:landing:rolling_friction_coefficient,0.025,unitless mission:takeoff:lift_coefficient_max,2.0,unitless mission:summary:cruise_mach,0.85,unitless From 979bb1c2ecb34434d4453bf33e0fcdbe3b291eff Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 17:03:38 -0500 Subject: [PATCH 08/68] update BWB models --- .../aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 754c80560..cd0ac286e 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 @@ -84,7 +84,6 @@ # Fuel # --------------------------- inputs.set_val(Aircraft.Fuel.AUXILIARY_FUEL_CAPACITY, 0.0, 'lbm') # FULAUX -inputs.set_val(Aircraft.Fuel.DENSITY, 6.7, 'lbm/galUS') # FULDEN inputs.set_val(Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER, 1.0) # WFSYS inputs.set_val(Aircraft.Fuel.FUSELAGE_FUEL_CAPACITY, 0.0, 'lbm') # FULFMX inputs.set_val(Aircraft.Fuel.NUM_TANKS, 7) # NTANK @@ -283,7 +282,7 @@ inputs.set_val(Mission.Constraints.MAX_MACH, 0.85) # VMMO # inputs.set_val(Mission.Takeoff.FUEL_SIMPLE, 577, 'lbm') # FTKOFL -inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM +# inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM inputs.set_val(Mission.Takeoff.LIFT_COEFFICIENT_MAX, 2) # CLTOM # inputs.set_val(Mission.Takeoff.LIFT_OVER_DRAG, 17.354) inputs.set_val(Aircraft.Design.LANDING_TO_TAKEOFF_MASS_RATIO, 0.8) # WRATIO From 9eb99a99be6b05af2b6af5e91a6b973680d0e1e7 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 17:04:44 -0500 Subject: [PATCH 09/68] update BWB models --- .../models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 610ebd9d5..0ca63dd28 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 @@ -84,7 +84,6 @@ # Fuel # --------------------------- inputs.set_val(Aircraft.Fuel.AUXILIARY_FUEL_CAPACITY, 0.0, 'lbm') # FULAUX -inputs.set_val(Aircraft.Fuel.DENSITY, 6.7, 'lbm/galUS') # FULDEN inputs.set_val(Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER, 1.0) # WFSYS inputs.set_val(Aircraft.Fuel.FUSELAGE_FUEL_CAPACITY, 0.0, 'lbm') # FULFMX inputs.set_val(Aircraft.Fuel.NUM_TANKS, 7) # NTANK @@ -230,7 +229,7 @@ inputs.set_val(Mission.Constraints.MAX_MACH, 0.85) # VMMO # inputs.set_val(Mission.Takeoff.FUEL_SIMPLE, 577, 'lbm') # FTKOFL -inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM +# inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM inputs.set_val(Mission.Takeoff.LIFT_COEFFICIENT_MAX, 2) # CLTOM # inputs.set_val(Mission.Takeoff.LIFT_OVER_DRAG, 17.354) inputs.set_val(Aircraft.Design.LANDING_TO_TAKEOFF_MASS_RATIO, 0.8) # WRATIO From 56f98f90a5a46644ba3661fee3f5e438bcc154c3 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 17:07:50 -0500 Subject: [PATCH 10/68] work in progress --- aviary/utils/fortran_to_aviary.py | 156 +++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 1 deletion(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index f4eab2248..57d946db4 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -914,6 +914,160 @@ def update_flops_options(vehicle_data): if Aircraft.Wing.INPUT_STATION_DIST in input_values: input_values.set_val(Aircraft.Wing.DETAILED_WING, [True]) + design_type, design_units = input_values.get_item(Aircraft.Design.TYPE) + if design_type[0] == 0: + input_values.set_val(Aircraft.Design.TYPE, ['transport'], design_units) + elif design_type[0] == 3: + input_values.set_val(Aircraft.Design.TYPE, ['BWB'], design_units) + + # BWB always have detailed wing. + input_values.set_val(Aircraft.Wing.DETAILED_WING, [True]) + if Aircraft.Wing.INPUT_STATION_DIST in input_values: + input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [True]) + else: + # If detail wing is not provided, initialize it to [0, 0.5, 1] + input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [False]) + input_values.set_val(Aircraft.Wing.INPUT_STATION_DIST, [0.0, 0.5, 1.0]) + + if Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS in input_values: + num_business_class = input_values.get_val( + Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS, 'unitless' + )[0] + else: + num_business_class = 0 + if Aircraft.CrewPayload.Design.NUM_FIRST_CLASS in input_values: + num_first_class = input_values.get_val( + Aircraft.CrewPayload.Design.NUM_FIRST_CLASS, 'unitless' + )[0] + else: + num_first_class = 0 + if Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS in input_values: + num_tourist_class = input_values.get_val( + Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS, 'unitless' + )[0] + else: + num_tourist_class = 0 + num_passengers = num_business_class + num_first_class + num_tourist_class + input_values.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, [num_passengers]) + + if not Aircraft.CrewPayload.NUM_GALLEY_CREW in input_values: + if num_passengers < 151: + num_galley_crew = 0 + else: + num_galley_crew = int(num_passengers / 250) + 1 + input_values.set_val(Aircraft.CrewPayload.NUM_GALLEY_CREW, [num_galley_crew]) + + if not Aircraft.Engine.NUM_ENGINES in input_values: + if Aircraft.Engine.NUM_FUSELAGE_ENGINES in input_values: + num_fuselage_engines = input_values.get_val( + Aircraft.Engine.NUM_FUSELAGE_ENGINES, 'unitless' + )[0] + else: + num_fuselage_engines = 0 + if Aircraft.Engine.NUM_WING_ENGINES in input_values: + num_wing_engines = input_values.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless')[0] + else: + num_wing_engines = 0 + num_engines = num_fuselage_engines + num_wing_engines + input_values.set_val(Aircraft.Engine.NUM_ENGINES, [num_engines]) + + if not Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER in input_values: + if Mission.Design.RANGE in input_values: + design_range = input_values.get_val(Mission.Design.RANGE, 'nmi')[0] + baggage_per_pax = 35.0 + if design_range > 2900: + baggage_per_pax = 44.0 + elif design_range > 900: + baggage_per_pax = 40.0 + input_values.set_val( + Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER, [baggage_per_pax], 'lbm' + ) + + if design_type[0] == 0: + if Aircraft.Fuselage.LENGTH in input_values: + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [True], 'unitless') + else: + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') + elif design_type[0] == 3: + if ( + Aircraft.Fuselage.LENGTH in input_values + and Aircraft.BWB.PASSENGER_LEADING_EDGE_SWEEP in input_values + ): + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [True], 'unitless') + else: + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') + + if design_type[0] == 3: + if Aircraft.Engine.SCALED_SLS_THRUST in input_values: + # not sure why THRUST=70000,1,0,0,0,0, just grab the first entry + # does it apply to transporters? + thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] + input_values.set_val(Aircraft.Engine.SCALED_SLS_THRUST, [thrust], 'lbf') + + if not Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO in input_values: + if Aircraft.Wing.THICKNESS_TO_CHORD in input_values: + wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] + input_values.set_val(Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO, [wing_tc], 'unitless') + + if ( + not Aircraft.HorizontalTail.THICKNESS_TO_CHORD in input_values + or input_values.get_val(Aircraft.HorizontalTail.THICKNESS_TO_CHORD, 'unitless')[0] == 0 + ): + if Aircraft.Wing.THICKNESS_TO_CHORD in input_values: + wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] + input_values.set_val(Aircraft.HorizontalTail.THICKNESS_TO_CHORD, [wing_tc], 'unitless') + + if (not Aircraft.VerticalTail.THICKNESS_TO_CHORD in input_values) or ( + input_values.get_val(Aircraft.VerticalTail.THICKNESS_TO_CHORD, 'unitless')[0] == 0 + ): + if Aircraft.Wing.THICKNESS_TO_CHORD in input_values: + wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] + input_values.set_val(Aircraft.VerticalTail.THICKNESS_TO_CHORD, [wing_tc], 'unitless') + + if design_type[0] == 3: + if not Aircraft.Fuel.WING_FUEL_FRACTION in input_values: + # Interpret value equivalently to FWMAX = wing_fuel_fraction * fuel_density * 2/3 + FWMAX = 23 # the default + if Aircraft.Fuel.DENSITY in input_values: + FULDEN = input_values.get_val(Aircraft.Fuel.DENSITY, 'lbm/ft**3')[0] + else: + FULDEN = 50.1194909 # lbm/ft**3 or 6.7 lbm/galUS + input_values.set_val( + Aircraft.Fuel.WING_FUEL_FRACTION, [FWMAX / (FULDEN * (2 / 3))], 'unitless' + ) + + # For BWB, wing area is always computed + if Aircraft.Wing.AREA in input_values: + input_values.delete(Aircraft.Wing.AREA) + if Aircraft.Wing.ASPECT_RATIO in input_values: + input_values.delete(Aircraft.Wing.ASPECT_RATIO) + + if ( + Aircraft.Engine.SCALED_SLS_THRUST in input_values + and Aircraft.Engine.REFERENCE_SLS_THRUST in input_values + ): + ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[0] + scaled_thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] + if scaled_thrust <= 0: + print( + 'Aircraft.Engine.REFERENCE_SLS_THRUST must be positive ' + f'but you have {scaled_thrust}' + ) + else: + engine_scale_factor = scaled_thrust / ref_thrust + input_values.set_val(Aircraft.Engine.SCALE_FACTOR, [engine_scale_factor], 'unitless') + + # These variables should be removed if they are zero. + rem_list = [ + (Aircraft.Fuselage.CABIN_AREA, 'ft**2'), + (Aircraft.Fuselage.MAX_HEIGHT, 'ft'), + (Aircraft.Fuselage.PASSENGER_COMPARTMENT_LENGTH, 'ft'), + ] + for var in rem_list: + val = input_values.get_val(var[0], var[1])[0] + if val == 0.0: + input_values.delete(var[0]) + vehicle_data['input_values'] = input_values return vehicle_data @@ -922,7 +1076,7 @@ def update_aviary_options(vehicle_data): """Special handling for variables that occurs for either legacy code.""" input_values: NamedValues = vehicle_data['input_values'] - # if reference + scaled thrust both provided, set scale factor + # if reference + scaled thrust both provided, set scale factor -- Is this comment still true? try: ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[0] ref_thrust = float(ref_thrust) From acf2348c4bbefc5449fccc2ef477e7c82c01ead5 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 19:04:25 -0500 Subject: [PATCH 11/68] fix a typo --- aviary/variable_info/variables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 6fe72918d..11cbd2e11 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -577,7 +577,7 @@ class Wing: NUM_INTEGRATION_STATIONS = 'aircraft:wing:num_integration_stations' OPTIMUM_FLAP_DEFLECTION = 'aircraft:wing:optimum_flap_deflection' OPTIMUM_SLAT_DEFLECTION = 'aircraft:wing:optimum_slat_deflection' - OUTBOARD_SEMISPAN = 'aircraft:wing:Outboard_semispan' + OUTBOARD_SEMISPAN = 'aircraft:wing:outboard_semispan' ROOT_CHORD = 'aircraft:wing:root_chord' SHEAR_CONTROL_MASS = 'aircraft:wing:shear_control_mass' From e04b45f6aeb66a50ee414d40ec0aba0202bd7e7e Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 6 Jan 2026 19:06:19 -0500 Subject: [PATCH 12/68] compute Aircraft.Wing.SPAN in case of simple wing of BWB --- aviary/utils/fortran_to_aviary.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index 57d946db4..f28cb1061 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -929,6 +929,20 @@ def update_flops_options(vehicle_data): input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [False]) input_values.set_val(Aircraft.Wing.INPUT_STATION_DIST, [0.0, 0.5, 1.0]) + if not input_values.get_val(Aircraft.BWB.DETAILED_WING_PROVIDED)[0]: + try: + ar = input_values.get_val(Aircraft.Wing.ASPECT_RATIO, 'unitless')[0] + sw = input_values.get_val(Aircraft.Wing.AREA, 'ft**2')[0] + glov = input_values.get_val(Aircraft.Wing.GLOVE_AND_BAT, 'ft**2')[0] + span = (ar * (sw - glov)) ** 0.5 + input_values.set_val(Aircraft.Wing.SPAN, [span], 'ft') + except KeyError: + pass + try: # needed only if detailed wing is provided + input_values.delete(Aircraft.Wing.OUTBOARD_SEMISPAN) + except KeyError: + pass + if Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS in input_values: num_business_class = input_values.get_val( Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS, 'unitless' From 42aad076112d55a697da666dabb0882ad864a9ab Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 7 Jan 2026 16:07:19 -0500 Subject: [PATCH 13/68] work in progress for fortran_to_aviary --- .../blended_wing_body/bwb_detailed_FLOPS.csv | 1 + .../bwb_detailed_FLOPS_data.py | 1 + .../blended_wing_body/bwb_simple_FLOPS.csv | 1 + .../bwb_simple_FLOPS_data.py | 1 + .../flops_based/test/test_unusable_fuel.py | 7 ++- aviary/utils/fortran_to_aviary.py | 54 +++++++++++-------- .../test/data/converter_test_N3CC_FLOPS.csv | 5 +- 7 files changed, 44 insertions(+), 26 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index fd91a650b..4d8e47387 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -73,6 +73,7 @@ aircraft:fins:num_fins,2,unitless aircraft:fins:taper_ratio,0.464,unitless aircraft:fins:mass_scaler,1.0,unitless aircraft:fuel:auxiliary_fuel_capacity,0.0,lbm +aircraft:fuel:density,6.7,lbm/galUS aircraft:fuel:ignore_fuel_capacity_constraint,False,unitless aircraft:fuel:num_tanks,7,unitless aircraft:fuel:fuel_system_mass_scaler,1.0,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py index 7c9396fee..3ec25e619 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 @@ -90,6 +90,7 @@ inputs.set_val(Aircraft.Fuel.UNUSABLE_FUEL_MASS_SCALER, 1.0) # WUF inputs.set_val(Aircraft.Fuel.IGNORE_FUEL_CAPACITY_CONSTRAINT, False) # IFUFU inputs.set_val(Aircraft.Fuel.WING_FUEL_FRACTION, 0.68835495693, 'unitless') +inputs.set_val(Aircraft.Fuel.DENSITY, 6.7, 'lbm/galUS') # Furnishings # --------------------------- diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index 095dbe0e6..b21e47b66 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -73,6 +73,7 @@ aircraft:fins:num_fins,2,unitless aircraft:fins:taper_ratio,0.464,unitless aircraft:fins:mass_scaler,1.0,unitless aircraft:fuel:auxiliary_fuel_capacity,0.0,lbm +aircraft:fuel:density,6.7,lbm/galUS aircraft:fuel:ignore_fuel_capacity_constraint,False,unitless aircraft:fuel:num_tanks,7,unitless aircraft:fuel:fuel_system_mass_scaler,1.0,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py index 0ca63dd28..1b7898eae 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 @@ -90,6 +90,7 @@ inputs.set_val(Aircraft.Fuel.UNUSABLE_FUEL_MASS_SCALER, 1.0) # WUF inputs.set_val(Aircraft.Fuel.IGNORE_FUEL_CAPACITY_CONSTRAINT, False) # IFUFU inputs.set_val(Aircraft.Fuel.WING_FUEL_FRACTION, 0.68835495693, 'unitless') +inputs.set_val(Aircraft.Fuel.DENSITY, 6.7, 'lbm/galUS') # Furnishings # --------------------------- diff --git a/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py b/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py index 449f44e62..0cadfa94b 100644 --- a/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py +++ b/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py @@ -163,8 +163,11 @@ class BWBTransportUnusableFuelMassTest(unittest.TestCase): def setUp(self): self.prob = om.Problem() - @parameterized.expand(get_flops_case_names(only=bwb_cases), name_func=print_case) - def test_case(self, case_name): + # @parameterized.expand(get_flops_case_names(only=bwb_cases), name_func=print_case) + def test_case( + self, + ): + case_name = 'BWBsimpleFLOPS' prob = self.prob prob.model.add_subsystem( diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index f28cb1061..fad6d5f41 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -969,7 +969,7 @@ def update_flops_options(vehicle_data): num_galley_crew = 0 else: num_galley_crew = int(num_passengers / 250) + 1 - input_values.set_val(Aircraft.CrewPayload.NUM_GALLEY_CREW, [num_galley_crew]) + input_values.set_val(Aircraft.CrewPayload.NUM_GALLEY_CREW, [num_galley_crew]) if not Aircraft.Engine.NUM_ENGINES in input_values: if Aircraft.Engine.NUM_FUSELAGE_ENGINES in input_values: @@ -1011,17 +1011,16 @@ def update_flops_options(vehicle_data): else: input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') - if design_type[0] == 3: if Aircraft.Engine.SCALED_SLS_THRUST in input_values: # not sure why THRUST=70000,1,0,0,0,0, just grab the first entry # does it apply to transporters? thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] input_values.set_val(Aircraft.Engine.SCALED_SLS_THRUST, [thrust], 'lbf') - if not Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO in input_values: - if Aircraft.Wing.THICKNESS_TO_CHORD in input_values: - wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] - input_values.set_val(Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO, [wing_tc], 'unitless') + if not Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO in input_values: + if Aircraft.Wing.THICKNESS_TO_CHORD in input_values: + wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] + input_values.set_val(Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO, [wing_tc], 'unitless') if ( not Aircraft.HorizontalTail.THICKNESS_TO_CHORD in input_values @@ -1046,6 +1045,7 @@ def update_flops_options(vehicle_data): FULDEN = input_values.get_val(Aircraft.Fuel.DENSITY, 'lbm/ft**3')[0] else: FULDEN = 50.1194909 # lbm/ft**3 or 6.7 lbm/galUS + input_values.set_val(Aircraft.Fuel.DENSITY, [6.7], 'lbm/galUS') input_values.set_val( Aircraft.Fuel.WING_FUEL_FRACTION, [FWMAX / (FULDEN * (2 / 3))], 'unitless' ) @@ -1056,20 +1056,22 @@ def update_flops_options(vehicle_data): if Aircraft.Wing.ASPECT_RATIO in input_values: input_values.delete(Aircraft.Wing.ASPECT_RATIO) - if ( - Aircraft.Engine.SCALED_SLS_THRUST in input_values - and Aircraft.Engine.REFERENCE_SLS_THRUST in input_values - ): - ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[0] - scaled_thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] - if scaled_thrust <= 0: - print( - 'Aircraft.Engine.REFERENCE_SLS_THRUST must be positive ' - f'but you have {scaled_thrust}' - ) - else: - engine_scale_factor = scaled_thrust / ref_thrust - input_values.set_val(Aircraft.Engine.SCALE_FACTOR, [engine_scale_factor], 'unitless') + if ( + Aircraft.Engine.SCALED_SLS_THRUST in input_values + and Aircraft.Engine.REFERENCE_SLS_THRUST in input_values + ): + ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[0] + scaled_thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] + if scaled_thrust <= 0: + print( + 'Aircraft.Engine.REFERENCE_SLS_THRUST must be positive ' + f'but you have {scaled_thrust}' + ) + else: + engine_scale_factor = scaled_thrust / ref_thrust + input_values.set_val( + Aircraft.Engine.SCALE_FACTOR, [engine_scale_factor], 'unitless' + ) # These variables should be removed if they are zero. rem_list = [ @@ -1078,9 +1080,15 @@ def update_flops_options(vehicle_data): (Aircraft.Fuselage.PASSENGER_COMPARTMENT_LENGTH, 'ft'), ] for var in rem_list: - val = input_values.get_val(var[0], var[1])[0] - if val == 0.0: - input_values.delete(var[0]) + try: + val = input_values.get_val(var[0], var[1])[0] + if val == 0.0: + input_values.delete(var[0]) + except: + pass + + if design_type[0] != 3: + input_values.delete(Aircraft.BWB.PASSENGER_LEADING_EDGE_SWEEP) vehicle_data['input_values'] = input_values return vehicle_data diff --git a/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv b/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv index db103ed1f..80b537dc3 100644 --- a/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv +++ b/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv @@ -11,6 +11,7 @@ aircraft:canard:mass_scaler,1.0,unitless aircraft:crew_and_payload:baggage_mass_per_passenger,35.0,lbm aircraft:crew_and_payload:design:num_business_class,20,unitless aircraft:crew_and_payload:design:num_first_class,16,unitless +aircraft:crew_and_payload:design:num_passengers,154,unitless aircraft:crew_and_payload:design:num_tourist_class,118,unitless aircraft:crew_and_payload:flight_crew_mass_scaler,1.0,unitless aircraft:crew_and_payload:mass_per_passenger,165.0,lbm @@ -28,6 +29,7 @@ aircraft:design:lift_dependent_drag_coeff_factor,0.93,unitless aircraft:design:subsonic_drag_coeff_factor,0.95,unitless aircraft:design:supersonic_drag_coeff_factor,1.0,unitless aircraft:design:touchdown_mass,0.0,lbm +aircraft:design:type,transport,unitless aircraft:design:use_alt_mass,False,unitless aircraft:design:zero_lift_drag_coeff_factor,0.96,unitless aircraft:electrical:mass_scaler,1.1976,unitless @@ -41,6 +43,7 @@ aircraft:engine:generate_flight_idle,True,unitless aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:mass_scaler,1.15,unitless +aircraft:engine:num_engines,2,unitless aircraft:engine:num_fuselage_engines,0,unitless aircraft:engine:num_wing_engines,2,unitless aircraft:engine:reference_mass,6293.8,lbm @@ -72,6 +75,7 @@ aircraft:fuselage:max_width,12.3,ft aircraft:fuselage:military_cargo_floor,False,unitless aircraft:fuselage:num_fuselages,1,unitless aircraft:fuselage:passenger_compartment_length,97.5,ft +aircraft:fuselage:simple_layout,True,unitless aircraft:fuselage:wetted_area,4235.082096,ft**2 aircraft:horizontal_tail:area,349.522730527158,ft**2 aircraft:horizontal_tail:aspect_ratio,5.22699386503068,unitless @@ -288,7 +292,6 @@ MISSIN.txfufl,0 MISSIN.vqlm,260.0,320.0 OPTION.ianal,3 OPTION.icost,0 -OPTION.ifite,0 OPTION.iland,1 OPTION.ineng,0 OPTION.iplths,0 From 739c5c9e760edba8b0936ed543c05cb48bbc7ba2 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 7 Jan 2026 16:59:54 -0500 Subject: [PATCH 14/68] add a comment --- aviary/utils/fortran_to_aviary.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index fad6d5f41..d5ec6dcb4 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -931,6 +931,8 @@ def update_flops_options(vehicle_data): if not input_values.get_val(Aircraft.BWB.DETAILED_WING_PROVIDED)[0]: try: + # FLOPS uses AR and SW to compute wing span. Later, AR and SW are updated. + # So, they will be removed from inputs. ar = input_values.get_val(Aircraft.Wing.ASPECT_RATIO, 'unitless')[0] sw = input_values.get_val(Aircraft.Wing.AREA, 'ft**2')[0] glov = input_values.get_val(Aircraft.Wing.GLOVE_AND_BAT, 'ft**2')[0] From 41132804e02cb1bc656a88d8f2b7c636b59571cd Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 7 Jan 2026 20:55:01 -0500 Subject: [PATCH 15/68] fix typo --- .../models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 2 +- aviary/subsystems/test/test_flops_based_premission.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index e219c6467..e9170d4f7 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -137,7 +137,7 @@ aircraft:wing:mass_scaler,1,unitless aircraft:wing:max_camber_at_70_semispan,2,unitless aircraft:wing:misc_mass_scaler,1.0,unitless aircraft:wing:num_integration_stations,50,unitless -aircraft:wing:Outboard_semispan,86.75,ft +aircraft:wing:outboard_semispan,86.75,ft aircraft:wing:shear_control_mass_scaler,1.0,unitless aircraft:wing:span,253.720756,ft aircraft:wing:span_efficiency_factor,0.0,unitless diff --git a/aviary/subsystems/test/test_flops_based_premission.py b/aviary/subsystems/test/test_flops_based_premission.py index a9cde4868..8cf08524b 100644 --- a/aviary/subsystems/test/test_flops_based_premission.py +++ b/aviary/subsystems/test/test_flops_based_premission.py @@ -1289,7 +1289,4 @@ def test_case_all_subsystems(self): if __name__ == '__main__': - # unittest.main() - test = BWBPreMissionGroupCSVTest2() - test.setUp() - test.test_case_geom_mass() + unittest.main() From f3c1c1a91606da3e4501704cc297061f0e5707f8 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 8 Jan 2026 20:36:05 -0500 Subject: [PATCH 16/68] update fortran_to_aviary.py for detailed BWB model --- aviary/utils/fortran_to_aviary.py | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index d5ec6dcb4..6c749fa22 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -923,28 +923,25 @@ def update_flops_options(vehicle_data): # BWB always have detailed wing. input_values.set_val(Aircraft.Wing.DETAILED_WING, [True]) if Aircraft.Wing.INPUT_STATION_DIST in input_values: + input_station_dist = input_values.get_val(Aircraft.Wing.INPUT_STATION_DIST) + input_station_dist = [0.0] + input_station_dist + input_values.set_val(Aircraft.Wing.INPUT_STATION_DIST, input_station_dist) + n_dist = len(input_station_dist) + chord_per_semispan_dist = input_values.get_val(Aircraft.Wing.CHORD_PER_SEMISPAN_DIST) + chord_per_semispan_dist = [-1.0] + chord_per_semispan_dist[0 : n_dist - 1] + input_values.set_val(Aircraft.Wing.CHORD_PER_SEMISPAN_DIST, chord_per_semispan_dist) + load_path_sweep_dist = input_values.get_val(Aircraft.Wing.LOAD_PATH_SWEEP_DIST, 'deg') + load_path_sweep_dist = [0.0] + load_path_sweep_dist[0 : n_dist - 2] + input_values.set_val(Aircraft.Wing.LOAD_PATH_SWEEP_DIST, load_path_sweep_dist, 'deg') + thickness_to_chord_dist = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD_DIST) + thickness_to_chord_dist = [-1.0] + thickness_to_chord_dist[0 : n_dist - 1] + input_values.set_val(Aircraft.Wing.THICKNESS_TO_CHORD_DIST, thickness_to_chord_dist) input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [True]) else: # If detail wing is not provided, initialize it to [0, 0.5, 1] input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [False]) input_values.set_val(Aircraft.Wing.INPUT_STATION_DIST, [0.0, 0.5, 1.0]) - if not input_values.get_val(Aircraft.BWB.DETAILED_WING_PROVIDED)[0]: - try: - # FLOPS uses AR and SW to compute wing span. Later, AR and SW are updated. - # So, they will be removed from inputs. - ar = input_values.get_val(Aircraft.Wing.ASPECT_RATIO, 'unitless')[0] - sw = input_values.get_val(Aircraft.Wing.AREA, 'ft**2')[0] - glov = input_values.get_val(Aircraft.Wing.GLOVE_AND_BAT, 'ft**2')[0] - span = (ar * (sw - glov)) ** 0.5 - input_values.set_val(Aircraft.Wing.SPAN, [span], 'ft') - except KeyError: - pass - try: # needed only if detailed wing is provided - input_values.delete(Aircraft.Wing.OUTBOARD_SEMISPAN) - except KeyError: - pass - if Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS in input_values: num_business_class = input_values.get_val( Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS, 'unitless' @@ -1080,6 +1077,9 @@ def update_flops_options(vehicle_data): (Aircraft.Fuselage.CABIN_AREA, 'ft**2'), (Aircraft.Fuselage.MAX_HEIGHT, 'ft'), (Aircraft.Fuselage.PASSENGER_COMPARTMENT_LENGTH, 'ft'), + (Aircraft.Fuselage.LENGTH, 'ft'), + (Aircraft.Fuselage.MAX_WIDTH, 'ft'), + (Aircraft.HorizontalTail.SWEEP, 'deg'), ] for var in rem_list: try: From 46791e7616a7bd24284b3e24f551618705eb0a8a Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 9 Jan 2026 12:10:30 -0500 Subject: [PATCH 17/68] put all BWB code together --- aviary/utils/fortran_to_aviary.py | 126 +++++++++++++++--------------- 1 file changed, 65 insertions(+), 61 deletions(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index 6c749fa22..1ce416f23 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -917,6 +917,11 @@ def update_flops_options(vehicle_data): design_type, design_units = input_values.get_item(Aircraft.Design.TYPE) if design_type[0] == 0: input_values.set_val(Aircraft.Design.TYPE, ['transport'], design_units) + + if Aircraft.Fuselage.LENGTH in input_values: + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [True], 'unitless') + else: + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') elif design_type[0] == 3: input_values.set_val(Aircraft.Design.TYPE, ['BWB'], design_units) @@ -942,6 +947,66 @@ def update_flops_options(vehicle_data): input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [False]) input_values.set_val(Aircraft.Wing.INPUT_STATION_DIST, [0.0, 0.5, 1.0]) + if ( + Aircraft.Fuselage.LENGTH in input_values + and Aircraft.BWB.PASSENGER_LEADING_EDGE_SWEEP in input_values + ): + if ( + input_values.get_val(Aircraft.Fuselage.LENGTH, 'ft')[0] > 0.0 + and input_values.get_val(Aircraft.BWB.PASSENGER_LEADING_EDGE_SWEEP, 'deg')[0] > 0.0 + ): + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [True], 'unitless') + else: + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') + else: + input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') + + if Aircraft.Engine.SCALED_SLS_THRUST in input_values: + # not sure why THRUST=70000,1,0,0,0,0, just grab the first entry + # does it apply to transporters? + thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] + input_values.set_val(Aircraft.Engine.SCALED_SLS_THRUST, [thrust], 'lbf') + + if not Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO in input_values: + if Aircraft.Wing.THICKNESS_TO_CHORD in input_values: + wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] + input_values.set_val(Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO, [wing_tc], 'unitless') + + if not Aircraft.Fuel.WING_FUEL_FRACTION in input_values: + # Interpret value equivalently to FWMAX = wing_fuel_fraction * fuel_density * 2/3 + FWMAX = 23 # the default + if Aircraft.Fuel.DENSITY in input_values: + FULDEN = input_values.get_val(Aircraft.Fuel.DENSITY, 'lbm/ft**3')[0] + else: + FULDEN = 50.1194909 # lbm/ft**3 or 6.7 lbm/galUS + input_values.set_val(Aircraft.Fuel.DENSITY, [6.7], 'lbm/galUS') + input_values.set_val( + Aircraft.Fuel.WING_FUEL_FRACTION, [FWMAX / (FULDEN * (2 / 3))], 'unitless' + ) + + # For BWB, wing area is always computed + if Aircraft.Wing.AREA in input_values: + input_values.delete(Aircraft.Wing.AREA) + if Aircraft.Wing.ASPECT_RATIO in input_values: + input_values.delete(Aircraft.Wing.ASPECT_RATIO) + + if ( + Aircraft.Engine.SCALED_SLS_THRUST in input_values + and Aircraft.Engine.REFERENCE_SLS_THRUST in input_values + ): + ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[0] + scaled_thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] + if scaled_thrust <= 0: + print( + 'Aircraft.Engine.REFERENCE_SLS_THRUST must be positive ' + f'but you have {scaled_thrust}' + ) + else: + engine_scale_factor = scaled_thrust / ref_thrust + input_values.set_val( + Aircraft.Engine.SCALE_FACTOR, [engine_scale_factor], 'unitless' + ) + if Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS in input_values: num_business_class = input_values.get_val( Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS, 'unitless' @@ -996,31 +1061,6 @@ def update_flops_options(vehicle_data): Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER, [baggage_per_pax], 'lbm' ) - if design_type[0] == 0: - if Aircraft.Fuselage.LENGTH in input_values: - input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [True], 'unitless') - else: - input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') - elif design_type[0] == 3: - if ( - Aircraft.Fuselage.LENGTH in input_values - and Aircraft.BWB.PASSENGER_LEADING_EDGE_SWEEP in input_values - ): - input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [True], 'unitless') - else: - input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') - - if Aircraft.Engine.SCALED_SLS_THRUST in input_values: - # not sure why THRUST=70000,1,0,0,0,0, just grab the first entry - # does it apply to transporters? - thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] - input_values.set_val(Aircraft.Engine.SCALED_SLS_THRUST, [thrust], 'lbf') - - if not Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO in input_values: - if Aircraft.Wing.THICKNESS_TO_CHORD in input_values: - wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] - input_values.set_val(Aircraft.Fuselage.HEIGHT_TO_WIDTH_RATIO, [wing_tc], 'unitless') - if ( not Aircraft.HorizontalTail.THICKNESS_TO_CHORD in input_values or input_values.get_val(Aircraft.HorizontalTail.THICKNESS_TO_CHORD, 'unitless')[0] == 0 @@ -1036,42 +1076,6 @@ def update_flops_options(vehicle_data): wing_tc = input_values.get_val(Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless')[0] input_values.set_val(Aircraft.VerticalTail.THICKNESS_TO_CHORD, [wing_tc], 'unitless') - if design_type[0] == 3: - if not Aircraft.Fuel.WING_FUEL_FRACTION in input_values: - # Interpret value equivalently to FWMAX = wing_fuel_fraction * fuel_density * 2/3 - FWMAX = 23 # the default - if Aircraft.Fuel.DENSITY in input_values: - FULDEN = input_values.get_val(Aircraft.Fuel.DENSITY, 'lbm/ft**3')[0] - else: - FULDEN = 50.1194909 # lbm/ft**3 or 6.7 lbm/galUS - input_values.set_val(Aircraft.Fuel.DENSITY, [6.7], 'lbm/galUS') - input_values.set_val( - Aircraft.Fuel.WING_FUEL_FRACTION, [FWMAX / (FULDEN * (2 / 3))], 'unitless' - ) - - # For BWB, wing area is always computed - if Aircraft.Wing.AREA in input_values: - input_values.delete(Aircraft.Wing.AREA) - if Aircraft.Wing.ASPECT_RATIO in input_values: - input_values.delete(Aircraft.Wing.ASPECT_RATIO) - - if ( - Aircraft.Engine.SCALED_SLS_THRUST in input_values - and Aircraft.Engine.REFERENCE_SLS_THRUST in input_values - ): - ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[0] - scaled_thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] - if scaled_thrust <= 0: - print( - 'Aircraft.Engine.REFERENCE_SLS_THRUST must be positive ' - f'but you have {scaled_thrust}' - ) - else: - engine_scale_factor = scaled_thrust / ref_thrust - input_values.set_val( - Aircraft.Engine.SCALE_FACTOR, [engine_scale_factor], 'unitless' - ) - # These variables should be removed if they are zero. rem_list = [ (Aircraft.Fuselage.CABIN_AREA, 'ft**2'), From 8867db27e2d0db5edfd7b1d4f1efef4c9bb5ff39 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 22 Jan 2026 13:54:57 -0500 Subject: [PATCH 18/68] minor update to match with main --- .../subsystems/mass/flops_based/test/test_unusable_fuel.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py b/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py index 0cadfa94b..449f44e62 100644 --- a/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py +++ b/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py @@ -163,11 +163,8 @@ class BWBTransportUnusableFuelMassTest(unittest.TestCase): def setUp(self): self.prob = om.Problem() - # @parameterized.expand(get_flops_case_names(only=bwb_cases), name_func=print_case) - def test_case( - self, - ): - case_name = 'BWBsimpleFLOPS' + @parameterized.expand(get_flops_case_names(only=bwb_cases), name_func=print_case) + def test_case(self, case_name): prob = self.prob prob.model.add_subsystem( From 35649ca8b17a31ea49a643613c244878c0da4f63 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 23 Jan 2026 12:49:20 -0500 Subject: [PATCH 19/68] add experiment mission tests --- .../test_bwb_Experiment_FwFm_1.py | 75 ++++++ .../test_bwb_Experiment_FwFm_2.py | 223 ++++++++++++++++++ 2 files changed, 298 insertions(+) create mode 100644 aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py create mode 100644 aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py new file mode 100644 index 000000000..d6423866d --- /dev/null +++ b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py @@ -0,0 +1,75 @@ +import unittest +from copy import deepcopy + +from openmdao.core.problem import _clear_problem_names +from openmdao.utils.assert_utils import assert_near_equal +from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs + +from aviary.models.aircraft.large_turboprop_freighter.phase_info import ( + energy_phase_info as phase_info, +) + +from aviary.interface.methods_for_level1 import run_aviary +from aviary.variable_info.variables import Mission + + +@use_tempdirs +class ProblemPhaseTestCase(unittest.TestCase): + """ + Test the setup and run of a BWB aircraft using FLOPS mass and aero method + and HEIGHT_ENERGY mission method. Expected outputs based on + 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv' model. + """ + + def setUp(self): + _clear_problem_names() # need to reset these to simulate separate runs + + @require_pyoptsparse(optimizer='SNOPT') + def test_bench_bwb_FwFm_SNOPT(self): + local_phase_info = deepcopy(phase_info) + prob = run_aviary( + 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv', + local_phase_info, + optimizer='SNOPT', + verbosity=0, + max_iter=60, + ) + + rtol = 1e-3 + + # There are no truth values for these. + assert_near_equal( + prob.get_val(Mission.Design.GROSS_MASS, units='lbm'), + 139803.667415, + tolerance=rtol, + ) + + assert_near_equal( + prob.get_val(Mission.Summary.OPERATING_MASS, units='lbm'), + 79873.05255347, + tolerance=rtol, + ) + + assert_near_equal( + prob.get_val(Mission.Summary.TOTAL_FUEL_MASS, units='lbm'), + 26180.61486153, + tolerance=rtol, + ) + + assert_near_equal( + prob.get_val(Mission.Landing.GROUND_DISTANCE, units='ft'), + 2216.0066613, + tolerance=rtol, + ) + + assert_near_equal(prob.get_val(Mission.Summary.RANGE, units='NM'), 3500.0, tolerance=rtol) + + assert_near_equal( + prob.get_val(Mission.Landing.TOUCHDOWN_MASS, units='lbm'), + 116003.31044998, + tolerance=rtol, + ) + + +if __name__ == '__main__': + unittest.main() diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py new file mode 100644 index 000000000..6aa68c53e --- /dev/null +++ b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py @@ -0,0 +1,223 @@ +import unittest + +import numpy as np +from openmdao.core.problem import _clear_problem_names +from openmdao.utils.mpi import MPI +from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs + +from aviary.api import Mission +from aviary.interface.methods_for_level1 import run_aviary +from aviary.validation_cases.benchmark_utils import compare_against_expected_values + +try: + from openmdao.vectors.petsc_vector import PETScVector +except ImportError: + PETScVector = None + + +@use_tempdirs +class ProblemPhaseTestCase(unittest.TestCase): + """ + Setup of a BWB aircraft using + FLOPS mass and aero method and HEIGHT_ENERGY mission method. Expected outputs based + on 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv' model. + """ + + def setUp(self): + expected_dict = {} + + # block auto-formatting of tables + # fmt: off + expected_dict['times'] = np.array( + [ + [120.],[163.76268404], [224.14625594], [243.25744998], [243.25744998], + [336.40804126], [464.93684491], [505.61577182], [505.61577182], [626.46953842], + [793.22306972], [845.99999224], [845.99999224], [966.85375884], [1133.60729014], + [1186.38421266], [1186.38421266], [1279.53480393], [1408.06360758], [1448.74253449], + [1448.74253449], [1492.50521853], [1552.88879042], [1571.99998447], [1571.99998447], + [10224.87383109], [22164.07366288], [25942.78958866], [25942.78958866], + [26009.11685074], [26100.63493484], [26129.60009555], [26129.60009555], + [26265.05921709], [26451.96515722], [26511.12024823], [26511.12024823], + [26672.16774132], [26894.38041154], [26964.7099619], [26964.7099619], + [27100.16908344], [27287.07502357], [27346.23011458], [27346.23011458], + [27412.55737667], [27504.07546076], [27533.04062147] + ] + ) + + expected_dict['altitudes'] = np.array( + [ + [10.668], [0.], [1001.70617719], [1429.27176545], [1429.27176545], [3413.27102762], + [5642.3831233], [6169.75300447], [6169.75300447], [7399.140983], [8514.78661356], + [8803.21405264], [8803.21405264], [9373.68426297], [10020.99237958], + [10196.42552457], [10196.42552457],[10451.72258036], [10652.38789684], [10668.], + [10668.], [10660.42246376], [10656.16585151], [10668.], [10668.], [10668.], + [10668.], [10668.], [10668.], [10668.], [10142.11478951], [9922.15743555], + [9922.15743555], [8891.66886638], [7502.1861348], [7069.1900852], [7069.1900852], + [5896.44637998], [4264.29354306], [3737.8471594], [3737.8471594], [2702.15624637], + [1248.18960736], [793.03526817], [793.03526817], [345.06939295], [10.668], [10.668] + ] + ) + + expected_dict['masses'] = np.array( + [ + [79303.30184763], [79221.39668215], [79075.19453181], [79028.6003426], + [79028.6003426], [78828.82221909], [78613.60466821], [78557.84739563], + [78557.84739563], [78411.06578989], [78238.0916773], [78186.75440341], + [78186.75440341], [78077.23953313], [77938.37965175], [77896.59718975], + [77896.59718975], [77825.81832958], [77732.75016916], [77704.11629998], + [77704.11629998], [77673.32196072], [77630.75735319], [77617.25716885], + [77617.25716885], [72178.78521803], [65072.41395049], [62903.84179505], + [62903.84179505], [62896.27636813], [62888.3612195], [62885.93748938], + [62885.93748938], [62874.48788511], [62857.70600096], [62852.13740881], + [62852.13740881], [62835.97069937], [62810.37776063], [62801.1924259], + [62801.1924259], [62781.32471014], [62748.91017128], [62737.32520462], + [62737.32520462], [62723.59895849], [62703.94977811], [62697.71513264] + ] + ) + + expected_dict['ranges'] = np.array( + [ + [1452.84514351], [6093.51223933], [15820.03029119], [19123.61258676], + [19123.61258676], [36374.65336952], [61265.3984918], [69106.49687132], + [69106.49687132], [92828.04820577], [126824.13801408], [138011.02420534], + [138011.02420534], [164027.18014424], [200524.66550565], [212113.49107256], + [212113.49107256], [232622.50720766], [261189.53466522], [270353.40501262], + [270353.40501262], [280350.48472685], [294356.27080588], [298832.61221641], + [298832.61221641], [2325837.11255987], [5122689.60556392], [6007883.85695889], + [6007883.85695889], [6022237.43153219], [6039575.06318219], [6044873.89820027], + [6044873.89820027], [6068553.1921364], [6099290.23732297], [6108673.67260778], + [6108673.67260778], [6133535.09572671], [6166722.19545137], [6177077.72115854], + [6177077.72115854], [6197011.1330154], [6224357.63792683], [6232920.45309764], + [6232920.45309764], [6242332.46480721], [6254144.50957549], [6257352.4] + ] + ) + + expected_dict['velocities'] = np.array( + [ + [69.30879167], [137.49019035], [174.54683946], [179.28863383], [179.28863383], + [191.76748742], [194.33322917], [194.52960387], [194.52960387], [199.01184603], + [209.81696863], [212.86546124], [212.86546124], [217.37467051], [219.67762167], + [219.97194272], [219.97194272], [220.67963782], [224.38113484], [226.77184704], + [226.77184704], [230.01128033], [233.72454583], [234.25795132], [234.25795132], + [234.25795132], [234.25795132], [234.25795132], [234.25795132], [201.23881], + [182.84158341], [180.10650108], [180.10650108], [169.77497514], [159.59034446], + [157.09907013], [157.09907013], [151.659491], [147.52098882], [147.07683999], + [147.07683999], [147.05392009], [145.31556891], [143.47446173], [143.47446173], + [138.99109332], [116.22447082], [102.07377559] + ] + ) + # fmt: on + + self.expected_dict = expected_dict + + phase_info = { + 'pre_mission': {'include_takeoff': True, 'optimize_mass': True}, + 'climb': { + 'subsystem_options': {'aerodynamics': {'method': 'computed'}}, + 'user_options': { + 'num_segments': 6, + 'order': 3, + 'mach_bounds': ((0.1, 0.8), 'unitless'), + 'mach_optimize': True, + 'altitude_bounds': ((0.0, 35000.0), 'ft'), + 'altitude_optimize': True, + 'throttle_enforcement': 'path_constraint', + 'mass_ref': (200000, 'lbm'), + 'time_initial': (0.0, 'min'), + 'time_duration_bounds': ((20.0, 60.0), 'min'), + 'no_descent': True, + }, + 'initial_guesses': { + 'time': ([0, 40.0], 'min'), + 'altitude': ([35, 35000.0], 'ft'), + 'mach': ([0.3, 0.79], 'unitless'), + }, + }, + 'cruise': { + 'subsystem_options': {'aerodynamics': {'method': 'computed'}}, + 'user_options': { + 'num_segments': 1, + 'order': 3, + 'mach_initial': (0.79, 'unitless'), + 'mach_bounds': ((0.79, 0.79), 'unitless'), + 'mach_optimize': True, + 'mach_polynomial_order': 1, + 'altitude_initial': (35000.0, 'ft'), + 'altitude_bounds': ((35000.0, 35000.0), 'ft'), + 'altitude_optimize': True, + 'altitude_polynomial_order': 1, + 'throttle_enforcement': 'boundary_constraint', + 'mass_ref': (200000, 'lbm'), + 'time_initial_bounds': ((20.0, 60.0), 'min'), + 'time_duration_bounds': ((60.0, 720.0), 'min'), + }, + 'initial_guesses': { + 'time': ([40, 200], 'min'), + 'altitude': ([35000, 35000.0], 'ft'), + 'mach': ([0.79, 0.79], 'unitless'), + }, + }, + 'descent': { + 'subsystem_options': {'aerodynamics': {'method': 'computed'}}, + 'user_options': { + 'num_segments': 5, + 'order': 3, + 'mach_initial': (0.79, 'unitless'), + 'mach_final': (0.3, 'unitless'), + 'mach_bounds': ((0.2, 0.8), 'unitless'), + 'mach_optimize': True, + 'altitude_initial': (35000.0, 'ft'), + 'altitude_final': (35.0, 'ft'), + 'altitude_bounds': ((0.0, 35000.0), 'ft'), + 'altitude_optimize': True, + 'throttle_enforcement': 'path_constraint', + 'mass_ref': (200000, 'lbm'), + 'distance_ref': (3375, 'nmi'), + 'time_initial_bounds': ((80.0, 780.0), 'min'), + 'time_duration_bounds': ((5.0, 45.0), 'min'), + 'no_climb': True, + }, + 'initial_guesses': { + 'time': ([240, 30], 'min'), + }, + }, + 'post_mission': { + 'include_landing': True, + 'constrain_range': True, + 'target_range': (3375.0, 'nmi'), + }, + } + + self.phase_info = phase_info + + _clear_problem_names() # need to reset these to simulate separate runs + + +class TestBenchFwFmSerial(ProblemPhaseTestCase): + """Run the model in serial that is setup in ProblemPhaseTestCase class.""" + + @require_pyoptsparse(optimizer='SNOPT') + def test_bench_FwFm_SNOPT(self): + prob = run_aviary( + 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv', + self.phase_info, + verbosity=1, + max_iter=50, + optimizer='SNOPT', + ) + + # self.assertTrue(prob.result.success) + compare_against_expected_values(prob, self.expected_dict) + + # This is one of the few places we test Height Energy + simple takeoff. + overall_fuel = prob.get_val(Mission.Summary.TOTAL_FUEL_MASS) + + # Making sure we include the fuel mass consumed in take-off and taxi. + self.assertGreater(overall_fuel, 40000.0) + + +if __name__ == '__main__': + # unittest.main() + test = TestBenchFwFmSerial() + test.setUp() + test.test_bench_FwFm_SNOPT() From 70d18ef39e3ed81040035e5b13d639e091e92d98 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 23 Jan 2026 18:57:24 -0500 Subject: [PATCH 20/68] add settings:verbosity to BWB csv files --- aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 1 + aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 1 + 2 files changed, 2 insertions(+) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index c28fdf40c..e91e3c86a 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -164,6 +164,7 @@ mission:summary:fuel_flow_scaler,1.0,unitless settings:aerodynamics_method,FLOPS,unitless settings:equations_of_motion,height_energy,unitless settings:mass_method,FLOPS,unitless +settings:verbosity,1,unitless # Unconverted Values AERIN.FLLDG,11000 diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index 47e12e0f2..f44c184c6 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -163,6 +163,7 @@ mission:summary:fuel_flow_scaler,1.0,unitless settings:aerodynamics_method,FLOPS,unitless settings:equations_of_motion,height_energy,unitless settings:mass_method,FLOPS,unitless +settings:verbosity,1,unitless # Unconverted Values AERIN.FLLDG,11000 From 3018e3eabccb4183292b31efd8f4230639407588 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 23 Jan 2026 18:58:48 -0500 Subject: [PATCH 21/68] work in progress --- .../benchmark_tests/test_bwb_Experiment_FwFm_1.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py index d6423866d..a8946ff13 100644 --- a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py +++ b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py @@ -13,7 +13,7 @@ from aviary.variable_info.variables import Mission -@use_tempdirs +# @use_tempdirs class ProblemPhaseTestCase(unittest.TestCase): """ Test the setup and run of a BWB aircraft using FLOPS mass and aero method @@ -34,6 +34,9 @@ def test_bench_bwb_FwFm_SNOPT(self): verbosity=0, max_iter=60, ) + # prob.list_indep_vars() + # prob.list_problem_vars() + prob.model.list_outputs() rtol = 1e-3 From 61c1d6ddeb741099d74ea91898569f5deb7bd987 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 23 Jan 2026 19:00:16 -0500 Subject: [PATCH 22/68] check divided by zero in ground_effect.py --- .../aerodynamics/flops_based/ground_effect.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/aviary/subsystems/aerodynamics/flops_based/ground_effect.py b/aviary/subsystems/aerodynamics/flops_based/ground_effect.py index 5eca2ce12..4b8c04d4f 100644 --- a/aviary/subsystems/aerodynamics/flops_based/ground_effect.py +++ b/aviary/subsystems/aerodynamics/flops_based/ground_effect.py @@ -11,8 +11,9 @@ import numpy as np import openmdao.api as om -from aviary.variable_info.functions import add_aviary_input -from aviary.variable_info.variables import Aircraft, Dynamic +from aviary.variable_info.enums import Verbosity +from aviary.variable_info.functions import add_aviary_input, add_aviary_option +from aviary.variable_info.variables import Aircraft, Dynamic, Settings class GroundEffect(om.ExplicitComponent): @@ -29,6 +30,7 @@ class GroundEffect(om.ExplicitComponent): def initialize(self): options = self.options + add_aviary_option(self, Settings.VERBOSITY) options.declare('num_nodes', default=1, types=int, lower=0) options.declare( @@ -138,6 +140,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): options = self.options ground_altitude = options['ground_altitude'] + verbosity = self.options[Settings.VERBOSITY] angle_of_attack = inputs[Dynamic.Vehicle.ANGLE_OF_ATTACK] altitude = inputs[Dynamic.Mission.ALTITUDE] @@ -148,6 +151,9 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): aspect_ratio = inputs[Aircraft.Wing.ASPECT_RATIO] height = inputs[Aircraft.Wing.HEIGHT] span = inputs[Aircraft.Wing.SPAN] + if span <= 0.0: + if verbosity > Verbosity.BRIEF: + raise UserWarning('Aircraft.Wing.SPAN is not positive.') ground_effect_state = ((altitude - ground_altitude) + height) / span height_factor = np.ones_like(ground_effect_state) @@ -164,6 +170,9 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): + 4.0 * ground_effect_state * aspect_ratio_term * np.sqrt(ground_effect_term0) ) + if lift_coeff_factor_denom <= 0.0: + if verbosity > Verbosity.BRIEF: + raise UserWarning('lift_coeff_factor_denom is not positive.') lift_coeff_factor = 1.0 + height_factor / lift_coeff_factor_denom lift_coefficient = base_lift_coefficient * lift_coeff_factor @@ -175,6 +184,9 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): 4.0 * ground_effect_state * np.sqrt(ground_effect_term1) + ground_effect_term1 ) + if drag_coeff_factor_denom <= 0.0: + if verbosity > Verbosity.BRIEF: + raise UserWarning('drag_coeff_factor_denom is not positive.') drag_coeff_factor = 1.0 - height_factor / drag_coeff_factor_denom drag_coefficient = ( From eead582ed2fc8368da40e9a6312df6a7ebfeda89 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 23 Jan 2026 19:01:49 -0500 Subject: [PATCH 23/68] add COMPUTED_CORE_INPUTS_BWB --- .../aerodynamics/aerodynamics_builder.py | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index e5167ffc9..69007339d 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -494,7 +494,12 @@ def get_parameters(self, aviary_inputs=None, **kwargs): params[Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR] = opts if method == 'computed': - for var in COMPUTED_CORE_INPUTS: + design_type = aviary_inputs.get_val(Aircraft.Design.TYPE) + if design_type is AircraftTypes.BLENDED_WING_BODY: + core_inputs_computed = COMPUTED_CORE_INPUTS_BWB + else: + core_inputs_computed = COMPUTED_CORE_INPUTS + for var in core_inputs_computed: meta = _MetaData[var] val = meta['default_value'] @@ -729,6 +734,37 @@ def report(self, prob, reports_folder, **kwargs): Mission.Design.MACH, ] +COMPUTED_CORE_INPUTS_BWB = [ + Aircraft.Design.BASE_AREA, + Aircraft.Design.LIFT_DEPENDENT_DRAG_COEFF_FACTOR, + Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, + Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, + Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, + Aircraft.Fuselage.CHARACTERISTIC_LENGTH, + Aircraft.Fuselage.CROSS_SECTION, + Aircraft.Fuselage.DIAMETER_TO_WING_SPAN, + Aircraft.Fuselage.FINENESS, + Aircraft.Fuselage.LAMINAR_FLOW_LOWER, + Aircraft.Fuselage.LAMINAR_FLOW_UPPER, + Aircraft.Fuselage.LENGTH_TO_DIAMETER, + Aircraft.Fuselage.WETTED_AREA, + Aircraft.Wing.AREA, + Aircraft.Wing.ASPECT_RATIO, + Aircraft.Wing.CHARACTERISTIC_LENGTH, + Aircraft.Wing.FINENESS, + Aircraft.Wing.LAMINAR_FLOW_LOWER, + Aircraft.Wing.LAMINAR_FLOW_UPPER, + Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, + Aircraft.Wing.SPAN_EFFICIENCY_FACTOR, + Aircraft.Wing.SWEEP, + Aircraft.Wing.TAPER_RATIO, + Aircraft.Wing.THICKNESS_TO_CHORD, + Aircraft.Wing.WETTED_AREA, + # Mission.Summary.GROSS_MASS, + Mission.Design.LIFT_COEFFICIENT, + Mission.Design.MACH, +] + TABULAR_CORE_INPUTS = [ Aircraft.Wing.AREA, Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, From 535929030b6876a34b26d7af8fbe09dee30a99f6 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 23 Jan 2026 19:02:56 -0500 Subject: [PATCH 24/68] deal with BWB where there is no horizontal tails --- .../aerodynamics/flops_based/skin_friction.py | 10 +++++++++- .../aerodynamics/flops_based/skin_friction_drag.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py index 502378cf3..e226d161b 100644 --- a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py +++ b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py @@ -1,6 +1,7 @@ import numpy as np import openmdao.api as om +from aviary.variable_info.enums import AircraftTypes from aviary.variable_info.functions import add_aviary_input, add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic @@ -36,17 +37,24 @@ def initialize(self): desc='The number of points at which the cross product is computed.', ) + add_aviary_option(self, Aircraft.Design.TYPE) add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) add_aviary_option(self, Aircraft.VerticalTail.NUM_TAILS) def setup(self): nn = self.options['num_nodes'] + design_type = self.options[Aircraft.Design.TYPE] num_engines = self.options[Aircraft.Engine.NUM_ENGINES] num_fuselages = self.options[Aircraft.Fuselage.NUM_FUSELAGES] num_tails = self.options[Aircraft.VerticalTail.NUM_TAILS] - self.nc = nc = 2 + num_tails + num_fuselages + int(sum(num_engines)) + if design_type is AircraftTypes.BLENDED_WING_BODY: + # No horizontal tail for BWB + nc = 1 + num_tails + num_fuselages + int(sum(num_engines)) + else: + nc = 2 + num_tails + num_fuselages + int(sum(num_engines)) + self.nc = nc # Simulation inputs add_aviary_input(self, Dynamic.Atmosphere.TEMPERATURE, shape=nn, units='degR') diff --git a/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py b/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py index 2324ecee4..e30ada57f 100644 --- a/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py @@ -1,6 +1,7 @@ import numpy as np import openmdao.api as om +from aviary.variable_info.enums import AircraftTypes from aviary.variable_info.functions import add_aviary_input, add_aviary_option, get_units from aviary.variable_info.variables import Aircraft @@ -33,6 +34,7 @@ def initialize(self): desc='The number of points at which the cross product is computed.', ) + add_aviary_option(self, Aircraft.Design.TYPE) add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) add_aviary_option(self, Aircraft.VerticalTail.NUM_TAILS) @@ -47,12 +49,18 @@ def initialize(self): def setup(self): nn = self.options['num_nodes'] + design_type = self.options[Aircraft.Design.TYPE] nvtail = self.options[Aircraft.VerticalTail.NUM_TAILS] nfuse = self.options[Aircraft.Fuselage.NUM_FUSELAGES] num_engines = self.options[Aircraft.Engine.NUM_ENGINES] - self.nc = nc = 2 + nvtail + nfuse + int(sum(num_engines)) + if design_type is AircraftTypes.BLENDED_WING_BODY: + # No horizontal tail for BWB + nc = 1 + nvtail + nfuse + int(sum(num_engines)) + else: + nc = 2 + nvtail + nfuse + int(sum(num_engines)) + self.nc = nc # Computed by other components in drag group. self.add_input('skin_friction_coeff', np.zeros((nn, nc)), units='unitless') From 4ec92d961e2f085d1eb6b30a801ab9e2028cdbc0 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 13:59:00 -0500 Subject: [PATCH 25/68] post mission require aircraft:wing:area. If it is not available, do not do landing --- aviary/mission/height_energy_problem_configurator.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/aviary/mission/height_energy_problem_configurator.py b/aviary/mission/height_energy_problem_configurator.py index 5f393aaa4..7e29b40d8 100644 --- a/aviary/mission/height_energy_problem_configurator.py +++ b/aviary/mission/height_energy_problem_configurator.py @@ -394,7 +394,11 @@ def add_post_mission_systems(self, aviary_group): ) if aviary_group.post_mission_info['include_landing']: - self._add_landing_systems(aviary_group) + if 'aircraft:wing:area' in aviary_group.aviary_inputs: + self._add_landing_systems(aviary_group) + else: + print('Aircraft.Wing.AREA is not given. Set include_landing = False') + aviary_group.post_mission_info['include_landing'] = False aviary_group.add_subsystem( 'range_constraint', From 67001d8de53db7e40781b2081d431ac28a415d64 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 13:59:30 -0500 Subject: [PATCH 26/68] work in progress. --- .../test_bwb_Experiment_FwFm_1.py | 74 ++++++++++++++++++- .../test_bwb_Experiment_FwFm_2.py | 37 +++++++++- 2 files changed, 103 insertions(+), 8 deletions(-) diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py index a8946ff13..ea2a65ab5 100644 --- a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py +++ b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py @@ -14,7 +14,7 @@ # @use_tempdirs -class ProblemPhaseTestCase(unittest.TestCase): +class BWBProblemPhaseTestCase(unittest.TestCase): """ Test the setup and run of a BWB aircraft using FLOPS mass and aero method and HEIGHT_ENERGY mission method. Expected outputs based on @@ -34,9 +34,10 @@ def test_bench_bwb_FwFm_SNOPT(self): verbosity=0, max_iter=60, ) + # prob.model.list_vars(units=True, print_arrays=True) # prob.list_indep_vars() # prob.list_problem_vars() - prob.model.list_outputs() + # prob.model.list_outputs() rtol = 1e-3 @@ -59,13 +60,75 @@ def test_bench_bwb_FwFm_SNOPT(self): tolerance=rtol, ) + assert_near_equal(prob.get_val(Mission.Summary.RANGE, units='NM'), 3500.0, tolerance=rtol) + assert_near_equal( prob.get_val(Mission.Landing.GROUND_DISTANCE, units='ft'), 2216.0066613, tolerance=rtol, ) - assert_near_equal(prob.get_val(Mission.Summary.RANGE, units='NM'), 3500.0, tolerance=rtol) + assert_near_equal( + prob.get_val(Mission.Landing.TOUCHDOWN_MASS, units='lbm'), + 116003.31044998, + tolerance=rtol, + ) + + +class ProblemPhaseTestCase(unittest.TestCase): + """ + Test the setup and run of a test aircraft using FLOPS mass and aero method + and HEIGHT_ENERGY mission method. Expected outputs based on + 'models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv' model. + """ + + def setUp(self): + _clear_problem_names() # need to reset these to simulate separate runs + + @require_pyoptsparse(optimizer='SNOPT') + def test_bench_FwFm_SNOPT(self): + local_phase_info = deepcopy(phase_info) + prob = run_aviary( + 'models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv', + local_phase_info, + optimizer='SNOPT', + verbosity=0, + max_iter=60, + ) + # prob.list_indep_vars() + # prob.list_problem_vars() + # prob.model.list_outputs() + + # self.assertTrue(prob.result.success) + + rtol = 1e-3 + + # There are no truth values for these. + assert_near_equal( + prob.get_val(Mission.Design.GROSS_MASS, units='lbm'), + 169804.16225263, + tolerance=rtol, + ) + + assert_near_equal( + prob.get_val(Mission.Summary.OPERATING_MASS, units='lbm'), + 97096.89284117, + tolerance=rtol, + ) + + assert_near_equal( + prob.get_val(Mission.Summary.TOTAL_FUEL_MASS, units='lbm'), + 34682.26941131, + tolerance=rtol, + ) + + assert_near_equal(prob.get_val(Mission.Summary.RANGE, units='NM'), 2020.0, tolerance=rtol) + + assert_near_equal( + prob.get_val(Mission.Landing.GROUND_DISTANCE, units='ft'), + 2216.0066613, + tolerance=rtol, + ) assert_near_equal( prob.get_val(Mission.Landing.TOUCHDOWN_MASS, units='lbm'), @@ -75,4 +138,7 @@ def test_bench_bwb_FwFm_SNOPT(self): if __name__ == '__main__': - unittest.main() + # unittest.main() + test = BWBProblemPhaseTestCase() + test.setUp() + test.test_bench_bwb_FwFm_SNOPT() diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py index 6aa68c53e..f24972bfb 100644 --- a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py +++ b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py @@ -193,13 +193,36 @@ def setUp(self): _clear_problem_names() # need to reset these to simulate separate runs +class TestBWBFwFmSerial(ProblemPhaseTestCase): + """Run the model in serial that is setup in ProblemPhaseTestCase class.""" + + @require_pyoptsparse(optimizer='SNOPT') + def test_bwb_FwFm_SNOPT(self): + prob = run_aviary( + 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv', + self.phase_info, + verbosity=1, + max_iter=50, + optimizer='SNOPT', + ) + + # self.assertTrue(prob.result.success) + compare_against_expected_values(prob, self.expected_dict) + + # This is one of the few places we test Height Energy + simple takeoff. + overall_fuel = prob.get_val(Mission.Summary.TOTAL_FUEL_MASS) + + # Making sure we include the fuel mass consumed in take-off and taxi. + self.assertGreater(overall_fuel, 40000.0) + + class TestBenchFwFmSerial(ProblemPhaseTestCase): """Run the model in serial that is setup in ProblemPhaseTestCase class.""" @require_pyoptsparse(optimizer='SNOPT') def test_bench_FwFm_SNOPT(self): prob = run_aviary( - 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv', + 'models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv', self.phase_info, verbosity=1, max_iter=50, @@ -218,6 +241,12 @@ def test_bench_FwFm_SNOPT(self): if __name__ == '__main__': # unittest.main() - test = TestBenchFwFmSerial() - test.setUp() - test.test_bench_FwFm_SNOPT() + test_bwb = True + if test_bwb: + test = TestBWBFwFmSerial() + test.setUp() + test.test_bwb_FwFm_SNOPT() + else: + test = TestBenchFwFmSerial() + test.setUp() + test.test_bench_FwFm_SNOPT() From ec1b682f0ffb0ad47f6ea1059698ebbb1b4ca229 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 14:02:04 -0500 Subject: [PATCH 27/68] if Aircraft.Design.TYPE is not in input, assume default AircraftTypes.TRANSPORT --- aviary/subsystems/aerodynamics/aerodynamics_builder.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index 69007339d..0172d7a43 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -494,7 +494,10 @@ def get_parameters(self, aviary_inputs=None, **kwargs): params[Aircraft.Design.LIFT_DEPENDENT_DRAG_POLAR] = opts if method == 'computed': - design_type = aviary_inputs.get_val(Aircraft.Design.TYPE) + try: + design_type = aviary_inputs.get_val(Aircraft.Design.TYPE) + except: + design_type = AircraftTypes.TRANSPORT if design_type is AircraftTypes.BLENDED_WING_BODY: core_inputs_computed = COMPUTED_CORE_INPUTS_BWB else: @@ -627,7 +630,10 @@ def get_parameters(self, aviary_inputs=None, **kwargs): 'tabular_cruise, low_speed, tabular_low_speed)' ) - design_type = aviary_inputs.get_val(Aircraft.Design.TYPE) + try: + design_type = aviary_inputs.get_val(Aircraft.Design.TYPE) + except: + design_type = AircraftTypes.TRANSPORT if design_type is AircraftTypes.BLENDED_WING_BODY: all_vars.add(Aircraft.Fuselage.LIFT_CURVE_SLOPE_MACH0) From 840f3cfa1f776a90a35face19b5706ad3decead2 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 14:02:53 -0500 Subject: [PATCH 28/68] add TODO. It is a question --- aviary/subsystems/geometry/flops_based/canard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aviary/subsystems/geometry/flops_based/canard.py b/aviary/subsystems/geometry/flops_based/canard.py index 40095d929..46bee4a1f 100644 --- a/aviary/subsystems/geometry/flops_based/canard.py +++ b/aviary/subsystems/geometry/flops_based/canard.py @@ -12,6 +12,7 @@ class Canard(om.ExplicitComponent): """Calculate the wetted area of canard.""" + # TODO: what is it for? def initialize(self): self.options.declare( 'aviary_options', From 8c2572e97bb8bbfedfb66e688d40d20c2d7dd22e Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 17:04:27 -0500 Subject: [PATCH 29/68] work in progress --- aviary/utils/fortran_to_aviary.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index 1ce416f23..2c90284ad 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -904,7 +904,10 @@ def update_flops_options(vehicle_data): if input_values.get_val(Aircraft.Fuel.WING_FUEL_CAPACITY, 'lbm')[0] < 50: # Interpret value equivalently to FWMAX = wing_fuel_fraction * fuel_density * 2/3 FWMAX = input_values.get_val(Aircraft.Fuel.WING_FUEL_CAPACITY, 'lbm')[0] - FULDEN = input_values.get_val(Aircraft.Fuel.DENSITY, 'lbm/ft**3')[0] + if Aircraft.Fuel.DENSITY in input_values: + FULDEN = input_values.get_val(Aircraft.Fuel.DENSITY, 'lbm/ft**3')[0] + else: + FULDEN = 50.12 # 50.12 lbm/ft**3 = 6.7 lbm/galUS input_values.set_val( Aircraft.Fuel.WING_FUEL_FRACTION, [FWMAX / (FULDEN * (2 / 3))], 'unitless' ) From 66925c2d6a73acd9392794c0ec5859dd41d289fc Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 18:05:10 -0500 Subject: [PATCH 30/68] remove mission:design:lift_coefficient from csv file --- aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 1 - aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 1 - 2 files changed, 2 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index e91e3c86a..105c4c780 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -152,7 +152,6 @@ aircraft:wing:var_sweep_mass_penalty,0.0,unitless aircraft:wing:wetted_area_scaler,1.0,unitless mission:constraints:max_mach,0.85,unitless mission:design:gross_mass,874099,lbm -mission:design:lift_coefficient,-1.0,unitless mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index f44c184c6..099e63e1c 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -151,7 +151,6 @@ aircraft:wing:var_sweep_mass_penalty,0.0,unitless aircraft:wing:wetted_area_scaler,1.0,unitless mission:constraints:max_mach,0.85,unitless mission:design:gross_mass,874099,lbm -mission:design:lift_coefficient,-1.0,unitless mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s From 88f22b73e6b85d48c4a2428941b9abc10781d089 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 18:05:40 -0500 Subject: [PATCH 31/68] work in progress --- .../benchmark_tests/test_bwb_Experiment_FwFm_1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py index ea2a65ab5..6bfff72c0 100644 --- a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py +++ b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py @@ -31,7 +31,7 @@ def test_bench_bwb_FwFm_SNOPT(self): 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv', local_phase_info, optimizer='SNOPT', - verbosity=0, + verbosity=1, max_iter=60, ) # prob.model.list_vars(units=True, print_arrays=True) From d87758e6cc949da2c51247f74c7f04d3462aa86e Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 19:00:39 -0500 Subject: [PATCH 32/68] smooth out int function --- aviary/subsystems/geometry/flops_based/fuselage.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aviary/subsystems/geometry/flops_based/fuselage.py b/aviary/subsystems/geometry/flops_based/fuselage.py index 68de29cf1..199678dda 100644 --- a/aviary/subsystems/geometry/flops_based/fuselage.py +++ b/aviary/subsystems/geometry/flops_based/fuselage.py @@ -480,7 +480,8 @@ def compute(self, inputs, outputs): # Enforce maximum number of bays num_bays_max = self.options[Aircraft.BWB.MAX_NUM_BAYS] - num_bays = int(0.5 + max_width.real / bay_width_max.real) + + num_bays = smooth_int_tanh(0.5 + max_width / bay_width_max, mu=20.0) if num_bays > num_bays_max and num_bays_max > 0: num_bays = num_bays_max outputs[Aircraft.BWB.NUM_BAYS] = smooth_int_tanh(num_bays, mu=20.0) @@ -659,7 +660,7 @@ def compute(self, inputs, outputs): # Enforce maximum number of bays z = 0.5 + max_width / bay_width_max z = z[0] - num_bays = int(z.real) + num_bays = smooth_int_tanh(z, mu=20.0) if num_bays > num_bays_max and num_bays_max > 0: num_bays = num_bays_max From 59de74b9f87636959e2e1dacca00a36adaa05eea Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 28 Jan 2026 22:48:04 -0500 Subject: [PATCH 33/68] roll back --- aviary/subsystems/geometry/flops_based/fuselage.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/aviary/subsystems/geometry/flops_based/fuselage.py b/aviary/subsystems/geometry/flops_based/fuselage.py index 199678dda..c5653a2d0 100644 --- a/aviary/subsystems/geometry/flops_based/fuselage.py +++ b/aviary/subsystems/geometry/flops_based/fuselage.py @@ -167,7 +167,7 @@ def compute(self, inputs, outputs): if verbosity > Verbosity.BRIEF: raise UserWarning( 'Passenger compartment lenght is longer than recommended maximum' - ' length (of 190 ft). Suggest using detailed layout algorithm.' + ' length. Suggest using detailed layout algorithm.' ) outputs[Aircraft.Fuselage.PASSENGER_COMPARTMENT_LENGTH] = pax_compart_length @@ -480,8 +480,7 @@ def compute(self, inputs, outputs): # Enforce maximum number of bays num_bays_max = self.options[Aircraft.BWB.MAX_NUM_BAYS] - - num_bays = smooth_int_tanh(0.5 + max_width / bay_width_max, mu=20.0) + num_bays = int(0.5 + max_width.real / bay_width_max.real) if num_bays > num_bays_max and num_bays_max > 0: num_bays = num_bays_max outputs[Aircraft.BWB.NUM_BAYS] = smooth_int_tanh(num_bays, mu=20.0) @@ -660,7 +659,7 @@ def compute(self, inputs, outputs): # Enforce maximum number of bays z = 0.5 + max_width / bay_width_max z = z[0] - num_bays = smooth_int_tanh(z, mu=20.0) + num_bays = int(z.real) if num_bays > num_bays_max and num_bays_max > 0: num_bays = num_bays_max From 849f7ad8d3bc82a83c60c568b66b2d04951b6b23 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 29 Jan 2026 13:30:18 -0500 Subject: [PATCH 34/68] lower tolerance for Aircraft.BWB.NUM_BAYS --- aviary/subsystems/test/test_flops_based_premission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/subsystems/test/test_flops_based_premission.py b/aviary/subsystems/test/test_flops_based_premission.py index 648e58885..04886134d 100644 --- a/aviary/subsystems/test/test_flops_based_premission.py +++ b/aviary/subsystems/test/test_flops_based_premission.py @@ -503,7 +503,7 @@ def test_case_geom(self): assert_near_equal(prob[Aircraft.Wing.ROOT_CHORD], 63.96, tol) assert_near_equal(prob[Aircraft.Fuselage.CABIN_AREA], 5173.187202504683, tol) assert_near_equal(prob[Aircraft.Fuselage.MAX_HEIGHT], 15.125, tol) - assert_near_equal(prob[Aircraft.BWB.NUM_BAYS], 5.0, tol) + assert_near_equal(prob[Aircraft.BWB.NUM_BAYS], 5.0, 1e-4) # BWBFuselagePrelim assert_near_equal(prob[Aircraft.Fuselage.REF_DIAMETER], 39.8525, tol) assert_near_equal(prob[Aircraft.Fuselage.PLANFORM_AREA], 7390.267432149546, tol) From dedfd72d6f9787337564233650dd2a81bbaa028e Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 29 Jan 2026 14:08:38 -0500 Subject: [PATCH 35/68] modify the computation of num_bays --- .../geometry/flops_based/fuselage.py | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/aviary/subsystems/geometry/flops_based/fuselage.py b/aviary/subsystems/geometry/flops_based/fuselage.py index c5653a2d0..ebfa5a8bb 100644 --- a/aviary/subsystems/geometry/flops_based/fuselage.py +++ b/aviary/subsystems/geometry/flops_based/fuselage.py @@ -480,8 +480,8 @@ def compute(self, inputs, outputs): # Enforce maximum number of bays num_bays_max = self.options[Aircraft.BWB.MAX_NUM_BAYS] - num_bays = int(0.5 + max_width.real / bay_width_max.real) - if num_bays > num_bays_max and num_bays_max > 0: + num_bays = int(0.5 + max_width / bay_width_max) + if num_bays.real > num_bays_max and num_bays_max > 0: num_bays = num_bays_max outputs[Aircraft.BWB.NUM_BAYS] = smooth_int_tanh(num_bays, mu=20.0) @@ -657,27 +657,30 @@ def compute(self, inputs, outputs): pax_compart_length = root_chord + tan_sweep * max_width / 2.0 # Enforce maximum number of bays - z = 0.5 + max_width / bay_width_max - z = z[0] - num_bays = int(z.real) - if num_bays > num_bays_max and num_bays_max > 0: + num_bays_tmp = 0.5 + max_width / bay_width_max + if num_bays_tmp[0].real > num_bays_max and num_bays_max > 0: num_bays = num_bays_max + else: + num_bays = int(num_bays_tmp[0].real) # Enforce maximum bay width bay_width = max_width / num_bays if bay_width > bay_width_max: bay_width = bay_width_max - num_bays = int(0.999 + max_width / bay_width) - if num_bays > num_bays_max and num_bays_max > 0: + num_bays_tmp = 0.999 + max_width / bay_width + if num_bays_tmp.real > num_bays_max and num_bays_max > 0: num_bays = num_bays_max max_width = bay_width_max * bay_width pax_compart_length = area_cabin / max_width + tan_sweep * max_width / 4.0 root_chord = pax_compart_length - tan_sweep * max_width / 2.0 + else: + num_bays = smooth_int_tanh(num_bays_tmp, mu=40.0) + # If number of bays has changed, recalculate cabin area length = pax_compart_length / rear_spar_percent_chord max_height = height_to_width * length - outputs[Aircraft.BWB.NUM_BAYS] = smooth_int_tanh(num_bays, mu=20.0) + outputs[Aircraft.BWB.NUM_BAYS] = num_bays outputs[Aircraft.Fuselage.LENGTH] = length outputs[Aircraft.Fuselage.PASSENGER_COMPARTMENT_LENGTH] = pax_compart_length From 858c4702c2bba22e032c480922827043186125f5 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 29 Jan 2026 14:09:33 -0500 Subject: [PATCH 36/68] modify function smooth_int_tanh() --- aviary/utils/math.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aviary/utils/math.py b/aviary/utils/math.py index 5c01de748..378184e98 100644 --- a/aviary/utils/math.py +++ b/aviary/utils/math.py @@ -215,7 +215,7 @@ def smooth_int_tanh(x, mu=10.0): """ Smooth approximation of int(x) using tanh. """ - f = np.floor(x) + f = np.floor(x.real) + x.imag * 1j frac = x - f t = np.tanh(mu * (frac - 0.5)) s = 0.5 * (t + 1) @@ -228,7 +228,7 @@ def d_smooth_int_tanh(x, mu=10.0): Smooth approximation of int(x) using tanh. Returns (y, dy_dx). """ - f = np.floor(x) + f = np.floor(x) + x.imag * 1j frac = x - f t = np.tanh(mu * (frac - 0.5)) dy_dx = 0.5 * mu * (1 - t**2) From 4387402db5a0bcabd0b3f41231b0ca0f213093c3 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 29 Jan 2026 14:10:52 -0500 Subject: [PATCH 37/68] remove test_bwb_Experiment_FwFm_2.py --- .../test_bwb_Experiment_FwFm_2.py | 252 ------------------ 1 file changed, 252 deletions(-) delete mode 100644 aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py b/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py deleted file mode 100644 index f24972bfb..000000000 --- a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_2.py +++ /dev/null @@ -1,252 +0,0 @@ -import unittest - -import numpy as np -from openmdao.core.problem import _clear_problem_names -from openmdao.utils.mpi import MPI -from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs - -from aviary.api import Mission -from aviary.interface.methods_for_level1 import run_aviary -from aviary.validation_cases.benchmark_utils import compare_against_expected_values - -try: - from openmdao.vectors.petsc_vector import PETScVector -except ImportError: - PETScVector = None - - -@use_tempdirs -class ProblemPhaseTestCase(unittest.TestCase): - """ - Setup of a BWB aircraft using - FLOPS mass and aero method and HEIGHT_ENERGY mission method. Expected outputs based - on 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv' model. - """ - - def setUp(self): - expected_dict = {} - - # block auto-formatting of tables - # fmt: off - expected_dict['times'] = np.array( - [ - [120.],[163.76268404], [224.14625594], [243.25744998], [243.25744998], - [336.40804126], [464.93684491], [505.61577182], [505.61577182], [626.46953842], - [793.22306972], [845.99999224], [845.99999224], [966.85375884], [1133.60729014], - [1186.38421266], [1186.38421266], [1279.53480393], [1408.06360758], [1448.74253449], - [1448.74253449], [1492.50521853], [1552.88879042], [1571.99998447], [1571.99998447], - [10224.87383109], [22164.07366288], [25942.78958866], [25942.78958866], - [26009.11685074], [26100.63493484], [26129.60009555], [26129.60009555], - [26265.05921709], [26451.96515722], [26511.12024823], [26511.12024823], - [26672.16774132], [26894.38041154], [26964.7099619], [26964.7099619], - [27100.16908344], [27287.07502357], [27346.23011458], [27346.23011458], - [27412.55737667], [27504.07546076], [27533.04062147] - ] - ) - - expected_dict['altitudes'] = np.array( - [ - [10.668], [0.], [1001.70617719], [1429.27176545], [1429.27176545], [3413.27102762], - [5642.3831233], [6169.75300447], [6169.75300447], [7399.140983], [8514.78661356], - [8803.21405264], [8803.21405264], [9373.68426297], [10020.99237958], - [10196.42552457], [10196.42552457],[10451.72258036], [10652.38789684], [10668.], - [10668.], [10660.42246376], [10656.16585151], [10668.], [10668.], [10668.], - [10668.], [10668.], [10668.], [10668.], [10142.11478951], [9922.15743555], - [9922.15743555], [8891.66886638], [7502.1861348], [7069.1900852], [7069.1900852], - [5896.44637998], [4264.29354306], [3737.8471594], [3737.8471594], [2702.15624637], - [1248.18960736], [793.03526817], [793.03526817], [345.06939295], [10.668], [10.668] - ] - ) - - expected_dict['masses'] = np.array( - [ - [79303.30184763], [79221.39668215], [79075.19453181], [79028.6003426], - [79028.6003426], [78828.82221909], [78613.60466821], [78557.84739563], - [78557.84739563], [78411.06578989], [78238.0916773], [78186.75440341], - [78186.75440341], [78077.23953313], [77938.37965175], [77896.59718975], - [77896.59718975], [77825.81832958], [77732.75016916], [77704.11629998], - [77704.11629998], [77673.32196072], [77630.75735319], [77617.25716885], - [77617.25716885], [72178.78521803], [65072.41395049], [62903.84179505], - [62903.84179505], [62896.27636813], [62888.3612195], [62885.93748938], - [62885.93748938], [62874.48788511], [62857.70600096], [62852.13740881], - [62852.13740881], [62835.97069937], [62810.37776063], [62801.1924259], - [62801.1924259], [62781.32471014], [62748.91017128], [62737.32520462], - [62737.32520462], [62723.59895849], [62703.94977811], [62697.71513264] - ] - ) - - expected_dict['ranges'] = np.array( - [ - [1452.84514351], [6093.51223933], [15820.03029119], [19123.61258676], - [19123.61258676], [36374.65336952], [61265.3984918], [69106.49687132], - [69106.49687132], [92828.04820577], [126824.13801408], [138011.02420534], - [138011.02420534], [164027.18014424], [200524.66550565], [212113.49107256], - [212113.49107256], [232622.50720766], [261189.53466522], [270353.40501262], - [270353.40501262], [280350.48472685], [294356.27080588], [298832.61221641], - [298832.61221641], [2325837.11255987], [5122689.60556392], [6007883.85695889], - [6007883.85695889], [6022237.43153219], [6039575.06318219], [6044873.89820027], - [6044873.89820027], [6068553.1921364], [6099290.23732297], [6108673.67260778], - [6108673.67260778], [6133535.09572671], [6166722.19545137], [6177077.72115854], - [6177077.72115854], [6197011.1330154], [6224357.63792683], [6232920.45309764], - [6232920.45309764], [6242332.46480721], [6254144.50957549], [6257352.4] - ] - ) - - expected_dict['velocities'] = np.array( - [ - [69.30879167], [137.49019035], [174.54683946], [179.28863383], [179.28863383], - [191.76748742], [194.33322917], [194.52960387], [194.52960387], [199.01184603], - [209.81696863], [212.86546124], [212.86546124], [217.37467051], [219.67762167], - [219.97194272], [219.97194272], [220.67963782], [224.38113484], [226.77184704], - [226.77184704], [230.01128033], [233.72454583], [234.25795132], [234.25795132], - [234.25795132], [234.25795132], [234.25795132], [234.25795132], [201.23881], - [182.84158341], [180.10650108], [180.10650108], [169.77497514], [159.59034446], - [157.09907013], [157.09907013], [151.659491], [147.52098882], [147.07683999], - [147.07683999], [147.05392009], [145.31556891], [143.47446173], [143.47446173], - [138.99109332], [116.22447082], [102.07377559] - ] - ) - # fmt: on - - self.expected_dict = expected_dict - - phase_info = { - 'pre_mission': {'include_takeoff': True, 'optimize_mass': True}, - 'climb': { - 'subsystem_options': {'aerodynamics': {'method': 'computed'}}, - 'user_options': { - 'num_segments': 6, - 'order': 3, - 'mach_bounds': ((0.1, 0.8), 'unitless'), - 'mach_optimize': True, - 'altitude_bounds': ((0.0, 35000.0), 'ft'), - 'altitude_optimize': True, - 'throttle_enforcement': 'path_constraint', - 'mass_ref': (200000, 'lbm'), - 'time_initial': (0.0, 'min'), - 'time_duration_bounds': ((20.0, 60.0), 'min'), - 'no_descent': True, - }, - 'initial_guesses': { - 'time': ([0, 40.0], 'min'), - 'altitude': ([35, 35000.0], 'ft'), - 'mach': ([0.3, 0.79], 'unitless'), - }, - }, - 'cruise': { - 'subsystem_options': {'aerodynamics': {'method': 'computed'}}, - 'user_options': { - 'num_segments': 1, - 'order': 3, - 'mach_initial': (0.79, 'unitless'), - 'mach_bounds': ((0.79, 0.79), 'unitless'), - 'mach_optimize': True, - 'mach_polynomial_order': 1, - 'altitude_initial': (35000.0, 'ft'), - 'altitude_bounds': ((35000.0, 35000.0), 'ft'), - 'altitude_optimize': True, - 'altitude_polynomial_order': 1, - 'throttle_enforcement': 'boundary_constraint', - 'mass_ref': (200000, 'lbm'), - 'time_initial_bounds': ((20.0, 60.0), 'min'), - 'time_duration_bounds': ((60.0, 720.0), 'min'), - }, - 'initial_guesses': { - 'time': ([40, 200], 'min'), - 'altitude': ([35000, 35000.0], 'ft'), - 'mach': ([0.79, 0.79], 'unitless'), - }, - }, - 'descent': { - 'subsystem_options': {'aerodynamics': {'method': 'computed'}}, - 'user_options': { - 'num_segments': 5, - 'order': 3, - 'mach_initial': (0.79, 'unitless'), - 'mach_final': (0.3, 'unitless'), - 'mach_bounds': ((0.2, 0.8), 'unitless'), - 'mach_optimize': True, - 'altitude_initial': (35000.0, 'ft'), - 'altitude_final': (35.0, 'ft'), - 'altitude_bounds': ((0.0, 35000.0), 'ft'), - 'altitude_optimize': True, - 'throttle_enforcement': 'path_constraint', - 'mass_ref': (200000, 'lbm'), - 'distance_ref': (3375, 'nmi'), - 'time_initial_bounds': ((80.0, 780.0), 'min'), - 'time_duration_bounds': ((5.0, 45.0), 'min'), - 'no_climb': True, - }, - 'initial_guesses': { - 'time': ([240, 30], 'min'), - }, - }, - 'post_mission': { - 'include_landing': True, - 'constrain_range': True, - 'target_range': (3375.0, 'nmi'), - }, - } - - self.phase_info = phase_info - - _clear_problem_names() # need to reset these to simulate separate runs - - -class TestBWBFwFmSerial(ProblemPhaseTestCase): - """Run the model in serial that is setup in ProblemPhaseTestCase class.""" - - @require_pyoptsparse(optimizer='SNOPT') - def test_bwb_FwFm_SNOPT(self): - prob = run_aviary( - 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv', - self.phase_info, - verbosity=1, - max_iter=50, - optimizer='SNOPT', - ) - - # self.assertTrue(prob.result.success) - compare_against_expected_values(prob, self.expected_dict) - - # This is one of the few places we test Height Energy + simple takeoff. - overall_fuel = prob.get_val(Mission.Summary.TOTAL_FUEL_MASS) - - # Making sure we include the fuel mass consumed in take-off and taxi. - self.assertGreater(overall_fuel, 40000.0) - - -class TestBenchFwFmSerial(ProblemPhaseTestCase): - """Run the model in serial that is setup in ProblemPhaseTestCase class.""" - - @require_pyoptsparse(optimizer='SNOPT') - def test_bench_FwFm_SNOPT(self): - prob = run_aviary( - 'models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv', - self.phase_info, - verbosity=1, - max_iter=50, - optimizer='SNOPT', - ) - - # self.assertTrue(prob.result.success) - compare_against_expected_values(prob, self.expected_dict) - - # This is one of the few places we test Height Energy + simple takeoff. - overall_fuel = prob.get_val(Mission.Summary.TOTAL_FUEL_MASS) - - # Making sure we include the fuel mass consumed in take-off and taxi. - self.assertGreater(overall_fuel, 40000.0) - - -if __name__ == '__main__': - # unittest.main() - test_bwb = True - if test_bwb: - test = TestBWBFwFmSerial() - test.setUp() - test.test_bwb_FwFm_SNOPT() - else: - test = TestBenchFwFmSerial() - test.setUp() - test.test_bench_FwFm_SNOPT() From 27a3972d4b22a3fbd0df66d8d6ac67aa3845b029 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 29 Jan 2026 14:13:17 -0500 Subject: [PATCH 38/68] rename test_bwb_Experiment_FwFm_1.py to test_bwb_FwFm.py --- .../{test_bwb_Experiment_FwFm_1.py => test_bwb_FwFm.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename aviary/validation_cases/benchmark_tests/{test_bwb_Experiment_FwFm_1.py => test_bwb_FwFm.py} (100%) diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py b/aviary/validation_cases/benchmark_tests/test_bwb_FwFm.py similarity index 100% rename from aviary/validation_cases/benchmark_tests/test_bwb_Experiment_FwFm_1.py rename to aviary/validation_cases/benchmark_tests/test_bwb_FwFm.py From fcb6723e87cbdc7e1a98ba17eb4d37ca6068c4a2 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 29 Jan 2026 20:11:48 -0500 Subject: [PATCH 39/68] roll back ground_effect.py --- .../aerodynamics/flops_based/ground_effect.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/aviary/subsystems/aerodynamics/flops_based/ground_effect.py b/aviary/subsystems/aerodynamics/flops_based/ground_effect.py index 4b8c04d4f..5eca2ce12 100644 --- a/aviary/subsystems/aerodynamics/flops_based/ground_effect.py +++ b/aviary/subsystems/aerodynamics/flops_based/ground_effect.py @@ -11,9 +11,8 @@ import numpy as np import openmdao.api as om -from aviary.variable_info.enums import Verbosity -from aviary.variable_info.functions import add_aviary_input, add_aviary_option -from aviary.variable_info.variables import Aircraft, Dynamic, Settings +from aviary.variable_info.functions import add_aviary_input +from aviary.variable_info.variables import Aircraft, Dynamic class GroundEffect(om.ExplicitComponent): @@ -30,7 +29,6 @@ class GroundEffect(om.ExplicitComponent): def initialize(self): options = self.options - add_aviary_option(self, Settings.VERBOSITY) options.declare('num_nodes', default=1, types=int, lower=0) options.declare( @@ -140,7 +138,6 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): options = self.options ground_altitude = options['ground_altitude'] - verbosity = self.options[Settings.VERBOSITY] angle_of_attack = inputs[Dynamic.Vehicle.ANGLE_OF_ATTACK] altitude = inputs[Dynamic.Mission.ALTITUDE] @@ -151,9 +148,6 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): aspect_ratio = inputs[Aircraft.Wing.ASPECT_RATIO] height = inputs[Aircraft.Wing.HEIGHT] span = inputs[Aircraft.Wing.SPAN] - if span <= 0.0: - if verbosity > Verbosity.BRIEF: - raise UserWarning('Aircraft.Wing.SPAN is not positive.') ground_effect_state = ((altitude - ground_altitude) + height) / span height_factor = np.ones_like(ground_effect_state) @@ -170,9 +164,6 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): + 4.0 * ground_effect_state * aspect_ratio_term * np.sqrt(ground_effect_term0) ) - if lift_coeff_factor_denom <= 0.0: - if verbosity > Verbosity.BRIEF: - raise UserWarning('lift_coeff_factor_denom is not positive.') lift_coeff_factor = 1.0 + height_factor / lift_coeff_factor_denom lift_coefficient = base_lift_coefficient * lift_coeff_factor @@ -184,9 +175,6 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): 4.0 * ground_effect_state * np.sqrt(ground_effect_term1) + ground_effect_term1 ) - if drag_coeff_factor_denom <= 0.0: - if verbosity > Verbosity.BRIEF: - raise UserWarning('drag_coeff_factor_denom is not positive.') drag_coeff_factor = 1.0 - height_factor / drag_coeff_factor_denom drag_coefficient = ( From 57df4f51e287654b49d7fa5f7f03fbc8cf381cbf Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 29 Jan 2026 20:13:30 -0500 Subject: [PATCH 40/68] minor update --- aviary/subsystems/aerodynamics/flops_based/skin_friction.py | 5 ++--- .../aerodynamics/flops_based/skin_friction_drag.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py index e226d161b..0cf9fb870 100644 --- a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py +++ b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py @@ -51,10 +51,9 @@ def setup(self): if design_type is AircraftTypes.BLENDED_WING_BODY: # No horizontal tail for BWB - nc = 1 + num_tails + num_fuselages + int(sum(num_engines)) + self.nc = nc = 1 + num_tails + num_fuselages + int(sum(num_engines)) else: - nc = 2 + num_tails + num_fuselages + int(sum(num_engines)) - self.nc = nc + self.nc = nc = 2 + num_tails + num_fuselages + int(sum(num_engines)) # Simulation inputs add_aviary_input(self, Dynamic.Atmosphere.TEMPERATURE, shape=nn, units='degR') diff --git a/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py b/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py index e30ada57f..284cc12e4 100644 --- a/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py @@ -57,10 +57,9 @@ def setup(self): if design_type is AircraftTypes.BLENDED_WING_BODY: # No horizontal tail for BWB - nc = 1 + nvtail + nfuse + int(sum(num_engines)) + self.nc = nc = 1 + nvtail + nfuse + int(sum(num_engines)) else: - nc = 2 + nvtail + nfuse + int(sum(num_engines)) - self.nc = nc + self.nc = nc = 2 + nvtail + nfuse + int(sum(num_engines)) # Computed by other components in drag group. self.add_input('skin_friction_coeff', np.zeros((nn, nc)), units='unitless') From 4d83c89f5319fedca6ea86e3e5052e9be3126585 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 2 Feb 2026 12:52:14 -0500 Subject: [PATCH 41/68] work in progress: updating based on Chris' comments --- aviary/utils/fortran_to_aviary.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index 2c90284ad..bc4575350 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -946,7 +946,7 @@ def update_flops_options(vehicle_data): input_values.set_val(Aircraft.Wing.THICKNESS_TO_CHORD_DIST, thickness_to_chord_dist) input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [True]) else: - # If detail wing is not provided, initialize it to [0, 0.5, 1] + # For BWB, if detail wing is not provided, initialize it to [0, 0.5, 1]. See doc page for detail. input_values.set_val(Aircraft.BWB.DETAILED_WING_PROVIDED, [False]) input_values.set_val(Aircraft.Wing.INPUT_STATION_DIST, [0.0, 0.5, 1.0]) @@ -1009,6 +1009,10 @@ def update_flops_options(vehicle_data): input_values.set_val( Aircraft.Engine.SCALE_FACTOR, [engine_scale_factor], 'unitless' ) + else: + raise RuntimeError( + f'Currently, Aircraft.Design.TYPE must be either 0 or 3 not {design_type[0]}.' + ) if Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS in input_values: num_business_class = input_values.get_val( @@ -1107,7 +1111,6 @@ def update_aviary_options(vehicle_data): """Special handling for variables that occurs for either legacy code.""" input_values: NamedValues = vehicle_data['input_values'] - # if reference + scaled thrust both provided, set scale factor -- Is this comment still true? try: ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[0] ref_thrust = float(ref_thrust) From e5507fda5d6a79acad64b55cac2b580bc43c08bd Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 2 Feb 2026 13:03:53 -0500 Subject: [PATCH 42/68] merge Ken's work --- .../blended_wing_body/bwb_detailed_FLOPS.csv | 6 + .../blended_wing_body/bwb_simple_FLOPS.csv | 6 + .../geometry/flops_based/wing_detailed_bwb.py | 2 +- .../benchmark_tests/test_bwb_FwFm.py | 140 +++++++++--------- 4 files changed, 87 insertions(+), 67 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index 105c4c780..eabd6ff90 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -41,6 +41,12 @@ aircraft:design:empty_mass_margin_scaler,0.0,unitless aircraft:design:landing_to_takeoff_mass_ratio,0.8,unitless aircraft:design:lift_dependent_drag_coeff_factor,1.0,unitless aircraft:design:subsonic_drag_coeff_factor,1.0,unitless + +# TODO: Needed to reduce the drag so that engine wasn't full throttle in cruise. +# There must be something about drag that still isn't working for BWB. +aircraft:design:subsonic_drag_coeff_factor,0.7,unitless +# aircraft:design:subsonic_drag_coeff_factor,1.0,unitless + aircraft:design:supersonic_drag_coeff_factor,1.0,unitless aircraft:design:type,BWB,unitless aircraft:design:use_alt_mass,False,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index 099e63e1c..46d09ce21 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -41,6 +41,12 @@ aircraft:design:empty_mass_margin_scaler,0.0,unitless aircraft:design:landing_to_takeoff_mass_ratio,0.8,unitless aircraft:design:lift_dependent_drag_coeff_factor,1.0,unitless aircraft:design:subsonic_drag_coeff_factor,1.0,unitless + +# TODO: Needed to reduce the drag so that engine wasn't full throttle in cruise. +# There must be something about drag that still isn't working for BWB. +aircraft:design:subsonic_drag_coeff_factor,0.7,unitless +# aircraft:design:subsonic_drag_coeff_factor,1.0,unitless + aircraft:design:supersonic_drag_coeff_factor,1.0,unitless aircraft:design:type,BWB,unitless aircraft:design:use_alt_mass,False,unitless diff --git a/aviary/subsystems/geometry/flops_based/wing_detailed_bwb.py b/aviary/subsystems/geometry/flops_based/wing_detailed_bwb.py index 62e37e64c..f00c81ede 100644 --- a/aviary/subsystems/geometry/flops_based/wing_detailed_bwb.py +++ b/aviary/subsystems/geometry/flops_based/wing_detailed_bwb.py @@ -397,7 +397,7 @@ def compute(self, inputs, outputs): # This part is repeated in _BWBWing() num_inp_stations = len(self.options[Aircraft.Wing.INPUT_STATION_DIST]) bwb_input_station_dist = np.array( - self.options[Aircraft.Wing.INPUT_STATION_DIST], dtype=float + self.options[Aircraft.Wing.INPUT_STATION_DIST], dtype=width.dtype ) bwb_input_station_dist = np.where( bwb_input_station_dist <= 1.0, diff --git a/aviary/validation_cases/benchmark_tests/test_bwb_FwFm.py b/aviary/validation_cases/benchmark_tests/test_bwb_FwFm.py index 6bfff72c0..b5d7be0e0 100644 --- a/aviary/validation_cases/benchmark_tests/test_bwb_FwFm.py +++ b/aviary/validation_cases/benchmark_tests/test_bwb_FwFm.py @@ -5,13 +5,83 @@ from openmdao.utils.assert_utils import assert_near_equal from openmdao.utils.testing_utils import require_pyoptsparse, use_tempdirs -from aviary.models.aircraft.large_turboprop_freighter.phase_info import ( - energy_phase_info as phase_info, -) - from aviary.interface.methods_for_level1 import run_aviary from aviary.variable_info.variables import Mission +phase_info = { + 'pre_mission': {'include_takeoff': False, 'optimize_mass': True}, + 'climb': { + 'subsystem_options': {'core_aerodynamics': {'method': 'cruise', 'solve_alpha': 'true'}}, + 'user_options': { + 'num_segments': 5, + 'order': 3, + 'mach_optimize': True, + 'mach_initial': (0.3, 'unitless'), + 'mach_bounds': ((0.3, 0.85), 'unitless'), + 'altitude_optimize': True, + 'altitude_initial': (500.0, 'ft'), + 'altitude_bounds': ((500.0, 35000.0), 'ft'), + 'no_descent': True, + 'mass_ref': (875000, 'lbm'), + 'throttle_enforcement': 'control', + 'time_initial_bounds': ((0.0, 0.0), 'min'), + 'time_duration_bounds': ((24.0, 90.0), 'min'), + }, + 'initial_guesses': { + 'altitude': ([500.5, 35000.0], 'ft'), + 'mach': ([0.3, 0.85], 'unitless'), + }, + }, + 'cruise': { + 'subsystem_options': {'core_aerodynamics': {'method': 'cruise', 'solve_alpha': 'true'}}, + 'user_options': { + 'num_segments': 5, + 'order': 3, + 'mach_optimize': False, + 'mach_initial': (0.85, 'unitless'), + 'mach_bounds': ((0.85, 0.85), 'unitless'), + 'altitude_optimize': False, + 'altitude_initial': (35000.0, 'ft'), + 'altitude_bounds': ((35000.0, 43000.0), 'ft'), + 'mass_ref': (875000, 'lbm'), + 'distance_ref': (7750, 'nmi'), + 'throttle_enforcement': 'control', + 'time_initial_bounds': ((24.0, 180.0), 'min'), + 'time_duration_bounds': ((10.0, 19.0), 'h'), + }, + 'initial_guesses': { + 'altitude': ([35000, 42000.0], 'ft'), + 'mach': ([0.85, 0.85], 'unitless'), + }, + }, + 'descent': { + 'subsystem_options': {'core_aerodynamics': {'method': 'cruise', 'solve_alpha': 'true'}}, + 'user_options': { + 'num_segments': 5, + 'order': 3, + 'mach_optimize': True, + 'mach_initial': (0.85, 'unitless'), + 'mach_final': (0.2, 'unitless'), + 'mach_bounds': ((0.2, 0.85), 'unitless'), + 'altitude_optimize': True, + 'altitude_initial': (42000.0, 'ft'), + 'altitude_final': (500.0, 'ft'), + 'altitude_bounds': ((500.0, 42000.0), 'ft'), + 'mass_ref': (875000, 'lbm'), + 'distance_ref': (7750, 'nmi'), + 'no_climb': True, + 'throttle_enforcement': 'control', + 'time_initial_bounds': ((10, 19.0), 'h'), + 'time_duration_bounds': ((0.15, 1.0), 'h'), + }, + }, + 'post_mission': { + 'include_landing': False, + 'constrain_range': True, + 'target_range': (7750.0, 'nmi'), + }, +} + # @use_tempdirs class BWBProblemPhaseTestCase(unittest.TestCase): @@ -75,68 +145,6 @@ def test_bench_bwb_FwFm_SNOPT(self): ) -class ProblemPhaseTestCase(unittest.TestCase): - """ - Test the setup and run of a test aircraft using FLOPS mass and aero method - and HEIGHT_ENERGY mission method. Expected outputs based on - 'models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv' model. - """ - - def setUp(self): - _clear_problem_names() # need to reset these to simulate separate runs - - @require_pyoptsparse(optimizer='SNOPT') - def test_bench_FwFm_SNOPT(self): - local_phase_info = deepcopy(phase_info) - prob = run_aviary( - 'models/aircraft/test_aircraft/aircraft_for_bench_FwFm.csv', - local_phase_info, - optimizer='SNOPT', - verbosity=0, - max_iter=60, - ) - # prob.list_indep_vars() - # prob.list_problem_vars() - # prob.model.list_outputs() - - # self.assertTrue(prob.result.success) - - rtol = 1e-3 - - # There are no truth values for these. - assert_near_equal( - prob.get_val(Mission.Design.GROSS_MASS, units='lbm'), - 169804.16225263, - tolerance=rtol, - ) - - assert_near_equal( - prob.get_val(Mission.Summary.OPERATING_MASS, units='lbm'), - 97096.89284117, - tolerance=rtol, - ) - - assert_near_equal( - prob.get_val(Mission.Summary.TOTAL_FUEL_MASS, units='lbm'), - 34682.26941131, - tolerance=rtol, - ) - - assert_near_equal(prob.get_val(Mission.Summary.RANGE, units='NM'), 2020.0, tolerance=rtol) - - assert_near_equal( - prob.get_val(Mission.Landing.GROUND_DISTANCE, units='ft'), - 2216.0066613, - tolerance=rtol, - ) - - assert_near_equal( - prob.get_val(Mission.Landing.TOUCHDOWN_MASS, units='lbm'), - 116003.31044998, - tolerance=rtol, - ) - - if __name__ == '__main__': # unittest.main() test = BWBProblemPhaseTestCase() From ea7cea50d605a578fee6de80e211f5e520ebc745 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 2 Feb 2026 13:38:53 -0500 Subject: [PATCH 43/68] add a comment that remove_preprocessed_options is not used --- aviary/utils/preprocessors.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index 26c4b3693..700d0d7aa 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -50,6 +50,7 @@ def preprocess_options(aviary_options: AviaryValues, meta_data=_MetaData, verbos preprocess_propulsion(aviary_options, engine_models, meta_data, verbosity) +# this function is not used def remove_preprocessed_options(aviary_options): """ Remove options whose values will be computed in the preprocessors. From bdd8b0c6441fb737682ef10bff6ca1f06dc414d5 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 2 Feb 2026 17:19:50 -0500 Subject: [PATCH 44/68] move Aircraft.Engine.NUM_ENGINES from fortran_to_aviary.py to preprocessors.py --- aviary/utils/fortran_to_aviary.py | 23 ++++++--------- aviary/utils/preprocessors.py | 47 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index bc4575350..5b2e27dcc 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -917,6 +917,15 @@ def update_flops_options(vehicle_data): if Aircraft.Wing.INPUT_STATION_DIST in input_values: input_values.set_val(Aircraft.Wing.DETAILED_WING, [True]) + if not Mission.Landing.LIFT_COEFFICIENT_MAX in input_values: + unused_values = vehicle_data['unused_values'] + try: + CLAPP = unused_values.get_item('TOLIN.CLAPP')[0][0] + CLLDM = 1.69 * CLAPP + except: + CLLDM = 3.0 + input_values.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, [CLLDM]) + design_type, design_units = input_values.get_item(Aircraft.Design.TYPE) if design_type[0] == 0: input_values.set_val(Aircraft.Design.TYPE, ['transport'], design_units) @@ -1042,20 +1051,6 @@ def update_flops_options(vehicle_data): num_galley_crew = int(num_passengers / 250) + 1 input_values.set_val(Aircraft.CrewPayload.NUM_GALLEY_CREW, [num_galley_crew]) - if not Aircraft.Engine.NUM_ENGINES in input_values: - if Aircraft.Engine.NUM_FUSELAGE_ENGINES in input_values: - num_fuselage_engines = input_values.get_val( - Aircraft.Engine.NUM_FUSELAGE_ENGINES, 'unitless' - )[0] - else: - num_fuselage_engines = 0 - if Aircraft.Engine.NUM_WING_ENGINES in input_values: - num_wing_engines = input_values.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless')[0] - else: - num_wing_engines = 0 - num_engines = num_fuselage_engines + num_wing_engines - input_values.set_val(Aircraft.Engine.NUM_ENGINES, [num_engines]) - if not Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER in input_values: if Mission.Design.RANGE in input_values: design_range = input_values.get_val(Mission.Design.RANGE, 'nmi')[0] diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index 700d0d7aa..44dfb4e3f 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -45,6 +45,7 @@ def preprocess_options(aviary_options: AviaryValues, meta_data=_MetaData, verbos preprocess_crewpayload(aviary_options, meta_data, verbosity) preprocess_fuel_capacities(aviary_options, verbosity) + preprocess_Engines(aviary_options, verbosity) if engine_models is not None: preprocess_propulsion(aviary_options, engine_models, meta_data, verbosity) @@ -531,6 +532,52 @@ def preprocess_fuel_capacities(aviary_options: AviaryValues, verbosity=None): return aviary_options +def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): + """ + Preprocesses the AviaryValues object to ensure the number of engines is + the sum of wing engines and body engines. + + Parameters + ---------- + aviary_options : AviaryValues + Options to be updated + + """ + if verbosity is not None: + # compatibility with being passed int for verbosity + verbosity = Verbosity(verbosity) + else: + verbosity = aviary_options.get_val(Settings.VERBOSITY) + + if Aircraft.Engine.NUM_FUSELAGE_ENGINES in aviary_options: + num_fuselage_engines = aviary_options.get_val( + Aircraft.Engine.NUM_FUSELAGE_ENGINES, 'unitless' + ) + else: + num_fuselage_engines = [0] + + if Aircraft.Engine.NUM_WING_ENGINES in aviary_options: + num_wing_engines = aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless') + else: + num_wing_engines = [0] + tot_engines = num_fuselage_engines + num_wing_engines + + if Aircraft.Engine.NUM_ENGINES in aviary_options: + num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + if num_engines == tot_engines: + pass + else: + raise UserWarning( + 'Your total number of engines is not the same as ' + 'the sum of wing engines and fuselage engines.' + ) + else: + num_engines = tot_engines + aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, num_engines) + + return aviary_options + + def preprocess_propulsion( aviary_options: AviaryValues, engine_models: list = None, From d2bad18842ed7efaea8e41d991611df8fe94c1c8 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 2 Feb 2026 19:09:25 -0500 Subject: [PATCH 45/68] remove aircraft:engine:num_engines becuase it will be handled in preprocess --- aviary/utils/test/data/converter_test_N3CC_FLOPS.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv b/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv index 80b537dc3..3d6b93ba8 100644 --- a/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv +++ b/aviary/utils/test/data/converter_test_N3CC_FLOPS.csv @@ -43,7 +43,6 @@ aircraft:engine:generate_flight_idle,True,unitless aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:mass_scaler,1.15,unitless -aircraft:engine:num_engines,2,unitless aircraft:engine:num_fuselage_engines,0,unitless aircraft:engine:num_wing_engines,2,unitless aircraft:engine:reference_mass,6293.8,lbm From a23b7da99b676668cc668e22636c3d14f3f416f7 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 2 Feb 2026 19:24:30 -0500 Subject: [PATCH 46/68] minor update --- aviary/utils/preprocessors.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index 44dfb4e3f..24dc1bc92 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -552,19 +552,19 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): if Aircraft.Engine.NUM_FUSELAGE_ENGINES in aviary_options: num_fuselage_engines = aviary_options.get_val( Aircraft.Engine.NUM_FUSELAGE_ENGINES, 'unitless' - ) + )[0] else: - num_fuselage_engines = [0] + num_fuselage_engines = 0 if Aircraft.Engine.NUM_WING_ENGINES in aviary_options: - num_wing_engines = aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless') + num_wing_engines = aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless')[0] else: - num_wing_engines = [0] - tot_engines = num_fuselage_engines + num_wing_engines + num_wing_engines = 0 + sum_engines = num_fuselage_engines + num_wing_engines if Aircraft.Engine.NUM_ENGINES in aviary_options: - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) - if num_engines == tot_engines: + num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)[0] + if num_engines == sum_engines: pass else: raise UserWarning( @@ -572,8 +572,8 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): 'the sum of wing engines and fuselage engines.' ) else: - num_engines = tot_engines - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, num_engines) + num_engines = sum_engines + aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, [num_engines]) return aviary_options From a726132ea5c3fe387daf8f865ab736277a548f4d Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Mon, 2 Feb 2026 20:48:14 -0500 Subject: [PATCH 47/68] deal with int in preprocess_Engines --- aviary/utils/preprocessors.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index 24dc1bc92..d7ab4e4a6 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -552,21 +552,31 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): if Aircraft.Engine.NUM_FUSELAGE_ENGINES in aviary_options: num_fuselage_engines = aviary_options.get_val( Aircraft.Engine.NUM_FUSELAGE_ENGINES, 'unitless' - )[0] + ) + if isinstance(num_fuselage_engines, np.ndarray): + num_fuselage_engines = num_fuselage_engines[0] + else: + num_fuselage_engines = int(num_fuselage_engines) else: num_fuselage_engines = 0 if Aircraft.Engine.NUM_WING_ENGINES in aviary_options: - num_wing_engines = aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless')[0] + num_wing_engines = aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless') + if isinstance(num_wing_engines, np.ndarray): + num_wing_engines = num_wing_engines[0] + else: + num_wing_engines = int(num_wing_engines) else: num_wing_engines = 0 sum_engines = num_fuselage_engines + num_wing_engines if Aircraft.Engine.NUM_ENGINES in aviary_options: - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)[0] - if num_engines == sum_engines: - pass + num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + if isinstance(num_engines, np.ndarray): + num_engines = num_engines[0] else: + num_engines = int(num_engines) + if num_engines != sum_engines: raise UserWarning( 'Your total number of engines is not the same as ' 'the sum of wing engines and fuselage engines.' From ffe4e503db278dd8f706123a982cba515e0c9164 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 3 Feb 2026 00:38:19 -0500 Subject: [PATCH 48/68] preprocess_Engines() does not work. comment it out --- aviary/utils/preprocessors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index d7ab4e4a6..29ab27427 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -45,7 +45,7 @@ def preprocess_options(aviary_options: AviaryValues, meta_data=_MetaData, verbos preprocess_crewpayload(aviary_options, meta_data, verbosity) preprocess_fuel_capacities(aviary_options, verbosity) - preprocess_Engines(aviary_options, verbosity) + # preprocess_Engines(aviary_options, verbosity) if engine_models is not None: preprocess_propulsion(aviary_options, engine_models, meta_data, verbosity) From ac219d5123605228e5a0f8607b2a9e2bcb08c2cd Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 3 Feb 2026 11:21:19 -0500 Subject: [PATCH 49/68] changed a comment --- aviary/utils/fortran_to_aviary.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index 5b2e27dcc..26d8f2c82 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -974,8 +974,7 @@ def update_flops_options(vehicle_data): input_values.set_val(Aircraft.Fuselage.SIMPLE_LAYOUT, [False], 'unitless') if Aircraft.Engine.SCALED_SLS_THRUST in input_values: - # not sure why THRUST=70000,1,0,0,0,0, just grab the first entry - # does it apply to transporters? + # This is a design variable. So, first entry is the initial value thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[0] input_values.set_val(Aircraft.Engine.SCALED_SLS_THRUST, [thrust], 'lbf') From 64596f847008e35a2e9dc9721ea1ae28fd54035a Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 3 Feb 2026 21:20:49 -0500 Subject: [PATCH 50/68] testing --- aviary/utils/preprocessors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index 29ab27427..d7ab4e4a6 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -45,7 +45,7 @@ def preprocess_options(aviary_options: AviaryValues, meta_data=_MetaData, verbos preprocess_crewpayload(aviary_options, meta_data, verbosity) preprocess_fuel_capacities(aviary_options, verbosity) - # preprocess_Engines(aviary_options, verbosity) + preprocess_Engines(aviary_options, verbosity) if engine_models is not None: preprocess_propulsion(aviary_options, engine_models, meta_data, verbosity) From 7fc0a9fe24d98acef06f0e631b52573b881d3a4a Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 3 Feb 2026 21:52:19 -0500 Subject: [PATCH 51/68] roll back testing --- aviary/utils/preprocessors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index d7ab4e4a6..29ab27427 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -45,7 +45,7 @@ def preprocess_options(aviary_options: AviaryValues, meta_data=_MetaData, verbos preprocess_crewpayload(aviary_options, meta_data, verbosity) preprocess_fuel_capacities(aviary_options, verbosity) - preprocess_Engines(aviary_options, verbosity) + # preprocess_Engines(aviary_options, verbosity) if engine_models is not None: preprocess_propulsion(aviary_options, engine_models, meta_data, verbosity) From 5da579c8637555ff7d98a6beeb504ce15d0f6c82 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Tue, 3 Feb 2026 23:29:57 -0500 Subject: [PATCH 52/68] still testing: change 'raise UserWarning' to print --- aviary/utils/preprocessors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index 29ab27427..b7db845e5 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -45,7 +45,7 @@ def preprocess_options(aviary_options: AviaryValues, meta_data=_MetaData, verbos preprocess_crewpayload(aviary_options, meta_data, verbosity) preprocess_fuel_capacities(aviary_options, verbosity) - # preprocess_Engines(aviary_options, verbosity) + preprocess_Engines(aviary_options, verbosity) if engine_models is not None: preprocess_propulsion(aviary_options, engine_models, meta_data, verbosity) @@ -577,7 +577,7 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): else: num_engines = int(num_engines) if num_engines != sum_engines: - raise UserWarning( + print( 'Your total number of engines is not the same as ' 'the sum of wing engines and fuselage engines.' ) From 1f753851ef68df1758ce4affd54ed1fbc3f1a7a5 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Wed, 4 Feb 2026 00:07:50 -0500 Subject: [PATCH 53/68] still testing --- aviary/utils/preprocessors.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index b7db845e5..f92a6bf91 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -553,7 +553,7 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): num_fuselage_engines = aviary_options.get_val( Aircraft.Engine.NUM_FUSELAGE_ENGINES, 'unitless' ) - if isinstance(num_fuselage_engines, np.ndarray): + if isinstance(num_fuselage_engines, np.ndarray) or isinstance(num_fuselage_engines, list): num_fuselage_engines = num_fuselage_engines[0] else: num_fuselage_engines = int(num_fuselage_engines) @@ -562,7 +562,7 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): if Aircraft.Engine.NUM_WING_ENGINES in aviary_options: num_wing_engines = aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES, 'unitless') - if isinstance(num_wing_engines, np.ndarray): + if isinstance(num_wing_engines, np.ndarray) or isinstance(num_wing_engines, list): num_wing_engines = num_wing_engines[0] else: num_wing_engines = int(num_wing_engines) @@ -572,7 +572,7 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): if Aircraft.Engine.NUM_ENGINES in aviary_options: num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) - if isinstance(num_engines, np.ndarray): + if isinstance(num_engines, np.ndarray) or isinstance(num_engines, list): num_engines = num_engines[0] else: num_engines = int(num_engines) From 511cc461186f38ead165f37c71aad38e8639c069 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 12:15:46 -0500 Subject: [PATCH 54/68] add verbosity check --- aviary/utils/preprocessors.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index f92a6bf91..95025918f 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -577,10 +577,11 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): else: num_engines = int(num_engines) if num_engines != sum_engines: - print( - 'Your total number of engines is not the same as ' - 'the sum of wing engines and fuselage engines.' - ) + if verbosity >= Verbosity.BRIEF: + print( + 'Your total number of engines is not the same as ' + 'the sum of wing engines and fuselage engines.' + ) else: num_engines = sum_engines aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, [num_engines]) From 6b14d98664e653153e2253f47466ecd3c39ac4f3 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 12:18:29 -0500 Subject: [PATCH 55/68] comment out 'aircraft:engine:num_engines,3,unitless' and 'inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3]))' for FLOPS based BWB models --- aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 2 +- .../aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py | 2 +- aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 2 +- .../models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index 7cdaf1b99..1ddafbf27 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -55,7 +55,7 @@ aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:interpolation_method,slinear,unitless aircraft:engine:mass_scaler,1,unitless -aircraft:engine:num_engines,3,unitless +# aircraft:engine:num_engines,3,unitless aircraft:engine:num_fuselage_engines,3,unitless aircraft:engine:num_wing_engines,0,unitless aircraft:engine:reference_mass,22017.0,lbm 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 f047f0a98..17665c590 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 @@ -154,7 +154,7 @@ inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 22017, 'lbm') # WENG inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 70000.0, 'lbf') # THRUST inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 86459.2, 'lbf') # THRSO -inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF +# inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF inputs.set_val(Aircraft.Engine.NUM_FUSELAGE_ENGINES, 3) # NEF inputs.set_val(Aircraft.Engine.NUM_WING_ENGINES, np.array([0])) # NEW inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 0.0) # WTHR diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index 61c1dd62f..0a98469f0 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -55,7 +55,7 @@ aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:interpolation_method,slinear,unitless aircraft:engine:mass_scaler,1,unitless -aircraft:engine:num_engines,3,unitless +# aircraft:engine:num_engines,3,unitless aircraft:engine:num_fuselage_engines,3,unitless aircraft:engine:num_wing_engines,0,unitless aircraft:engine:reference_mass,22017.0,lbm 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 eee3f9cea..9c2d0c8dc 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 @@ -156,7 +156,7 @@ inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 22017, 'lbm') # WENG inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 70000.0, 'lbf') # THRUST inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 86459.2, 'lbf') # THRSO -inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF +# inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF inputs.set_val(Aircraft.Engine.NUM_FUSELAGE_ENGINES, 3) # NEF inputs.set_val(Aircraft.Engine.NUM_WING_ENGINES, np.array([0])) # NEW inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 0.0) # WTHR From 43acd6c2174fd22cf38a1435a336192a0cff909f Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 13:14:26 -0500 Subject: [PATCH 56/68] add 'aircraft:engine:num_engines,3,unitless' and 'inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3]))' for FLOPS based BWB models for now --- aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 2 +- .../aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py | 2 +- aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 2 +- .../models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index b0fa68674..62289325a 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -57,7 +57,7 @@ aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:interpolation_method,slinear,unitless aircraft:engine:mass_scaler,1,unitless -# aircraft:engine:num_engines,3,unitless +aircraft:engine:num_engines,3,unitless aircraft:engine:num_fuselage_engines,3,unitless aircraft:engine:num_wing_engines,0,unitless aircraft:engine:reference_mass,22017.0,lbm 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 340e063cb..25c8589f9 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 @@ -158,7 +158,7 @@ inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 22017, 'lbm') # WENG inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 70000.0, 'lbf') # THRUST inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 86459.2, 'lbf') # THRSO -# inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF +inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF inputs.set_val(Aircraft.Engine.NUM_FUSELAGE_ENGINES, 3) # NEF inputs.set_val(Aircraft.Engine.NUM_WING_ENGINES, np.array([0])) # NEW inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 0.0) # WTHR diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index b2b1d016a..cbc607618 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -57,7 +57,7 @@ aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:interpolation_method,slinear,unitless aircraft:engine:mass_scaler,1,unitless -# aircraft:engine:num_engines,3,unitless +aircraft:engine:num_engines,3,unitless aircraft:engine:num_fuselage_engines,3,unitless aircraft:engine:num_wing_engines,0,unitless aircraft:engine:reference_mass,22017.0,lbm 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 2a5f58097..d92f93eec 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 @@ -160,7 +160,7 @@ inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 22017, 'lbm') # WENG inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 70000.0, 'lbf') # THRUST inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 86459.2, 'lbf') # THRSO -# inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF +inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF inputs.set_val(Aircraft.Engine.NUM_FUSELAGE_ENGINES, 3) # NEF inputs.set_val(Aircraft.Engine.NUM_WING_ENGINES, np.array([0])) # NEW inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 0.0) # WTHR From 30b2f547b6974b5ec021f5ccf38a75e7119376ae Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 14:27:34 -0500 Subject: [PATCH 57/68] work in progress: Do not set Aircraft.CrewPayload.Design.NUM_PASSENGERS. It will be moved to preprocess --- aviary/utils/fortran_to_aviary.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index a1d1dcef3..0e333b1fb 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -1034,14 +1034,15 @@ def update_flops_options(vehicle_data): )[0] else: num_first_class = 0 - if Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS in input_values: - num_tourist_class = input_values.get_val( - Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS, 'unitless' + if Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS in input_values: + num_economy_class = input_values.get_val( + Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS, 'unitless' )[0] else: - num_tourist_class = 0 - num_passengers = num_business_class + num_first_class + num_tourist_class - input_values.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, [num_passengers]) + num_economy_class = 0 + num_passengers = num_business_class + num_first_class + num_economy_class + # TODO: will be moved to preprocess + # input_values.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, [num_passengers]) if not Aircraft.CrewPayload.NUM_GALLEY_CREW in input_values: if num_passengers < 151: From dfa036f3965533d9225b4ee0cdf53956cfa577c6 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 15:47:43 -0500 Subject: [PATCH 58/68] changes based on Chris' comments --- .../blended_wing_body/bwb_detailed_FLOPS.csv | 2 ++ .../blended_wing_body/bwb_simple_FLOPS.csv | 7 ++++-- .../test/test_flops_based_premission.py | 6 +++++ aviary/utils/fortran_to_aviary.py | 22 ------------------- 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index 62289325a..d4d6b3a70 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -30,6 +30,8 @@ aircraft:crew_and_payload:mass_per_passenger,165.0,lbm aircraft:crew_and_payload:num_flight_attendants,22,unitless aircraft:crew_and_payload:num_flight_crew,2,unitless aircraft:crew_and_payload:num_galley_crew,2,unitless +aircraft:crew_and_payload:num_business_class,100,unitless +aircraft:crew_and_payload:num_first_class,28,unitless aircraft:crew_and_payload:num_passengers,468,unitless aircraft:crew_and_payload:num_economy_class,340,unitless aircraft:crew_and_payload:passenger_service_mass_scaler,1.0,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index cbc607618..2559ce8b8 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -15,7 +15,7 @@ aircraft:crew_and_payload:baggage_mass_per_passenger,44.0,lbm aircraft:crew_and_payload:cargo_container_mass_scaler,1.0,unitless aircraft:crew_and_payload:design:num_business_class,100,unitless aircraft:crew_and_payload:design:num_first_class,28,unitless -aircraft:crew_and_payload:design:num_passengers,468,unitless +# aircraft:crew_and_payload:design:num_passengers,468,unitless aircraft:crew_and_payload:design:num_economy_class,340,unitless aircraft:crew_and_payload:design:num_seats_abreast_business,4,unitless aircraft:crew_and_payload:design:num_seats_abreast_first,4,unitless @@ -30,7 +30,9 @@ aircraft:crew_and_payload:mass_per_passenger,165.0,lbm aircraft:crew_and_payload:num_flight_attendants,22,unitless aircraft:crew_and_payload:num_flight_crew,2,unitless aircraft:crew_and_payload:num_galley_crew,2,unitless -aircraft:crew_and_payload:num_passengers,468,unitless +# aircraft:crew_and_payload:num_passengers,468,unitless +aircraft:crew_and_payload:num_business_class,100,unitless +aircraft:crew_and_payload:num_first_class,28,unitless aircraft:crew_and_payload:num_economy_class,340,unitless aircraft:crew_and_payload:passenger_service_mass_scaler,1.0,unitless aircraft:crew_and_payload:wing_cargo,0.0,lbm @@ -143,6 +145,7 @@ aircraft:wing:surface_control_mass_scaler,1.0,unitless aircraft:wing:sweep,35.7,deg aircraft:wing:taper_ratio,0.311,unitless aircraft:wing:thickness_to_chord,0.11,unitless +aircraft:wing:thickness_to_chord_reference,0.11,unitless aircraft:wing:ultimate_load_factor,3.75,unitless aircraft:wing:var_sweep_mass_penalty,0.0,unitless aircraft:wing:wetted_area_scaler,1.0,unitless diff --git a/aviary/subsystems/test/test_flops_based_premission.py b/aviary/subsystems/test/test_flops_based_premission.py index 2ef158f33..451b2d693 100644 --- a/aviary/subsystems/test/test_flops_based_premission.py +++ b/aviary/subsystems/test/test_flops_based_premission.py @@ -1223,3 +1223,9 @@ def test_case_all_subsystems(self): if __name__ == '__main__': unittest.main() + import numpy as np + + np.seterr(divide='raise') + test = BWBPreMissionGroupCSVTest1() + test.setUp() + # test.test_case_geom_mass() diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index 0e333b1fb..22c5db307 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -1040,28 +1040,6 @@ def update_flops_options(vehicle_data): )[0] else: num_economy_class = 0 - num_passengers = num_business_class + num_first_class + num_economy_class - # TODO: will be moved to preprocess - # input_values.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, [num_passengers]) - - if not Aircraft.CrewPayload.NUM_GALLEY_CREW in input_values: - if num_passengers < 151: - num_galley_crew = 0 - else: - num_galley_crew = int(num_passengers / 250) + 1 - input_values.set_val(Aircraft.CrewPayload.NUM_GALLEY_CREW, [num_galley_crew]) - - if not Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER in input_values: - if Mission.Design.RANGE in input_values: - design_range = input_values.get_val(Mission.Design.RANGE, 'nmi')[0] - baggage_per_pax = 35.0 - if design_range > 2900: - baggage_per_pax = 44.0 - elif design_range > 900: - baggage_per_pax = 40.0 - input_values.set_val( - Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER, [baggage_per_pax], 'lbm' - ) if ( not Aircraft.HorizontalTail.THICKNESS_TO_CHORD in input_values From 7b6c16d36d9963a60a05e5c91d041a767f7f26e2 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 16:21:24 -0500 Subject: [PATCH 59/68] minor update --- aviary/utils/fortran_to_aviary.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index 22c5db307..307ec4554 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -1022,25 +1022,6 @@ def update_flops_options(vehicle_data): f'Currently, Aircraft.Design.TYPE must be either 0 or 3 not {design_type[0]}.' ) - if Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS in input_values: - num_business_class = input_values.get_val( - Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS, 'unitless' - )[0] - else: - num_business_class = 0 - if Aircraft.CrewPayload.Design.NUM_FIRST_CLASS in input_values: - num_first_class = input_values.get_val( - Aircraft.CrewPayload.Design.NUM_FIRST_CLASS, 'unitless' - )[0] - else: - num_first_class = 0 - if Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS in input_values: - num_economy_class = input_values.get_val( - Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS, 'unitless' - )[0] - else: - num_economy_class = 0 - if ( not Aircraft.HorizontalTail.THICKNESS_TO_CHORD in input_values or input_values.get_val(Aircraft.HorizontalTail.THICKNESS_TO_CHORD, 'unitless')[0] == 0 From acfcdde8a8268fd7da4ee5887a360f8d3ea5d51f Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 18:52:17 -0500 Subject: [PATCH 60/68] removed num_engines from BWB data sets --- .../aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 6 +++--- .../aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py | 6 +++--- .../models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 2 +- .../aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index d4d6b3a70..cd8882bc3 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -15,7 +15,7 @@ aircraft:crew_and_payload:baggage_mass_per_passenger,44.0,lbm aircraft:crew_and_payload:cargo_container_mass_scaler,1.0,unitless aircraft:crew_and_payload:design:num_business_class,100,unitless aircraft:crew_and_payload:design:num_first_class,28,unitless -aircraft:crew_and_payload:design:num_passengers,468,unitless +# aircraft:crew_and_payload:design:num_passengers,468,unitless aircraft:crew_and_payload:design:num_economy_class,340,unitless aircraft:crew_and_payload:design:num_seats_abreast_business,4,unitless aircraft:crew_and_payload:design:num_seats_abreast_first,4,unitless @@ -32,7 +32,7 @@ aircraft:crew_and_payload:num_flight_crew,2,unitless aircraft:crew_and_payload:num_galley_crew,2,unitless aircraft:crew_and_payload:num_business_class,100,unitless aircraft:crew_and_payload:num_first_class,28,unitless -aircraft:crew_and_payload:num_passengers,468,unitless +# aircraft:crew_and_payload:num_passengers,468,unitless aircraft:crew_and_payload:num_economy_class,340,unitless aircraft:crew_and_payload:passenger_service_mass_scaler,1.0,unitless aircraft:crew_and_payload:wing_cargo,0.0,lbm @@ -59,7 +59,7 @@ aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:interpolation_method,slinear,unitless aircraft:engine:mass_scaler,1,unitless -aircraft:engine:num_engines,3,unitless +# aircraft:engine:num_engines,3,unitless aircraft:engine:num_fuselage_engines,3,unitless aircraft:engine:num_wing_engines,0,unitless aircraft:engine:reference_mass,22017.0,lbm 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 25c8589f9..cf2d45e65 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 @@ -49,11 +49,11 @@ # --------------------------- inputs.set_val(Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS, 100) # NPB inputs.set_val(Aircraft.CrewPayload.Design.NUM_FIRST_CLASS, 28) # NPF -inputs.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, 468, units='unitless') # NPB+NPF+NPT +# inputs.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, 468, units='unitless') # NPB+NPF+NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS, 340) # NPT inputs.set_val(Aircraft.CrewPayload.NUM_BUSINESS_CLASS, 100) # NPB inputs.set_val(Aircraft.CrewPayload.NUM_FIRST_CLASS, 28) # NPF -inputs.set_val(Aircraft.CrewPayload.NUM_PASSENGERS, 468, units='unitless') # sum of three classes +# inputs.set_val(Aircraft.CrewPayload.NUM_PASSENGERS, 468, units='unitless') # sum of three classes inputs.set_val(Aircraft.CrewPayload.NUM_ECONOMY_CLASS, 340) # NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BUSINESS, 4) # NBABR inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST, 4) # NFABR @@ -158,7 +158,7 @@ inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 22017, 'lbm') # WENG inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 70000.0, 'lbf') # THRUST inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 86459.2, 'lbf') # THRSO -inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF +# inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF inputs.set_val(Aircraft.Engine.NUM_FUSELAGE_ENGINES, 3) # NEF inputs.set_val(Aircraft.Engine.NUM_WING_ENGINES, np.array([0])) # NEW inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 0.0) # WTHR diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index 2559ce8b8..4f91fbc50 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -59,7 +59,7 @@ aircraft:engine:geopotential_alt,False,unitless aircraft:engine:ignore_negative_thrust,False,unitless aircraft:engine:interpolation_method,slinear,unitless aircraft:engine:mass_scaler,1,unitless -aircraft:engine:num_engines,3,unitless +# aircraft:engine:num_engines,3,unitless aircraft:engine:num_fuselage_engines,3,unitless aircraft:engine:num_wing_engines,0,unitless aircraft:engine:reference_mass,22017.0,lbm 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 d92f93eec..f4cea0919 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 @@ -49,11 +49,11 @@ # --------------------------- inputs.set_val(Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS, 100) # NPB inputs.set_val(Aircraft.CrewPayload.Design.NUM_FIRST_CLASS, 28) # NPF -inputs.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, 468, units='unitless') # NPB+NPF+NPT +# inputs.set_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS, 468, units='unitless') # NPB+NPF+NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS, 340) # NPT inputs.set_val(Aircraft.CrewPayload.NUM_BUSINESS_CLASS, 100) # NPB inputs.set_val(Aircraft.CrewPayload.NUM_FIRST_CLASS, 28) # NPF -inputs.set_val(Aircraft.CrewPayload.NUM_PASSENGERS, 468, units='unitless') # sum of three classes +# inputs.set_val(Aircraft.CrewPayload.NUM_PASSENGERS, 468, units='unitless') # sum of three classes inputs.set_val(Aircraft.CrewPayload.NUM_ECONOMY_CLASS, 340) # NPT inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BUSINESS, 4) # NBABR inputs.set_val(Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST, 4) # NFABR @@ -160,7 +160,7 @@ inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 22017, 'lbm') # WENG inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 70000.0, 'lbf') # THRUST inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 86459.2, 'lbf') # THRSO -inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF +# inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3])) # NEW+NEF inputs.set_val(Aircraft.Engine.NUM_FUSELAGE_ENGINES, 3) # NEF inputs.set_val(Aircraft.Engine.NUM_WING_ENGINES, np.array([0])) # NEW inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 0.0) # WTHR From fa1a33abcc3fe104c6240410f867492c61632465 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 18:53:26 -0500 Subject: [PATCH 61/68] set np.array, otherwise, it fails some unit tests. --- aviary/utils/preprocessors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index caa6af385..cc0c6fd49 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -604,7 +604,7 @@ def preprocess_Engines(aviary_options: AviaryValues, verbosity=None): ) else: num_engines = sum_engines - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, [num_engines]) + aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([num_engines])) return aviary_options From e5808659679b211edb8da0694a7e2d5997705647 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 18:53:43 -0500 Subject: [PATCH 62/68] minor update --- aviary/subsystems/test/test_flops_based_premission.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/aviary/subsystems/test/test_flops_based_premission.py b/aviary/subsystems/test/test_flops_based_premission.py index 451b2d693..2ef158f33 100644 --- a/aviary/subsystems/test/test_flops_based_premission.py +++ b/aviary/subsystems/test/test_flops_based_premission.py @@ -1223,9 +1223,3 @@ def test_case_all_subsystems(self): if __name__ == '__main__': unittest.main() - import numpy as np - - np.seterr(divide='raise') - test = BWBPreMissionGroupCSVTest1() - test.setUp() - # test.test_case_geom_mass() From cbf9e4f70f6dd4f20cdffec61b5b200e317bc7cf Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 19:24:37 -0500 Subject: [PATCH 63/68] add unit test data files for FLOPS based BWB model --- .../converter_test_BWB_detailed_FLOPS.csv | 160 ++++++++++++++++++ .../data/converter_test_BWB_simple_FLOPS.csv | 159 +++++++++++++++++ 2 files changed, 319 insertions(+) create mode 100644 aviary/utils/test/data/converter_test_BWB_detailed_FLOPS.csv create mode 100644 aviary/utils/test/data/converter_test_BWB_simple_FLOPS.csv diff --git a/aviary/utils/test/data/converter_test_BWB_detailed_FLOPS.csv b/aviary/utils/test/data/converter_test_BWB_detailed_FLOPS.csv new file mode 100644 index 000000000..088447e70 --- /dev/null +++ b/aviary/utils/test/data/converter_test_BWB_detailed_FLOPS.csv @@ -0,0 +1,160 @@ +# FLOPS-derived aircraft input deck converted from bwb_detailed_FLOPS.in + +# Input Values +aircraft:avionics:mass_scaler,1,unitless +aircraft:blended_wing_body_design:detailed_wing_provided,True,unitless +aircraft:blended_wing_body_design:passenger_leading_edge_sweep,45.0,deg +aircraft:crew_and_payload:design:num_business_class,100,unitless +aircraft:crew_and_payload:design:num_economy_class,340,unitless +aircraft:crew_and_payload:design:num_first_class,28,unitless +aircraft:crew_and_payload:design:num_seats_abreast_business,4,unitless +aircraft:crew_and_payload:design:num_seats_abreast_economy,6,unitless +aircraft:crew_and_payload:design:num_seats_abreast_first,4,unitless +aircraft:crew_and_payload:design:seat_pitch_business,39,inch +aircraft:crew_and_payload:design:seat_pitch_economy,32,inch +aircraft:crew_and_payload:design:seat_pitch_first,61,inch +aircraft:crew_and_payload:mass_per_passenger,165.0,lbm +aircraft:crew_and_payload:num_flight_attendants,22,unitless +aircraft:crew_and_payload:num_flight_crew,2,unitless +aircraft:design:landing_to_takeoff_mass_ratio,0.8,unitless +aircraft:design:lift_dependent_drag_coeff_factor,1,unitless +aircraft:design:type,BWB,unitless +aircraft:design:use_alt_mass,False,unitless +aircraft:design:zero_lift_drag_coeff_factor,1,unitless +aircraft:engine:data_file,'ENGDEK',unitless +aircraft:engine:generate_flight_idle,True,unitless +aircraft:engine:geopotential_alt,False,unitless +aircraft:engine:ignore_negative_thrust,False,unitless +aircraft:engine:mass_scaler,1,unitless +aircraft:engine:num_fuselage_engines,3,unitless +aircraft:engine:num_wing_engines,0,unitless +aircraft:engine:reference_mass,22017,lbm +aircraft:engine:reference_sls_thrust,86459.2,lbf +aircraft:engine:scale_factor,0.8096304384033163,unitless +aircraft:engine:scaled_sls_thrust,70000,lbf +aircraft:fins:area,184.89,ft**2 +aircraft:fins:num_fins,2,unitless +aircraft:fins:taper_ratio,0.464,unitless +aircraft:fuel:density,6.7,lbm/galUS +aircraft:fuel:ignore_fuel_capacity_constraint,False,unitless +aircraft:fuel:wing_fuel_fraction,0.688354956933531,unitless +aircraft:furnishings:mass_scaler,1,unitless +aircraft:fuselage:height_to_width_ratio,0.11,unitless +aircraft:fuselage:mass_scaler,1,unitless +aircraft:fuselage:military_cargo_floor,False,unitless +aircraft:fuselage:num_fuselages,1,unitless +aircraft:fuselage:simple_layout,False,unitless +aircraft:fuselage:wetted_area_scaler,1,unitless +aircraft:horizontal_tail:area,0,ft**2 +aircraft:horizontal_tail:aspect_ratio,0,unitless +aircraft:horizontal_tail:mass_scaler,1,unitless +aircraft:horizontal_tail:taper_ratio,0,unitless +aircraft:horizontal_tail:thickness_to_chord,0.11,unitless +aircraft:hydraulics:mass_scaler,1,unitless +aircraft:hydraulics:system_pressure,3000.0,psi +aircraft:landing_gear:main_gear_oleo_length,85,inch +aircraft:landing_gear:nose_gear_oleo_length,87,inch +aircraft:nacelle:avg_diameter,12.608,ft +aircraft:nacelle:avg_length,17.433,ft +aircraft:propulsion:misc_mass_scaler,0,unitless +aircraft:vertical_tail:mass_scaler,1,unitless +aircraft:vertical_tail:num_tails,0,unitless +aircraft:vertical_tail:thickness_to_chord,0.11,unitless +aircraft:vertical_tail:wetted_area_scaler,1,unitless +aircraft:wing:aeroelastic_tailoring_factor,0,unitless +aircraft:wing:airfoil_technology,2,unitless +aircraft:wing:chord_per_semispan_dist,-1.0,58.03,0.4491,0.3884,0.3317,0.2886,0.2537,0.2269,0.2121,0.1983,0.1843,0.1704,0.1565,0.1426,0.1287,unitless +aircraft:wing:composite_fraction,1,unitless +aircraft:wing:control_surface_area_ratio,0.333,unitless +aircraft:wing:detailed_wing,True,unitless +aircraft:wing:dihedral,3,deg +aircraft:wing:glove_and_bat,121.05,ft**2 +aircraft:wing:input_station_dist,0.0,0.35,0.4,0.45,0.5,0.55,0.6,0.6499,0.7,0.75,0.8,0.85,0.8999,0.95,1,unitless +aircraft:wing:load_path_sweep_dist,0.0,0,0,0,0,0,0,0,42.9,42.9,42.9,42.9,42.9,42.9,deg +aircraft:wing:mass_scaler,1,unitless +aircraft:wing:max_camber_at_70_semispan,2,unitless +aircraft:wing:outboard_semispan,86.75,ft +aircraft:wing:span_efficiency_factor,0,unitless +aircraft:wing:span_efficiency_reduction,False,unitless +aircraft:wing:strut_bracing_factor,0,unitless +aircraft:wing:sweep,35.7,deg +aircraft:wing:taper_ratio,0.311,unitless +aircraft:wing:thickness_to_chord,0.11,unitless +aircraft:wing:thickness_to_chord_dist,-1.0,0.15,0.1132,0.0928,0.0822,0.0764,0.0742,0.0746,0.0758,0.0758,0.0756,0.0756,0.0758,0.076,0.076,unitless +aircraft:wing:ultimate_load_factor,3.75,unitless +aircraft:wing:var_sweep_mass_penalty,0,unitless +mission:constraints:max_mach,0.85,unitless +mission:design:gross_mass,874099,lbm +mission:design:range,7750,NM +mission:design:thrust_takeoff_per_eng,0.25,lbf +mission:landing:initial_velocity,140,ft/s +mission:landing:lift_coefficient_max,3.0,unitless +mission:summary:cruise_mach,0.85,unitless +settings:aerodynamics_method,FLOPS,unitless +settings:equations_of_motion,height_energy,unitless +settings:mass_method,FLOPS,unitless + +# Unconverted Values +AERIN.FLLDG,11000 +AERIN.FLTO,11000 +AERIN.ITPAER,2 +AERIN.MYAERO,0 +AERIN.XLLAM,0 +CONFIN.CH,39000 +CONFIN.GW,874099 +CONFIN.OFF,0 +CONFIN.OFG,1 +ENGDIN.MAXCR,1 +MISSIN.ALTRAN,200 +MISSIN.APPRTM,4 +MISSIN.CLAMIN,0 +MISSIN.CRALT,45000,25000,1500 +MISSIN.CRMACH,0.85,0.6,0 +MISSIN.DEAMIN,0 +MISSIN.FWF,-0.001 +MISSIN.HOLDTM,30 +MISSIN.IATA,0 +MISSIN.IFLAG,2 +MISSIN.IHOPOS,1 +MISSIN.IOC,1,4,4 +MISSIN.IRS,1 +MISSIN.IRW,1 +MISSIN.ISKAL,1 +MISSIN.ITTFF,1 +MISSIN.IVS,1 +MISSIN.MSUMPT,1 +MISSIN.NCLIMB,1 +MISSIN.NCLRES,1 +MISSIN.NCRHOL,3 +MISSIN.NCRRES,2 +MISSIN.NCRTH,1 +MISSIN.NCRUSE,3 +MISSIN.NPCON,0 +MISSIN.RCIN,300 +MISSIN.RESTRP,0.05 +MISSIN.TAKOTM,2 +MISSIN.TAXITM,5 +MISSIN.TAXOTM,9 +MISSIN.THOLD,0.1 +MISSIN.TIMMAP,2 +OPTION.IANAL,3 +OPTION.ICOST,0 +OPTION.ILAND,0 +OPTION.INENG,1 +OPTION.IPLTTH,0 +OPTION.ITAKOF,0 +OPTION.IXFL,1 +OPTION.MPRINT,1 +OPTION.NOPRO,0 +PCONIN.CONALT,35000 +PCONIN.CONLIM,300 +PCONIN.CONMCH,0.85 +PCONIN.CONPC,1 +PCONIN.ICONSG,2 +PCONIN.ICONTP,5 +WTIN.ARFIN,1.952 +WTIN.ISPOWE,0 +WTIN.NETAW,14 +WTIN.SWPFIN,39.42 +WTIN.TCFIN,0.08 +WTIN.WINL,0 diff --git a/aviary/utils/test/data/converter_test_BWB_simple_FLOPS.csv b/aviary/utils/test/data/converter_test_BWB_simple_FLOPS.csv new file mode 100644 index 000000000..58d33a586 --- /dev/null +++ b/aviary/utils/test/data/converter_test_BWB_simple_FLOPS.csv @@ -0,0 +1,159 @@ +# FLOPS-derived aircraft input deck converted from bwb_simple_FLOPS.in + +# Input Values +aircraft:avionics:mass_scaler,1,unitless +aircraft:blended_wing_body_design:detailed_wing_provided,False,unitless +aircraft:blended_wing_body_design:passenger_leading_edge_sweep,45.0,deg +aircraft:crew_and_payload:design:num_business_class,100,unitless +aircraft:crew_and_payload:design:num_economy_class,340,unitless +aircraft:crew_and_payload:design:num_first_class,28,unitless +aircraft:crew_and_payload:design:num_seats_abreast_business,4,unitless +aircraft:crew_and_payload:design:num_seats_abreast_economy,6,unitless +aircraft:crew_and_payload:design:num_seats_abreast_first,4,unitless +aircraft:crew_and_payload:design:seat_pitch_business,39,inch +aircraft:crew_and_payload:design:seat_pitch_economy,32,inch +aircraft:crew_and_payload:design:seat_pitch_first,61,inch +aircraft:crew_and_payload:mass_per_passenger,165.0,lbm +aircraft:crew_and_payload:num_flight_attendants,22,unitless +aircraft:crew_and_payload:num_flight_crew,2,unitless +aircraft:design:landing_to_takeoff_mass_ratio,0.8,unitless +aircraft:design:lift_dependent_drag_coeff_factor,1,unitless +aircraft:design:type,BWB,unitless +aircraft:design:use_alt_mass,False,unitless +aircraft:design:zero_lift_drag_coeff_factor,1,unitless +aircraft:engine:data_file,'ENGDEK',unitless +aircraft:engine:generate_flight_idle,True,unitless +aircraft:engine:geopotential_alt,False,unitless +aircraft:engine:ignore_negative_thrust,False,unitless +aircraft:engine:mass_scaler,1,unitless +aircraft:engine:num_fuselage_engines,3,unitless +aircraft:engine:num_wing_engines,0,unitless +aircraft:engine:reference_mass,22017,lbm +aircraft:engine:reference_sls_thrust,86459.2,lbf +aircraft:engine:scale_factor,0.8096304384033163,unitless +aircraft:engine:scaled_sls_thrust,70000,lbf +aircraft:fins:area,184.89,ft**2 +aircraft:fins:num_fins,2,unitless +aircraft:fins:taper_ratio,0.464,unitless +aircraft:fuel:density,6.7,lbm/galUS +aircraft:fuel:ignore_fuel_capacity_constraint,False,unitless +aircraft:fuel:wing_fuel_fraction,0.688354956933531,unitless +aircraft:furnishings:mass_scaler,1,unitless +aircraft:fuselage:height_to_width_ratio,0.11,unitless +aircraft:fuselage:length,137.5,ft +aircraft:fuselage:mass_scaler,1,unitless +aircraft:fuselage:max_width,64.58,ft +aircraft:fuselage:military_cargo_floor,False,unitless +aircraft:fuselage:num_fuselages,1,unitless +aircraft:fuselage:simple_layout,True,unitless +aircraft:fuselage:wetted_area_scaler,1,unitless +aircraft:horizontal_tail:area,0,ft**2 +aircraft:horizontal_tail:aspect_ratio,0,unitless +aircraft:horizontal_tail:mass_scaler,1,unitless +aircraft:horizontal_tail:taper_ratio,0,unitless +aircraft:horizontal_tail:thickness_to_chord,0.11,unitless +aircraft:hydraulics:mass_scaler,1,unitless +aircraft:hydraulics:system_pressure,3000.0,psi +aircraft:landing_gear:main_gear_oleo_length,85,inch +aircraft:landing_gear:nose_gear_oleo_length,87,inch +aircraft:nacelle:avg_diameter,12.608,ft +aircraft:nacelle:avg_length,17.433,ft +aircraft:propulsion:misc_mass_scaler,0,unitless +aircraft:vertical_tail:mass_scaler,1,unitless +aircraft:vertical_tail:num_tails,0,unitless +aircraft:vertical_tail:thickness_to_chord,0.11,unitless +aircraft:vertical_tail:wetted_area_scaler,1,unitless +aircraft:wing:aeroelastic_tailoring_factor,0,unitless +aircraft:wing:airfoil_technology,2,unitless +aircraft:wing:composite_fraction,1,unitless +aircraft:wing:control_surface_area_ratio,0.333,unitless +aircraft:wing:detailed_wing,True,unitless +aircraft:wing:dihedral,3,deg +aircraft:wing:glove_and_bat,121.05,ft**2 +aircraft:wing:input_station_dist,0.0,0.5,1.0,unitless +aircraft:wing:mass_scaler,1,unitless +aircraft:wing:max_camber_at_70_semispan,2,unitless +aircraft:wing:outboard_semispan,86.75,ft +aircraft:wing:span_efficiency_factor,0,unitless +aircraft:wing:span_efficiency_reduction,False,unitless +aircraft:wing:strut_bracing_factor,0,unitless +aircraft:wing:sweep,35.7,deg +aircraft:wing:taper_ratio,0.311,unitless +aircraft:wing:thickness_to_chord,0.11,unitless +aircraft:wing:ultimate_load_factor,3.75,unitless +aircraft:wing:var_sweep_mass_penalty,0,unitless +mission:constraints:max_mach,0.85,unitless +mission:design:gross_mass,874099,lbm +mission:design:range,7750,NM +mission:design:thrust_takeoff_per_eng,0.25,lbf +mission:landing:initial_velocity,140,ft/s +mission:landing:lift_coefficient_max,3.0,unitless +mission:summary:cruise_mach,0.85,unitless +settings:aerodynamics_method,FLOPS,unitless +settings:equations_of_motion,height_energy,unitless +settings:mass_method,FLOPS,unitless + +# Unconverted Values +AERIN.FLLDG,11000 +AERIN.FLTO,11000 +AERIN.ITPAER,2 +AERIN.MYAERO,0 +AERIN.XLLAM,0 +CONFIN.CH,39000 +CONFIN.GW,874099 +CONFIN.OFF,0 +CONFIN.OFG,1 +ENGDIN.MAXCR,1 +MISSIN.ALTRAN,200 +MISSIN.APPRTM,4 +MISSIN.CLAMIN,0 +MISSIN.CRALT,45000,25000,1500 +MISSIN.CRMACH,0.85,0.6,0 +MISSIN.DEAMIN,0 +MISSIN.FWF,-0.001 +MISSIN.HOLDTM,30 +MISSIN.IATA,0 +MISSIN.IFLAG,2 +MISSIN.IHOPOS,1 +MISSIN.IOC,1,4,4 +MISSIN.IRS,1 +MISSIN.IRW,1 +MISSIN.ISKAL,1 +MISSIN.ITTFF,1 +MISSIN.IVS,1 +MISSIN.MSUMPT,1 +MISSIN.NCLIMB,1 +MISSIN.NCLRES,1 +MISSIN.NCRHOL,3 +MISSIN.NCRRES,2 +MISSIN.NCRTH,1 +MISSIN.NCRUSE,3 +MISSIN.NPCON,0 +MISSIN.RCIN,300 +MISSIN.RESTRP,0.05 +MISSIN.TAKOTM,2 +MISSIN.TAXITM,5 +MISSIN.TAXOTM,9 +MISSIN.THOLD,0.1 +MISSIN.TIMMAP,2 +OPTION.IANAL,3 +OPTION.ICOST,0 +OPTION.ILAND,0 +OPTION.INENG,1 +OPTION.IPLTTH,0 +OPTION.ITAKOF,0 +OPTION.IXFL,1 +OPTION.MPRINT,1 +OPTION.NOPRO,0 +PCONIN.CONALT,35000 +PCONIN.CONLIM,300 +PCONIN.CONMCH,0.85 +PCONIN.CONPC,1 +PCONIN.ICONSG,2 +PCONIN.ICONTP,5 +WTIN.ARFIN,1.952 +WTIN.ISPOWE,0 +WTIN.NETAW,0 +WTIN.SWPFIN,39.42 +WTIN.TCFIN,0.08 +WTIN.WINL,0 From 220a4be2a33d1022c40e3381409eb2129aa0c610 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 19:25:26 -0500 Subject: [PATCH 64/68] add two unit tests for FLOPS based BWB datasets --- aviary/utils/test/test_fortran_to_aviary.py | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/aviary/utils/test/test_fortran_to_aviary.py b/aviary/utils/test/test_fortran_to_aviary.py index e312b4154..f5bf0d002 100644 --- a/aviary/utils/test/test_fortran_to_aviary.py +++ b/aviary/utils/test/test_fortran_to_aviary.py @@ -94,6 +94,28 @@ def test_bwb_gasp(self): ) self.compare_files(comparison_filepath) + def test_bwb_detailed_flops(self): + filepath = 'models/aircraft/blended_wing_body/bwb_detailed_FLOPS.in' + comparison_filepath = 'utils/test/data/converter_test_BWB_detailed_FLOPS.csv' + + self.prepare_and_run( + filepath, + out_file=Path.cwd() / Path('TEST_' + comparison_filepath), + legacy_code=LegacyCode.FLOPS, + ) + self.compare_files(comparison_filepath) + + def test_bwb_simple_flops(self): + filepath = 'models/aircraft/blended_wing_body/bwb_simple_FLOPS.in' + comparison_filepath = 'utils/test/data/converter_test_BWB_simple_FLOPS.csv' + + self.prepare_and_run( + filepath, + out_file=Path.cwd() / Path('TEST_' + comparison_filepath), + legacy_code=LegacyCode.FLOPS, + ) + self.compare_files(comparison_filepath) + def test_advanced_single_aisle(self): # Note: The csv comparison file N3CC_generic_low_speed_polars_FLOPSinp.csv was generated # using the fortran-to-Aviary converter and was not evaluated for comparison to the original. From d432a883272e5ac6743a3975aa402b79c500253d Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Thu, 5 Feb 2026 19:45:52 -0500 Subject: [PATCH 65/68] add preprocess --- .../geometry/flops_based/test/test_nacelle.py | 6 +++--- .../flops_based/test/test_air_conditioning.py | 2 +- .../subsystems/mass/flops_based/test/test_apu.py | 15 +++++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/aviary/subsystems/geometry/flops_based/test/test_nacelle.py b/aviary/subsystems/geometry/flops_based/test/test_nacelle.py index 9f408ba40..0c1468e50 100644 --- a/aviary/subsystems/geometry/flops_based/test/test_nacelle.py +++ b/aviary/subsystems/geometry/flops_based/test/test_nacelle.py @@ -60,9 +60,9 @@ def test_case_BWB(self): prob = self.prob options = get_flops_options('BWBsimpleFLOPS') - # options = { - # Aircraft.Engine.NUM_ENGINES: np.array([3]), - # } + options = { + Aircraft.Engine.NUM_ENGINES: np.array([3]), + } prob.model.add_subsystem( 'nacelles', Nacelles(), promotes_outputs=['*'], promotes_inputs=['*'] diff --git a/aviary/subsystems/mass/flops_based/test/test_air_conditioning.py b/aviary/subsystems/mass/flops_based/test/test_air_conditioning.py index 7200c7641..39d9f73c3 100644 --- a/aviary/subsystems/mass/flops_based/test/test_air_conditioning.py +++ b/aviary/subsystems/mass/flops_based/test/test_air_conditioning.py @@ -185,7 +185,7 @@ def test_case(self, case_name): promotes_outputs=['*'], ) - prob.model_options['*'] = get_flops_options(case_name) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/subsystems/mass/flops_based/test/test_apu.py b/aviary/subsystems/mass/flops_based/test/test_apu.py index 47d1e31d9..3c9ee7dc5 100644 --- a/aviary/subsystems/mass/flops_based/test/test_apu.py +++ b/aviary/subsystems/mass/flops_based/test/test_apu.py @@ -1,5 +1,6 @@ import unittest +import numpy as np import openmdao.api as om from openmdao.utils.assert_utils import assert_check_partials from openmdao.utils.testing_utils import use_tempdirs @@ -88,8 +89,11 @@ class BWBAPUMassTest(unittest.TestCase): def setUp(self): self.prob = om.Problem() - @parameterized.expand(get_flops_case_names(only=bwb_cases), name_func=print_case) - def test_case(self, case_name): + # @parameterized.expand(get_flops_case_names(only=bwb_cases), name_func=print_case) + def test_case( + self, + ): + case_name = 'BWBsimpleFLOPS' prob = self.prob prob.model.add_subsystem( @@ -99,7 +103,7 @@ def test_case(self, case_name): promotes_outputs=['*'], ) - prob.model_options['*'] = get_flops_options(case_name, preprocess=False) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) prob.setup(check=False, force_alloc_complex=True) @@ -114,4 +118,7 @@ def test_case(self, case_name): if __name__ == '__main__': - unittest.main() + # unittest.main() + test = BWBAPUMassTest() + test.setUp() + test.test_case() From 93f0044bde0ecac3a6455568e7a493adff0cd8ca Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 6 Feb 2026 11:24:30 -0500 Subject: [PATCH 66/68] add comments --- aviary/subsystems/geometry/flops_based/fuselage.py | 4 +++- aviary/variable_info/variable_meta_data.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/aviary/subsystems/geometry/flops_based/fuselage.py b/aviary/subsystems/geometry/flops_based/fuselage.py index 35c4cfaf1..82198e496 100644 --- a/aviary/subsystems/geometry/flops_based/fuselage.py +++ b/aviary/subsystems/geometry/flops_based/fuselage.py @@ -70,7 +70,9 @@ def setup(self): 'Rear_spar_percent_chord', 0.7, units='unitless', - desc='RSPSOB: Rear spar percent chord for BWB at side of body', + desc='RSPSOB: Rear spar percent chord for BWB at side of body, ' + ' or more precisely, the passenger compartment ends at the ' + ' 70% of fuselage length from the leading edge.', ) add_aviary_output(self, Aircraft.Fuselage.REF_DIAMETER, units='ft') diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 1f90e65f2..a576afd65 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -3699,7 +3699,7 @@ meta_data=_MetaData, historical_name={'GASP': None, 'FLOPS': None, 'LEAPS1': None}, units='unitless', - desc='carry out simple or detailed layout of fuselage.', + desc='carry out simple or detailed layout of fuselage (for FLOPS based geometry).', option=True, default_value=True, ) From c5101c0af68826f59310089b6d1a4d63b0a3e9a5 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 6 Feb 2026 14:25:59 -0500 Subject: [PATCH 67/68] modify comments --- .../aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py | 2 +- .../models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 cf2d45e65..5045f972e 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 @@ -113,7 +113,7 @@ # Horizontal Tail # --------------------------- inputs.set_val(Aircraft.HorizontalTail.AREA, 0.0, 'ft**2') # SHT -inputs.set_val(Aircraft.HorizontalTail.ASPECT_RATIO, 0.1) # SHT +inputs.set_val(Aircraft.HorizontalTail.ASPECT_RATIO, 0.1) # ARHT inputs.set_val(Aircraft.HorizontalTail.TAPER_RATIO, 0.0) # TRHT inputs.set_val(Aircraft.HorizontalTail.THICKNESS_TO_CHORD, 0.11) # TCHT # inputs.set_val(Aircraft.HorizontalTail.VERTICAL_TAIL_FRACTION, 0.0) # HHT 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 f4cea0919..25c7e3563 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 @@ -115,7 +115,7 @@ # Horizontal Tail # --------------------------- inputs.set_val(Aircraft.HorizontalTail.AREA, 0.0, 'ft**2') # SHT -inputs.set_val(Aircraft.HorizontalTail.ASPECT_RATIO, 0.1) # SHT +inputs.set_val(Aircraft.HorizontalTail.ASPECT_RATIO, 0.1) # ARHT inputs.set_val(Aircraft.HorizontalTail.TAPER_RATIO, 0.0) # TRHT inputs.set_val(Aircraft.HorizontalTail.THICKNESS_TO_CHORD, 0.11) # TCHT # inputs.set_val(Aircraft.HorizontalTail.VERTICAL_TAIL_FRACTION, 0.0) # HHT From b3c6481e0a7a864aeb36cb44f9510754794e5c14 Mon Sep 17 00:00:00 2001 From: Xun Jiang Date: Fri, 6 Feb 2026 21:09:55 -0500 Subject: [PATCH 68/68] add Mission.Landing.LIFT_COEFFICIENT_MAX back to model --- aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv | 2 +- .../aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py | 2 +- aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv | 2 +- .../models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv index cd8882bc3..edafe8699 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS.csv @@ -155,7 +155,7 @@ mission:design:gross_mass,874099,lbm mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s -#mission:landing:lift_coefficient_max,3.0,unitless +mission:landing:lift_coefficient_max,3.0,unitless mission:landing:rolling_friction_coefficient,0.025,unitless mission:takeoff:lift_coefficient_max,2.0,unitless mission:summary:cruise_mach,0.85,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_detailed_FLOPS_data.py index 5045f972e..3c21bf170 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 @@ -287,7 +287,7 @@ inputs.set_val(Mission.Constraints.MAX_MACH, 0.85) # VMMO # inputs.set_val(Mission.Takeoff.FUEL_SIMPLE, 577, 'lbm') # FTKOFL -# inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM +inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM inputs.set_val(Mission.Takeoff.LIFT_COEFFICIENT_MAX, 2) # CLTOM # inputs.set_val(Mission.Takeoff.LIFT_OVER_DRAG, 17.354) inputs.set_val(Aircraft.Design.LANDING_TO_TAKEOFF_MASS_RATIO, 0.8) # WRATIO diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv index 4f91fbc50..4267713bd 100644 --- a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv +++ b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS.csv @@ -154,7 +154,7 @@ mission:design:gross_mass,874099,lbm mission:design:range,7750,NM mission:design:thrust_takeoff_per_eng,0.25,lbf mission:landing:initial_velocity,140,ft/s -#mission:landing:lift_coefficient_max,3.0,unitless +mission:landing:lift_coefficient_max,3.0,unitless mission:landing:rolling_friction_coefficient,0.025,unitless mission:takeoff:lift_coefficient_max,2.0,unitless mission:summary:cruise_mach,0.85,unitless diff --git a/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py b/aviary/models/aircraft/blended_wing_body/bwb_simple_FLOPS_data.py index 25c7e3563..516de7c23 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 @@ -234,7 +234,7 @@ inputs.set_val(Mission.Constraints.MAX_MACH, 0.85) # VMMO # inputs.set_val(Mission.Takeoff.FUEL_SIMPLE, 577, 'lbm') # FTKOFL -# inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM +inputs.set_val(Mission.Landing.LIFT_COEFFICIENT_MAX, 3.0) # CLLDM inputs.set_val(Mission.Takeoff.LIFT_COEFFICIENT_MAX, 2) # CLTOM # inputs.set_val(Mission.Takeoff.LIFT_OVER_DRAG, 17.354) inputs.set_val(Aircraft.Design.LANDING_TO_TAKEOFF_MASS_RATIO, 0.8) # WRATIO