Skip to content
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

Distinction between max payload and max pax #81

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions example/cryo_input.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,19 @@ name = "TASOPT Model with cryo fuel and HX"
[Mission]
N_missions = 1 # Number of missions to be modeled (first mission is the design mission)
pax = 180 # Number of passengers in each mission
max_pax = 189 # Maximum number of passengers for aircarft
# defines the maximum payload carrying capacity of the aircraft

range = "3000.0 nmi" # Design Range

weight_per_pax = "215.0 lbf" # Specify weight per passenger -
# includes luggage [lbm or lbf or kg or N]
# judging you if you use imperial units but wtvs

exit_limit = 189 # Maximum number of passengers that can sit in the cabin

max_payload_in_pax_equivalent = 189 # Defines the maximum payload carrying capacity of the aircraft
# It is the maximum payload that the aircraft can carry (including cargo),
# as an equivalent number of passengers

fuel_reserves = 0.20 # W_reserveFuel / W_fuelburned

Nlift = 3.0 # Max vertical load factor for wing bending loads
Expand Down
8 changes: 6 additions & 2 deletions example/example_regional.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,19 @@
[Mission]
N_missions = 1 # Number of missions to be modeled (first mission is the design mission)
pax = 118 # Number of passengers in each mission
max_pax = 122 # Maximum number of passengers for aircarft
# defines the maximum payload carrying capacity of the aircraft

range = "2200.0 nmi"
# Design Range + second mission range
weight_per_pax = "215.0 lbf" # Specify weight per passenger -
# includes luggage [lbm or lbf or kg or N]
# judging you if you use imperial units but wtvs

exit_limit = 122 # Maximum number of passengers that can sit in the cabin

max_payload_in_pax_equivalent = 122 # Defines the maximum payload carrying capacity of the aircraft
# It is the maximum payload that the aircraft can carry (including cargo),
# as an equivalent number of passengers

fuel_reserves = 0.05 # W_reserveFuel / W_fuelburned

Nlift = 3.0 # Max vertical load factor for wing bending loads
Expand Down
8 changes: 6 additions & 2 deletions example/example_widebody.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,19 @@
[Mission]
N_missions = 1 # Number of missions to be modeled (first mission is the design mission)
pax = 370 # Number of passengers in each mission
max_pax = 450 # Maximum number of passengers for aircarft
# defines the maximum payload carrying capacity of the aircraft

range = "7800.0 nmi" # Design Range

weight_per_pax = "230.0 lbf" # Specify weight per passenger -
# includes luggage [lbm or lbf or kg or N]
# judging you if you use imperial units but wtvs

exit_limit = 450 # Maximum number of passengers that can sit in the cabin

max_payload_in_pax_equivalent = 450 # Defines the maximum payload carrying capacity of the aircraft
# It is the maximum payload that the aircraft can carry (including cargo),
# as an equivalent number of passengers

fuel_reserves = 0.07 # W_reserveFuel / W_fuelburned

Nlift = 3.0 # Max vertical load factor for wing bending loads
Expand Down
8 changes: 6 additions & 2 deletions src/IO/default_input.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@

[Mission]
N_missions = 2 # Number of missions to be modeled (first mission is the design mission)
max_pax = 230 # Maximum number of passengers for aircarft
# defines the maximum payload carrying capacity of the aircraft

range = ["3000.0 nmi", "2000.0 nmi"] # Design Range + second mission range

Expand All @@ -101,6 +99,12 @@
# includes luggage [lbm or lbf or kg or N]
# judging you if you use imperial units but wtvs

exit_limit = 189 # Maximum number of passengers that can sit in the cabin

max_payload_in_pax_equivalent = 230 # Defines the maximum payload carrying capacity of the aircraft
# It is the maximum payload that the aircraft can carry (including cargo),
# as an equivalent number of passengers

fuel_reserves = 0.20 # W_reserveFuel / W_fuelburned

