-
Notifications
You must be signed in to change notification settings - Fork 132
Fuselage layout enhancement and modification #1205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
363a42e
a00038e
1ba5541
17997a0
bb2fb13
df38d4a
9f24c4c
d9c7d5d
2c47b5e
9476478
769eb24
6f972aa
df14090
303a3a8
01d6ebf
cd4295a
5e7fd7f
1deece1
1b2c2b7
3206ad0
0b3355b
c6a9c87
c30fa28
8b10ad2
f53ed86
1de0fde
f608b9c
ec1f18d
eb1df71
8691551
ed479e1
c165efa
2942a08
3803d7d
bacf737
1544895
8686233
33c4c26
170eede
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |
| from aviary.utils.math import smooth_int_tanh, d_smooth_int_tanh | ||
| from aviary.variable_info.enums import Verbosity | ||
| from aviary.variable_info.functions import add_aviary_input, add_aviary_option, add_aviary_output | ||
| from aviary.variable_info.variables import Aircraft, Mission, Settings | ||
| from aviary.variable_info.variables import Aircraft, Settings | ||
|
|
||
|
|
||
| class FuselagePrelim(om.ExplicitComponent): | ||
|
|
@@ -191,13 +191,20 @@ class DetailedCabinLayout(om.ExplicitComponent): | |
| """ | ||
|
|
||
| def initialize(self): | ||
| add_aviary_option(self, Aircraft.Fuselage.SEAT_WIDTH_BUSINESS) | ||
| add_aviary_option(self, Aircraft.Fuselage.SEAT_WIDTH_FIRST) | ||
| add_aviary_option(self, Aircraft.Fuselage.SEAT_WIDTH_ECONOMY) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BUSINESS) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_ECONOMY) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.SEAT_PITCH_BUSINESS) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.SEAT_PITCH_FIRST) | ||
| add_aviary_option(self, Aircraft.CrewPayload.Design.SEAT_PITCH_ECONOMY) | ||
| add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) | ||
| add_aviary_option(self, Settings.VERBOSITY) | ||
|
|
||
| def setup(self): | ||
| add_aviary_input(self, Aircraft.Design.RANGE, units='NM') | ||
|
|
@@ -210,36 +217,80 @@ def setup(self): | |
| self.declare_partials('*', '*', method='fd', form='forward') | ||
|
|
||
| def compute(self, inputs, outputs): | ||
| verbosity = self.options[Settings.VERBOSITY] | ||
|
|
||
| num_first_class_pax = self.options[Aircraft.CrewPayload.Design.NUM_FIRST_CLASS] | ||
| num_business_class_pax = self.options[Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS] | ||
| num_economy_class_pax = self.options[Aircraft.CrewPayload.Design.NUM_ECONOMY_CLASS] | ||
| fuselage_multiplier = 1.0 | ||
|
|
||
| num_seat_abreast_first = self.options[Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST] | ||
| num_seat_abreast_business = self.options[ | ||
| Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BUSINESS | ||
| ] | ||
| num_seat_abreast_economy = self.options[ | ||
| Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_ECONOMY | ||
| ] | ||
|
|
||
| # The 200 was derived from B757 - the largest single aisle western desig. | ||
| if num_economy_class_pax > 200: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is outside the scope of the PR, and probably one for @jkirk5 - should these if/else blocks that set the values of inputs/options be moved out of the fuselage calculation component and into preprocessors? That would clean up the component, and set the 'defaults' for sensible values elsewhere in the code...? |
||
| if num_seat_abreast_economy <= 0: | ||
| num_seat_abreast_economy = 8 | ||
| if num_seat_abreast_first > 0 and num_seat_abreast_first <= 0: | ||
| if verbosity > Verbosity.BRIEF: | ||
| print('Set Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_ECONOMY = 8') | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very small comment - Perhaps remove hardcoded value of '8' in the print() and format with f'{num_seat_abreast_economy'} like the print statements below for consistency. |
||
| if num_first_class_pax > 0 and num_seat_abreast_first <= 0: | ||
| num_seat_abreast_first = num_seat_abreast_economy - 2 | ||
| if verbosity > Verbosity.BRIEF: | ||
| print( | ||
| 'Set Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST = ' | ||
| f'{num_seat_abreast_first}' | ||
| ) | ||
| if num_business_class_pax > 0 and num_seat_abreast_business <= 0: | ||
| num_seat_abreast_business = num_seat_abreast_economy - 2 | ||
| if verbosity > Verbosity.BRIEF: | ||
| print( | ||
| 'Set Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BASINESS = ' | ||
| f'{num_seat_abreast_business}' | ||
| ) | ||
|
|
||
| if num_seat_abreast_first <= 0 and num_first_class_pax > 0: | ||
| num_seat_abreast_first = 4 | ||
| if verbosity > Verbosity.BRIEF: | ||
| print( | ||
| 'Set Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_FIRST = ' | ||
| f'{num_seat_abreast_first}' | ||
| ) | ||
| if num_seat_abreast_economy <= 0 and num_economy_class_pax > 0: | ||
| num_seat_abreast_economy = 6 | ||
| if verbosity > Verbosity.BRIEF: | ||
| print( | ||
| 'Set Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_ECONOMY = ' | ||
| f'{num_seat_abreast_economy}' | ||
| ) | ||
| if num_seat_abreast_business <= 0 and num_business_class_pax > 0: | ||
| num_seat_abreast_business = 5 | ||
| if verbosity > Verbosity.BRIEF: | ||
| print( | ||
| 'Set Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_BUSINESS = ' | ||
| f'{num_seat_abreast_business}' | ||
| ) | ||
|
|
||
| # Though these are not user definable, the values here are typical for most transport | ||
| aisle_width_first_class = 20.0 # inch | ||
| aisle_width_business_class = 19.0 # inch | ||
| aisle_width_economy_class = 18.0 # inch | ||
|
|
||
| # If there are less than 60 passengers on board, then the aisle should be slightly narrow. | ||
| # Also, if the number of passengers abreast was not specified, then set it to 5 as 6 is too much | ||
| # for a typical short range transport. | ||
| # Also, if the number of passengers abreast was not specified, then set it to 5 because 6 | ||
| # is too much for a typical short range transport. | ||
| if num_economy_class_pax < 60: | ||
| if num_seat_abreast_economy <= 0: | ||
| num_seat_abreast_economy = 5 | ||
| if verbosity > Verbosity.BRIEF: | ||
| print( | ||
| 'Set Aircraft.CrewPayload.Design.NUM_SEATS_ABREAST_ECONOMY = ' | ||
| f'{num_seat_abreast_economy}' | ||
| ) | ||
| aisle_width_economy_class = 15.0 | ||
|
|
||
| if num_seat_abreast_economy > 6: | ||
|
|
@@ -252,18 +303,29 @@ def compute(self, inputs, outputs): | |
| # 4 or 6 as shown below that we are working with a widebody aircraft. | ||
| if num_seat_abreast_first > 4: | ||
| aisle_width_first_class = 18.0 | ||
| if num_seat_abreast_business > 5: | ||
| aisle_width_first_class = 17.0 | ||
| if num_seat_abreast_economy > 6: | ||
| aisle_width_economy_class = 15.0 | ||
|
|
||
| seat_pitch_first = self.options[Aircraft.CrewPayload.Design.SEAT_PITCH_FIRST][0] | ||
| if seat_pitch_first <= 0 and num_first_class_pax > 0: | ||
| seat_pitch_first = 38.0 # inch | ||
| if verbosity > Verbosity.BRIEF: | ||
| print('Set Aircraft.CrewPayload.Design.SEAT_PITCH_FIRST = 38.0 inches') | ||
| seat_pitch_business = self.options[Aircraft.CrewPayload.Design.SEAT_PITCH_BUSINESS][0] | ||
| if seat_pitch_business <= 0 and num_business_class_pax > 0: | ||
| seat_pitch_business = 36.0 # inch | ||
| if verbosity > Verbosity.BRIEF: | ||
| print('Set Aircraft.CrewPayload.Design.SEAT_PITCH_BUSINESS = 36.0 inches') | ||
| seat_pitch_economy = self.options[Aircraft.CrewPayload.Design.SEAT_PITCH_ECONOMY][0] | ||
| if seat_pitch_economy <= 0 and num_economy_class_pax > 0: | ||
| seat_pitch_economy = 34.0 # inch | ||
| if verbosity > Verbosity.BRIEF: | ||
| print('Set Aircraft.CrewPayload.Design.SEAT_PITCH_ECONOMY = 34.0 inches') | ||
|
|
||
| # set maximum number of galleys based on statistics (this block is not from FLOPS) | ||
| num_pax = num_first_class_pax + num_economy_class_pax | ||
| num_pax = num_first_class_pax + num_business_class_pax + num_economy_class_pax | ||
| if num_pax < 80: | ||
| max_galleys = 1 | ||
| max_lav = 1 | ||
|
|
@@ -311,10 +373,12 @@ def compute(self, inputs, outputs): | |
| # The above settings are necessary because FLOPS didn't cover all the scenarios. | ||
| # They will be over written if FLOPS covered a particular scenario as we see below. | ||
|
|
||
| num_first_business_pax = num_first_class_pax + num_business_class_pax | ||
|
|
||
| # Set constraints on the maximum number of galleys and other items so that we don't have | ||
| # a flying kitchen or closet or whatever. | ||
| # Note: Some of these may need relaxing for larger aircraft. | ||
| if num_first_class_pax == 0: | ||
| if num_first_business_pax == 0: | ||
| design_range = inputs[Aircraft.Design.RANGE] | ||
| if design_range < 1250.0: | ||
| max_lav = 2 | ||
|
|
@@ -325,7 +389,7 @@ def compute(self, inputs, outputs): | |
| max_galleys = 2 | ||
| max_closets = 2 | ||
|
|
||
| if num_first_class_pax == 0 and num_economy_class_pax < 110: | ||
| if num_first_business_pax == 0 and num_economy_class_pax < 110: | ||
| max_lav = 1 | ||
| max_galleys = 1 | ||
| max_closets = 1 | ||
|
|
@@ -339,17 +403,17 @@ def compute(self, inputs, outputs): | |
| max_galleys = 8 | ||
| max_closets = 8 | ||
|
|
||
| if num_first_class_pax > 0 and num_seat_abreast_economy < 8: | ||
| if num_first_business_pax > 0 and num_seat_abreast_economy < 8: | ||
| fuselage_multiplier = 0.95 | ||
|
|
||
| # Calculate the number of galleys, lavatories and closets | ||
| num_galleys = int(1 + ((num_first_class_pax + num_economy_class_pax) / 100)) | ||
| num_galleys = int(1 + (num_pax / 100)) | ||
| if num_galleys > max_galleys: | ||
| num_galleys = max_galleys | ||
| num_lavas = int(1 + (num_economy_class_pax / 60)) + int(1 + (num_first_class_pax / 100)) | ||
| num_lavas = int(1 + (num_economy_class_pax / 60)) + int(1 + (num_first_business_pax / 100)) | ||
| if num_lavas > max_lav: | ||
| num_lavas = max_lav | ||
| num_closets = int(1 + (num_first_class_pax / 30)) + int(1 + (num_economy_class_pax / 60)) | ||
| num_closets = int(1 + (num_first_business_pax / 30)) + int(1 + (num_economy_class_pax / 60)) | ||
| if num_closets > max_closets: | ||
| num_closets = max_closets | ||
|
|
||
|
|
@@ -358,9 +422,13 @@ def compute(self, inputs, outputs): | |
| num_engines = self.options[Aircraft.Engine.NUM_ENGINES][0] | ||
| eng_flag = num_engines - 2 * int(num_engines / 2) # a center mounted engine if 1. | ||
| first_class_len = num_first_class_pax * seat_pitch_first / num_seat_abreast_first | ||
| business_class_len = ( | ||
| num_business_class_pax * seat_pitch_business / num_seat_abreast_business | ||
| ) | ||
| economy_class_len = num_economy_class_pax * seat_pitch_economy / num_seat_abreast_economy | ||
| pax_compart_length = ( | ||
| first_class_len | ||
| + business_class_len | ||
| + (num_galleys + num_lavas) * 36.0 | ||
| + economy_class_len | ||
| + num_closets * 12.0 | ||
|
|
@@ -378,17 +446,32 @@ def compute(self, inputs, outputs): | |
| # Calculate the number of rows of each class of passenger (not needed) | ||
| if num_first_class_pax > 0: | ||
| num_rows_first = int(np.ceil(num_first_class_pax / num_seat_abreast_first)) | ||
| if num_business_class_pax > 0: | ||
| num_rows_business = int(np.ceil(num_business_class_pax / num_seat_abreast_business)) | ||
| if num_economy_class_pax > 0: | ||
| num_rows_economy = int(np.ceil(num_economy_class_pax / num_seat_abreast_economy)) | ||
|
|
||
| # Calculate the fuselage width of the passenger seats | ||
| width_first_class = ( | ||
| num_aisles * aisle_width_first_class + num_seat_abreast_first * 20.0 | ||
| ) / 12.0 | ||
| seat_width_first = self.options[Aircraft.Fuselage.SEAT_WIDTH_FIRST][0] | ||
| seat_width_business = self.options[Aircraft.Fuselage.SEAT_WIDTH_BUSINESS][0] | ||
| seat_width_economy = self.options[Aircraft.Fuselage.SEAT_WIDTH_ECONOMY][0] | ||
| if num_first_class_pax > 0: | ||
| width_first_class = ( | ||
| num_aisles * aisle_width_first_class + num_seat_abreast_first * seat_width_first | ||
| ) / 12.0 | ||
| else: | ||
| width_first_class = 0.0 | ||
| if num_business_class_pax > 0: | ||
| width_business_class = ( | ||
| num_aisles * aisle_width_business_class | ||
| + num_seat_abreast_business * seat_width_business | ||
| ) / 12.0 | ||
| else: | ||
| width_business_class = 0.0 | ||
| width_economy_class = ( | ||
| num_aisles * aisle_width_economy_class + num_seat_abreast_economy * 25.0 | ||
| num_aisles * aisle_width_economy_class + num_seat_abreast_economy * seat_width_economy | ||
| ) / 12.0 | ||
| width_fuselage = np.maximum(width_first_class, width_economy_class) * 1.06 | ||
| width_fuselage = max(width_first_class, width_economy_class, width_business_class) * 1.06 | ||
| outputs[Aircraft.Fuselage.MAX_WIDTH] = width_fuselage | ||
| outputs[Aircraft.Fuselage.MAX_HEIGHT] = width_fuselage + 0.9 | ||
|
|
||
|
|
@@ -460,7 +543,7 @@ def compute(self, inputs, outputs): | |
|
|
||
| if length <= 0.0: | ||
| raise ValueError( | ||
| f'Aircraft.Fuselage.LENGTH must be positive to use simple cabin layout.' | ||
| 'Aircraft.Fuselage.LENGTH must be positive to use simple cabin layout.' | ||
| ) | ||
| if max_width <= 0.0: | ||
| raise ValueError( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.