Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f426b62
work in progress: removed V3_bug_fixed_IO from onboarding_level2.ipynb
xjjiang Aug 27, 2026
5d68717
Merge branch 'OpenMDAO:main' into GASP_Tail
xjjiang Aug 28, 2026
b89f323
work in progress: added a temp class MassPremissionTestCase2a
xjjiang Aug 28, 2026
c2ff1d1
work in progress: testing overriding in GASP based test_mass_premissi…
xjjiang Aug 28, 2026
2b78c27
temp added aircraft:design:compute_htail_volume_coeff and aircraft:de…
xjjiang Aug 31, 2026
8190b8a
work in progress: adding MomentRatio class
xjjiang Aug 31, 2026
347345c
work in progress: added TestMomentRatio. used override feature in BWB…
xjjiang Aug 31, 2026
139ba04
work in progress: used override feature in BWBSizeGroupTestCase1.
xjjiang Aug 31, 2026
fa37ee4
added Aircraft.HorizontalTail.VOLUME_COEFFICIENT and Aircraft.Vertica…
xjjiang Aug 31, 2026
cdc1559
added a helper class for overriding
xjjiang Aug 31, 2026
6f9feb3
modified MassPremissionTestCase1 by using PreMission helper class
xjjiang Aug 31, 2026
2c26e29
Aircraft.Design.COMPUTE_[HV]TAIL_VOLUME_COEFF = True
xjjiang Aug 31, 2026
9178d95
Merge branch 'main' into GASP_Tail
xjjiang Aug 31, 2026
68ef1b3
minor update
xjjiang Aug 31, 2026
079f5ad
Merge branch 'GASP_Tail' of github.com:xjjiang/om-Aviary into GASP_Tail
xjjiang Aug 31, 2026
81b0fba
fix error due to merge
xjjiang Aug 31, 2026
5085c65
modification due to merge
xjjiang Aug 31, 2026
dfe0c80
found one test that needs helper class
xjjiang Aug 31, 2026
7a71e47
remove Aircraft.Design.COMPUTE_HTAIL_VOLUME_COEFF and Aircraft.Design…
xjjiang Aug 31, 2026
aaabfff
add MomentRatio into EmpennageSize
xjjiang Sep 1, 2026
451f0d3
modified unit tests where moment ratios are fixed
xjjiang Sep 1, 2026
c3a5d91
minor updates
xjjiang Sep 1, 2026
3aa547c
added use_tempdirs
xjjiang Sep 1, 2026
8ff2b1c
Merge branch 'main' into GASP_Tail
xjjiang Sep 1, 2026
f44f757
added a new class ChordCheck
xjjiang Sep 2, 2026
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
5 changes: 2 additions & 3 deletions aviary/docs/user_guide_unreviewed/onboarding_level2.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,6 @@
"from aviary.models.missions.two_dof_default import phase_info\n",
"\n",
"prob = AviaryProblem()\n",
"from aviary.validation_cases.validation_data.test_data.V3_bug_fixed_IO import V3_bug_fixed_options\n",
"from aviary.utils.doctape import check_contains\n",
"from aviary.validation_cases.validation_tests import get_flops_inputs\n",
"\n",
Expand Down Expand Up @@ -1014,7 +1013,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "base",
"language": "python",
"name": "python3"
},
Expand All @@ -1028,7 +1027,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.11"
"version": "3.12.9"
}
},
"nbformat": 4,
Expand Down
136 changes: 118 additions & 18 deletions aviary/subsystems/geometry/gasp_based/empennage.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,60 @@
import numpy as np
import openmdao.api as om
import warnings

from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option
from aviary.variable_info.variables import Aircraft


class MomentRatio(om.ExplicitComponent):
"""GASP tail moment ratio"""

def initialize(self):
self.options.declare(
'orientation',
values=['horizontal', 'vertical'],
desc='Tail orientation, can be horizontal or vertical.',
)

def setup(self):
veritcal = self.options['orientation'] == 'vertical'
if veritcal:
self.io_names = {
'moment_ratio': Aircraft.VerticalTail.MOMENT_RATIO,
}
else:
self.io_names = {
'moment_ratio': Aircraft.HorizontalTail.MOMENT_RATIO,
}

# coefficients used in the empirical equation
if veritcal:
self.k = [1.862, 0.338]
else:
self.k = [0.271, 0.0955]

add_aviary_input(
self, Aircraft.HorizontalTail.VERTICAL_TAIL_MOUNT_LOCATION, units='unitless'
)

add_aviary_output(self, self.io_names['moment_ratio'], units='unitless')

def setup_partials(self):
self.declare_partials(self.io_names['moment_ratio'], '*')