Nlift = 3.0 # Max vertical load factor for wing bending loads
Expand Down
7 changes: 5 additions & 2 deletions src/IO/read_input.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,9 @@ parg[igrWfmax] = readfuel("fuel_usability_factor")
ranges = readmis("range")
parm[imRange, :] .= Distance.(ranges)

maxpax = readmis("max_pax")
maxpax = readmis("max_payload_in_pax_equivalent")
pax = readmis("pax")
exitlimit = readmis("exit_limit")
despax = pax[1] #Design number of passengers
Wpax = Force(readmis("weight_per_pax"))
parm[imWperpax, :] .= Wpax
Expand All @@ -174,6 +175,8 @@ parg[igWpaymax] = maxpax * Wpax
parg[igfreserve] = readmis("fuel_reserves")
parg[igVne] = Speed(readmis("Vne"))
parg[igNlift] = readmis("Nlift")
fuselage.cabin.design_pax = despax
fuselage.cabin.exit_limit = exitlimit

##Takeoff
takeoff = readmis("Takeoff")
Expand Down Expand Up @@ -643,7 +646,7 @@ readvtail(x) = read_input(x, vtail, dvtail)
if calculate_cabin #Resize the cabin if desired, keeping deltas
@info "Fuselage and stabilizer layouts have been overwritten; deltas will be maintained."

update_fuse_for_pax!(pari, parg, parm, fuselage, fuse_tank) #update fuselage dimensions
update_fuse_for_pax!(pari, parg, fuselage, fuse_tank) #update fuselage dimensions
end
# ---------------------------------

Expand Down
2 changes: 1 addition & 1 deletion src/misc/fuselage.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ $TYPEDFIELDS

# Misc properties
"""Number of decks in fuselage"""
n_decks::Float64 = 0
n_decks::Int64 = 0
"""Fuselage Weight fraction of stringers """
weight_frac_stringers::Float64 = 0
"""Fuselage Weight fraction of frame """
Expand Down
14 changes: 9 additions & 5 deletions src/misc/layout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,20 @@ Contains dimensions, heights, etc. to design a fuselage
$TYPEDFIELDS
"""
@kwdef mutable struct Cabin <: AbstractCabin
"""Design number of passengers"""
design_pax::Int64 = 0
"""Maximum number of passengers"""
exit_limit::Int64 = 0
"""Longitudinal seat pitch [m]"""
seat_pitch = 0.0
seat_pitch::Float64 = 0.0
"""Transverse seat width [m]"""
seat_width = 0.0
seat_width::Float64 = 0.0
"""Seat height [m]"""
seat_height = 0.0
seat_height::Float64 = 0.0
"""Aisle half-width [m]"""
aisle_halfwidth = 0.0
aisle_halfwidth::Float64 = 0.0
"""Distance between double decker floors [m]"""
floor_distance = 0.0
floor_distance::Float64 = 0.0
"""Main cabin width [m]"""
cabin_width_main::Float64 = 0.0
"""Top cabin width [m]"""
Expand Down
26 changes: 11 additions & 15 deletions src/structures/size_cabin.jl
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function find_floor_angles(fdoubledecker::Bool, Rfuse::Float64, dRfuse::Float64;
end

"""
find_double_decker_cabin_length(x::Vector{Float64}, parg, fuse, parm)
find_double_decker_cabin_length(x::Vector{Float64}, parg, fuse)

This function can be used to calculate the length of a double decker cabin with different number of
passengers on each deck.
Expand All @@ -199,12 +199,11 @@ passengers on each deck.
- `x::Vector{Float64}`: vector with optimization variables
- `parg::Vector{Float64}`: vector with aircraft geometric and mass parameters
- `fuse::Fuselage`: structure with fuselage parameters
- `parm::Array{Float64}`: array with mission parameters

**Outputs:**
- `maxl::Float64`: required cabin length (m)
"""
function find_double_decker_cabin_length(x::Vector{Float64}, parg, fuse, parm)
function find_double_decker_cabin_length(x::Vector{Float64}, fuse)
seat_pitch = fuse.cabin.seat_pitch
seat_width = fuse.cabin.seat_width
aisle_halfwidth = fuse.cabin.aisle_halfwidth
Expand All @@ -214,9 +213,9 @@ function find_double_decker_cabin_length(x::Vector{Float64}, parg, fuse, parm)
dRfuse = fuse.layout.bubble_lower_downward_shift
wfb = fuse.layout.bubble_center_y_offset
nfweb = fuse.layout.n_webs
d_floor = parg[igfloordist]
d_floor = fuse.cabin.floor_distance

paxsize = parg[igWpaymax]/parm[imWperpax,1] #maximum number of passengers #TODO replace with better measure
paxsize = fuse.cabin.exit_limit #maximum number of passengers

paxmain = x[1]
paxtop = paxsize - paxmain
Expand Down Expand Up @@ -281,29 +280,28 @@ function EvaluateCabinProps!(fuse)
end

"""
optimize_double_decker_cabin(parg, fuse, parm)
optimize_double_decker_cabin(fuse)

This function can be used to optimize the passenger distribution across two decks in a double decker aircraft.
If the cross-section is circular, it also optimizes the deck layouts.
!!! details "🔃 Inputs and Outputs"
**Inputs:**
- `parg::Vector{Float64}`: vector with aircraft geometric and mass parameters
- `fuse::Fuselage`: structure with fuselage parameters
- `parm::Array{Float64}`: array with mission parameters

**Outputs:**
- `xopt::Vector{Float64}`: vector with optimization results
"""
function optimize_double_decker_cabin(parg, fuse, parm)
function optimize_double_decker_cabin(fuse)
dRfuse = fuse.layout.bubble_lower_downward_shift

paxsize = parg[igWpaymax]/parm[imWperpax,1] #maximum number of passengers #TODO replace with better measure
paxsize = fuse.cabin.exit_limit #maximum number of passengers

initial_x = [paxsize/2, -pi/4]
lower = [1.0, -pi/2]
upper = [paxsize - 1.0, pi/2]

obj(x, grad) = find_double_decker_cabin_length(x, parg, fuse, parm)[1] #Objective function is cabin length
obj(x, grad) = find_double_decker_cabin_length(x, fuse)[1] #Objective function is cabin length

opt = Opt(:GN_AGS, length(initial_x)) #Use a global optimizer as it is only 1 or 2 variables
opt.lower_bounds = lower
Expand All @@ -312,15 +310,13 @@ function optimize_double_decker_cabin(parg, fuse, parm)

opt.min_objective = obj

if dRfuse ≈ 0.0 #Apply constraints on lower floor if it can be moved around
inequality_constraint!(opt, (x, grad) -> MinCargoHeightConst(x, fuse), 1e-5) #Minimum height of cargo hold
inequality_constraint!(opt, (x, grad) -> MinCabinHeightConst(x, fuse), 1e-5) #Minimum height of upper cabin
end
inequality_constraint!(opt, (x, grad) -> MinCargoHeightConst(x, fuse), 1e-5) #Minimum height of cargo hold
inequality_constraint!(opt, (x, grad) -> MinCabinHeightConst(x, fuse), 1e-5) #Minimum height of upper cabin

(minf,xopt,ret) = NLopt.optimize(opt, initial_x) #Solve optimization problem

#Evaluate number of passengers per row in main cabin
_, seats_per_row_main = find_double_decker_cabin_length(xopt, parg, fuse, parm)
_, seats_per_row_main = find_double_decker_cabin_length(xopt, fuse)

return xopt, seats_per_row_main
end
Expand Down
22 changes: 13 additions & 9 deletions src/structures/update_fuse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function update_fuse!(fuselage, pari, parg)
end

"""
update_fuse_for_pax!(pari, parg, parm, fuse, fuse_tank)
update_fuse_for_pax!(pari, parg, fuse, fuse_tank)