def compute(self, inputs, outputs):
htail_loc = inputs[Aircraft.HorizontalTail.VERTICAL_TAIL_MOUNT_LOCATION]
k1, k2 = self.k
ch2 = k1 + k2 * htail_loc
outputs[self.io_names['moment_ratio']] = ch2

def compute_partials(self, inputs, J):
str_moment_ratio = self.io_names['moment_ratio']

k1, k2 = self.k
J[str_moment_ratio, Aircraft.HorizontalTail.VERTICAL_TAIL_MOUNT_LOCATION] = k2


class TailVolCoef(om.ExplicitComponent):
"""GASP tail volume coefficient fallback calculation.

Expand Down Expand Up @@ -232,34 +282,78 @@ def compute_partials(self, inputs, J):
J[str_arm, str_wing_ref] = 1.0 / r_arm


class ChordCheck(om.ExplicitComponent):
def setup(self):
add_aviary_input(
self, Aircraft.HorizontalTail.VERTICAL_TAIL_MOUNT_LOCATION, units='unitless'
)
add_aviary_input(self, Aircraft.HorizontalTail.AREA, units='ft**2')
add_aviary_input(self, Aircraft.HorizontalTail.SPAN, units='ft')
add_aviary_input(self, Aircraft.HorizontalTail.ROOT_CHORD, units='ft')
add_aviary_input(self, Aircraft.VerticalTail.ROOT_CHORD, units='ft')
add_aviary_input(self, Aircraft.VerticalTail.TAPER_RATIO, units='unitless')

def compute(self, inputs, outputs):
htail_loc = inputs[Aircraft.HorizontalTail.VERTICAL_TAIL_MOUNT_LOCATION]
hrchord = inputs[Aircraft.HorizontalTail.ROOT_CHORD]
vrchord = inputs[Aircraft.HorizontalTail.ROOT_CHORD]
v_tr = inputs[Aircraft.VerticalTail.TAPER_RATIO]
h_area = inputs[Aircraft.HorizontalTail.AREA]
h_span = inputs[Aircraft.HorizontalTail.SPAN]

if htail_loc > 0:
chord_check = vrchord * (1.0 - htail_loc * (1.0 - v_tr))
if chord_check < hrchord:
corr_hrchord = chord_check
warnings.warn(
f'Horizontal tail center-line chord must be {corr_hrchord} '
'(ft) to be located at specified position on vertical tail.'
)
corr_h_tr = 2.0 * h_area / corr_hrchord / h_span - 1.0
if corr_h_tr <= 1.0:
warnings.warn(f'Horizontal taper ratio should be {corr_h_tr}.')
else:
corr_h_tr = 1.0
corr_h_ar = h_area / corr_hrchord / corr_hrchord
warnings.warn(f'Horizontal taper ratio should be {corr_h_tr}.')
warnings.warn(f'Horizontal aspect ratio should be {corr_h_ar}.')


class EmpennageSize(om.Group):
"""GASP geometry calculations for both horizontal and vertical tails.

Volume coefficients for the tails may be either specified directly (default) or
computed via empirical relationships to general airplane parameters.
"""

def initialize(self):
add_aviary_option(self, Aircraft.Design.COMPUTE_HTAIL_VOLUME_COEFF)
add_aviary_option(self, Aircraft.Design.COMPUTE_VTAIL_VOLUME_COEFF)

def setup(self):
# For cruciform/T-tail configurations, see issue #1089

if self.options[Aircraft.Design.COMPUTE_HTAIL_VOLUME_COEFF]:
self.add_subsystem(
'htail_vc',
TailVolCoef(orientation='horizontal'),
promotes_inputs=['*'],
promotes_outputs=['*'],
)
if self.options[Aircraft.Design.COMPUTE_VTAIL_VOLUME_COEFF]:
self.add_subsystem(
'vtail_vc',
TailVolCoef(orientation='vertical'),
promotes_inputs=['*'],
promotes_outputs=['*'],
)
self.add_subsystem(
'htail_mr',
MomentRatio(orientation='horizontal'),
promotes_inputs=['*'],
promotes_outputs=['*'],
)
self.add_subsystem(
'vtail_mr',
MomentRatio(orientation='vertical'),
promotes_inputs=['*'],
promotes_outputs=['*'],
)

self.add_subsystem(
'htail_vc',
TailVolCoef(orientation='horizontal'),
promotes_inputs=['*'],
promotes_outputs=['*'],
)
self.add_subsystem(
'vtail_vc',
TailVolCoef(orientation='vertical'),
promotes_inputs=['*'],
promotes_outputs=['*'],
)

self.add_subsystem(
'htail',
Expand All @@ -274,3 +368,9 @@ def setup(self):
promotes_inputs=['*'],
promotes_outputs=['*'],
)

self.add_subsystem(
'chord_check',
ChordCheck(),
promotes_inputs=['*'],
)
Loading
Loading