Function to update the fuselage layout when the cabin length is not known a priori, for example if the radius is changed.
It sizes the cabin for the design number of passengers.
Expand All @@ -62,15 +62,14 @@ It sizes the cabin for the design number of passengers.
**Inputs:**
- `pari::Vector{Int64}`: vector with aircraft integer parameters
- `parg::Vector{Float64}`: vector with aircraft geometric and mass parameters
- `parm::Array{Float64}`: array with mission parameters
- `fuse::Fuselage`: structure with fuselage parameters
- `fuse_tank::fuselage_tank`: structure with cryogenic fuel tank parameters

**Outputs:**
Parameters in `parg` are modified. It also outputs:
- `seats_per_row::Float64`: number of seats per row in main cabin (lower deck if double decker)
"""
function update_fuse_for_pax!(pari, parg, parm, fuse, fuse_tank)
function update_fuse_for_pax!(pari, parg, fuse, fuse_tank)

seat_pitch = fuse.cabin.seat_pitch
seat_width = fuse.cabin.seat_width
Expand All @@ -84,13 +83,13 @@ function update_fuse_for_pax!(pari, parg, parm, fuse, fuse_tank)

#Find cabin length by placing seats
if fuse.n_decks == 2 #if the aircraft is a double decker
xopt, seats_per_row = optimize_double_decker_cabin(parg, fuse, parm) #Optimize the floor layout and passenger distributions
xopt, seats_per_row = optimize_double_decker_cabin(fuse) #Optimize the floor layout and passenger distributions

lcyl, _ = find_double_decker_cabin_length(xopt, parg, fuse, parm) #Total length is maximum of the two
lcyl, _ = find_double_decker_cabin_length(xopt, fuse) #Total length is maximum of the two

else
θ = find_floor_angles(false, Rfuse, dRfuse, h_seat = h_seat) #Find the floor angle
paxsize = parg[igWpaymax]/parm[imWperpax,1] #maximum number of passengers
paxsize = fuse.cabin.exit_limit #maximum number of passengers
w = find_cabin_width(Rfuse, wfb, nfweb, θ, h_seat) #Cabin width
lcyl, _, seats_per_row = place_cabin_seats(paxsize, w, seat_pitch, seat_width, aisle_halfwidth) #Cabin length
end
Expand Down Expand Up @@ -183,7 +182,13 @@ function find_minimum_radius_for_seats_per_row(seats_per_row, ac_base)
(minf,xopt,ret) = NLopt.optimize(opt, xopt) #Solve optimization problem starting from global solution

R = xopt[1]
return R
#Check if constraint is met
diff = check_seats_per_row_diff(seats_per_row, xopt, ac)
if diff ≈ 0.0
return R
else
return 0.0
end
end

"""
Expand All @@ -205,12 +210,11 @@ function check_seats_per_row_diff(seats_per_row, x, ac)
Rfuse = x[1]
ac.fuselage.layout.cross_section.radius = Rfuse
try #Sometimes update_fuse_for_pax may fail
seats_per_row_rad = update_fuse_for_pax!(ac.pari, ac.parg, ac.parm, ac.fuselage, ac.fuse_tank)
seats_per_row_rad = update_fuse_for_pax!(ac.pari, ac.parg, ac.fuselage, ac.fuse_tank)
diff = seats_per_row_rad - seats_per_row
#println("R = $Rfuse, s = $seats_per_row_rad")
return diff
catch
#println("failed")
return 1.0
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test_structures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ update_fuse_out_test = [29.5656, 31.0896, 18.716634144, 36.57600000000001, 37.79

# fuse_tank = TASOPT.fuselage_tank()

# TASOPT.update_fuse_for_pax!(pari, parg, parm, fuselage, fuse_tank)
# TASOPT.update_fuse_for_pax!(pari, parg, fuselage, fuse_tank)

# parg_check = [47.091600000000014, 6.096, 38.86200000000001, 40.38600000000001, 44.95800000000001, 18.460895740194808, 19.98489574019481, 44.19600000000001, 42.82440000000001, 45.87240000000001, 23.595756720000004, 1.9558, 219964.5779, 32.76600000000001, 1.5239999999999991, 0.762, 0.4826, 0.254]
# parg_nz = deepcopy(parg)
Expand Down