diff --git a/.github/workflows/test_benchmarks.yml b/.github/workflows/test_benchmarks.yml index bc2a5dce3..5b18b2c2c 100644 --- a/.github/workflows/test_benchmarks.yml +++ b/.github/workflows/test_benchmarks.yml @@ -18,7 +18,7 @@ on: jobs: latest_benchmarks: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 90 steps: diff --git a/.github/workflows/test_docs.yml b/.github/workflows/test_docs.yml index 31977627d..287fc9510 100644 --- a/.github/workflows/test_docs.yml +++ b/.github/workflows/test_docs.yml @@ -18,7 +18,7 @@ on: jobs: latest_docs: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 90 steps: diff --git a/.github/workflows/test_workflow.yml b/.github/workflows/test_workflow.yml index 7f028d92d..ce705719b 100644 --- a/.github/workflows/test_workflow.yml +++ b/.github/workflows/test_workflow.yml @@ -18,7 +18,7 @@ jobs: pre_commit: # run pre-commit checks - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -28,7 +28,7 @@ jobs: - uses: pre-commit/action@v3.0.1 test_ubuntu: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/test_workflow_dev_deps.yml b/.github/workflows/test_workflow_dev_deps.yml index 92daf1528..fed5ad912 100644 --- a/.github/workflows/test_workflow_dev_deps.yml +++ b/.github/workflows/test_workflow_dev_deps.yml @@ -14,7 +14,7 @@ on: jobs: test_ubuntu: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/test_workflow_no_dev_install.yml b/.github/workflows/test_workflow_no_dev_install.yml index dd8f1f67e..d58ffea15 100644 --- a/.github/workflows/test_workflow_no_dev_install.yml +++ b/.github/workflows/test_workflow_no_dev_install.yml @@ -17,7 +17,7 @@ on: jobs: test_ubuntu_no_dev_install: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 timeout-minutes: 90 diff --git a/aviary/api.py b/aviary/api.py index c0b6b026a..4136c3aa8 100644 --- a/aviary/api.py +++ b/aviary/api.py @@ -23,7 +23,7 @@ from aviary.variable_info.options import get_option_defaults, is_option from aviary.utils.develop_metadata import add_meta_data, update_meta_data from aviary.variable_info.variable_meta_data import CoreMetaData -from aviary.variable_info.functions import add_aviary_input, add_aviary_output, get_units, override_aviary_vars, setup_trajectory_params +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, get_units, override_aviary_vars, setup_trajectory_params, setup_model_options from aviary.utils.merge_hierarchies import merge_hierarchies from aviary.utils.merge_variable_metadata import merge_meta_data from aviary.utils.named_values import NamedValues, get_keys, get_items, get_values diff --git a/aviary/docs/developer_guide/doctape.ipynb b/aviary/docs/developer_guide/doctape.ipynb index b4db14ae8..4fc24a74c 100644 --- a/aviary/docs/developer_guide/doctape.ipynb +++ b/aviary/docs/developer_guide/doctape.ipynb @@ -82,41 +82,17 @@ " doctape.glue_variable(key, md_code=True)\n", " class_list += f'- `{key}` {val}\\n'\n", "\n", - "# testing_list = ''\n", - "# for key,val in testing_functions.items():\n", - "# testing_list += f'- `{key}` {val}\\n'\n", - "\n", "utility_list = '```{eval-rst}\\n'\n", "for key in utility_functions:\n", " doctape.glue_variable(key, md_code=True)\n", " utility_list += ' '*4+f'.. autofunction:: aviary.utils.doctape.{key}\\n{\" \"*8}:noindex:\\n\\n'\n", "utility_list += '```'\n", "\n", - "# testing_list = '```{eval-rst}\\n'\n", - "# for key in testing_functions:\n", - "# utils.glue_variable(key, md_code=True)\n", - "# testing_list += ' '*4+f'.. autofunction:: aviary.utils.doctape.{key}\\n{\" \"*8}:noindex:\\n\\n'\n", - "# testing_list += '```'\n", - "\n", - "# testing_list = '
\\n\\nFunction Docs\\n\\n'\n", "testing_list = '```{eval-rst}\\n'\n", "for key in testing_functions:\n", " doctape.glue_variable(key, md_code=True)\n", " testing_list += ' '*4+f'.. autofunction:: aviary.utils.doctape.{key}\\n{\" \"*8}:noindex:\\n\\n'\n", "testing_list += '```'\n", - "# testing_list += '\\n\\n
'\n", - "\n", - "# glue_list = ''\n", - "# for key,val in glue_functions.items():\n", - "# glue_list += f'- `{key}` {key}\\n'\n", - "\n", - "# glue_list = ''\n", - "# for key in glue_functions:\n", - "# # doc_str = inspect.getdoc(imported_functions[key])\n", - "# doc_str = imported_functions[key].__doc__.split('\\n')[1]\n", - "# # doc_str = '\\n'.join([s+' ' for s in imported_functions[key].__doc__.split('\\n')])\n", - "# print(doc_str)\n", - "# glue_list += f'- `{key}`: {doc_str}\\n'\n", "\n", "glue_list = '```{eval-rst}\\n'\n", "for key in glue_functions:\n", diff --git a/aviary/docs/developer_guide/doctape_examples.ipynb b/aviary/docs/developer_guide/doctape_examples.ipynb index 378bfe52e..4fb7f3006 100644 --- a/aviary/docs/developer_guide/doctape_examples.ipynb +++ b/aviary/docs/developer_guide/doctape_examples.ipynb @@ -407,12 +407,12 @@ "outputs": [], "source": [ "# Testing Cell\n", - "from aviary.api import Mission\n", + "from aviary.api import Aircraft\n", "from aviary.utils.doctape import glue_variable, get_previous_line, get_variable_name\n", "\n", - "glue_variable('value', Mission.Design.MACH, md_code=True)\n", + "glue_variable('value', Aircraft.Design.EMPTY_MASS, md_code=True)\n", "glue_variable('var_value_code', get_previous_line(), md_code=True)\n", - "glue_variable(get_variable_name(Mission.Design.MACH), md_code=True)\n", + "glue_variable(get_variable_name(Aircraft.Design.EMPTY_MASS), md_code=True)\n", "glue_variable('var_name_code', get_previous_line(), md_code=True)\n" ] }, @@ -423,7 +423,7 @@ "If you want to glue the name of a variable, instead of the value that variable holds, you can use the {glue:md}`get_variable_name` to extract it.\n", "\n", "For example:\n", - "Using {glue:md}`var_value_code` will result in {glue:md}`value`, whereas using {glue:md}`var_name_code` will result in {glue:md}`Mission.Design.MACH`\n", + "Using {glue:md}`var_value_code` will result in {glue:md}`value`, whereas using {glue:md}`var_name_code` will result in {glue:md}`Aircraft.Design.EMPTY_MASS`\n", "\n", "### {glue:md}`get_attribute_name`\n", "allows users to get the name of object attributes in order to glue them into documentation. This works well for Enums or Class Variables that have unique values." @@ -482,6 +482,71 @@ "p1_alt = get_value(simplified_dict, 'phase1.altitude.val')\n", "print(p1_alt)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [ + "remove-cell" + ] + }, + "outputs": [], + "source": [ + "# Testing Cell\n", + "from aviary.utils.doctape import glue_variable, check_args, get_all_keys, get_previous_line\n", + "from aviary.api import Aircraft, Mission\n", + "\n", + "glue_variable(Aircraft.__name__)\n", + "glue_variable(Mission.__name__)\n", + "\n", + "track_layers = 'track_layers'\n", + "check_args(get_all_keys, track_layers)\n", + "glue_variable(track_layers)\n", + "\n", + "get_all_keys(Mission, track_layers='Mission')\n", + "track_layers_with_name = get_previous_line().split(', ')[1].split(')')[0]\n", + "glue_variable('track_layers_with_Mission', track_layers_with_name, display=False)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These can also be used to recursively get all of the attributes from a complex object, like the {glue:md}`Aircraft` or {glue:md}`Mission` hierarchies.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from aviary.utils.doctape import get_all_keys, get_value, glue_keys\n", + "from aviary.api import Mission\n", + "\n", + "k1=get_all_keys(Mission)\n", + "print(k1[:5]) # Display the first 5 keys in Mission\n", + "k2=get_all_keys(Mission, track_layers=True)\n", + "print(k2[:5]) # Display the first 5 keys in Mission\n", + "k3=get_all_keys(Mission, track_layers='Mission')\n", + "print(k3[:5]) # Display the first 5 keys in Mission\n", + "\n", + "glue_keys(Mission, False)\n", + "\n", + "print(get_value(Mission,'Constraints.GEARBOX_SHAFT_POWER_RESIDUAL'))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If {glue:md}`get_all_keys` is used on an object like {glue:md}`Mission` without specifying a value for {glue:md}`track_layers` will return all of the uniquely named attributes of the object (such as {glue:md}GEARBOX_SHAFT_POWER_RESIDUAL). Setting {glue:md}`track_layers` to `True` will get all of the attributes in dot notation, but will not include the name of the original object ({glue:md}Constraints.GEARBOX_SHAFT_POWER_RESIDUAL). If you want the full name of the attribute, including the name of the original object, you can use that name as the value of {glue:md}`track_layers` (using {glue:md}track_layers_with_Mission gives us access to {glue:md}Mission.Constraints.GEARBOX_SHAFT_POWER_RESIDUAL)\n", + "\n", + "Using {glue:md}`glue_keys` handles this for us automatically by using the `__name__` attribute of the object passed to it as the value of {glue:md}`track_layers`.\n", + "\n", + "As with the dict_of_dicts, we can recusively get the value of an attribute using the full path along with {glue:md}`get_value`." + ] } ], "metadata": { diff --git a/aviary/docs/examples/modified_aircraft.csv b/aviary/docs/examples/modified_aircraft.csv index 43ac7ba2f..445c8e328 100644 --- a/aviary/docs/examples/modified_aircraft.csv +++ b/aviary/docs/examples/modified_aircraft.csv @@ -114,7 +114,7 @@ aircraft:wing:aeroelastic_tailoring_factor,0.0,unitless aircraft:wing:airfoil_technology,1.92669766647637,unitless aircraft:wing:area,1370.0,ft**2 aircraft:wing:aspect_ratio,11.02091,unitless -aircraft:wing:bending_material_mass_scaler,1.0,unitless +aircraft:wing:BENDING_MATERIAL_MASS_SCALER,1.0,unitless aircraft:wing:chord_per_semispan,0.31,0.23,0.084,unitless aircraft:wing:composite_fraction,0.2,unitless aircraft:wing:control_surface_area,137,ft**2 diff --git a/aviary/docs/getting_started/onboarding_level3.ipynb b/aviary/docs/getting_started/onboarding_level3.ipynb index 6b02bffa0..f710cf9c2 100644 --- a/aviary/docs/getting_started/onboarding_level3.ipynb +++ b/aviary/docs/getting_started/onboarding_level3.ipynb @@ -95,6 +95,7 @@ "\n", "import aviary.api as av\n", "from aviary.validation_cases.validation_tests import get_flops_inputs\n", + "from aviary.variable_info.functions import setup_model_options\n", "\n", "\n", "prob = om.Problem(model=om.Group())\n", @@ -459,6 +460,8 @@ "]\n", "av.set_aviary_input_defaults(prob.model, varnames, aviary_inputs)\n", "\n", + "av.setup_model_options(prob, aviary_inputs)\n", + "\n", "prob.setup(force_alloc_complex=True)\n", "\n", "av.set_aviary_initial_values(prob, aviary_inputs)\n", @@ -709,7 +712,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb b/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb index c0912aff1..be08a70b0 100644 --- a/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb +++ b/aviary/docs/user_guide/examples_of_the_same_mission_at_different_UI_levels.ipynb @@ -434,6 +434,8 @@ "]\n", "av.set_aviary_input_defaults(prob.model, varnames, aviary_inputs)\n", "\n", + "av.setup_model_options(prob, aviary_inputs)\n", + "\n", "prob.setup(force_alloc_complex=True)\n", "\n", "av.set_aviary_initial_values(prob, aviary_inputs)\n", @@ -505,7 +507,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/aviary/docs/user_guide/variable_metadata.ipynb b/aviary/docs/user_guide/variable_metadata.ipynb index 15fea1c3b..a8bf93016 100644 --- a/aviary/docs/user_guide/variable_metadata.ipynb +++ b/aviary/docs/user_guide/variable_metadata.ipynb @@ -42,6 +42,7 @@ " 'option': False,\n", " 'types': None,\n", " 'historical_name': None,\n", + " 'multivalue': False,\n", " }\n", "\n", "meta_data = {}\n", @@ -447,7 +448,7 @@ "hash": "e6c7471802ed76737b16357fb02af5587f3a4cbee5ea7658f3f9a6981469039b" }, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -461,7 +462,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.12.3" }, "orphan": true }, diff --git a/aviary/examples/external_subsystems/OAS_weight/OAS_wing_weight_analysis.py b/aviary/examples/external_subsystems/OAS_weight/OAS_wing_weight_analysis.py index 3d38ed265..ae6215974 100644 --- a/aviary/examples/external_subsystems/OAS_weight/OAS_wing_weight_analysis.py +++ b/aviary/examples/external_subsystems/OAS_weight/OAS_wing_weight_analysis.py @@ -491,7 +491,6 @@ def compute(self, inputs, outputs): prob.driver = om.ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-8 - # Set up the problem with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=om.PromotionWarning) diff --git a/aviary/examples/multi_mission/run_multimission_example_large_single_aisle.py b/aviary/examples/multi_mission/run_multimission_example_large_single_aisle.py index 5d76cfbb2..bbc388816 100644 --- a/aviary/examples/multi_mission/run_multimission_example_large_single_aisle.py +++ b/aviary/examples/multi_mission/run_multimission_example_large_single_aisle.py @@ -2,17 +2,18 @@ authors: Jatin Soni, Eliot Aretskin Multi Mission Optimization Example using Aviary -In this example, a monolithic optimization is created by instantiating two aviary problems -using typical AviaryProblem calls like load_inputs(), check_and_preprocess_payload(), -etc. Once those problems are setup and all of their phases are linked together, we copy -those problems as group into a super_problem. We then promote GROSS_MASS, RANGE, and -wing SWEEP from each of those sub-groups (group1 and group2) up to the super_probem so -the optimizer can control them. The fuel_burn results from each of the group1 and group2 +In this example, a monolithic optimization is created by instantiating two aviary problems +using typical AviaryProblem calls like load_inputs(), check_and_preprocess_payload(), +etc. Once those problems are setup and all of their phases are linked together, we copy +those problems as group into a super_problem. We then promote GROSS_MASS, RANGE, and +wing SWEEP from each of those sub-groups (group1 and group2) up to the super_probem so +the optimizer can control them. The fuel_burn results from each of the group1 and group2 dymos missions are summed and weighted to create the objective function the optimizer sees. """ import copy as copy from aviary.examples.example_phase_info import phase_info +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Mission, Aircraft, Settings from aviary.variable_info.enums import ProblemType import aviary.api as av @@ -146,11 +147,16 @@ def add_objective(self): def setup_wrapper(self): """Wrapper for om.Problem setup with warning ignoring and setting options""" - for prob in self.probs: + for i, prob in enumerate(self.probs): prob.model.options['aviary_options'] = prob.aviary_inputs prob.model.options['aviary_metadata'] = prob.meta_data prob.model.options['phase_info'] = prob.phase_info + # Use OpenMDAO's model options to pass all options through the system hierarchy. + prefix = self.group_prefix + f'_{i}' + setup_model_options(self, prob.aviary_inputs, prob.meta_data, + prefix=f'{prefix}.') + # Aviary's problem setup wrapper uses these ignored warnings to suppress # some warnings related to variable promotion. Replicating that here with # setup for the super problem diff --git a/aviary/interface/methods_for_level2.py b/aviary/interface/methods_for_level2.py index 6c7df771f..bdd8b03e0 100644 --- a/aviary/interface/methods_for_level2.py +++ b/aviary/interface/methods_for_level2.py @@ -77,7 +77,11 @@ LegacyCode, Verbosity, ) -from aviary.variable_info.functions import setup_trajectory_params, override_aviary_vars +from aviary.variable_info.functions import ( + setup_trajectory_params, + override_aviary_vars, + setup_model_options, +) from aviary.variable_info.variables import Aircraft, Mission, Dynamic, Settings from aviary.variable_info.variable_meta_data import _MetaData as BaseMetaData @@ -2506,6 +2510,9 @@ def setup(self, **kwargs): """ Lightly wrapped setup() method for the problem. """ + # Use OpenMDAO's model options to pass all options through the system hierarchy. + setup_model_options(self, self.aviary_inputs, self.meta_data) + # suppress warnings: # "input variable '...' promoted using '*' was already promoted using 'aircraft:*' with warnings.catch_warnings(): @@ -2516,6 +2523,7 @@ def setup(self, **kwargs): warnings.simplefilter("ignore", om.OpenMDAOWarning) warnings.simplefilter("ignore", om.PromotionWarning) + super().setup(**kwargs) def set_initial_guesses(self, parent_prob=None, parent_prefix="", verbosity=None): diff --git a/aviary/mission/energy_phase.py b/aviary/mission/energy_phase.py index 35a28c128..194b6bc98 100644 --- a/aviary/mission/energy_phase.py +++ b/aviary/mission/energy_phase.py @@ -3,7 +3,6 @@ from aviary.mission.flight_phase_builder import FlightPhaseBase, register from aviary.mission.initial_guess_builders import InitialGuessIntegrationVariable, InitialGuessState -from aviary.utils.aviary_values import AviaryValues from aviary.mission.flops_based.ode.mission_ODE import MissionODE diff --git a/aviary/mission/flops_based/ode/mission_ODE.py b/aviary/mission/flops_based/ode/mission_ODE.py index bc1c4832e..389ce80a5 100644 --- a/aviary/mission/flops_based/ode/mission_ODE.py +++ b/aviary/mission/flops_based/ode/mission_ODE.py @@ -230,8 +230,7 @@ def setup(self): "throttle_allocator", ThrottleAllocator( num_nodes=nn, - aviary_options=aviary_options, - throttle_allocation=self.options['throttle_allocation'], + throttle_allocation=self.options['throttle_allocation'] ), promotes_inputs=['*'], promotes_outputs=['*'], diff --git a/aviary/mission/flops_based/phases/test/test_time_integration_phases.py b/aviary/mission/flops_based/phases/test/test_time_integration_phases.py index 788fe0823..ce7055735 100644 --- a/aviary/mission/flops_based/phases/test/test_time_integration_phases.py +++ b/aviary/mission/flops_based/phases/test/test_time_integration_phases.py @@ -1,3 +1,7 @@ +import warnings +import unittest +import importlib + import openmdao.api as om from openmdao.utils.assert_utils import assert_near_equal @@ -12,13 +16,10 @@ from aviary.utils.process_input_decks import create_vehicle from aviary.utils.test_utils.default_subsystems import get_default_premission_subsystems from aviary.variable_info.enums import EquationsOfMotion +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variable_meta_data import _MetaData as BaseMetaData from aviary.variable_info.variables import Aircraft, Dynamic, Mission, Settings -import warnings -import unittest -import importlib - @unittest.skipUnless(importlib.util.find_spec("pyoptsparse") is not None, "pyoptsparse is not installed") class HE_SGMDescentTestCase(unittest.TestCase): @@ -108,6 +109,8 @@ def setup_prob(self, phases) -> om.Problem: prob.model.add_objective(Mission.Objectives.FUEL, ref=1e4) + setup_model_options(prob, aviary_options) + with warnings.catch_warnings(): warnings.simplefilter("ignore", om.PromotionWarning) diff --git a/aviary/mission/gasp_based/ode/taxi_eom.py b/aviary/mission/gasp_based/ode/taxi_eom.py index 8f4f5d5c0..eceb83bd7 100644 --- a/aviary/mission/gasp_based/ode/taxi_eom.py +++ b/aviary/mission/gasp_based/ode/taxi_eom.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input +from aviary.variable_info.functions import add_aviary_input, add_aviary_option from aviary.variable_info.variables import Dynamic, Mission @@ -12,9 +11,7 @@ class TaxiFuelComponent(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Mission.Taxi.DURATION, units='s') def setup(self): self.add_input( @@ -51,12 +48,12 @@ def setup_partials(self): def compute(self, inputs, outputs): fuelflow, takeoff_mass = inputs.values() - dt_taxi = self.options['aviary_options'].get_val(Mission.Taxi.DURATION, 's') + dt_taxi, _ = self.options[Mission.Taxi.DURATION] outputs["taxi_fuel_consumed"] = -fuelflow * dt_taxi outputs[Dynamic.Vehicle.MASS] = takeoff_mass - outputs["taxi_fuel_consumed"] def compute_partials(self, inputs, J): - dt_taxi = self.options['aviary_options'].get_val(Mission.Taxi.DURATION, 's') + dt_taxi, _ = self.options[Mission.Taxi.DURATION] J[ "taxi_fuel_consumed", diff --git a/aviary/mission/gasp_based/ode/taxi_ode.py b/aviary/mission/gasp_based/ode/taxi_ode.py index dce4fe403..fa593c47a 100644 --- a/aviary/mission/gasp_based/ode/taxi_ode.py +++ b/aviary/mission/gasp_based/ode/taxi_ode.py @@ -80,7 +80,7 @@ def setup(self): ) self.add_subsystem( - "taxifuel", TaxiFuelComponent(aviary_options=options), promotes=["*"] + "taxifuel", TaxiFuelComponent(), promotes=["*"] ) ParamPort.set_default_vals(self) diff --git a/aviary/mission/gasp_based/ode/test/test_landing_ode.py b/aviary/mission/gasp_based/ode/test/test_landing_ode.py index d22520f6c..74498ded9 100644 --- a/aviary/mission/gasp_based/ode/test/test_landing_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_landing_ode.py @@ -12,6 +12,7 @@ from aviary.subsystems.propulsion.utils import build_engine_deck from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems from aviary.utils.test_utils.IO_test_util import check_prob_outputs +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Dynamic, Mission @@ -32,6 +33,8 @@ def setUp(self): self.prob.model = LandingSegment( aviary_options=options, core_subsystems=core_subsystems) + setup_model_options(self.prob, options) + @unittest.skipIf(version.parse(openmdao.__version__) < version.parse("3.26"), "Skipping due to OpenMDAO version being too low (<3.26)") def test_dland(self): self.prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/mission/gasp_based/ode/test/test_taxi_eom.py b/aviary/mission/gasp_based/ode/test/test_taxi_eom.py index 5afa6a3cd..0eacbbb6a 100644 --- a/aviary/mission/gasp_based/ode/test/test_taxi_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_taxi_eom.py @@ -6,6 +6,7 @@ from aviary.utils.aviary_values import AviaryValues from aviary.mission.gasp_based.ode.taxi_eom import TaxiFuelComponent +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Dynamic, Mission @@ -15,13 +16,15 @@ class TaxiFuelComponentTestCase(unittest.TestCase): """ def setUp(self): - self.prob = om.Problem(model=om.Group()) + self.prob = om.Problem() aviary_options = AviaryValues() aviary_options.set_val(Mission.Taxi.DURATION, 0.1677, units="h") - self.prob.model.add_subsystem('taxi', TaxiFuelComponent( - aviary_options=aviary_options), promotes=['*']) + self.prob.model.add_subsystem('taxi', TaxiFuelComponent(), + promotes=['*']) + + setup_model_options(self.prob, aviary_options) def test_fuel_consumed(self): self.prob.setup(force_alloc_complex=True) diff --git a/aviary/mission/gasp_based/ode/test/test_taxi_ode.py b/aviary/mission/gasp_based/ode/test/test_taxi_ode.py index 95825f8db..9bbdcb5e9 100644 --- a/aviary/mission/gasp_based/ode/test/test_taxi_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_taxi_ode.py @@ -10,6 +10,7 @@ from aviary.subsystems.propulsion.utils import build_engine_deck from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems from aviary.utils.test_utils.IO_test_util import check_prob_outputs +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Dynamic, Mission @@ -33,6 +34,8 @@ def setUp(self): aviary_options=options, core_subsystems=default_mission_subsystems ) + setup_model_options(self.prob, options) + self.prob.model.set_input_defaults( Mission.Takeoff.AIRPORT_ALTITUDE, 0.0, diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_alpha_thrust_iter_group.py b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_alpha_thrust_iter_group.py index b59740665..1486d307e 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_alpha_thrust_iter_group.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_alpha_thrust_iter_group.py @@ -41,7 +41,6 @@ def _test_unsteady_alpha_thrust_iter_group(self, ground_roll=False): g = UnsteadyControlIterGroup(num_nodes=nn, ground_roll=ground_roll, clean=True, - aviary_options=get_option_defaults(), core_subsystems=[aero]) ig = p.model.add_subsystem("iter_group", diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_control_iter_group.py b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_control_iter_group.py index d8221697b..37a2fcb65 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_control_iter_group.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_control_iter_group.py @@ -21,6 +21,7 @@ def initialize(self): "output and adjusts the TAS rate equation.") self.options.declare("clean", types=bool, default=False, desc="If true then no flaps or gear are included. Useful for high-speed flight phases.") + self.options.declare( 'aviary_options', types=AviaryValues, default=None, desc='collection of Aircraft/Mission specific options' diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index 679e91c29..0dd98dfd8 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -104,10 +104,10 @@ def build_pre_mission(self, aviary_inputs): code_origin = self.code_origin if code_origin is GASP: - aero_group = PreMissionAero(aviary_options=aviary_inputs) + aero_group = PreMissionAero() elif code_origin is FLOPS: - aero_group = Design(aviary_options=aviary_inputs) + aero_group = Design() return aero_group @@ -118,12 +118,10 @@ def build_mission(self, num_nodes, aviary_inputs, **kwargs): method = None if self.code_origin is FLOPS: if method is None: - aero_group = ComputedAeroGroup(num_nodes=num_nodes, - aviary_options=aviary_inputs) + aero_group = ComputedAeroGroup(num_nodes=num_nodes) elif method == 'computed': aero_group = ComputedAeroGroup(num_nodes=num_nodes, - aviary_options=aviary_inputs, **kwargs) elif method == 'low_speed': @@ -162,7 +160,6 @@ def build_mission(self, num_nodes, aviary_inputs, **kwargs): **kwargs) else: aero_group = CruiseAero(num_nodes=num_nodes, - aviary_options=aviary_inputs, **kwargs) elif method == 'low_speed': @@ -180,7 +177,6 @@ def build_mission(self, num_nodes, aviary_inputs, **kwargs): else: aero_group = LowSpeedAero(num_nodes=num_nodes, - aviary_options=aviary_inputs, **kwargs) else: diff --git a/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py b/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py index 22ff6ea54..93f80e009 100644 --- a/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py @@ -17,7 +17,6 @@ from aviary.subsystems.aerodynamics.flops_based.skin_friction import SkinFriction from aviary.subsystems.aerodynamics.flops_based.skin_friction_drag import \ SkinFrictionDrag -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft, Dynamic, Mission @@ -33,16 +32,12 @@ def initialize(self): self.options.declare( 'gamma', default=1.4, desc='Ratio of specific heats for air.') - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') def setup(self): num_nodes = self.options["num_nodes"] gamma = self.options['gamma'] - aviary_options: AviaryValues = self.options['aviary_options'] - comp = MuxComponent(aviary_options=aviary_options) + comp = MuxComponent() self.add_subsystem( 'Mux', comp, promotes_inputs=['aircraft:*'], @@ -91,7 +86,7 @@ def setup(self): ) comp = InducedDrag( - num_nodes=num_nodes, gamma=gamma, aviary_options=aviary_options) + num_nodes=num_nodes, gamma=gamma) self.add_subsystem( 'InducedDrag', comp, @@ -127,7 +122,7 @@ def setup(self): ], ) - comp = SkinFriction(num_nodes=num_nodes, aviary_options=aviary_options) + comp = SkinFriction(num_nodes=num_nodes) self.add_subsystem( 'SkinFrictionCoef', comp, @@ -140,7 +135,7 @@ def setup(self): promotes_outputs=['skin_friction_coeff', 'Re'], ) - comp = SkinFrictionDrag(num_nodes=num_nodes, aviary_options=aviary_options) + comp = SkinFrictionDrag(num_nodes=num_nodes) self.add_subsystem( 'SkinFrictionDrag', comp, promotes_inputs=[ diff --git a/aviary/subsystems/aerodynamics/flops_based/design.py b/aviary/subsystems/aerodynamics/flops_based/design.py index 0ab64ccd4..81213642f 100644 --- a/aviary/subsystems/aerodynamics/flops_based/design.py +++ b/aviary/subsystems/aerodynamics/flops_based/design.py @@ -7,8 +7,7 @@ import openmdao.api as om from openmdao.components.interp_util.interp import InterpND -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -27,9 +26,8 @@ def __init__(self, **kwargs): self.des_mach_coeff = [0.32, 57.2958, 0.144] def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Wing.AIRFOIL_TECHNOLOGY) + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): # Aircraft design inputs @@ -46,9 +44,8 @@ def setup_partials(self): self.declare_partials(of='*', wrt='*') def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - AITEK = aviary_options.get_val(Aircraft.Wing.AIRFOIL_TECHNOLOGY) - VMAX = aviary_options.get_val(Mission.Constraints.MAX_MACH) + AITEK = self.options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] + VMAX = self.options[Mission.Constraints.MAX_MACH] AR, CAM, SW25, TC = inputs.values() @@ -89,9 +86,8 @@ def compute(self, inputs, outputs): outputs[Mission.Design.MACH] = DESM2D + DMDSWP + DMDAR def compute_partials(self, inputs, partials): - aviary_options: AviaryValues = self.options['aviary_options'] - AITEK = aviary_options.get_val(Aircraft.Wing.AIRFOIL_TECHNOLOGY) - VMAX = aviary_options.get_val(Mission.Constraints.MAX_MACH) + AITEK = self.options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] + VMAX = self.options[Mission.Constraints.MAX_MACH] AR, CAM, SW25, TC = inputs.values() diff --git a/aviary/subsystems/aerodynamics/flops_based/drag_polar.py b/aviary/subsystems/aerodynamics/flops_based/drag_polar.py index 4d55ed77b..9b1455fa7 100644 --- a/aviary/subsystems/aerodynamics/flops_based/drag_polar.py +++ b/aviary/subsystems/aerodynamics/flops_based/drag_polar.py @@ -6,7 +6,7 @@ import openmdao.api as om from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input +from aviary.variable_info.functions import add_aviary_input, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -20,13 +20,10 @@ class DragPolar(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - aviary_options = self.options['aviary_options'] - num_engine_type = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Canard.WETTED_AREA, 0.0) add_aviary_input(self, Aircraft.Fuselage.WETTED_AREA, 0.0) diff --git a/aviary/subsystems/aerodynamics/flops_based/induced_drag.py b/aviary/subsystems/aerodynamics/flops_based/induced_drag.py index 001fa60f8..33bc9f033 100644 --- a/aviary/subsystems/aerodynamics/flops_based/induced_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/induced_drag.py @@ -2,8 +2,7 @@ import openmdao.api as om import scipy.constants as _units -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input +from aviary.variable_info.functions import add_aviary_input, add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic @@ -19,9 +18,8 @@ def initialize(self): self.options.declare( 'gamma', default=1.4, desc='Ratio of specific heats for air.') - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + + add_aviary_option(self, Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) def setup(self): nn = self.options["num_nodes"] @@ -79,13 +77,11 @@ def setup_partials(self): def compute(self, inputs, outputs): options = self.options gamma = options['gamma'] - aviary_options: AviaryValues = options['aviary_options'] mach, lift, P, Sref, AR, span_efficiency_factor, SW25, TR = inputs.values() CL = 2.0 * lift / (Sref * gamma * P * mach ** 2) - redux, _ = aviary_options.get_item( - Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, (False, None)) + redux = self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] if redux: # Adjustment for extreme taper ratios. @@ -124,10 +120,8 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, partials): options = self.options gamma = options['gamma'] - aviary_options: AviaryValues = options['aviary_options'] mach, lift, P, Sref, AR, span_efficiency_factor, SW25, TR = inputs.values() - redux, _ = aviary_options.get_item( - Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, (False, None)) + redux = self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] if redux: sqrt_AR = np.sqrt(AR) diff --git a/aviary/subsystems/aerodynamics/flops_based/mux_component.py b/aviary/subsystems/aerodynamics/flops_based/mux_component.py index bd0ce2f44..a1560a477 100644 --- a/aviary/subsystems/aerodynamics/flops_based/mux_component.py +++ b/aviary/subsystems/aerodynamics/flops_based/mux_component.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, get_units +from aviary.variable_info.functions import add_aviary_input, get_units, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -23,13 +22,12 @@ def __init__(self, **kwargs): super().__init__(**kwargs) def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + 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): nc = 2 - aviary_options: AviaryValues = self.options['aviary_options'] # Wing (Always 1) add_aviary_input(self, Aircraft.Wing.WETTED_AREA, 1.0) @@ -45,9 +43,8 @@ def setup(self): add_aviary_input(self, Aircraft.HorizontalTail.LAMINAR_FLOW_UPPER, 0.0) add_aviary_input(self, Aircraft.HorizontalTail.LAMINAR_FLOW_LOWER, 0.0) - zero_count = (0, None) - # Vertical Tail - num, _ = aviary_options.get_item(Aircraft.VerticalTail.NUM_TAILS, zero_count) + num = self.options[Aircraft.VerticalTail.NUM_TAILS] + self.num_tails = num if num > 0: add_aviary_input(self, Aircraft.VerticalTail.WETTED_AREA, 1.0) @@ -58,7 +55,7 @@ def setup(self): nc += num # Fuselage - num, _ = aviary_options.get_item(Aircraft.Fuselage.NUM_FUSELAGES, zero_count) + num = self.options[Aircraft.Fuselage.NUM_FUSELAGES] self.num_fuselages = num if num > 0: add_aviary_input(self, Aircraft.Fuselage.WETTED_AREA, 1.0) @@ -68,19 +65,21 @@ def setup(self): add_aviary_input(self, Aircraft.Fuselage.LAMINAR_FLOW_LOWER, 0.0) nc += num - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] + num_engine_models = len(num_engines) self.num_nacelles = int(sum(num_engines)) + if self.num_nacelles > 0: add_aviary_input(self, Aircraft.Nacelle.WETTED_AREA, - np.zeros(len(num_engines))) + np.zeros(num_engine_models)) add_aviary_input(self, Aircraft.Nacelle.FINENESS, - np.zeros(len(num_engines))) + np.zeros(num_engine_models)) add_aviary_input(self, Aircraft.Nacelle.CHARACTERISTIC_LENGTH, - np.zeros(len(num_engines))) + np.zeros(num_engine_models)) add_aviary_input(self, Aircraft.Nacelle.LAMINAR_FLOW_UPPER, - np.zeros(len(num_engines))) + np.zeros(num_engine_models)) add_aviary_input(self, Aircraft.Nacelle.LAMINAR_FLOW_LOWER, - np.zeros(len(num_engines))) + np.zeros(num_engine_models)) nc += self.num_nacelles self.add_output( @@ -185,8 +184,8 @@ def setup_partials(self): # Nacelle if self.num_nacelles > 0: # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engines = self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] + rows = ic + np.arange(self.num_nacelles) cols = [item for sublist in [[i]*j for i, j in enumerate(num_engines)] for item in sublist] @@ -268,7 +267,7 @@ def compute(self, inputs, outputs): ic += self.num_fuselages # Nacelle - num_engines = self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] wetted_areas = inputs[Aircraft.Nacelle.WETTED_AREA] fineness = inputs[Aircraft.Nacelle.FINENESS] diff --git a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py index 0f79e9fcb..27d5bce16 100644 --- a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py +++ b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py @@ -1,7 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues +from aviary.variable_info.functions import add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic @@ -35,21 +35,17 @@ def initialize(self): self.options.declare( 'num_nodes', types=int, default=1, desc='The number of points at which the cross product is computed.') - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + + 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'] - aviary_options: AviaryValues = self.options['aviary_options'] - zero_count = (0, None) - num_tails, _ = aviary_options.get_item( - Aircraft.VerticalTail.NUM_TAILS, zero_count) - num_fuselages, _ = aviary_options.get_item( - Aircraft.Fuselage.NUM_FUSELAGES, zero_count) - # TODO does not used vectorized heterogeneous engines. Temp using single engine - num_engines, _ = aviary_options.get_item( - Aircraft.Engine.NUM_ENGINES, zero_count) + 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)) # Simulation inputs diff --git a/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py b/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py index c7a9edd0f..3f377ba6b 100644 --- a/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/skin_friction_drag.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, get_units +from aviary.variable_info.functions import add_aviary_input, get_units, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -27,23 +26,24 @@ def initialize(self): self.options.declare( 'num_nodes', types=int, default=1, desc='The number of points at which the cross product is computed.') - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - # TODO: Convert these into aviary_options entries. + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) + add_aviary_option(self, Aircraft.VerticalTail.NUM_TAILS) + add_aviary_option(self, Aircraft.Wing.AIRFOIL_TECHNOLOGY) + + # TODO: Bring this into the variable hierarchy. self.options.declare( 'excrescences_drag', default=0.06, desc='Drag contribution of excrescences as a percentage.') def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] nn = self.options['num_nodes'] - zero_count = (0, None) - nvtail, _ = aviary_options.get_item(Aircraft.VerticalTail.NUM_TAILS, zero_count) - nfuse, _ = aviary_options.get_item(Aircraft.Fuselage.NUM_FUSELAGES, zero_count) - num_engines, _ = aviary_options.get_item(Aircraft.Engine.NUM_ENGINES, zero_count) + 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)) # Computed by other components in drag group. @@ -96,7 +96,6 @@ def setup_partials(self): def compute(self, inputs, outputs): nc = self.nc - aviary_options: AviaryValues = self.options['aviary_options'] cf = inputs['skin_friction_coeff'] Re = inputs['Re'] @@ -136,7 +135,7 @@ def compute(self, inputs, outputs): # Form factor for surfaces. idx_surf = np.where(fineness <= 0.5)[0] fine = fineness[idx_surf] - airfoil = aviary_options.get_val(Aircraft.Wing.AIRFOIL_TECHNOLOGY) + airfoil = self.options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] FF1 = 1.0 + fine * (F[7] + fine * (F[8] + fine * (F[9] + fine * (F[10] + fine * (F[11] + fine * F[12]))))) @@ -163,7 +162,6 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, partials): nc = self.nc nn = self.options["num_nodes"] - aviary_options: AviaryValues = self.options['aviary_options'] cf = inputs['skin_friction_coeff'] Re = inputs['Re'] @@ -209,7 +207,7 @@ def compute_partials(self, inputs, partials): idx_surf = np.where(fineness <= 0.5)[0] fine = fineness[idx_surf] - airfoil = aviary_options.get_val(Aircraft.Wing.AIRFOIL_TECHNOLOGY) + airfoil = self.options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] FF1 = 1.0 + fine * ( F[7] + fine diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_computed_aero_group.py b/aviary/subsystems/aerodynamics/flops_based/test/test_computed_aero_group.py index 350d10b6d..53561b65a 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_computed_aero_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_computed_aero_group.py @@ -10,6 +10,7 @@ from aviary.utils.preprocessors import preprocess_options from aviary.utils.test_utils.default_subsystems import get_default_premission_subsystems from aviary.validation_cases.validation_tests import get_flops_inputs, get_flops_outputs +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic, Settings @@ -82,6 +83,8 @@ def test_basic_large_single_aisle_1(self): promotes=['*'] ) + # Set all options + setup_model_options(prob, flops_inputs) prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) prob.setup(force_alloc_complex=True) @@ -196,6 +199,9 @@ def test_n3cc_drag(self): promotes=['*'] ) + # Set all options + setup_model_options(prob, flops_inputs) + prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) prob.setup() @@ -309,6 +315,9 @@ def test_large_single_aisle_2_drag(self): promotes=['*'] ) + # Set all options + setup_model_options(prob, flops_inputs) + prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) prob.setup() diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_design.py b/aviary/subsystems/aerodynamics/flops_based/test/test_design.py index 8b9bcb94c..99da39a97 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_design.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_design.py @@ -4,7 +4,6 @@ from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal from aviary.subsystems.aerodynamics.flops_based.design import Design -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft, Mission @@ -17,12 +16,12 @@ def test_derivs_supersonic1(self): model = prob.model options = {} - options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = (1.0, 'unitless') - options[Mission.Constraints.MAX_MACH] = (1.2, 'unitless') + options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = 1.0 + options[Mission.Constraints.MAX_MACH] = 1.2 model.add_subsystem( 'design', - Design(aviary_options=AviaryValues(options)), + Design(**options), promotes_inputs=['*'], promotes_outputs=[Mission.Design.MACH, Mission.Design.LIFT_COEFFICIENT] ) @@ -50,12 +49,12 @@ def test_derivs_subsonic1(self): model = prob.model options = {} - options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = (1.0, 'unitless') - options[Mission.Constraints.MAX_MACH] = (0.9, 'unitless') + options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = 1.0 + options[Mission.Constraints.MAX_MACH] = 0.9 model.add_subsystem( 'design', - Design(aviary_options=AviaryValues(options)), + Design(**options), promotes_inputs=['*'], promotes_outputs=[Mission.Design.MACH, Mission.Design.LIFT_COEFFICIENT], ) @@ -83,12 +82,12 @@ def test_derivs_supersonic2(self): model = prob.model options = {} - options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = (1.0, 'unitless') - options[Mission.Constraints.MAX_MACH] = (1.2, 'unitless') + options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = 1.0 + options[Mission.Constraints.MAX_MACH] = 1.2 model.add_subsystem( 'design', - Design(aviary_options=AviaryValues(options)), + Design(**options), promotes_inputs=['*'], promotes_outputs=[Mission.Design.MACH, Mission.Design.LIFT_COEFFICIENT], ) @@ -116,12 +115,12 @@ def test_derivs_subsonic2(self): model = prob.model options = {} - options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = (1.0, 'unitless') - options[Mission.Constraints.MAX_MACH] = (0.9, 'unitless') + options[Aircraft.Wing.AIRFOIL_TECHNOLOGY] = 1.0 + options[Mission.Constraints.MAX_MACH] = 0.9 model.add_subsystem( 'design', - Design(aviary_options=AviaryValues(options)), + Design(**options), promotes_inputs=['*'], promotes_outputs=[Mission.Design.MACH, Mission.Design.LIFT_COEFFICIENT], ) diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_induced_drag.py b/aviary/subsystems/aerodynamics/flops_based/test/test_induced_drag.py index dd990ccdf..e73ac37c3 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_induced_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_induced_drag.py @@ -5,7 +5,6 @@ from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal from aviary.subsystems.aerodynamics.flops_based.induced_drag import InducedDrag -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft, Dynamic @@ -21,13 +20,13 @@ def test_derivs(self): nn = len(CL) - prob = om.Problem(model=om.Group()) + prob = om.Problem() options = {} - options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] = (False, 'unitless') + options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] = False prob.model.add_subsystem('induced_drag', InducedDrag( - num_nodes=nn, aviary_options=AviaryValues(options)), promotes=['*']) + num_nodes=nn, **options), promotes=['*']) prob.setup(force_alloc_complex=True) prob.set_val(Dynamic.Atmosphere.MACH, val=mach) @@ -60,13 +59,13 @@ def test_derivs_span_eff_redux(self): # High factor - prob = om.Problem(model=om.Group()) + prob = om.Problem() options = {} - options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] = (True, 'unitless') + options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] = True prob.model.add_subsystem('drag', InducedDrag( - num_nodes=nn, aviary_options=AviaryValues(options)), promotes=['*']) + num_nodes=nn, **options), promotes=['*']) prob.setup(force_alloc_complex=True) prob.set_val(Dynamic.Atmosphere.MACH, val=mach) @@ -92,10 +91,10 @@ def test_derivs_span_eff_redux(self): prob = om.Problem(model=om.Group()) options = {} - options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] = (True, 'unitless') + options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] = True prob.model.add_subsystem('drag', InducedDrag( - num_nodes=nn, aviary_options=AviaryValues(options)), promotes=['*']) + num_nodes=nn, **options), promotes=['*']) prob.setup(force_alloc_complex=True) prob.set_val(Dynamic.Atmosphere.MACH, val=mach) diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_mux_component.py b/aviary/subsystems/aerodynamics/flops_based/test/test_mux_component.py index e26321f57..592e71d06 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_mux_component.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_mux_component.py @@ -6,7 +6,6 @@ from openmdao.utils.assert_utils import assert_check_partials from aviary.subsystems.aerodynamics.flops_based.mux_component import MuxComponent -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft @@ -16,13 +15,14 @@ def test_mux(self): prob = om.Problem() model = prob.model - aviary_options = AviaryValues() - aviary_options.set_val(Aircraft.VerticalTail.NUM_TAILS, 1) - aviary_options.set_val(Aircraft.Fuselage.NUM_FUSELAGES, 1) - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2])) + aviary_options = { + Aircraft.Engine.NUM_ENGINES: np.array([2]), + Aircraft.Fuselage.NUM_FUSELAGES: 1, + Aircraft.VerticalTail.NUM_TAILS: 1, + } model.add_subsystem( - 'mux', MuxComponent(aviary_options=aviary_options), + 'mux', MuxComponent(**aviary_options), promotes_inputs=['*']) prob.setup(force_alloc_complex=True) @@ -91,13 +91,14 @@ def test_mux_multiengine(self): prob = om.Problem() model = prob.model - aviary_options = AviaryValues() - aviary_options.set_val(Aircraft.VerticalTail.NUM_TAILS, 1) - aviary_options.set_val(Aircraft.Fuselage.NUM_FUSELAGES, 1) - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2, 3])) + aviary_options = { + Aircraft.Engine.NUM_ENGINES: np.array([2, 3]), + Aircraft.Fuselage.NUM_FUSELAGES: 1, + Aircraft.VerticalTail.NUM_TAILS: 1, + } model.add_subsystem( - 'mux', MuxComponent(aviary_options=aviary_options), + 'mux', MuxComponent(**aviary_options), promotes_inputs=['*']) prob.setup(force_alloc_complex=True) diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_coef.py b/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_coef.py index cbb63666b..e4fd91f5d 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_coef.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_coef.py @@ -5,7 +5,6 @@ from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal from aviary.subsystems.aerodynamics.flops_based.skin_friction import SkinFriction -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft @@ -24,12 +23,12 @@ def test_derivs(self): model = prob.model options = {} - options[Aircraft.VerticalTail.NUM_TAILS] = (0, 'unitless') - options[Aircraft.Fuselage.NUM_FUSELAGES] = (1, 'unitless') - options[Aircraft.Engine.NUM_ENGINES] = ([0], 'unitless') + options[Aircraft.VerticalTail.NUM_TAILS] = 0 + options[Aircraft.Fuselage.NUM_FUSELAGES] = 1 + options[Aircraft.Engine.NUM_ENGINES] = [0] model.add_subsystem( - 'cf', SkinFriction(num_nodes=n, aviary_options=AviaryValues(options)), promotes=['*']) + 'cf', SkinFriction(num_nodes=n, **options), promotes=['*']) prob.setup(force_alloc_complex=True) @@ -122,12 +121,12 @@ def test_derivs_multiengine(self): model = prob.model options = {} - options[Aircraft.VerticalTail.NUM_TAILS] = (0, 'unitless') - options[Aircraft.Fuselage.NUM_FUSELAGES] = (1, 'unitless') - options[Aircraft.Engine.NUM_ENGINES] = ([2, 4], 'unitless') + options[Aircraft.VerticalTail.NUM_TAILS] = 0 + options[Aircraft.Fuselage.NUM_FUSELAGES] = 1 + options[Aircraft.Engine.NUM_ENGINES] = [2, 4] model.add_subsystem( - 'cf', SkinFriction(num_nodes=n, aviary_options=AviaryValues(options)), promotes=['*']) + 'cf', SkinFriction(num_nodes=n, **options), promotes=['*']) prob.setup(force_alloc_complex=True) @@ -281,12 +280,12 @@ def test_skin_friction_algorithm(self): model = prob.model options = {} - options[Aircraft.VerticalTail.NUM_TAILS] = (0, 'unitless') - options[Aircraft.Fuselage.NUM_FUSELAGES] = (1, 'unitless') - options[Aircraft.Engine.NUM_ENGINES] = ([0], 'unitless') + options[Aircraft.VerticalTail.NUM_TAILS] = 0 + options[Aircraft.Fuselage.NUM_FUSELAGES] = 1 + options[Aircraft.Engine.NUM_ENGINES] = [0] model.add_subsystem( - 'cf', SkinFriction(num_nodes=n, aviary_options=AviaryValues(options))) + 'cf', SkinFriction(num_nodes=n, **options)) prob.setup(force_alloc_complex=True) diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_drag.py b/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_drag.py index 3be06d264..63435d039 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_skinfriction_drag.py @@ -6,7 +6,6 @@ from aviary.subsystems.aerodynamics.flops_based.skin_friction_drag import \ SkinFrictionDrag -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft @@ -28,14 +27,15 @@ def test_derivs(self): prob = om.Problem() model = prob.model - options = AviaryValues() - options.set_val(Aircraft.Fuselage.NUM_FUSELAGES, 1) - options.set_val(Aircraft.Engine.NUM_ENGINES, [2]) - options.set_val(Aircraft.VerticalTail.NUM_TAILS, 1) - options.set_val(Aircraft.Wing.AIRFOIL_TECHNOLOGY, 1.93) + options = { + Aircraft.Fuselage.NUM_FUSELAGES: 1, + Aircraft.Engine.NUM_ENGINES: [2], + Aircraft.VerticalTail.NUM_TAILS: 1, + Aircraft.Wing.AIRFOIL_TECHNOLOGY: 1.93, + } model.add_subsystem( - 'CDf', SkinFrictionDrag(num_nodes=nn, aviary_options=options), + 'CDf', SkinFrictionDrag(num_nodes=nn, **options), promotes_inputs=[Aircraft.Wing.AREA], promotes_outputs=['skin_friction_drag_coeff']) @@ -77,14 +77,15 @@ def test_derivs_multiengine(self): prob = om.Problem() model = prob.model - options = AviaryValues() - options.set_val(Aircraft.Fuselage.NUM_FUSELAGES, 1) - options.set_val(Aircraft.Engine.NUM_ENGINES, [2, 4]) - options.set_val(Aircraft.VerticalTail.NUM_TAILS, 1) - options.set_val(Aircraft.Wing.AIRFOIL_TECHNOLOGY, 1.93) + options = { + Aircraft.Fuselage.NUM_FUSELAGES: 1, + Aircraft.Engine.NUM_ENGINES: [2, 4], + Aircraft.VerticalTail.NUM_TAILS: 1, + Aircraft.Wing.AIRFOIL_TECHNOLOGY: 1.93, + } model.add_subsystem( - 'CDf', SkinFrictionDrag(num_nodes=nn, aviary_options=options), + 'CDf', SkinFrictionDrag(num_nodes=nn, **options), promotes_inputs=[Aircraft.Wing.AREA], promotes_outputs=['skin_friction_drag_coeff']) diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_tabular_aero_group.py b/aviary/subsystems/aerodynamics/flops_based/test/test_tabular_aero_group.py index 2bc808c6d..fd7a698e2 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_tabular_aero_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_tabular_aero_group.py @@ -21,6 +21,7 @@ get_flops_outputs, print_case) from aviary.variable_info.enums import LegacyCode +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic, Mission, Settings FLOPS = LegacyCode.FLOPS @@ -50,6 +51,8 @@ def setUp(self): promotes_outputs=['*'], ) + setup_model_options(self.prob, aviary_options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case(self): @@ -163,6 +166,8 @@ def setUp(self): promotes_outputs=['*'], ) + setup_model_options(self.prob, aviary_options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case(self): @@ -283,6 +288,8 @@ def test_case(self, case_name): promotes_outputs=['*'], ) + setup_model_options(prob, flops_inputs) + prob.setup(check=False, force_alloc_complex=True) for (key, (val, units)) in dynamic_inputs: @@ -581,6 +588,8 @@ def _run_computed_aero_harness(flops_inputs, dynamic_inputs, num_nodes): prob = om.Problem( _ComputedAeroHarness(num_nodes=num_nodes, aviary_options=flops_inputs)) + setup_model_options(prob, flops_inputs) + prob.setup() set_aviary_initial_values(prob, dynamic_inputs) diff --git a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/flaps_model.py b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/flaps_model.py index 0f35af711..3dc28dc5f 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/flaps_model.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/flaps_model.py @@ -12,9 +12,9 @@ from aviary.subsystems.aerodynamics.gasp_based.flaps_model.meta_model import ( MetaModelGroup, ) -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import FlapType from aviary.variable_info.variables import Aircraft, Dynamic +from aviary.variable_info.functions import add_aviary_option class FlapsGroup(om.Group): @@ -25,11 +25,7 @@ class FlapsGroup(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) + add_aviary_option(self, Aircraft.Wing.FLAP_TYPE) # optimum trailing edge flap deflection angle defaults (ADELTO table in GASP) self.optimum_flap_defls = { @@ -44,8 +40,6 @@ def initialize(self): def setup(self): - aviary_options = self.options['aviary_options'] - self.add_subsystem( "BasicFlapsCalculations", BasicFlapsCalculations(), @@ -87,7 +81,7 @@ def setup(self): self.add_subsystem( "LookupTables", - MetaModelGroup(aviary_options=aviary_options), + MetaModelGroup(), promotes_inputs=[ "flap_defl_ratio", "flap_defl", @@ -151,10 +145,6 @@ def setup(self): # set default trailing edge deflection angle per GASP self.set_input_defaults( Aircraft.Wing.OPTIMUM_FLAP_DEFLECTION, - self.optimum_flap_defls[ - self.options["aviary_options"].get_val( - Aircraft.Wing.FLAP_TYPE, units='unitless' - ) - ], + self.optimum_flap_defls[self.options[Aircraft.Wing.FLAP_TYPE]], units="deg", ) diff --git a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/meta_model.py b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/meta_model.py index e45bfecd6..fe52c8d55 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/meta_model.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/meta_model.py @@ -1,8 +1,8 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import FlapType +from aviary.variable_info.functions import add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic @@ -13,15 +13,11 @@ class MetaModelGroup(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.FLAP_TYPE) def setup(self): - flap_type = self.options["aviary_options"].get_val( - Aircraft.Wing.FLAP_TYPE, units='unitless') + flap_type = self.options[Aircraft.Wing.FLAP_TYPE] # VDEL1 VDEL1_interp = self.add_subsystem( diff --git a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_flaps_group.py b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_flaps_group.py index a061652df..ef008d9eb 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_flaps_group.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_flaps_group.py @@ -5,6 +5,7 @@ from aviary.subsystems.aerodynamics.gasp_based.flaps_model.flaps_model import \ FlapsGroup +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.enums import FlapType from aviary.variable_info.variables import Aircraft, Dynamic @@ -23,7 +24,9 @@ def setUp(self): options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.TRIPLE_SLOTTED, units='unitless') - self.prob.model = FCC = FlapsGroup(aviary_options=options) + self.prob.model = FCC = FlapsGroup() + + setup_model_options(self.prob, options) self.prob.setup() @@ -130,7 +133,9 @@ def setUp(self): options = get_option_defaults() options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.SPLIT, units='unitless') - self.prob.model = FCC = FlapsGroup(aviary_options=options) + self.prob.model = FCC = FlapsGroup() + + setup_model_options(self.prob, options) self.prob.setup() @@ -238,7 +243,9 @@ def setUp(self): options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.SINGLE_SLOTTED, units='unitless') - self.prob.model = FCC = FlapsGroup(aviary_options=options) + self.prob.model = FCC = FlapsGroup() + + setup_model_options(self.prob, options) self.prob.setup() @@ -346,7 +353,9 @@ def setUp(self): options = get_option_defaults() options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.PLAIN, units='unitless') - self.prob.model = FCC = FlapsGroup(aviary_options=options) + self.prob.model = FCC = FlapsGroup() + + setup_model_options(self.prob, options) self.prob.setup() @@ -453,7 +462,9 @@ def setUp(self): options = get_option_defaults() options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.FOWLER, units='unitless') - self.prob.model = FCC = FlapsGroup(aviary_options=options) + self.prob.model = FCC = FlapsGroup() + + setup_model_options(self.prob, options) self.prob.setup() @@ -561,7 +572,9 @@ def setUp(self): options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.DOUBLE_SLOTTED_FOWLER, units='unitless') - self.prob.model = FCC = FlapsGroup(aviary_options=options) + self.prob.model = FCC = FlapsGroup() + + setup_model_options(self.prob, options) self.prob.setup() diff --git a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_metamodel.py b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_metamodel.py index 3a0e37f04..cb0f903ec 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_metamodel.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_metamodel.py @@ -20,9 +20,10 @@ class MetaModelTestCasePlain(unittest.TestCase): def setUp(self): self.prob = om.Problem() - options = get_option_defaults() - options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.PLAIN, units='unitless') - self.prob.model = LuTMMa = MetaModelGroup(aviary_options=options) + options = { + Aircraft.Wing.FLAP_TYPE: FlapType.PLAIN, + } + self.prob.model = LuTMMa = MetaModelGroup(**options) self.prob.setup() self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) @@ -113,10 +114,10 @@ class MetaModelTestCaseSingleSlotted(unittest.TestCase): def setUp(self): self.prob = om.Problem() - options = get_option_defaults() - options.set_val(Aircraft.Wing.FLAP_TYPE, - val=FlapType.SINGLE_SLOTTED, units='unitless') - self.prob.model = LuTMMb = MetaModelGroup(aviary_options=options) + options = { + Aircraft.Wing.FLAP_TYPE: FlapType.SINGLE_SLOTTED, + } + self.prob.model = LuTMMb = MetaModelGroup(**options) self.prob.setup() self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) @@ -152,9 +153,10 @@ class MetaModelTestCaseFowler(unittest.TestCase): def setUp(self): self.prob = om.Problem() - options = get_option_defaults() - options.set_val(Aircraft.Wing.FLAP_TYPE, val=FlapType.FOWLER, units='unitless') - self.prob.model = LuTMMc = MetaModelGroup(aviary_options=options) + options = { + Aircraft.Wing.FLAP_TYPE: FlapType.FOWLER, + } + self.prob.model = LuTMMc = MetaModelGroup(**options) self.prob.setup() self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) diff --git a/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py b/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py index 4542d9589..cd45e5a5c 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py +++ b/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py @@ -10,11 +10,8 @@ CLFromLift, TanhRampComp, ) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input +from aviary.variable_info.functions import add_aviary_input, add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic, Mission -from aviary.utils.aviary_values import AviaryValues -from aviary.subsystems.aerodynamics.gasp_based.interference import WingFuselageInterferenceMission # @@ -393,17 +390,12 @@ class AeroGeom(om.ExplicitComponent): def initialize(self): self.options.declare("num_nodes", default=1, types=int) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Wing.HAS_STRUT) def setup(self): nn = self.options["num_nodes"] - num_engine_type = len( - self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) - ) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) self.add_input( Dynamic.Atmosphere.MACH, @@ -718,9 +710,7 @@ def compute(self, inputs, outputs): fnre[good_mask] = (np.log10(reli[good_mask] * nac_len) / 7) ** -2.6 fvtre[good_mask] = (np.log10(reli[good_mask] * vtail_chord) / 7) ** -2.6 fhtre[good_mask] = (np.log10(reli[good_mask] * htail_chord) / 7) ** -2.6 - include_strut = self.options["aviary_options"].get_val( - Aircraft.Wing.HAS_STRUT, units='unitless' - ) + include_strut = self.options[Aircraft.Wing.HAS_STRUT] if include_strut: fstrtre = (np.log10(reli[good_mask] * strut_chord) / 7) ** -2.6 @@ -796,11 +786,6 @@ class AeroSetup(om.Group): def initialize(self): self.options.declare("num_nodes", default=1, types=int) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) self.options.declare( "input_atmos", default=False, @@ -808,15 +793,9 @@ def initialize(self): desc="Directly input speed of sound and kinematic viscosity instead of " "computing them with an atmospherics component. For testing.", ) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) def setup(self): nn = self.options["num_nodes"] - aviary_options = self.options['aviary_options'] self.add_subsystem("ratios", WingTailRatios(), promotes=["*"]) self.add_subsystem("xlifts", Xlifts(num_nodes=nn), promotes=["*"]) @@ -865,8 +844,8 @@ def setup(self): self.add_subsystem( "geom", - AeroGeom(num_nodes=nn, aviary_options=aviary_options), - promotes=["*"], + AeroGeom(num_nodes=nn), + promotes=["*"] ) @@ -1401,11 +1380,6 @@ class CruiseAero(om.Group): def initialize(self): self.options.declare("num_nodes", default=1, types=int) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) self.options.declare( "output_alpha", @@ -1420,20 +1394,13 @@ def initialize(self): desc="Directly input speed of sound and kinematic viscosity instead of " "computing them with an atmospherics component. For testing.", ) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) def setup(self): nn = self.options["num_nodes"] - aviary_options = self.options["aviary_options"] self.add_subsystem( "aero_setup", AeroSetup( num_nodes=nn, - aviary_options=aviary_options, input_atmos=self.options["input_atmos"], ), promotes=["*"], @@ -1455,11 +1422,6 @@ class LowSpeedAero(om.Group): def initialize(self): self.options.declare("num_nodes", default=1, types=int) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) self.options.declare( "retract_gear", default=True, @@ -1488,21 +1450,14 @@ def initialize(self): desc="Directly input speed of sound and kinematic viscosity instead of " "computing them with an atmospherics component. For testing.", ) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) def setup(self): nn = self.options["num_nodes"] output_alpha = self.options["output_alpha"] - aviary_options = self.options["aviary_options"] self.add_subsystem( "aero_setup", AeroSetup( num_nodes=nn, - aviary_options=aviary_options, input_atmos=self.options["input_atmos"], ), promotes=["*"], diff --git a/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py b/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py index c22a99ff1..d3ebf67a9 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py +++ b/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py @@ -8,7 +8,6 @@ from aviary.subsystems.atmosphere.atmosphere import Atmosphere from aviary.subsystems.aerodynamics.gasp_based.flaps_model import FlapsGroup -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft, Dynamic, Mission from aviary.variable_info.enums import SpeedType from aviary.subsystems.aerodynamics.gasp_based.gasp_aero_coeffs import AeroFormfactors @@ -21,17 +20,8 @@ class PreMissionAero(om.Group): """Takeoff and landing flaps modeling""" - def initialize(self): - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) - def setup(self): - aviary_options = self.options['aviary_options'] - self.add_subsystem("wing_fus_interference_premission", WingFuselageInterferencePremission(), promotes_inputs=["aircraft:*"], @@ -70,7 +60,7 @@ def setup(self): self.add_subsystem( "flaps_up", - FlapsGroup(aviary_options=aviary_options), + FlapsGroup(), promotes_inputs=[ "*", ("flap_defl", "flap_defl_up"), @@ -80,7 +70,7 @@ def setup(self): ) self.add_subsystem( "flaps_takeoff", - FlapsGroup(aviary_options=aviary_options), + FlapsGroup(), # slat deflection same for takeoff and landing promotes_inputs=[ "*", @@ -101,7 +91,7 @@ def setup(self): ) self.add_subsystem( "flaps_landing", - FlapsGroup(aviary_options=aviary_options), + FlapsGroup(), promotes_inputs=[ "*", ("flap_defl", Aircraft.Wing.FLAP_DEFLECTION_LANDING), diff --git a/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py b/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py index 410df07eb..ed962e8ed 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py +++ b/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py @@ -30,9 +30,7 @@ def test_cruise(self): prob = om.Problem() prob.model.add_subsystem( "aero", - CruiseAero( - num_nodes=2, aviary_options=get_option_defaults(), input_atmos=True - ), + CruiseAero(num_nodes=2, input_atmos=True), promotes=["*"], ) prob.setup(check=False, force_alloc_complex=True) @@ -71,7 +69,8 @@ def test_ground(self): prob.model.add_subsystem( "aero", LowSpeedAero( - num_nodes=2, aviary_options=get_option_defaults(), input_atmos=True + num_nodes=2, + input_atmos=True, ), promotes=["*"], ) @@ -130,14 +129,14 @@ def test_ground_alpha_out(self): prob = om.Problem() prob.model.add_subsystem( "alpha_in", - LowSpeedAero(aviary_options=get_option_defaults()), + LowSpeedAero(), promotes_inputs=["*", ("alpha", "alpha_in")], promotes_outputs=[(Dynamic.Vehicle.LIFT, "lift_req")], ) prob.model.add_subsystem( "alpha_out", - LowSpeedAero(aviary_options=get_option_defaults(), output_alpha=True), + LowSpeedAero(output_alpha=True), promotes_inputs=["*", "lift_req"], ) diff --git a/aviary/subsystems/geometry/combined_geometry.py b/aviary/subsystems/geometry/combined_geometry.py index f9f21c070..c4403dc95 100644 --- a/aviary/subsystems/geometry/combined_geometry.py +++ b/aviary/subsystems/geometry/combined_geometry.py @@ -18,11 +18,6 @@ class CombinedGeometry(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - self.options.declare('code_origin_to_prioritize', values=[GASP, FLOPS, None], default=None, @@ -31,18 +26,17 @@ def initialize(self): ) def setup(self): - aviary_inputs = self.options['aviary_options'] self.add_subsystem( 'gasp_based_geom', - SizeGroup(aviary_options=aviary_inputs,), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( 'flops_based_geom', - PrepGeom(aviary_options=aviary_inputs), + PrepGeom(), promotes_inputs=['*'], promotes_outputs=['*'] ) diff --git a/aviary/subsystems/geometry/flops_based/characteristic_lengths.py b/aviary/subsystems/geometry/flops_based/characteristic_lengths.py index 474fa7381..ef9ce92dc 100644 --- a/aviary/subsystems/geometry/flops_based/characteristic_lengths.py +++ b/aviary/subsystems/geometry/flops_based/characteristic_lengths.py @@ -2,8 +2,7 @@ import openmdao.api as om from aviary.subsystems.geometry.flops_based.utils import Names -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -14,13 +13,11 @@ class CharacteristicLengths(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) self.add_input(Names.CROOT, 0.0, units='unitless') @@ -93,9 +90,8 @@ def setup_partials(self): self._setup_partials_nacelles() self._setup_partials_canard() - def compute( - self, inputs, outputs, discrete_inputs=None, discrete_outputs=None - ): + def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): + self._compute_wing(inputs, outputs, discrete_inputs, discrete_outputs) self._compute_horizontal_tail( @@ -141,9 +137,7 @@ def _setup_partials_wing(self): Aircraft.Wing.GLOVE_AND_BAT, ] - aviary_options: AviaryValues = self.options['aviary_options'] - - if aviary_options.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION): + if self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION]: wrt = [ Names.CROOT, Aircraft.Wing.TAPER_RATIO, @@ -199,8 +193,7 @@ def _setup_partials_fuselage(self): def _setup_partials_nacelles(self): # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) self.declare_partials( @@ -239,9 +232,7 @@ def _compute_wing( length = ((area - glove_and_bat) / aspect_ratio)**0.5 - aviary_options: AviaryValues = self.options['aviary_options'] - - if aviary_options.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION): + if self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION]: taper_ratio = inputs[Aircraft.Wing.TAPER_RATIO] CROOT = inputs[Names.CROOT] @@ -310,7 +301,7 @@ def _compute_nacelles( ): # TODO do all engines support nacelles? If not, is this deliberate, or # just an artifact of the implementation? - num_eng = self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] avg_diam = inputs[Aircraft.Nacelle.AVG_DIAMETER] avg_length = inputs[Aircraft.Nacelle.AVG_LENGTH] @@ -411,9 +402,8 @@ def _compute_canard( outputs[Aircraft.Canard.FINENESS] = thickness_to_chord def _compute_partials_wing(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - if aviary_options.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION): + if self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION]: taper_ratio = inputs[Aircraft.Wing.TAPER_RATIO] CROOT = inputs[Names.CROOT] @@ -518,7 +508,7 @@ def _compute_partials_fuselage(self, inputs, J, discrete_inputs=None): ] = -length / avg_diam**2.0 def _compute_partials_nacelles(self, inputs, J, discrete_inputs=None): - num_eng = self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] avg_diam = inputs[Aircraft.Nacelle.AVG_DIAMETER] avg_length = inputs[Aircraft.Nacelle.AVG_LENGTH] diff --git a/aviary/subsystems/geometry/flops_based/fuselage.py b/aviary/subsystems/geometry/flops_based/fuselage.py index ff2f87c48..2b73da704 100644 --- a/aviary/subsystems/geometry/flops_based/fuselage.py +++ b/aviary/subsystems/geometry/flops_based/fuselage.py @@ -4,7 +4,6 @@ import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -16,11 +15,6 @@ class FuselagePrelim(om.ExplicitComponent): Aircraft.Fuselage.PLANFORM_AREA = length * max_width """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Fuselage.LENGTH, val=0.0) add_aviary_input(self, Aircraft.Fuselage.MAX_HEIGHT, val=0.0) diff --git a/aviary/subsystems/geometry/flops_based/nacelle.py b/aviary/subsystems/geometry/flops_based/nacelle.py index a2f0d58ba..c8c9adf97 100644 --- a/aviary/subsystems/geometry/flops_based/nacelle.py +++ b/aviary/subsystems/geometry/flops_based/nacelle.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -15,13 +14,10 @@ class Nacelles(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Nacelle.AVG_DIAMETER, val=np.zeros(num_engine_type)) add_aviary_input(self, Aircraft.Nacelle.AVG_LENGTH, @@ -35,8 +31,7 @@ def setup(self): def setup_partials(self): # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) self.declare_partials( @@ -59,9 +54,9 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] # how many of each unique engine type are on the aircraft (array) - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] + # how many unique engine types are there (int) num_engine_type = len(num_engines) @@ -82,8 +77,7 @@ def compute( outputs[Aircraft.Nacelle.TOTAL_WETTED_AREA] = total_wetted_area def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] avg_diam = inputs[Aircraft.Nacelle.AVG_DIAMETER] avg_length = inputs[Aircraft.Nacelle.AVG_LENGTH] diff --git a/aviary/subsystems/geometry/flops_based/prep_geom.py b/aviary/subsystems/geometry/flops_based/prep_geom.py index 2d54dab22..37cf27e1b 100644 --- a/aviary/subsystems/geometry/flops_based/prep_geom.py +++ b/aviary/subsystems/geometry/flops_based/prep_geom.py @@ -5,9 +5,10 @@ TODO: blended-wing-body support TODO: multiple engine model support ''' -import openmdao.api as om from numpy import pi +import openmdao.api as om + from aviary.subsystems.geometry.flops_based.canard import Canard from aviary.subsystems.geometry.flops_based.characteristic_lengths import \ CharacteristicLengths @@ -18,8 +19,7 @@ d_calc_fuselage_adjustment, thickness_to_chord_scaler) from aviary.subsystems.geometry.flops_based.wetted_area_total import TotalWettedArea from aviary.subsystems.geometry.flops_based.wing import WingPrelim -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -28,33 +28,27 @@ class PrepGeom(om.Group): Prepare derived values of aircraft geometry for aerodynamics analysis. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): - aviary_options = self.options['aviary_options'] self.add_subsystem( - 'fuselage_prelim', FuselagePrelim(aviary_options=aviary_options), + 'fuselage_prelim', FuselagePrelim(), promotes_inputs=['*'], promotes_outputs=['*'] ) self.add_subsystem( - 'wing_prelim', WingPrelim(aviary_options=aviary_options), + 'wing_prelim', WingPrelim(), promotes_inputs=['*'], promotes_outputs=['*'] ) self.add_subsystem( - 'prelim', _Prelim(aviary_options=aviary_options), + 'prelim', _Prelim(), promotes_inputs=['*'], ) self.add_subsystem( - 'wing', _Wing(aviary_options=aviary_options), + 'wing', _Wing(), promotes_inputs=['aircraft*'], promotes_outputs=['*'] ) @@ -65,7 +59,7 @@ def setup(self): self.connect(f'prelim.{Names.XMULT}', f'wing.{Names.XMULT}') self.add_subsystem( - 'tail', _Tail(aviary_options=aviary_options), + 'tail', _Tail(), promotes_inputs=['aircraft*'], promotes_outputs=['*'] ) @@ -74,7 +68,7 @@ def setup(self): self.connect(f'prelim.{Names.XMULTV}', f'tail.{Names.XMULTV}') self.add_subsystem( - 'fuselage', _Fuselage(aviary_options=aviary_options), + 'fuselage', _Fuselage(), promotes_inputs=['aircraft*'], promotes_outputs=['*'] ) @@ -84,20 +78,20 @@ def setup(self): self.connect(f'prelim.{Names.CRTHTB}', f'fuselage.{Names.CRTHTB}') self.add_subsystem( - 'nacelles', Nacelles(aviary_options=aviary_options), + 'nacelles', Nacelles(), promotes_inputs=['aircraft*'], promotes_outputs=['*'] ) self.add_subsystem( - 'canard', Canard(aviary_options=aviary_options), + 'canard', Canard(), promotes_inputs=['aircraft*'], promotes_outputs=['*'] ) self.add_subsystem( 'characteristic_lengths', - CharacteristicLengths(aviary_options=aviary_options), + CharacteristicLengths(), promotes_inputs=['aircraft*'], promotes_outputs=['*'] ) @@ -107,7 +101,7 @@ def setup(self): ) self.add_subsystem( - 'total_wetted_area', TotalWettedArea(aviary_options=aviary_options), + 'total_wetted_area', TotalWettedArea(), promotes_inputs=['*'], promotes_outputs=['*'] ) @@ -119,9 +113,7 @@ class _Prelim(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) def setup(self): add_aviary_input(self, Aircraft.Fuselage.AVG_DIAMETER, 0.0) @@ -479,9 +471,8 @@ def fuselage_var(self): Define the variable name associated with XDX. ''' value = Aircraft.Fuselage.AVG_DIAMETER - aviary_options: AviaryValues = self.options['aviary_options'] - if aviary_options.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION): + if self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION]: value = Aircraft.Fuselage.MAX_WIDTH return value @@ -493,9 +484,7 @@ class _Wing(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) def setup(self): self.add_input(Names.CROOT, 0.0, units='unitless') @@ -520,8 +509,7 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] - num_fuselage = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) + num_fuselage = self.options[Aircraft.Fuselage.NUM_FUSELAGES] area = inputs[Aircraft.Wing.AREA] CROOT = inputs[Names.CROOT] @@ -538,8 +526,7 @@ def compute( outputs[Aircraft.Wing.WETTED_AREA] = wetted_area def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - num_fuselage = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) + num_fuselage = self.options[Aircraft.Fuselage.NUM_FUSELAGES] area = inputs[Aircraft.Wing.AREA] CROOT = inputs[Names.CROOT] @@ -573,9 +560,8 @@ class _Tail(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + add_aviary_option(self, Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) def setup(self): self.add_input(Names.XMULTH, 0.0, units='unitless') @@ -612,8 +598,7 @@ def setup_partials(self): ] ) - aviary_options: AviaryValues = self.options['aviary_options'] - redux = aviary_options.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) + redux = self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] if not redux: self.declare_partials( @@ -631,12 +616,11 @@ def compute( wetted_area = scaler * XMULTH * area - aviary_options: AviaryValues = self.options['aviary_options'] - redux = aviary_options.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) + redux = self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] if not redux: num_fuselage_engines = \ - aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] vertical_tail_fraction = \ inputs[Aircraft.HorizontalTail.VERTICAL_TAIL_FRACTION] @@ -658,8 +642,7 @@ def compute( outputs[Aircraft.VerticalTail.WETTED_AREA] = wetted_area def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - redux = aviary_options.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) + redux = self.options[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] # horizontal tail XMULTH = inputs[Names.XMULTH] @@ -667,8 +650,8 @@ def compute_partials(self, inputs, J, discrete_inputs=None): scaler = inputs[Aircraft.HorizontalTail.WETTED_AREA_SCALER] if not redux: - num_fuselage_engines = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + num_fuselage_engines = \ + self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] vertical_tail_fraction = \ inputs[Aircraft.HorizontalTail.VERTICAL_TAIL_FRACTION] @@ -736,9 +719,8 @@ class _Fuselage(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION) + add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) def setup(self): self.add_input(Names.CROOTB, 0.0, units='unitless') @@ -810,8 +792,7 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] - num_fuselages = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) + num_fuselages = self.options[Aircraft.Fuselage.NUM_FUSELAGES] area = inputs[Aircraft.Wing.AREA] aspect_ratio = inputs[Aircraft.Wing.ASPECT_RATIO] @@ -869,8 +850,7 @@ def compute( outputs[Aircraft.Fuselage.WETTED_AREA] = wetted_area def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - num_fuselages = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) + num_fuselages = self.options[Aircraft.Fuselage.NUM_FUSELAGES] area = inputs[Aircraft.Wing.AREA] aspect_ratio = inputs[Aircraft.Wing.ASPECT_RATIO] diff --git a/aviary/subsystems/geometry/flops_based/test/test_characteristic_lengths.py b/aviary/subsystems/geometry/flops_based/test/test_characteristic_lengths.py index f4fe31abe..a5f47faaa 100644 --- a/aviary/subsystems/geometry/flops_based/test/test_characteristic_lengths.py +++ b/aviary/subsystems/geometry/flops_based/test/test_characteristic_lengths.py @@ -20,13 +20,16 @@ def test_case_multiengine(self): # test with multiple engine types prob = self.prob - aviary_options = get_flops_inputs('LargeSingleAisle1FLOPS') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2, 2, 3])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 7) + aviary_inputs = get_flops_inputs('LargeSingleAisle1FLOPS') + + aviary_options = { + Aircraft.Engine.NUM_ENGINES: np.array([2, 2, 3]), + Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION: aviary_inputs.get_val(Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION), + } prob.model.add_subsystem( 'char_lengths', - CharacteristicLengths(aviary_options=aviary_options), + CharacteristicLengths(**aviary_options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -52,7 +55,7 @@ def test_case_multiengine(self): (Aircraft.Wing.THICKNESS_TO_CHORD, 'unitless') ] for var, units in input_list: - prob.set_val(var, aviary_options.get_val(var, units)) + prob.set_val(var, aviary_inputs.get_val(var, units)) # this is another component's output prob.set_val(Aircraft.Fuselage.AVG_DIAMETER, val=12.75) diff --git a/aviary/subsystems/geometry/flops_based/test/test_nacelle.py b/aviary/subsystems/geometry/flops_based/test/test_nacelle.py index 61f2ebbaf..1ca18d748 100644 --- a/aviary/subsystems/geometry/flops_based/test/test_nacelle.py +++ b/aviary/subsystems/geometry/flops_based/test/test_nacelle.py @@ -6,7 +6,6 @@ from aviary.subsystems.geometry.flops_based.nacelle import Nacelles from aviary.utils.test_utils.variable_test import assert_match_varnames -from aviary.validation_cases.validation_tests import get_flops_inputs from aviary.variable_info.variables import Aircraft @@ -22,13 +21,13 @@ def test_case_multiengine(self): # test with multiple engine types prob = self.prob - aviary_options = get_flops_inputs('LargeSingleAisle1FLOPS') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2, 2, 3])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 7) + options = { + Aircraft.Engine.NUM_ENGINES: np.array([2, 2, 3]), + } prob.model.add_subsystem( 'nacelles', - Nacelles(aviary_options=aviary_options), + Nacelles(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) diff --git a/aviary/subsystems/geometry/flops_based/test/test_prep_geom.py b/aviary/subsystems/geometry/flops_based/test/test_prep_geom.py index 58a239103..66ebf3098 100644 --- a/aviary/subsystems/geometry/flops_based/test/test_prep_geom.py +++ b/aviary/subsystems/geometry/flops_based/test/test_prep_geom.py @@ -55,9 +55,7 @@ def initialize(self): desc='collection of Aircraft/Mission specific options') def setup(self): - aviary_options = self.options['aviary_options'] - - self.add_subsystem('prep_geom', PrepGeom(aviary_options=aviary_options), + self.add_subsystem('prep_geom', PrepGeom(), promotes=['*']) def configure(self): @@ -65,15 +63,19 @@ def configure(self): override_aviary_vars(self, aviary_options) - options = get_flops_data(case_name, preprocess=True, - keys=[ - Aircraft.Fuselage.NUM_FUSELAGES, - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES, - Aircraft.VerticalTail.NUM_TAILS, - Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, - Aircraft.Engine.NUM_ENGINES, - Aircraft.Propulsion.TOTAL_NUM_ENGINES, - ]) + keys = [ + Aircraft.Fuselage.NUM_FUSELAGES, + Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES, + Aircraft.VerticalTail.NUM_TAILS, + Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, + Aircraft.Engine.NUM_ENGINES, + Aircraft.Propulsion.TOTAL_NUM_ENGINES, + ] + + options = get_flops_data(case_name, preprocess=True, keys=keys) + model_options = {} + for key in keys: + model_options[key] = options.get_item(key)[0] prob = self.prob @@ -81,6 +83,8 @@ def configure(self): 'premission', PreMission(aviary_options=options), promotes=['*'] ) + prob.model_options['*'] = model_options + prob.setup(check=False, force_alloc_complex=True) output_keys = [Aircraft.Fuselage.AVG_DIAMETER, @@ -206,10 +210,15 @@ def test_case(self, case_name): prob = self.prob + keys = [Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION] + flops_inputs = get_flops_inputs(case_name, keys=keys) + options = {} + for key in keys: + options[key] = flops_inputs.get_item(key)[0] + prob.model.add_subsystem( 'prelim', - _Prelim(aviary_options=get_flops_inputs(case_name, - keys=[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION])), + _Prelim(**options), promotes=['*'] ) @@ -264,10 +273,15 @@ def test_case(self, case_name): prob = self.prob + keys = [Aircraft.Fuselage.NUM_FUSELAGES] + flops_inputs = get_flops_inputs(case_name, keys=keys) + options = {} + for key in keys: + options[key] = flops_inputs.get_item(key)[0] + prob.model.add_subsystem( 'wings', - _Wing(aviary_options=get_flops_inputs(case_name, - keys=[Aircraft.Fuselage.NUM_FUSELAGES])), + _Wing(**options), promotes=['*']) prob.setup(check=False, force_alloc_complex=True) @@ -303,11 +317,16 @@ def test_case(self, case_name): prob = self.prob + keys = [Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, + Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] + flops_inputs = get_flops_data(case_name, keys=keys) + options = {} + for key in keys: + options[key] = flops_inputs.get_item(key)[0] + prob.model.add_subsystem( 'tails', - _Tail(aviary_options=get_flops_inputs(case_name, preprocess=True, - keys=[Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES])), + _Tail(**options), promotes=['*']) prob.setup(check=False, force_alloc_complex=True) @@ -345,10 +364,15 @@ def test_case(self, case_name): prob = self.prob + keys = [Aircraft.Fuselage.NUM_FUSELAGES] + flops_inputs = get_flops_inputs(case_name, keys=keys) + options = {} + for key in keys: + options[key] = flops_inputs.get_item(key)[0] + prob.model.add_subsystem( 'fuse', - _Fuselage(aviary_options=get_flops_inputs(case_name, - keys=[Aircraft.Fuselage.NUM_FUSELAGES])), + _Fuselage(**options), promotes=['*']) prob.setup(check=False, force_alloc_complex=True) @@ -401,14 +425,15 @@ def test_case(self, case_name): prob = self.prob - flops_inputs = get_flops_inputs(case_name, preprocess=True, - keys=[Aircraft.Engine.NUM_ENGINES, - Aircraft.Fuselage.NUM_FUSELAGES, - ]) + keys = [Aircraft.Engine.NUM_ENGINES] + flops_inputs = get_flops_inputs(case_name, keys=keys) + options = {} + for key in keys: + options[key] = flops_inputs.get_item(key)[0] prob.model.add_subsystem( 'nacelles', - Nacelles(aviary_options=flops_inputs), + Nacelles(**options), promotes=['*']) prob.setup(check=False, force_alloc_complex=True) @@ -438,7 +463,7 @@ def test_case(self): prob.model.add_subsystem( 'canard', - Canard(aviary_options=AviaryValues()), + Canard(), promotes=['*']) prob.setup(check=False, force_alloc_complex=True) @@ -471,16 +496,16 @@ def test_case(self, case_name): prob = self.prob - flops_inputs = get_flops_inputs(case_name, preprocess=True, - keys=[Aircraft.Engine.NUM_ENGINES, - Aircraft.Fuselage.NUM_FUSELAGES, - Aircraft.VerticalTail.NUM_TAILS, - Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, - ]) + keys = [Aircraft.Engine.NUM_ENGINES, + Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION,] + flops_inputs = get_flops_inputs(case_name, keys=keys) + options = {} + for key in keys: + options[key] = flops_inputs.get_item(key)[0] prob.model.add_subsystem( 'characteristic_lengths', - CharacteristicLengths(aviary_options=flops_inputs), + CharacteristicLengths(**options), promotes=['*'] ) diff --git a/aviary/subsystems/geometry/flops_based/wetted_area_total.py b/aviary/subsystems/geometry/flops_based/wetted_area_total.py index 4bb08d3e8..63b2a4fab 100644 --- a/aviary/subsystems/geometry/flops_based/wetted_area_total.py +++ b/aviary/subsystems/geometry/flops_based/wetted_area_total.py @@ -1,6 +1,5 @@ import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -11,11 +10,6 @@ class TotalWettedArea(om.ExplicitComponent): It is simple enought to skip unit test """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Canard.WETTED_AREA, 0.0) add_aviary_input(self, Aircraft.Fuselage.WETTED_AREA, 0.0) diff --git a/aviary/subsystems/geometry/flops_based/wing.py b/aviary/subsystems/geometry/flops_based/wing.py index 7eb02513c..f6c7c09e2 100644 --- a/aviary/subsystems/geometry/flops_based/wing.py +++ b/aviary/subsystems/geometry/flops_based/wing.py @@ -4,7 +4,6 @@ import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -14,11 +13,6 @@ class WingPrelim(om.ExplicitComponent): preliminary calculations of wing aspect ratio """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Wing.AREA, val=0.0) add_aviary_input(self, Aircraft.Wing.GLOVE_AND_BAT, val=0.0) diff --git a/aviary/subsystems/geometry/gasp_based/electric.py b/aviary/subsystems/geometry/gasp_based/electric.py index 3196bb92b..07d423edd 100644 --- a/aviary/subsystems/geometry/gasp_based/electric.py +++ b/aviary/subsystems/geometry/gasp_based/electric.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -12,16 +11,10 @@ class CableSize(om.ExplicitComponent): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) def setup(self): - aviary_options = self.options['aviary_options'] - total_num_wing_engines = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) + total_num_wing_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES] add_aviary_input(self, Aircraft.Engine.WING_LOCATIONS, val=np.full(int(total_num_wing_engines/2), 0.35)) diff --git a/aviary/subsystems/geometry/gasp_based/empennage.py b/aviary/subsystems/geometry/gasp_based/empennage.py index c0133bc54..5cdb6aa03 100644 --- a/aviary/subsystems/geometry/gasp_based/empennage.py +++ b/aviary/subsystems/geometry/gasp_based/empennage.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input +from aviary.variable_info.functions import add_aviary_input, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -17,10 +16,6 @@ class TailVolCoef(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) self.options.declare( "vertical", default=False, @@ -93,13 +88,6 @@ class TailSize(om.ExplicitComponent): to tail moment arm and the wing span are input. """ - def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): # defaults here for Large Single Aisle 1 horizontal tail self.add_input( @@ -207,10 +195,8 @@ class EmpennageSize(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Design.COMPUTE_HTAIL_VOLUME_COEFF) + add_aviary_option(self, Aircraft.Design.COMPUTE_VTAIL_VOLUME_COEFF) def setup(self): # TODO: For cruciform/T-tail configurations, GASP checks to make sure the V tail @@ -220,8 +206,6 @@ def setup(self): # overrides the H tail aspect ratio. H tail taper ratio is used in landing gear # mass calculation. - aviary_options = self.options['aviary_options'] - # higher inputs that are input to groups other than this one, or calculated in groups other than this one higher_level_inputs_htail_vc = [ ("cab_w", Aircraft.Fuselage.AVG_DIAMETER), @@ -288,24 +272,24 @@ def setup(self): ("vol_coef", Aircraft.VerticalTail.VOLUME_COEFFICIENT), ] - if self.options["aviary_options"].get_val(Aircraft.Design.COMPUTE_HTAIL_VOLUME_COEFF, units='unitless'): + if self.options[Aircraft.Design.COMPUTE_HTAIL_VOLUME_COEFF]: self.add_subsystem( "htail_vc", - TailVolCoef(aviary_options=aviary_options), + TailVolCoef(), promotes_inputs=higher_level_inputs_htail_vc + ["aircraft:*"], promotes_outputs=connected_outputs_htail_vc, ) - if self.options["aviary_options"].get_val(Aircraft.Design.COMPUTE_VTAIL_VOLUME_COEFF, units='unitless'): + if self.options[Aircraft.Design.COMPUTE_VTAIL_VOLUME_COEFF]: self.add_subsystem( "vtail_vc", - TailVolCoef(aviary_options=aviary_options, vertical=True), + TailVolCoef(vertical=True), promotes_inputs=higher_level_inputs_vtail_vc + ["aircraft:*"], promotes_outputs=connected_outputs_vtail_vc, ) self.add_subsystem( "htail", - TailSize(aviary_options=aviary_options,), + TailSize(), promotes_inputs=higher_level_inputs_htail + rename_inputs_htail + connected_inputs_htail @@ -315,7 +299,7 @@ def setup(self): self.add_subsystem( "vtail", - TailSize(aviary_options=aviary_options,), + TailSize(), promotes_inputs=higher_level_inputs_vtail + rename_inputs_vtail + connected_inputs_vtail diff --git a/aviary/subsystems/geometry/gasp_based/engine.py b/aviary/subsystems/geometry/gasp_based/engine.py index b39c7f836..545427ac7 100644 --- a/aviary/subsystems/geometry/gasp_based/engine.py +++ b/aviary/subsystems/geometry/gasp_based/engine.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -13,15 +12,10 @@ class EngineSize(om.ExplicitComponent): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Engine.REFERENCE_DIAMETER, np.full(num_engine_type, 5.8)) @@ -39,8 +33,7 @@ def setup(self): def setup_partials(self): # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) innames = [ diff --git a/aviary/subsystems/geometry/gasp_based/fuselage.py b/aviary/subsystems/geometry/gasp_based/fuselage.py index 9e6c3ffd0..f525118f1 100644 --- a/aviary/subsystems/geometry/gasp_based/fuselage.py +++ b/aviary/subsystems/geometry/gasp_based/fuselage.py @@ -1,9 +1,8 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import Verbosity -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Settings @@ -25,11 +24,13 @@ class FuselageParameters(om.ExplicitComponent): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) + add_aviary_option(self, Aircraft.Fuselage.AISLE_WIDTH, units='inch') + add_aviary_option(self, Aircraft.Fuselage.NUM_AISLES) + add_aviary_option(self, Aircraft.Fuselage.NUM_SEATS_ABREAST) + add_aviary_option(self, Aircraft.Fuselage.SEAT_PITCH, units='inch') + add_aviary_option(self, Aircraft.Fuselage.SEAT_WIDTH, units='inch') + add_aviary_option(self, Settings.VERBOSITY) def setup(self): @@ -55,14 +56,15 @@ def setup(self): ) def compute(self, inputs, outputs): - verbosity = self.options['aviary_options'].get_val(Settings.VERBOSITY) - aviary_options: AviaryValues = self.options['aviary_options'] - seats_abreast = aviary_options.get_val(Aircraft.Fuselage.NUM_SEATS_ABREAST) - seat_width = aviary_options.get_val(Aircraft.Fuselage.SEAT_WIDTH, units='inch') - num_aisle = aviary_options.get_val(Aircraft.Fuselage.NUM_AISLES) - aisle_width = aviary_options.get_val(Aircraft.Fuselage.AISLE_WIDTH, units='inch') - PAX = aviary_options.get_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS) - seat_pitch = aviary_options.get_val(Aircraft.Fuselage.SEAT_PITCH, units='inch') + options = self.options + verbosity = options[Settings.VERBOSITY] + seats_abreast = options[Aircraft.Fuselage.NUM_SEATS_ABREAST] + seat_width, _ = options[Aircraft.Fuselage.SEAT_WIDTH] + num_aisle = options[Aircraft.Fuselage.NUM_AISLES] + aisle_width, _ = options[Aircraft.Fuselage.AISLE_WIDTH] + PAX = options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] + seat_pitch, _ = options[Aircraft.Fuselage.SEAT_PITCH] + delta_diameter = inputs[Aircraft.Fuselage.DELTA_DIAMETER] cabin_width = seats_abreast * seat_width + num_aisle * aisle_width + 12 @@ -94,8 +96,8 @@ def compute(self, inputs, outputs): nose_height_b*sigX(100*(seats_abreast-1.5)) def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - seats_abreast = aviary_options.get_val(Aircraft.Fuselage.NUM_SEATS_ABREAST) + options = self.options + seats_abreast = options[Aircraft.Fuselage.NUM_SEATS_ABREAST] J["nose_height", Aircraft.Fuselage.DELTA_DIAMETER] = sigX( 100*(seats_abreast-1.5))*(-1) @@ -106,16 +108,9 @@ def compute_partials(self, inputs, J): class FuselageSize(om.ExplicitComponent): """ Computation of fuselage length, fuselage wetted area, and cabin length - for the tail boom fuselage. + for the tail boom fuselage. """ - def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input(self, Aircraft.Fuselage.NOSE_FINENESS, val=1) @@ -254,32 +249,21 @@ class FuselageGroup(om.Group): Group to pull together FuselageParameters and FuselageSize. """ - def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): - aviary_options = self.options['aviary_options'] - # outputs from parameters that are used in size but not outside of this group connected_input_outputs = ["cabin_height", "cabin_len", "nose_height"] parameters = self.add_subsystem( "parameters", - FuselageParameters( - aviary_options=aviary_options, - ), + FuselageParameters(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] + connected_input_outputs, ) size = self.add_subsystem( "size", - FuselageSize(aviary_options=aviary_options,), + FuselageSize(), promotes_inputs=connected_input_outputs + ["aircraft:*"], promotes_outputs=["aircraft:*"], ) diff --git a/aviary/subsystems/geometry/gasp_based/non_dimensional_conversion.py b/aviary/subsystems/geometry/gasp_based/non_dimensional_conversion.py index 0fd18fdc9..c8da2494b 100644 --- a/aviary/subsystems/geometry/gasp_based/non_dimensional_conversion.py +++ b/aviary/subsystems/geometry/gasp_based/non_dimensional_conversion.py @@ -1,7 +1,6 @@ import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -11,15 +10,13 @@ class StrutCalcs(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED) + add_aviary_option(self, Aircraft.Wing.HAS_STRUT) def setup(self): add_aviary_input(self, Aircraft.Wing.SPAN, val=0) - if self.options["aviary_options"].get_val(Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED]: add_aviary_input(self, Aircraft.Strut.ATTACHMENT_LOCATION, val=0) add_aviary_output( self, Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS, val=0) @@ -30,7 +27,7 @@ def setup(self): def setup_partials(self): - if self.options["aviary_options"].get_val(Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED]: self.declare_partials( Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS, [Aircraft.Strut.ATTACHMENT_LOCATION, Aircraft.Wing.SPAN]) else: @@ -41,8 +38,8 @@ def compute(self, inputs, outputs): wing_span = inputs[Aircraft.Wing.SPAN] strut_loc_name = Aircraft.Strut.ATTACHMENT_LOCATION - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): - if self.options["aviary_options"].get_val(Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Wing.HAS_STRUT]: + if self.options[Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED]: strut_x = inputs[strut_loc_name] outputs[strut_loc_name+"_dimensionless"] = strut_x / wing_span else: @@ -53,8 +50,8 @@ def compute_partials(self, inputs, partials): wing_span = inputs[Aircraft.Wing.SPAN] strut_loc_name = Aircraft.Strut.ATTACHMENT_LOCATION - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): - if self.options["aviary_options"].get_val(Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Wing.HAS_STRUT]: + if self.options[Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED]: partials[strut_loc_name+"_dimensionless", strut_loc_name] = 1 / wing_span partials[strut_loc_name+"_dimensionless", Aircraft.Wing.SPAN] = - inputs[strut_loc_name] / wing_span**2 @@ -70,15 +67,12 @@ class FoldCalcs(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED) def setup(self): add_aviary_input(self, Aircraft.Wing.SPAN, val=0) - if self.options["aviary_options"].get_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED]: add_aviary_input(self, Aircraft.Wing.FOLDED_SPAN, val=25) add_aviary_output(self, Aircraft.Wing.FOLDED_SPAN_DIMENSIONLESS, val=0) else: @@ -87,7 +81,7 @@ def setup(self): def setup_partials(self): - if self.options["aviary_options"].get_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED]: self.declare_partials( Aircraft.Wing.FOLDED_SPAN_DIMENSIONLESS, [Aircraft.Wing.FOLDED_SPAN, Aircraft.Wing.SPAN]) else: @@ -98,7 +92,7 @@ def compute(self, inputs, outputs): wing_span = inputs[Aircraft.Wing.SPAN] folded_span_name = Aircraft.Wing.FOLDED_SPAN - if self.options["aviary_options"].get_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED]: fold_y = inputs[folded_span_name] outputs[folded_span_name+"_dimensionless"] = fold_y / wing_span else: @@ -109,7 +103,7 @@ def compute_partials(self, inputs, partials): wing_span = inputs[Aircraft.Wing.SPAN] folded_span_name = Aircraft.Wing.FOLDED_SPAN - if self.options["aviary_options"].get_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, units='unitless'): + if self.options[Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED]: partials[folded_span_name+"_dimensionless", folded_span_name] = 1 / wing_span partials[folded_span_name+"_dimensionless", Aircraft.Wing.SPAN] = - \ inputs[folded_span_name] / (wing_span**2) @@ -125,28 +119,23 @@ class DimensionalNonDimensionalInterchange(om.Group): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.HAS_FOLD) + add_aviary_option(self, Aircraft.Wing.HAS_STRUT) def setup(self): - aviary_options = self.options['aviary_options'] - - if aviary_options.get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if self.options[Aircraft.Wing.HAS_STRUT]: self.add_subsystem( "strut_calcs", - StrutCalcs(aviary_options=aviary_options,), + StrutCalcs(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) - if aviary_options.get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if self.options[Aircraft.Wing.HAS_FOLD]: self.add_subsystem( "fold_calcs", - FoldCalcs(aviary_options=aviary_options,), + FoldCalcs(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) diff --git a/aviary/subsystems/geometry/gasp_based/size_group.py b/aviary/subsystems/geometry/gasp_based/size_group.py index c17acae03..bb061764c 100644 --- a/aviary/subsystems/geometry/gasp_based/size_group.py +++ b/aviary/subsystems/geometry/gasp_based/size_group.py @@ -5,61 +5,50 @@ from aviary.subsystems.geometry.gasp_based.engine import EngineSize from aviary.subsystems.geometry.gasp_based.fuselage import FuselageGroup from aviary.subsystems.geometry.gasp_based.wing import WingGroup -from aviary.utils.aviary_values import AviaryValues +from aviary.variable_info.functions import add_aviary_option from aviary.variable_info.variables import Aircraft class SizeGroup(om.Group): - """ Group to pull together all the different components and subgroups of the SIZE subroutine - """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Electrical.HAS_HYBRID_SYSTEM) def setup(self): - aviary_options = self.options['aviary_options'] self.add_subsystem( "fuselage", - FuselageGroup( - aviary_options=aviary_options, - ), + FuselageGroup(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( "wing", - WingGroup( - aviary_options=aviary_options, - ), + WingGroup(), promotes=["aircraft:*", "mission:*"], ) self.add_subsystem( "empennage", - EmpennageSize(aviary_options=aviary_options,), + EmpennageSize(), promotes=["aircraft:*"], ) self.add_subsystem( "engine", - EngineSize(aviary_options=aviary_options,), + EngineSize(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) - if self.options["aviary_options"].get_val(Aircraft.Electrical.HAS_HYBRID_SYSTEM, units='unitless'): + if self.options[Aircraft.Electrical.HAS_HYBRID_SYSTEM]: self.add_subsystem( "cable", - CableSize(aviary_options=aviary_options,), + CableSize(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) diff --git a/aviary/subsystems/geometry/gasp_based/strut.py b/aviary/subsystems/geometry/gasp_based/strut.py index c6443cc4d..2c3fd83f0 100644 --- a/aviary/subsystems/geometry/gasp_based/strut.py +++ b/aviary/subsystems/geometry/gasp_based/strut.py @@ -3,7 +3,6 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -13,12 +12,6 @@ class StrutGeom(om.ExplicitComponent): Computation of strut length, strut area, and strut chord for GASP-based geometry. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input(self, Aircraft.Wing.AREA, val=150) diff --git a/aviary/subsystems/geometry/gasp_based/test/test_electric.py b/aviary/subsystems/geometry/gasp_based/test/test_electric.py index 05ac0bd71..9116a4dc7 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_electric.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_electric.py @@ -5,6 +5,7 @@ from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal from aviary.subsystems.geometry.gasp_based.electric import CableSize +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft from aviary.utils.aviary_values import AviaryValues @@ -17,8 +18,7 @@ def setUp(self): aviary_options = AviaryValues() aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES, 2) - self.prob.model.add_subsystem("cable", CableSize( - aviary_options=aviary_options), promotes=["*"]) + self.prob.model.add_subsystem("cable", CableSize(), promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.Engine.WING_LOCATIONS, 0.35, units="unitless" @@ -30,6 +30,8 @@ def setUp(self): Aircraft.Fuselage.AVG_DIAMETER, 10, units="ft" ) # not actual GASP value + setup_model_options(self.prob, aviary_options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -53,8 +55,7 @@ def test_case_multiengine(self): # aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2, 4])) aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES, 6) - prob.model.add_subsystem("cable", CableSize( - aviary_options=aviary_options), promotes=["*"]) + prob.model.add_subsystem("cable", CableSize(), promotes=["*"]) prob.model.set_input_defaults( Aircraft.Engine.WING_LOCATIONS, np.array([0.35, 0.2, 0.6]), units="unitless" @@ -66,6 +67,8 @@ def test_case_multiengine(self): Aircraft.Fuselage.AVG_DIAMETER, 10, units="ft" ) + setup_model_options(prob, aviary_options) + prob.setup(check=False, force_alloc_complex=True) prob.run_model() diff --git a/aviary/subsystems/geometry/gasp_based/test/test_empennage.py b/aviary/subsystems/geometry/gasp_based/test/test_empennage.py index d5eb4e813..aa77dbeab 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_empennage.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_empennage.py @@ -7,6 +7,7 @@ from aviary.subsystems.geometry.gasp_based.empennage import (EmpennageSize, TailSize, TailVolCoef) +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft @@ -158,7 +159,6 @@ def setUp(self): ) def test_large_sinle_aisle_1_defaults(self): - self.prob.model.emp.options["aviary_options"] = get_option_defaults() self.prob.setup(check=False, force_alloc_complex=True) @@ -193,7 +193,9 @@ def test_large_sinle_aisle_1_calc_volcoefs(self): val=True, units='unitless') options.set_val(Aircraft.Design.COMPUTE_VTAIL_VOLUME_COEFF, val=True, units='unitless') - self.prob.model.emp.options["aviary_options"] = options + + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) self.prob.set_val( diff --git a/aviary/subsystems/geometry/gasp_based/test/test_engine.py b/aviary/subsystems/geometry/gasp_based/test/test_engine.py index 5e9538972..09fbe365e 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_engine.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_engine.py @@ -5,6 +5,7 @@ from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal from aviary.subsystems.geometry.gasp_based.engine import EngineSize +from aviary.variable_info.functions import setup_model_options, extract_options from aviary.variable_info.variables import Aircraft from aviary.utils.aviary_values import AviaryValues @@ -18,8 +19,7 @@ def setUp(self): aviary_options = AviaryValues() aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2])) - self.prob.model.add_subsystem("engsz", EngineSize( - aviary_options=aviary_options), promotes=["*"]) + self.prob.model.add_subsystem("engsz", EngineSize(), promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.Engine.REFERENCE_DIAMETER, 5.8, units="ft") @@ -31,6 +31,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Nacelle.FINENESS, 2, units="unitless") + setup_model_options(self.prob, aviary_options) + self.prob.setup(check=False, force_alloc_complex=True) def test_large_sinle_aisle_1_defaults(self): @@ -52,8 +54,7 @@ def test_case_multiengine(self): aviary_options = AviaryValues() aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2, 4])) - prob.model.add_subsystem("cable", EngineSize( - aviary_options=aviary_options), promotes=["*"]) + prob.model.add_subsystem("cable", EngineSize(), promotes=["*"]) prob.model.set_input_defaults( Aircraft.Engine.REFERENCE_DIAMETER, np.array([5.8, 8.2]), units="ft") @@ -65,6 +66,8 @@ def test_case_multiengine(self): prob.model.set_input_defaults( Aircraft.Nacelle.FINENESS, np.array([2, 2.21]), units="unitless") + prob.model_options['*'] = extract_options(aviary_options) + prob.setup(check=False, force_alloc_complex=True) prob.run_model() diff --git a/aviary/subsystems/geometry/gasp_based/test/test_fuselage.py b/aviary/subsystems/geometry/gasp_based/test/test_fuselage.py index ed0d33693..efd6a29d8 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_fuselage.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_fuselage.py @@ -6,6 +6,7 @@ from aviary.subsystems.geometry.gasp_based.fuselage import (FuselageGroup, FuselageParameters, FuselageSize) +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft @@ -28,7 +29,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "parameters", - FuselageParameters(aviary_options=options), + FuselageParameters(), promotes=["*"], ) @@ -37,6 +38,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Fuselage.PILOT_COMPARTMENT_LENGTH, 9.5, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -68,7 +71,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "parameters", - FuselageParameters(aviary_options=options), + FuselageParameters(), promotes=["*"], ) @@ -77,6 +80,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Fuselage.PILOT_COMPARTMENT_LENGTH, 9.5, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case2(self): @@ -101,9 +106,7 @@ class FuselageSizeTestCase1(unittest.TestCase): def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem( - "size", FuselageSize(aviary_options=get_option_defaults()), promotes=["*"] - ) + self.prob.model.add_subsystem("size", FuselageSize(), promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.Fuselage.NOSE_FINENESS, 1, units="unitless") @@ -145,7 +148,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "parameters", FuselageSize(aviary_options=options), promotes=["*"] + "parameters", FuselageSize(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -160,6 +163,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Fuselage.WETTED_AREA_SCALER, 1, units="unitless") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case2(self): @@ -198,7 +203,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - FuselageGroup(aviary_options=options), + FuselageGroup(), promotes=["*"], ) @@ -213,6 +218,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Fuselage.PILOT_COMPARTMENT_LENGTH, 9.5, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -251,7 +258,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - FuselageGroup(aviary_options=options), + FuselageGroup(), promotes=["*"], ) @@ -270,6 +277,8 @@ def setUp(self): Aircraft.Fuselage.PILOT_COMPARTMENT_LENGTH, 9.5, units="ft" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -312,7 +321,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - FuselageGroup(aviary_options=options), + FuselageGroup(), promotes=["*"], ) @@ -331,6 +340,8 @@ def setUp(self): Aircraft.Fuselage.PILOT_COMPARTMENT_LENGTH, 9.5, units="ft" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -373,7 +384,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - FuselageGroup(aviary_options=options), + FuselageGroup(), promotes=["*"], ) @@ -392,6 +403,8 @@ def setUp(self): Aircraft.Fuselage.PILOT_COMPARTMENT_LENGTH, 9.5, units="ft" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): diff --git a/aviary/subsystems/geometry/gasp_based/test/test_non_dimensional_conversion.py b/aviary/subsystems/geometry/gasp_based/test/test_non_dimensional_conversion.py index adc7f6963..7aaf3a7c5 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_non_dimensional_conversion.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_non_dimensional_conversion.py @@ -8,6 +8,7 @@ from aviary.variable_info.variables import Aircraft from aviary.subsystems.geometry.gasp_based.non_dimensional_conversion import DimensionalNonDimensionalInterchange +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults @@ -20,8 +21,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("dimensionless_calcs", - DimensionalNonDimensionalInterchange( - aviary_options=options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) @@ -33,6 +33,8 @@ def setUp(self): Aircraft.Wing.FOLDED_SPAN, val=118.0, units="ft" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -55,8 +57,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("dimensionless_calcs", - DimensionalNonDimensionalInterchange( - aviary_options=options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) @@ -68,6 +69,8 @@ def setUp(self): Aircraft.Wing.FOLDED_SPAN_DIMENSIONLESS, val=0.5, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -90,8 +93,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("dimensionless_calcs", - DimensionalNonDimensionalInterchange( - aviary_options=options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) @@ -103,6 +105,8 @@ def setUp(self): Aircraft.Strut.ATTACHMENT_LOCATION, val=118.0, units="ft" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -125,8 +129,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("dimensionless_calcs", - DimensionalNonDimensionalInterchange( - aviary_options=options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) @@ -138,6 +141,8 @@ def setUp(self): Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS, val=0.5, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -163,8 +168,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("dimensionless_calcs", - DimensionalNonDimensionalInterchange( - aviary_options=options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) @@ -179,6 +183,8 @@ def setUp(self): Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS, val=0.5, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -207,8 +213,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("dimensionless_calcs", - DimensionalNonDimensionalInterchange( - aviary_options=options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) @@ -223,6 +228,8 @@ def setUp(self): Aircraft.Strut.ATTACHMENT_LOCATION, val=90.0, units="ft" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -251,8 +258,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("dimensionless_calcs", - DimensionalNonDimensionalInterchange( - aviary_options=options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) @@ -267,6 +273,8 @@ def setUp(self): Aircraft.Strut.ATTACHMENT_LOCATION, val=108.0, units="ft" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): diff --git a/aviary/subsystems/geometry/gasp_based/test/test_override.py b/aviary/subsystems/geometry/gasp_based/test/test_override.py index 2b7973093..e26311714 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_override.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_override.py @@ -10,6 +10,7 @@ from aviary.subsystems.aerodynamics.gasp_based.gaspaero import AeroGeom from aviary.utils.process_input_decks import create_vehicle from aviary.utils.preprocessors import preprocess_propulsion +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variable_meta_data import _MetaData as BaseMetaData import warnings @@ -53,6 +54,8 @@ def test_case1(self): self.aviary_inputs.set_val( Aircraft.Fuselage.WETTED_AREA, val=4000.0, units="ft**2") + setup_model_options(prob, self.aviary_inputs) + with warnings.catch_warnings(): warnings.simplefilter("ignore", om.PromotionWarning) prob.setup() @@ -67,6 +70,8 @@ def test_case2(self): # self.aviary_inputs.set_val(Aircraft.Fuselage.WETTED_AREA, val=4000, units="ft**2") + setup_model_options(prob, self.aviary_inputs) + with warnings.catch_warnings(): warnings.simplefilter("ignore", om.PromotionWarning) prob.setup() @@ -83,6 +88,8 @@ def test_case3(self): self.aviary_inputs.set_val( Aircraft.Fuselage.WETTED_AREA_SCALER, val=0.5, units="unitless") + setup_model_options(prob, self.aviary_inputs) + with warnings.catch_warnings(): warnings.simplefilter("ignore", om.PromotionWarning) prob.setup() @@ -100,6 +107,8 @@ def test_case4(self): self.aviary_inputs.set_val( Aircraft.Fuselage.WETTED_AREA_SCALER, val=0.5, units="unitless") + setup_model_options(prob, self.aviary_inputs) + with warnings.catch_warnings(): warnings.simplefilter("ignore", om.PromotionWarning) prob.setup() @@ -114,10 +123,11 @@ def test_case_aero_coeffs(self): Also checks non-overriden (wing) and default (strut) """ prob = self.prob - prob.model.add_subsystem("geom", AeroGeom( - aviary_options=self.aviary_inputs), promotes=["*"]) + prob.model.add_subsystem("geom", AeroGeom(), promotes=["*"]) self.aviary_inputs.set_val(Aircraft.HorizontalTail.FORM_FACTOR, val=1.5) + setup_model_options(prob, self.aviary_inputs) + with warnings.catch_warnings(): warnings.simplefilter("ignore", om.PromotionWarning) prob.setup() diff --git a/aviary/subsystems/geometry/gasp_based/test/test_size_group.py b/aviary/subsystems/geometry/gasp_based/test/test_size_group.py index dc7c1bb1f..90ad3170a 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_size_group.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_size_group.py @@ -5,6 +5,7 @@ from openmdao.utils.assert_utils import assert_check_partials, assert_near_equal from aviary.subsystems.geometry.gasp_based.size_group import SizeGroup +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Mission @@ -28,9 +29,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes=["*"], ) @@ -98,6 +97,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Nacelle.FINENESS, 2, units="unitless") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -181,9 +182,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes=["*"], ) @@ -254,6 +253,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Nacelle.FINENESS, 2, units="unitless") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -399,9 +400,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes=["*"], ) @@ -478,6 +477,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Nacelle.FINENESS, 2, units="unitless") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -621,9 +622,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes=["*"], ) @@ -700,6 +699,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Nacelle.FINENESS, 2, units="unitless") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): diff --git a/aviary/subsystems/geometry/gasp_based/test/test_strut.py b/aviary/subsystems/geometry/gasp_based/test/test_strut.py index d2c14daa8..e3eaf569b 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_strut.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_strut.py @@ -12,8 +12,7 @@ class SizeGroupTestCase1(unittest.TestCase): def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("strut", StrutGeom( - aviary_options=get_option_defaults()), promotes=["*"]) + self.prob.model.add_subsystem("strut", StrutGeom(), promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.Strut.AREA_RATIO, val=.2, units=None diff --git a/aviary/subsystems/geometry/gasp_based/test/test_wing.py b/aviary/subsystems/geometry/gasp_based/test/test_wing.py index 0bbd89fbc..5cb91f101 100644 --- a/aviary/subsystems/geometry/gasp_based/test/test_wing.py +++ b/aviary/subsystems/geometry/gasp_based/test/test_wing.py @@ -6,6 +6,7 @@ from aviary.subsystems.geometry.gasp_based.wing import (WingFold, WingGroup, WingParameters, WingSize) +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Mission @@ -71,7 +72,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "parameters", WingParameters(aviary_options=get_option_defaults()), promotes=["*"] + "parameters", WingParameters(), promotes=["*"] ) self.prob.model.set_input_defaults(Aircraft.Wing.AREA, 1370.3, units="ft**2") @@ -121,7 +122,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "parameters", WingParameters(aviary_options=options), promotes=["*"] + "parameters", WingParameters(), promotes=["*"] ) self.prob.model.set_input_defaults(Aircraft.Wing.AREA, 1370.3, units="ft**2") @@ -141,6 +142,8 @@ def setUp(self): Aircraft.Wing.THICKNESS_TO_CHORD_TIP, 0.12, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -170,9 +173,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingFold( - aviary_options=options, - ), + WingFold(), promotes=["*"], ) @@ -195,6 +196,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, 0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -236,9 +239,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingFold( - aviary_options=options - ), + WingFold(), promotes=["*"], ) @@ -261,6 +262,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, 0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -299,7 +302,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "group", WingGroup(aviary_options=get_option_defaults()), promotes=["*"] + "group", WingGroup(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -371,9 +374,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingGroup( - aviary_options=options, - ), + WingGroup(), promotes=["*"], ) @@ -410,6 +411,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, 0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -473,9 +476,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingGroup( - aviary_options=options, - ), + WingGroup(), promotes=["*"], ) @@ -508,6 +509,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, 0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -567,9 +570,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingGroup( - aviary_options=options, - ), + WingGroup(), promotes=["*"], ) @@ -580,6 +581,8 @@ def setUp(self): Aircraft.Strut.ATTACHMENT_LOCATION, val=0, units="ft" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -623,9 +626,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingGroup( - aviary_options=options, - ), + WingGroup(), promotes=["*"], ) @@ -668,6 +669,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, 0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): diff --git a/aviary/subsystems/geometry/gasp_based/wing.py b/aviary/subsystems/geometry/gasp_based/wing.py index 122938c2d..85ce6cf1b 100644 --- a/aviary/subsystems/geometry/gasp_based/wing.py +++ b/aviary/subsystems/geometry/gasp_based/wing.py @@ -5,9 +5,8 @@ from aviary.subsystems.geometry.gasp_based.non_dimensional_conversion import \ DimensionalNonDimensionalInterchange from aviary.subsystems.geometry.gasp_based.strut import StrutGeom -from aviary.utils.aviary_values import AviaryValues from aviary.utils.conflict_checks import check_fold_location_definition -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -16,12 +15,6 @@ class WingSize(om.ExplicitComponent): Computation of wing area and wing span for GASP-based aerodynamics. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input(self, Mission.Design.GROSS_MASS, val=152000) @@ -86,11 +79,7 @@ class WingParameters(om.ExplicitComponent): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.HAS_FOLD) def setup(self): @@ -103,7 +92,7 @@ def setup(self): add_aviary_input(self, Aircraft.Fuselage.AVG_DIAMETER, val=10) add_aviary_input(self, Aircraft.Wing.THICKNESS_TO_CHORD_TIP, val=0.1) - if not self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if not self.options[Aircraft.Wing.HAS_FOLD]: add_aviary_input(self, Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6) add_aviary_output(self, Aircraft.Fuel.WING_VOLUME_GEOMETRIC_MAX, val=0) @@ -214,7 +203,7 @@ def compute(self, inputs, outputs): outputs[Aircraft.Wing.ROOT_CHORD] = root_chord outputs[Aircraft.Wing.THICKNESS_TO_CHORD_UNWEIGHTED] = tc_ratio_avg - if not self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if not self.options[Aircraft.Wing.HAS_FOLD]: fuel_vol_frac = inputs[Aircraft.Fuel.WING_FUEL_FRACTION] geometric_fuel_vol = ( @@ -430,7 +419,7 @@ def compute_partials(self, inputs, J): np.pi * AR**2 * trp1**2 / denom / 180 / np.cos(swprad) ** 2 ) - if not self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if not self.options[Aircraft.Wing.HAS_FOLD]: fuel_vol_frac = inputs[Aircraft.Fuel.WING_FUEL_FRACTION] geometric_fuel_vol = ( fuel_vol_frac @@ -523,15 +512,11 @@ class WingFold(om.ExplicitComponent): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.CHOOSE_FOLD_LOCATION) def setup(self): - if not self.options["aviary_options"].get_val(Aircraft.Wing.CHOOSE_FOLD_LOCATION, units='unitless'): + if not self.options[Aircraft.Wing.CHOOSE_FOLD_LOCATION]: self.add_input( "strut_y", val=25, @@ -639,7 +624,7 @@ def compute(self, inputs, outputs): tc_ratio_tip = inputs[Aircraft.Wing.THICKNESS_TO_CHORD_TIP] fuel_vol_frac = inputs[Aircraft.Fuel.WING_FUEL_FRACTION] - if not self.options["aviary_options"].get_val(Aircraft.Wing.CHOOSE_FOLD_LOCATION, units='unitless'): + if not self.options[Aircraft.Wing.CHOOSE_FOLD_LOCATION]: strut_y = inputs["strut_y"] location = strut_y @@ -692,7 +677,7 @@ def compute_partials(self, inputs, J): tc_ratio_tip = inputs[Aircraft.Wing.THICKNESS_TO_CHORD_TIP] fuel_vol_frac = inputs[Aircraft.Fuel.WING_FUEL_FRACTION] - if not self.options["aviary_options"].get_val(Aircraft.Wing.CHOOSE_FOLD_LOCATION, units='unitless'): + if not self.options[Aircraft.Wing.CHOOSE_FOLD_LOCATION]: strut_y = inputs["strut_y"] location = strut_y @@ -971,60 +956,56 @@ class WingGroup(om.Group): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.CHOOSE_FOLD_LOCATION) + add_aviary_option(self, Aircraft.Wing.HAS_FOLD) + add_aviary_option(self, Aircraft.Wing.HAS_STRUT) def setup(self): - aviary_options = self.options['aviary_options'] + has_fold = self.options[Aircraft.Wing.HAS_FOLD] + has_strut = self.options[Aircraft.Wing.HAS_STRUT] size = self.add_subsystem( "size", - WingSize(aviary_options=aviary_options,), + WingSize(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=["aircraft:*"], ) - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless') or self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if has_fold or has_strut: self.add_subsystem( "dimensionless_calcs", - DimensionalNonDimensionalInterchange(aviary_options=aviary_options), + DimensionalNonDimensionalInterchange(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"] ) parameters = self.add_subsystem( "parameters", - WingParameters(aviary_options=aviary_options,), + WingParameters(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if has_strut: strut = self.add_subsystem( "strut", - StrutGeom( - aviary_options=aviary_options, - ), + StrutGeom(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if has_fold: fold = self.add_subsystem( "fold", - WingFold( - aviary_options=aviary_options, - ), + WingFold(), promotes_inputs=["aircraft:*"], promotes_outputs=["aircraft:*"], ) - if not self.options["aviary_options"].get_val(Aircraft.Wing.CHOOSE_FOLD_LOCATION, units='unitless'): - check_fold_location_definition(None, aviary_options) + choose_fold_location = self.options[Aircraft.Wing.CHOOSE_FOLD_LOCATION] + if not choose_fold_location: + check_fold_location_definition(choose_fold_location, has_strut) self.promotes("strut", outputs=["strut_y"]) self.promotes("fold", inputs=["strut_y"]) diff --git a/aviary/subsystems/geometry/geometry_builder.py b/aviary/subsystems/geometry/geometry_builder.py index 93c2352bb..37c3b7358 100644 --- a/aviary/subsystems/geometry/geometry_builder.py +++ b/aviary/subsystems/geometry/geometry_builder.py @@ -90,15 +90,16 @@ def build_pre_mission(self, aviary_inputs): geom_group = None if both_geom: - geom_group = CombinedGeometry(aviary_options=aviary_inputs, - code_origin_to_prioritize=code_origin_to_prioritize) + geom_group = CombinedGeometry( + code_origin_to_prioritize=code_origin_to_prioritize + ) elif code_origin is GASP: - geom_group = SizeGroup(aviary_options=aviary_inputs) + geom_group = SizeGroup() geom_group.manual_overrides = None elif code_origin is FLOPS: - geom_group = PrepGeom(aviary_options=aviary_inputs) + geom_group = PrepGeom() geom_group.manual_overrides = None return geom_group diff --git a/aviary/subsystems/mass/flops_based/air_conditioning.py b/aviary/subsystems/mass/flops_based/air_conditioning.py index 894ca14dd..4e2db1cfe 100644 --- a/aviary/subsystems/mass/flops_based/air_conditioning.py +++ b/aviary/subsystems/mass/flops_based/air_conditioning.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import ( distributed_engine_count_factor, distributed_thrust_factor) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -16,9 +15,8 @@ class TransportAirCondMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): add_aviary_input(self, Aircraft.AirConditioning.MASS_SCALER, val=1.0) @@ -35,30 +33,26 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] scaler = inputs[Aircraft.AirConditioning.MASS_SCALER] avionics_wt = inputs[Aircraft.Avionics.MASS] * GRAV_ENGLISH_LBM height = inputs[Aircraft.Fuselage.MAX_HEIGHT] planform = inputs[Aircraft.Fuselage.PLANFORM_AREA] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] outputs[Aircraft.AirConditioning.MASS] = \ ((3.2 * (planform * height)**0.6 + 9 * pax**0.83) * max_mach + 0.075 * avionics_wt) * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] scaler = inputs[Aircraft.AirConditioning.MASS_SCALER] avionics_wt = inputs[Aircraft.Avionics.MASS] * GRAV_ENGLISH_LBM height = inputs[Aircraft.Fuselage.MAX_HEIGHT] planform = inputs[Aircraft.Fuselage.PLANFORM_AREA] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] planform_exp = planform**0.6 height_exp = height**0.6 @@ -86,9 +80,7 @@ class AltAirCondMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) def setup(self): add_aviary_input(self, Aircraft.AirConditioning.MASS_SCALER, val=1.0) @@ -99,9 +91,7 @@ def setup_partials(self): self.declare_partials(of=Aircraft.AirConditioning.MASS, wrt='*') def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - num_pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + num_pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] scaler = inputs[Aircraft.AirConditioning.MASS_SCALER] @@ -109,9 +99,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): 26.0 * num_pax * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + num_pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] J[Aircraft.AirConditioning.MASS, Aircraft.AirConditioning.MASS_SCALER] = \ 26.0 * num_pax / GRAV_ENGLISH_LBM diff --git a/aviary/subsystems/mass/flops_based/anti_icing.py b/aviary/subsystems/mass/flops_based/anti_icing.py index 779fc3ca0..9d7a485da 100644 --- a/aviary/subsystems/mass/flops_based/anti_icing.py +++ b/aviary/subsystems/mass/flops_based/anti_icing.py @@ -6,8 +6,7 @@ distributed_engine_count_factor, distributed_nacelle_diam_factor, distributed_nacelle_diam_factor_deriv) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -18,13 +17,11 @@ class AntiIcingMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.AntiIcing.MASS_SCALER, val=1.0) @@ -43,9 +40,8 @@ def setup_partials(self): self.declare_partials("*", "*") def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - total_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + total_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] scaler = inputs[Aircraft.AntiIcing.MASS_SCALER] max_width = inputs[Aircraft.Fuselage.MAX_WIDTH] @@ -61,9 +57,8 @@ def compute(self, inputs, outputs): + 3.8 * f_nacelle * count_factor + 1.5 * max_width) * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - total_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + total_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] scaler = inputs[Aircraft.AntiIcing.MASS_SCALER] max_width = inputs[Aircraft.Fuselage.MAX_WIDTH] diff --git a/aviary/subsystems/mass/flops_based/apu.py b/aviary/subsystems/mass/flops_based/apu.py index 3a8fec051..d71b2ac38 100644 --- a/aviary/subsystems/mass/flops_based/apu.py +++ b/aviary/subsystems/mass/flops_based/apu.py @@ -1,8 +1,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -13,9 +12,7 @@ class TransportAPUMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) def setup(self): add_aviary_input(self, Aircraft.APU.MASS_SCALER, val=1.0) @@ -28,9 +25,7 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] scaler = inputs[Aircraft.APU.MASS_SCALER] planform = inputs[Aircraft.Fuselage.PLANFORM_AREA] @@ -38,9 +33,7 @@ def compute(self, inputs, outputs): 54.0 * planform ** 0.3 + 5.4 * pax ** 0.9) * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] scaler = inputs[Aircraft.APU.MASS_SCALER] planform = inputs[Aircraft.Fuselage.PLANFORM_AREA] diff --git a/aviary/subsystems/mass/flops_based/avionics.py b/aviary/subsystems/mass/flops_based/avionics.py index 0c6e54522..1f7e75f7d 100644 --- a/aviary/subsystems/mass/flops_based/avionics.py +++ b/aviary/subsystems/mass/flops_based/avionics.py @@ -1,8 +1,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -14,9 +13,7 @@ class TransportAvionicsMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.NUM_FLIGHT_CREW) def setup(self): add_aviary_input(self, Aircraft.Avionics.MASS_SCALER, val=1.0) @@ -31,8 +28,7 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - crew = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) + crew = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] scaler = inputs[Aircraft.Avionics.MASS_SCALER] planform = inputs[Aircraft.Fuselage.PLANFORM_AREA] des_range = inputs[Mission.Design.RANGE] @@ -41,8 +37,7 @@ def compute(self, inputs, outputs): 15.8 * des_range**0.1 * crew**0.7 * planform**0.43 * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - crew = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) + crew = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] scaler = inputs[Aircraft.Avionics.MASS_SCALER] planform = inputs[Aircraft.Fuselage.PLANFORM_AREA] des_range = inputs[Mission.Design.RANGE] diff --git a/aviary/subsystems/mass/flops_based/canard.py b/aviary/subsystems/mass/flops_based/canard.py index 9223872f1..e40b374d3 100644 --- a/aviary/subsystems/mass/flops_based/canard.py +++ b/aviary/subsystems/mass/flops_based/canard.py @@ -1,7 +1,6 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft, Mission @@ -12,11 +11,6 @@ class CanardMass(om.ExplicitComponent): equations, modified to output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Mission.Design.GROSS_MASS, val=0.0) add_aviary_input(self, Aircraft.Canard.AREA, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/cargo.py b/aviary/subsystems/mass/flops_based/cargo.py index 8ac83f493..dd388e067 100644 --- a/aviary/subsystems/mass/flops_based/cargo.py +++ b/aviary/subsystems/mass/flops_based/cargo.py @@ -5,8 +5,7 @@ ''' import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -17,9 +16,10 @@ class CargoMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER, + units='lbm') + add_aviary_option(self, Aircraft.CrewPayload.MASS_PER_PASSENGER, units='lbm') + add_aviary_option(self, Aircraft.CrewPayload.NUM_PASSENGERS) def setup(self): add_aviary_output(self, Aircraft.CrewPayload.PASSENGER_MASS, 0.) @@ -54,14 +54,9 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] - passenger_count = aviary_options.get_val(Aircraft.CrewPayload.NUM_PASSENGERS) - - mass_per_passenger = aviary_options.get_val( - Aircraft.CrewPayload.MASS_PER_PASSENGER, units='lbm') - - baggage_mass_per_passenger = aviary_options.get_val( - Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER, 'lbm') + passenger_count = self.options[Aircraft.CrewPayload.NUM_PASSENGERS] + mass_per_passenger, _ = self.options[Aircraft.CrewPayload.MASS_PER_PASSENGER] + baggage_mass_per_passenger, _ = self.options[Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER] outputs[Aircraft.CrewPayload.PASSENGER_MASS] = \ mass_per_passenger * passenger_count diff --git a/aviary/subsystems/mass/flops_based/cargo_containers.py b/aviary/subsystems/mass/flops_based/cargo_containers.py index df0967439..18460dcaf 100644 --- a/aviary/subsystems/mass/flops_based/cargo_containers.py +++ b/aviary/subsystems/mass/flops_based/cargo_containers.py @@ -2,7 +2,6 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -14,11 +13,6 @@ class TransportCargoContainersMass(om.ExplicitComponent): the FLOPS weight equations, modified to output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input( self, Aircraft.CrewPayload.CARGO_CONTAINER_MASS_SCALER, val=1.0) diff --git a/aviary/subsystems/mass/flops_based/crew.py b/aviary/subsystems/mass/flops_based/crew.py index 60030710b..924840101 100644 --- a/aviary/subsystems/mass/flops_based/crew.py +++ b/aviary/subsystems/mass/flops_based/crew.py @@ -4,8 +4,7 @@ ''' import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -15,9 +14,8 @@ class NonFlightCrewMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.NUM_FLIGHT_ATTENDANTS) + add_aviary_option(self, Aircraft.CrewPayload.NUM_GALLEY_CREW) def setup(self): add_aviary_input( @@ -34,11 +32,8 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] - flight_attendants_count = \ - aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_ATTENDANTS) - galley_crew_count = \ - aviary_options.get_val(Aircraft.CrewPayload.NUM_GALLEY_CREW) + flight_attendants_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_ATTENDANTS] + galley_crew_count = self.options[Aircraft.CrewPayload.NUM_GALLEY_CREW] mass_per_flight_attendant = self._mass_per_flight_attendant mass_per_galley_crew = self._mass_per_galley_crew @@ -52,11 +47,8 @@ def compute( ) * mass_scaler def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - flight_attendants_count = \ - aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_ATTENDANTS) - galley_crew_count = \ - aviary_options.get_val(Aircraft.CrewPayload.NUM_GALLEY_CREW) + flight_attendants_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_ATTENDANTS] + galley_crew_count = self.options[Aircraft.CrewPayload.NUM_GALLEY_CREW] mass_per_flight_attendant = self._mass_per_flight_attendant mass_per_galley_crew = self._mass_per_galley_crew @@ -79,9 +71,8 @@ class FlightCrewMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.NUM_FLIGHT_CREW) + add_aviary_option(self, Aircraft.LandingGear.CARRIER_BASED) def setup(self): add_aviary_input( @@ -98,9 +89,7 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] - flight_crew_count = \ - aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) + flight_crew_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] mass_per_flight_crew = self._mass_per_flight_crew(inputs) @@ -110,9 +99,7 @@ def compute( flight_crew_count * mass_per_flight_crew * mass_scaler def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - flight_crew_count = \ - aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) + flight_crew_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] mass_per_flight_crew = self._mass_per_flight_crew(inputs) @@ -126,11 +113,10 @@ def _mass_per_flight_crew(self, inputs): Return the mass, in pounds, of one member of the flight crew and their baggage. ''' - aviary_options: AviaryValues = self.options['aviary_options'] mass_per_flight_crew = 225.0 # lbm # account for machine precision error - if 0.9 <= aviary_options.get_val(Aircraft.LandingGear.CARRIER_BASED): + if self.options[Aircraft.LandingGear.CARRIER_BASED]: mass_per_flight_crew -= 35.0 # lbm return mass_per_flight_crew diff --git a/aviary/subsystems/mass/flops_based/electrical.py b/aviary/subsystems/mass/flops_based/electrical.py index 1430945f7..7ba6ee967 100644 --- a/aviary/subsystems/mass/flops_based/electrical.py +++ b/aviary/subsystems/mass/flops_based/electrical.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import \ distributed_engine_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -15,9 +14,10 @@ class ElectricalMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.NUM_FLIGHT_CREW) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) + add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): add_aviary_input(self, Aircraft.Fuselage.LENGTH, 0.0) @@ -30,14 +30,13 @@ def setup_partials(self): self.declare_partials(of='*', wrt='*') def compute(self, inputs, outputs): - options: AviaryValues = self.options['aviary_options'] - nfuse = options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) - ncrew = options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - npass = options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + nfuse = self.options[Aircraft.Fuselage.NUM_FUSELAGES] + ncrew = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + npass = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] + length = inputs[Aircraft.Fuselage.LENGTH] width = inputs[Aircraft.Fuselage.MAX_WIDTH] - num_eng = options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_engines_factor = distributed_engine_count_factor(num_eng) mass_scaler = inputs[Aircraft.Electrical.MASS_SCALER] @@ -46,14 +45,13 @@ def compute(self, inputs, outputs): * (1.0 + 0.044 * ncrew + 0.0015 * npass) * mass_scaler / GRAV_ENGLISH_LBM) def compute_partials(self, inputs, J): - options: AviaryValues = self.options['aviary_options'] - nfuse = options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) - ncrew = options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - npass = options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + nfuse = self.options[Aircraft.Fuselage.NUM_FUSELAGES] + ncrew = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + npass = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] + length = inputs[Aircraft.Fuselage.LENGTH] width = inputs[Aircraft.Fuselage.MAX_WIDTH] - num_eng = options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_engines_factor = distributed_engine_count_factor(num_eng) mass_scaler = inputs[Aircraft.Electrical.MASS_SCALER] @@ -80,9 +78,7 @@ class AltElectricalMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) def setup(self): add_aviary_input(self, Aircraft.Electrical.MASS_SCALER, 1.0) @@ -93,18 +89,14 @@ def setup_partials(self): self.declare_partials(of='*', wrt='*') def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - npass = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + npass = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] mass_scaler = inputs[Aircraft.Electrical.MASS_SCALER] outputs[Aircraft.Electrical.MASS] = 16.3 * \ npass * mass_scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - npass = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + npass = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] J[Aircraft.Electrical.MASS, Aircraft.Electrical.MASS_SCALER] = \ 16.3 * npass / GRAV_ENGLISH_LBM diff --git a/aviary/subsystems/mass/flops_based/empty_margin.py b/aviary/subsystems/mass/flops_based/empty_margin.py index 4c4b5cf33..43fca2b20 100644 --- a/aviary/subsystems/mass/flops_based/empty_margin.py +++ b/aviary/subsystems/mass/flops_based/empty_margin.py @@ -1,6 +1,5 @@ import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -10,11 +9,6 @@ class EmptyMassMargin(om.ExplicitComponent): Calculates the empty mass margin. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Propulsion.MASS, val=0.) diff --git a/aviary/subsystems/mass/flops_based/engine.py b/aviary/subsystems/mass/flops_based/engine.py index ac9644327..93740cccb 100644 --- a/aviary/subsystems/mass/flops_based/engine.py +++ b/aviary/subsystems/mass/flops_based/engine.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -16,13 +15,14 @@ class EngineMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.ADDITIONAL_MASS_FRACTION) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Engine.REFERENCE_MASS, units='lbm') + add_aviary_option(self, Aircraft.Engine.REFERENCE_SLS_THRUST, units='lbf') + add_aviary_option(self, Aircraft.Engine.SCALE_MASS) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Engine.SCALED_SLS_THRUST, val=np.zeros(num_engine_type)) @@ -36,17 +36,12 @@ def setup(self): add_aviary_output(self, Aircraft.Propulsion.TOTAL_ENGINE_MASS, val=0.0) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - - # cast to numpy arrays to ensure values are always correct type - num_engines = np.array(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) - scale_mass = np.array(aviary_options.get_val(Aircraft.Engine.SCALE_MASS)) - addtl_mass_fraction = np.array(aviary_options.get_val( - Aircraft.Engine.ADDITIONAL_MASS_FRACTION)) - ref_engine_mass = np.array(aviary_options.get_val( - Aircraft.Engine.REFERENCE_MASS, units='lbm')) - ref_sls_thrust = np.array(aviary_options.get_val( - Aircraft.Engine.REFERENCE_SLS_THRUST, units='lbf')) + options = self.options + num_engines = options[Aircraft.Engine.NUM_ENGINES] + scale_mass = options[Aircraft.Engine.SCALE_MASS] + addtl_mass_fraction = options[Aircraft.Engine.ADDITIONAL_MASS_FRACTION] + ref_engine_mass, _ = options[Aircraft.Engine.REFERENCE_MASS] + ref_sls_thrust, _ = options[Aircraft.Engine.REFERENCE_SLS_THRUST] scaled_sls_thrust = np.array(inputs[Aircraft.Engine.SCALED_SLS_THRUST]) scaling_parameter = np.array(inputs[Aircraft.Engine.MASS_SCALER]) @@ -76,8 +71,7 @@ def compute(self, inputs, outputs): outputs[Aircraft.Engine.ADDITIONAL_MASS] = addtl_mass def setup_partials(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) self.declare_partials(Aircraft.Engine.MASS, @@ -92,17 +86,14 @@ def setup_partials(self): ['*']) def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_engine_type = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) - - num_engines = np.array(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) - scale_mass = np.array(aviary_options.get_val(Aircraft.Engine.SCALE_MASS)) - addtl_mass_fraction = np.array(aviary_options.get_val( - Aircraft.Engine.ADDITIONAL_MASS_FRACTION)) - ref_engine_mass = np.array(aviary_options.get_val( - Aircraft.Engine.REFERENCE_MASS, units='lbm')) - ref_sls_thrust = np.array(aviary_options.get_val( - Aircraft.Engine.REFERENCE_SLS_THRUST, units='lbf')) + options = self.options + num_engines = options[Aircraft.Engine.NUM_ENGINES] + num_engine_type = len(num_engines) + + scale_mass = options[Aircraft.Engine.SCALE_MASS] + addtl_mass_fraction = options[Aircraft.Engine.ADDITIONAL_MASS_FRACTION] + ref_engine_mass, _ = options[Aircraft.Engine.REFERENCE_MASS] + ref_sls_thrust, _ = options[Aircraft.Engine.REFERENCE_SLS_THRUST] scaled_sls_thrust = np.array(inputs[Aircraft.Engine.SCALED_SLS_THRUST]) scaling_parameter = np.array(inputs[Aircraft.Engine.MASS_SCALER]) diff --git a/aviary/subsystems/mass/flops_based/engine_controls.py b/aviary/subsystems/mass/flops_based/engine_controls.py index c17868c1f..17058a821 100644 --- a/aviary/subsystems/mass/flops_based/engine_controls.py +++ b/aviary/subsystems/mass/flops_based/engine_controls.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import ( distributed_engine_count_factor, distributed_thrust_factor) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -25,9 +24,7 @@ class TransportEngineCtrlsMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): add_aviary_input( @@ -41,9 +38,7 @@ def setup_partials(self): [Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST]) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - - num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_engines_factor = distributed_engine_count_factor(num_engines) max_sls_thrust = inputs[Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST] @@ -55,9 +50,7 @@ def compute(self, inputs, outputs): total_controls_weight / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - - num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] max_sls_thrust = inputs[Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST] thrust_factor = distributed_thrust_factor(max_sls_thrust, num_engines) diff --git a/aviary/subsystems/mass/flops_based/engine_oil.py b/aviary/subsystems/mass/flops_based/engine_oil.py index d82cd8e63..14fc7f429 100644 --- a/aviary/subsystems/mass/flops_based/engine_oil.py +++ b/aviary/subsystems/mass/flops_based/engine_oil.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import ( distributed_engine_count_factor, distributed_thrust_factor) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -22,9 +21,7 @@ class TransportEngineOilMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): add_aviary_input(self, Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER, val=1.0) @@ -37,9 +34,8 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] scaler = inputs[Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER] - num_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_eng_fact = distributed_engine_count_factor(num_eng) max_sls_thrust = inputs[Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST] thrust_factor = distributed_thrust_factor(max_sls_thrust, num_eng) @@ -48,9 +44,8 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): 0.082 * num_eng_fact * thrust_factor**0.65 * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] scaler = inputs[Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER] - num_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_eng_fact = distributed_engine_count_factor(num_eng) max_sls_thrust = inputs[Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST] thrust_factor = distributed_thrust_factor(max_sls_thrust, num_eng) @@ -72,9 +67,7 @@ class AltEngineOilMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) def setup(self): add_aviary_input(self, Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER, val=1.0) @@ -85,9 +78,7 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] scaler = inputs[Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER] @@ -95,9 +86,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): 240.0 * ((pax + 39) // 40) * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - pax = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] J[Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER diff --git a/aviary/subsystems/mass/flops_based/engine_pod.py b/aviary/subsystems/mass/flops_based/engine_pod.py index 256c26d26..c1c262481 100644 --- a/aviary/subsystems/mass/flops_based/engine_pod.py +++ b/aviary/subsystems/mass/flops_based/engine_pod.py @@ -2,8 +2,7 @@ import openmdao.api as om from aviary.subsystems.mass.flops_based.distributed_prop import nacelle_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -18,13 +17,10 @@ class EnginePodMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Electrical.MASS, val=0.0) add_aviary_input(self, Aircraft.Fuel.FUEL_SYSTEM_MASS, val=0.0) @@ -46,8 +42,7 @@ def setup_partials(self): self.declare_partials('*', '*') # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) self.declare_partials(Aircraft.Engine.POD_MASS, @@ -67,8 +62,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): # BUG this methodology completely ignores miscellaneous mass. There is a discrepency between this calculation # and miscellaneous mass. Engine control, starter, and additional mass have a scaler applied to them, and # if their calculated values are used directly this scaler is skipped - aviary_options: AviaryValues = self.options['aviary_options'] - num_eng = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] nacelle_count = nacelle_count_factor(num_eng) eng_thrust = inputs[Aircraft.Engine.SCALED_SLS_THRUST] @@ -113,8 +107,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): outputs[Aircraft.Engine.POD_MASS] = pod_mass def compute_partials(self, inputs, partials, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - num_eng = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] count_factor = nacelle_count_factor(num_eng) m_start = inputs[Aircraft.Propulsion.TOTAL_STARTER_MASS] diff --git a/aviary/subsystems/mass/flops_based/fin.py b/aviary/subsystems/mass/flops_based/fin.py index 989ee1ee2..b4e9f79ab 100644 --- a/aviary/subsystems/mass/flops_based/fin.py +++ b/aviary/subsystems/mass/flops_based/fin.py @@ -1,8 +1,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -13,9 +12,7 @@ class FinMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Fins.NUM_FINS) def setup(self): add_aviary_input(self, Mission.Design.GROSS_MASS, val=0.0) @@ -29,8 +26,7 @@ def setup_partials(self): self.declare_partials("*", "*") def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - num_fins = aviary_options.get_val(Aircraft.Fins.NUM_FINS) + num_fins = self.options[Aircraft.Fins.NUM_FINS] if num_fins > 0: togw = inputs[Mission.Design.GROSS_MASS] * GRAV_ENGLISH_LBM area = inputs[Aircraft.Fins.AREA] @@ -41,8 +37,7 @@ def compute(self, inputs, outputs): inputs[Aircraft.Fins.MASS_SCALER] / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_fins = aviary_options.get_val(Aircraft.Fins.NUM_FINS) + num_fins = self.options[Aircraft.Fins.NUM_FINS] if num_fins > 0: area = inputs[Aircraft.Fins.AREA] taper_ratio = inputs[Aircraft.Fins.TAPER_RATIO] diff --git a/aviary/subsystems/mass/flops_based/fuel_capacity.py b/aviary/subsystems/mass/flops_based/fuel_capacity.py index 98d50b2e9..d1d2009b6 100644 --- a/aviary/subsystems/mass/flops_based/fuel_capacity.py +++ b/aviary/subsystems/mass/flops_based/fuel_capacity.py @@ -1,6 +1,5 @@ import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -10,17 +9,11 @@ class FuelCapacityGroup(om.Group): Compute the maximum fuel that can be carried. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): - aviary_options = self.options['aviary_options'] self.add_subsystem( 'wing_fuel_capacity', - WingFuelCapacity(aviary_options=aviary_options), + WingFuelCapacity(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( @@ -126,11 +119,6 @@ class WingFuelCapacity(om.ExplicitComponent): Compute the maximum fuel that can be carried in the wing's enclosed space. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Fuel.DENSITY_RATIO, 1.0) add_aviary_input(self, Aircraft.Fuel.WING_REF_CAPACITY, 0.0) diff --git a/aviary/subsystems/mass/flops_based/fuel_system.py b/aviary/subsystems/mass/flops_based/fuel_system.py index a78851fe2..78dfe92bc 100644 --- a/aviary/subsystems/mass/flops_based/fuel_system.py +++ b/aviary/subsystems/mass/flops_based/fuel_system.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import \ distributed_engine_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -16,9 +15,8 @@ class TransportFuelSystemMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): add_aviary_input(self, Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER, val=1.0) @@ -31,24 +29,22 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] scaler = inputs[Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER] capacity = inputs[Aircraft.Fuel.TOTAL_CAPACITY] - num_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_eng_fact = distributed_engine_count_factor(num_eng) - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] outputs[Aircraft.Fuel.FUEL_SYSTEM_MASS] = ( 1.07 * capacity**0.58 * num_eng_fact**0.43 * max_mach**0.34 * scaler) / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] scaler = inputs[Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER] capacity = inputs[Aircraft.Fuel.TOTAL_CAPACITY] - num_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_eng_fact = distributed_engine_count_factor(num_eng) - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] J[Aircraft.Fuel.FUEL_SYSTEM_MASS, Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER] = ( 1.07 * capacity**0.58 * num_eng_fact**0.43 * max_mach**0.34 / GRAV_ENGLISH_LBM) @@ -66,9 +62,7 @@ class AltFuelSystemMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Fuel.NUM_TANKS) def setup(self): add_aviary_input(self, Aircraft.Fuel.TOTAL_CAPACITY, val=0.0) @@ -81,8 +75,7 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - number_of_fuel_tanks = aviary_options.get_val(Aircraft.Fuel.NUM_TANKS) + number_of_fuel_tanks = self.options[Aircraft.Fuel.NUM_TANKS] total_fuel_capacity = inputs[Aircraft.Fuel.TOTAL_CAPACITY] scaler = inputs[Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER] @@ -97,8 +90,7 @@ def compute(self, inputs, outputs): fuel_sys_weight / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - number_of_fuel_tanks = aviary_options.get_val(Aircraft.Fuel.NUM_TANKS) + number_of_fuel_tanks = self.options[Aircraft.Fuel.NUM_TANKS] total_fuel_capacity = inputs[Aircraft.Fuel.TOTAL_CAPACITY] scaler = inputs[Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER] diff --git a/aviary/subsystems/mass/flops_based/furnishings.py b/aviary/subsystems/mass/flops_based/furnishings.py index 3dfa8416b..edba25346 100644 --- a/aviary/subsystems/mass/flops_based/furnishings.py +++ b/aviary/subsystems/mass/flops_based/furnishings.py @@ -2,8 +2,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -14,9 +13,11 @@ class TransportFurnishingsGroupMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) + add_aviary_option(self, Aircraft.CrewPayload.NUM_FLIGHT_CREW) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) + add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) def setup(self): add_aviary_input(self, Aircraft.Furnishings.MASS_SCALER, val=1.0) @@ -32,22 +33,14 @@ def setup(self): def setup_partials(self): self.declare_partials(of=Aircraft.Furnishings.MASS, wrt='*') - def compute( - self, inputs, outputs, discrete_inputs=None, discrete_outputs=None - ): - aviary_options: AviaryValues = self.options['aviary_options'] - - flight_crew_count = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - first_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) - - business_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) + def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - tourist_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) + flight_crew_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + first_class_count = self.options[Aircraft.CrewPayload.Design.NUM_FIRST_CLASS] + business_class_count = self.options[Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS] + tourist_class_count = self.options[Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS] - fuse_count = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) + fuse_count = self.options[Aircraft.Fuselage.NUM_FUSELAGES] scaler = inputs[Aircraft.Furnishings.MASS_SCALER] @@ -65,19 +58,12 @@ def compute( ) * scaler def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] + flight_crew_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + first_class_count = self.options[Aircraft.CrewPayload.Design.NUM_FIRST_CLASS] + business_class_count = self.options[Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS] + tourist_class_count = self.options[Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS] - flight_crew_count = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - first_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) - - business_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) - - tourist_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) - - fuse_count = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) + fuse_count = self.options[Aircraft.Fuselage.NUM_FUSELAGES] scaler = inputs[Aircraft.Furnishings.MASS_SCALER] fuse_max_width = inputs[Aircraft.Fuselage.MAX_WIDTH] @@ -109,9 +95,12 @@ class BWBFurnishingsGroupMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.BWB.NUM_BAYS) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) + add_aviary_option(self, Aircraft.CrewPayload.NUM_FLIGHT_CREW) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) + add_aviary_option(self, Aircraft.Fuselage.MILITARY_CARGO_FLOOR) def setup(self): add_aviary_input(self, Aircraft.Furnishings.MASS_SCALER, val=1.0) @@ -131,20 +120,12 @@ def setup(self): def setup_partials(self): self.declare_partials(of=Aircraft.Furnishings.MASS, wrt='*') - def compute( - self, inputs, outputs, discrete_inputs=None, discrete_outputs=None - ): - aviary_options: AviaryValues = self.options['aviary_options'] - - flight_crew_count = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - first_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) + def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - business_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) - - tourist_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) + flight_crew_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + first_class_count = self.options[Aircraft.CrewPayload.Design.NUM_FIRST_CLASS] + business_class_count = self.options[Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS] + tourist_class_count = self.options[Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS] scaler = inputs[Aircraft.Furnishings.MASS_SCALER] fuse_max_width = inputs[Aircraft.Fuselage.MAX_WIDTH] @@ -156,9 +137,9 @@ def compute( ) # outputs[Aircraft.Furnishings.MASS] = weight / GRAV_ENGLISH_LBM - if not aviary_options.get_val(Aircraft.Fuselage.MILITARY_CARGO_FLOOR): + if not self.options[Aircraft.Fuselage.MILITARY_CARGO_FLOOR]: acabin = inputs[Aircraft.BWB.CABIN_AREA] - nbay = aviary_options.get_val(Aircraft.BWB.NUM_BAYS) + nbay = self.options[Aircraft.BWB.NUM_BAYS] cos = np.cos( np.pi/180*(inputs[Aircraft.BWB.PASSENGER_LEADING_EDGE_SWEEP]) @@ -173,17 +154,10 @@ def compute( outputs[Aircraft.Furnishings.MASS] = weight * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - - flight_crew_count = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - first_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) - - business_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) - - tourist_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) + flight_crew_count = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + first_class_count = self.options[Aircraft.CrewPayload.Design.NUM_FIRST_CLASS] + business_class_count = self.options[Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS] + tourist_class_count = self.options[Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS] scaler = inputs[Aircraft.Furnishings.MASS_SCALER] @@ -192,7 +166,7 @@ def compute_partials(self, inputs, J): + 78.0 * business_class_count + 44.0 * tourist_class_count ) / GRAV_ENGLISH_LBM - if aviary_options.get_val(Aircraft.Fuselage.MILITARY_CARGO_FLOOR): + if self.options[Aircraft.Fuselage.MILITARY_CARGO_FLOOR]: J[Aircraft.Furnishings.MASS, Aircraft.BWB.CABIN_AREA] = 0.0 J[Aircraft.Furnishings.MASS, Aircraft.Fuselage.MAX_WIDTH] = 0.0 @@ -210,7 +184,7 @@ def compute_partials(self, inputs, J): tan = np.tan(d2r) acabin = inputs[Aircraft.BWB.CABIN_AREA] - nbay = aviary_options.get_val(Aircraft.BWB.NUM_BAYS) + nbay = self.options[Aircraft.BWB.NUM_BAYS] fuse_max_width = inputs[Aircraft.Fuselage.MAX_WIDTH] fuse_max_height = inputs[Aircraft.Fuselage.MAX_HEIGHT] cabin_area = inputs[Aircraft.BWB.CABIN_AREA] @@ -262,9 +236,7 @@ class AltFurnishingsGroupMassBase(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) def setup(self): add_aviary_input(self, Aircraft.Furnishings.MASS_SCALER, val=1.0) @@ -277,18 +249,14 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] - pax_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax_count = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] scaler = inputs[Aircraft.Furnishings.MASS_SCALER] outputs[Aircraft.Furnishings.MASS_BASE] = \ (82.15 * pax_count + 3600.0) * scaler def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - pax_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + pax_count = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] J[ Aircraft.Furnishings.MASS_BASE, @@ -303,11 +271,6 @@ class AltFurnishingsGroupMass(om.ExplicitComponent): equations, modified to output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Furnishings.MASS_BASE, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/fuselage.py b/aviary/subsystems/mass/flops_based/fuselage.py index 6b349ec20..dc0ad71ec 100644 --- a/aviary/subsystems/mass/flops_based/fuselage.py +++ b/aviary/subsystems/mass/flops_based/fuselage.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import \ distributed_engine_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -16,9 +15,9 @@ class TransportFuselageMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Fuselage.MILITARY_CARGO_FLOOR) + add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) def setup(self): add_aviary_input(self, Aircraft.Fuselage.LENGTH, val=0.0) @@ -33,16 +32,15 @@ def setup_partials(self): self.declare_partials(Aircraft.Fuselage.MASS, "*") def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] length = inputs[Aircraft.Fuselage.LENGTH] scaler = inputs[Aircraft.Fuselage.MASS_SCALER] avg_diameter = inputs[Aircraft.Fuselage.AVG_DIAMETER] - num_fuse = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) - num_fuse_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + num_fuse = self.options[Aircraft.Fuselage.NUM_FUSELAGES] + num_fuse_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] + num_fuse_eng_fact = distributed_engine_count_factor(num_fuse_eng) - military_cargo = aviary_options.get_val(Aircraft.Fuselage.MILITARY_CARGO_FLOOR) + military_cargo = self.options[Aircraft.Fuselage.MILITARY_CARGO_FLOOR] mil_factor = 1.38 if military_cargo else 1.0 @@ -52,15 +50,13 @@ def compute(self, inputs, outputs): ) def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] length = inputs[Aircraft.Fuselage.LENGTH] scaler = inputs[Aircraft.Fuselage.MASS_SCALER] avg_diameter = inputs[Aircraft.Fuselage.AVG_DIAMETER] - num_fuse = aviary_options.get_val(Aircraft.Fuselage.NUM_FUSELAGES) - num_fuse_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + num_fuse = self.options[Aircraft.Fuselage.NUM_FUSELAGES] + num_fuse_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] num_fuse_eng_fact = distributed_engine_count_factor(num_fuse_eng) - military_cargo = aviary_options.get_val(Aircraft.Fuselage.MILITARY_CARGO_FLOOR) + military_cargo = self.options[Aircraft.Fuselage.MILITARY_CARGO_FLOOR] # avg_diameter = (max_height + max_width) / 2. avg_diameter_exp = avg_diameter ** 1.28 @@ -84,11 +80,6 @@ class AltFuselageMass(om.ExplicitComponent): of weight. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Fuselage.MASS_SCALER, 1.0) diff --git a/aviary/subsystems/mass/flops_based/horizontal_tail.py b/aviary/subsystems/mass/flops_based/horizontal_tail.py index 3c182a5b2..a647ebd8f 100644 --- a/aviary/subsystems/mass/flops_based/horizontal_tail.py +++ b/aviary/subsystems/mass/flops_based/horizontal_tail.py @@ -1,7 +1,6 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft, Mission @@ -12,11 +11,6 @@ class HorizontalTailMass(om.ExplicitComponent): equations, modified to output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.HorizontalTail.AREA, val=0.0) @@ -70,11 +64,6 @@ class AltHorizontalTailMass(om.ExplicitComponent): output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.HorizontalTail.AREA, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/hydraulics.py b/aviary/subsystems/mass/flops_based/hydraulics.py index aed93313f..e2f5ca58c 100644 --- a/aviary/subsystems/mass/flops_based/hydraulics.py +++ b/aviary/subsystems/mass/flops_based/hydraulics.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import \ distributed_engine_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission # TODO: update non-transport components to new standard to remove these variables @@ -23,9 +22,9 @@ class TransportHydraulicsGroupMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): add_aviary_input(self, Aircraft.Fuselage.PLANFORM_AREA, val=0.0) @@ -44,11 +43,8 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - num_wing_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) - num_fuse_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + num_wing_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES] + num_fuse_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] num_wing_eng_fact = distributed_engine_count_factor(num_wing_eng) num_fuse_eng_fact = distributed_engine_count_factor(num_fuse_eng) @@ -57,7 +53,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): scaler = inputs[Aircraft.Hydraulics.MASS_SCALER] area = inputs[Aircraft.Wing.AREA] var_sweep = inputs[Aircraft.Wing.VAR_SWEEP_MASS_PENALTY] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] outputs[Aircraft.Hydraulics.MASS] = ( 0.57 * (planform + 0.27 * area) @@ -66,11 +62,8 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): * scaler / GRAV_ENGLISH_LBM) def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_wing_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) - num_fuse_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + num_wing_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES] + num_fuse_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] num_wing_eng_fact = distributed_engine_count_factor(num_wing_eng) num_fuse_eng_fact = distributed_engine_count_factor(num_fuse_eng) @@ -79,7 +72,7 @@ def compute_partials(self, inputs, J): scaler = inputs[Aircraft.Hydraulics.MASS_SCALER] area = inputs[Aircraft.Wing.AREA] var_sweep = inputs[Aircraft.Wing.VAR_SWEEP_MASS_PENALTY] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] term1 = (planform + 0.27 * area) term2 = (1.0 + 0.03 * num_wing_eng_fact + 0.05 * num_fuse_eng_fact) @@ -111,11 +104,6 @@ class AltHydraulicsGroupMass(om.ExplicitComponent): output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Wing.AREA, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/instruments.py b/aviary/subsystems/mass/flops_based/instruments.py index 3b0c50f84..04bcda862 100644 --- a/aviary/subsystems/mass/flops_based/instruments.py +++ b/aviary/subsystems/mass/flops_based/instruments.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import \ distributed_engine_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -18,9 +17,10 @@ class TransportInstrumentMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.NUM_FLIGHT_CREW) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): add_aviary_input(self, Aircraft.Fuselage.PLANFORM_AREA, 0.0) @@ -31,17 +31,14 @@ def setup(self): self.declare_partials("*", "*") def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - num_crew = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - num_wing_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) - num_fuse_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + num_crew = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + num_wing_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES] + num_fuse_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] num_wing_eng_fact = distributed_engine_count_factor(num_wing_eng) num_fuse_eng_fact = distributed_engine_count_factor(num_fuse_eng) fuse_area = inputs[Aircraft.Fuselage.PLANFORM_AREA] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] mass_scaler = inputs[Aircraft.Instruments.MASS_SCALER] instrument_weight = ( @@ -53,17 +50,14 @@ def compute(self, inputs, outputs): mass_scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_crew = aviary_options.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW) - num_wing_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) - num_fuse_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES) + num_crew = self.options[Aircraft.CrewPayload.NUM_FLIGHT_CREW] + num_wing_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES] + num_fuse_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES] num_wing_eng_fact = distributed_engine_count_factor(num_wing_eng) num_fuse_eng_fact = distributed_engine_count_factor(num_fuse_eng) fuse_area = inputs[Aircraft.Fuselage.PLANFORM_AREA] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] mass_scaler = inputs[Aircraft.Instruments.MASS_SCALER] fact = (10.0 + 2.5 * num_crew + num_wing_eng_fact + 1.5 * num_fuse_eng_fact) diff --git a/aviary/subsystems/mass/flops_based/landing_gear.py b/aviary/subsystems/mass/flops_based/landing_gear.py index f053a2586..97f03615f 100644 --- a/aviary/subsystems/mass/flops_based/landing_gear.py +++ b/aviary/subsystems/mass/flops_based/landing_gear.py @@ -4,8 +4,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import ( distributed_nacelle_diam_factor, distributed_nacelle_diam_factor_deriv) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission DEG2RAD = np.pi / 180.0 @@ -19,11 +18,6 @@ class LandingGearMass(om.ExplicitComponent): # TODO: add in aircraft type and carrier factors as options and modify # equations - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.LandingGear.MAIN_GEAR_OLEO_LENGTH, val=0.0) @@ -136,11 +130,6 @@ class AltLandingGearMass(om.ExplicitComponent): to output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.LandingGear.MAIN_GEAR_OLEO_LENGTH, val=0.0) @@ -255,11 +244,6 @@ class NoseGearLength(om.ExplicitComponent): NOSE_GEAR_OLEO_LENGTH = 0.7 * MAIN_GEAR_OLEO_LENGTH """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.LandingGear.MAIN_GEAR_OLEO_LENGTH, val=0.0) add_aviary_output(self, Aircraft.LandingGear.NOSE_GEAR_OLEO_LENGTH, val=0.0) @@ -280,15 +264,12 @@ class MainGearLength(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Engine.NUM_WING_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) - num_wing_engines = self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_WING_ENGINES) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) + num_wing_engines = self.options[Aircraft.Engine.NUM_WING_ENGINES] add_aviary_input(self, Aircraft.Fuselage.LENGTH, val=0.0) add_aviary_input(self, Aircraft.Fuselage.MAX_WIDTH, val=0.0) @@ -309,10 +290,11 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - options: AviaryValues = self.options['aviary_options'] + num_eng = self.options[Aircraft.Engine.NUM_ENGINES][0] + # TODO temp using first engine, heterogeneous engines not supported - num_eng = options.get_val(Aircraft.Engine.NUM_ENGINES)[0] - num_wing_eng = options.get_val(Aircraft.Engine.NUM_WING_ENGINES)[0] + num_wing_eng = self.options[Aircraft.Engine.NUM_WING_ENGINES][0] + y_eng_fore = inputs[Aircraft.Engine.WING_LOCATIONS][0][0] # TODO: high engine-count configuation. @@ -348,10 +330,10 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): outputs[Aircraft.LandingGear.MAIN_GEAR_OLEO_LENGTH] = cmlg def compute_partials(self, inputs, partials, discrete_inputs=None): - options: AviaryValues = self.options['aviary_options'] # TODO temp using first engine, heterogeneous engines not supported - num_eng = options.get_val(Aircraft.Engine.NUM_ENGINES)[0] - num_wing_eng = options.get_val(Aircraft.Engine.NUM_WING_ENGINES)[0] + num_eng = self.options[Aircraft.Engine.NUM_ENGINES][0] + num_wing_eng = self.options[Aircraft.Engine.NUM_WING_ENGINES][0] + y_eng_fore = inputs[Aircraft.Engine.WING_LOCATIONS][0][0] y_eng_aft = 0 diff --git a/aviary/subsystems/mass/flops_based/landing_group.py b/aviary/subsystems/mass/flops_based/landing_group.py index 13978daf8..468e1efad 100644 --- a/aviary/subsystems/mass/flops_based/landing_group.py +++ b/aviary/subsystems/mass/flops_based/landing_group.py @@ -4,8 +4,8 @@ AltLandingGearMass, LandingGearMass, MainGearLength, NoseGearLength) from aviary.subsystems.mass.flops_based.landing_mass import ( LandingMass, LandingTakeoffMassRatio) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.variables import Aircraft +from aviary.variable_info.functions import add_aviary_option +from aviary.variable_info.variables import Aircraft, Mission class LandingMassGroup(om.Group): @@ -15,35 +15,32 @@ class LandingMassGroup(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Design.USE_ALT_MASS) def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] - alt_mass = aviary_options.get_val(Aircraft.Design.USE_ALT_MASS) + alt_mass = self.options[Aircraft.Design.USE_ALT_MASS] self.add_subsystem('landing_to_takeoff_mass_ratio', - LandingTakeoffMassRatio(aviary_options=aviary_options), + LandingTakeoffMassRatio(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem('main_landing_gear_length', - MainGearLength(aviary_options=aviary_options), + MainGearLength(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem('nose_landing_gear_length', - NoseGearLength(aviary_options=aviary_options), + NoseGearLength(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem('landing_mass', - LandingMass(aviary_options=aviary_options), + LandingMass(), promotes_inputs=['*'], promotes_outputs=['*']) if alt_mass: self.add_subsystem('landing_gear', - AltLandingGearMass(aviary_options=aviary_options), + AltLandingGearMass(), promotes_inputs=['*'], promotes_outputs=['*']) else: self.add_subsystem('landing_gear', - LandingGearMass(aviary_options=aviary_options), + LandingGearMass(), promotes_inputs=['*'], promotes_outputs=['*']) diff --git a/aviary/subsystems/mass/flops_based/landing_mass.py b/aviary/subsystems/mass/flops_based/landing_mass.py index c34686fbe..b809b51dc 100644 --- a/aviary/subsystems/mass/flops_based/landing_mass.py +++ b/aviary/subsystems/mass/flops_based/landing_mass.py @@ -1,7 +1,6 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft, Mission @@ -11,11 +10,6 @@ class LandingTakeoffMassRatio(om.ExplicitComponent): Calculate the ratio of maximum landing mass to maximum takeoff gross mass. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Mission.Summary.CRUISE_MACH, val=0.0) @@ -58,11 +52,6 @@ class LandingMass(om.ExplicitComponent): Maximum landing mass is maximum takeoff gross mass times the ratio of landing/takeoff mass. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Mission.Design.GROSS_MASS, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/mass_premission.py b/aviary/subsystems/mass/flops_based/mass_premission.py index b60b2ebd3..c477b562c 100644 --- a/aviary/subsystems/mass/flops_based/mass_premission.py +++ b/aviary/subsystems/mass/flops_based/mass_premission.py @@ -45,7 +45,7 @@ from aviary.subsystems.mass.flops_based.vertical_tail import ( AltVerticalTailMass, VerticalTailMass) from aviary.subsystems.mass.flops_based.wing_group import WingMassGroup -from aviary.utils.aviary_values import AviaryValues +from aviary.variable_info.functions import add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -57,249 +57,241 @@ class MassPremission(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Design.USE_ALT_MASS) def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] - alt_mass = aviary_options.get_val(Aircraft.Design.USE_ALT_MASS) + alt_mass = self.options[Aircraft.Design.USE_ALT_MASS] self.add_subsystem( 'cargo', - CargoMass(aviary_options=aviary_options), + CargoMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'cargo_containers', - TransportCargoContainersMass( - aviary_options=aviary_options), + TransportCargoContainersMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'engine_controls', - TransportEngineCtrlsMass(aviary_options=aviary_options), + TransportEngineCtrlsMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'avionics', - TransportAvionicsMass(aviary_options=aviary_options), + TransportAvionicsMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'fuel_capacity_group', - FuelCapacityGroup(aviary_options=aviary_options), + FuelCapacityGroup(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'engine_mass', - EngineMass(aviary_options=aviary_options), + EngineMass(), promotes_inputs=['*'], promotes_outputs=['*']) if alt_mass: self.add_subsystem( 'fuel_system', - AltFuelSystemMass(aviary_options=aviary_options), + AltFuelSystemMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'AC', - AltAirCondMass(aviary_options=aviary_options), + AltAirCondMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'engine_oil', - AltEngineOilMass(aviary_options=aviary_options), + AltEngineOilMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'furnishing_base', - AltFurnishingsGroupMassBase( - aviary_options=aviary_options), + AltFurnishingsGroupMassBase(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'furnishings', - AltFurnishingsGroupMass(aviary_options=aviary_options), + AltFurnishingsGroupMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'hydraulics', - AltHydraulicsGroupMass(aviary_options=aviary_options), + AltHydraulicsGroupMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'pass_service', - AltPassengerServiceMass( - aviary_options=aviary_options), + AltPassengerServiceMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'unusable_fuel', - AltUnusableFuelMass(aviary_options=aviary_options), + AltUnusableFuelMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'electrical', - AltElectricalMass(aviary_options=aviary_options), + AltElectricalMass(), promotes_inputs=['*'], promotes_outputs=['*']) else: self.add_subsystem( 'fuel_system', - TransportFuelSystemMass(aviary_options=aviary_options), + TransportFuelSystemMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'AC', - TransportAirCondMass(aviary_options=aviary_options), + TransportAirCondMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'engine_oil', - TransportEngineOilMass(aviary_options=aviary_options), + TransportEngineOilMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'furnishings', - TransportFurnishingsGroupMass( - aviary_options=aviary_options), + TransportFurnishingsGroupMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'hydraulics', - TransportHydraulicsGroupMass( - aviary_options=aviary_options), + TransportHydraulicsGroupMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'pass_service', - PassengerServiceMass(aviary_options=aviary_options), + PassengerServiceMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'unusable_fuel', - TransportUnusableFuelMass(aviary_options=aviary_options), + TransportUnusableFuelMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'electrical', - ElectricalMass(aviary_options=aviary_options), + ElectricalMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'starter', - TransportStarterMass(aviary_options=aviary_options), + TransportStarterMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'anti_icing', - AntiIcingMass(aviary_options=aviary_options), + AntiIcingMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'apu', - TransportAPUMass(aviary_options=aviary_options), + TransportAPUMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'nonflight_crew', - NonFlightCrewMass(aviary_options=aviary_options), + NonFlightCrewMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'flight_crew', - FlightCrewMass(aviary_options=aviary_options), + FlightCrewMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'instruments', - TransportInstrumentMass(aviary_options=aviary_options), + TransportInstrumentMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'misc_engine', - EngineMiscMass(aviary_options=aviary_options), + EngineMiscMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'nacelle', - NacelleMass(aviary_options=aviary_options), + NacelleMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'paint', - PaintMass(aviary_options=aviary_options), + PaintMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'thrust_rev', - ThrustReverserMass(aviary_options=aviary_options), + ThrustReverserMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'landing_group', - LandingMassGroup(aviary_options=aviary_options), + LandingMassGroup(), promotes_inputs=['*'], promotes_outputs=['*']) if alt_mass: self.add_subsystem( 'surf_ctrl', - AltSurfaceControlMass(aviary_options=aviary_options), + AltSurfaceControlMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'fuselage', - AltFuselageMass(aviary_options=aviary_options), + AltFuselageMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'htail', - AltHorizontalTailMass(aviary_options=aviary_options), + AltHorizontalTailMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'vert_tail', - AltVerticalTailMass(aviary_options=aviary_options), + AltVerticalTailMass(), promotes_inputs=['*'], promotes_outputs=['*']) else: self.add_subsystem( 'surf_ctrl', - SurfaceControlMass(aviary_options=aviary_options), + SurfaceControlMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'fuselage', - TransportFuselageMass(aviary_options=aviary_options), + TransportFuselageMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'htail', - HorizontalTailMass(aviary_options=aviary_options), + HorizontalTailMass(), promotes_inputs=['*', ], promotes_outputs=['*', ]) self.add_subsystem( 'vert_tail', - VerticalTailMass(aviary_options=aviary_options), + VerticalTailMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'canard', - CanardMass(aviary_options=aviary_options), + CanardMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'fin', - FinMass(aviary_options=aviary_options), + FinMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'wing_group', - WingMassGroup(aviary_options=aviary_options), + WingMassGroup(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'total_mass', - MassSummation(aviary_options=aviary_options), + MassSummation(), promotes_inputs=['*'], promotes_outputs=['*']) diff --git a/aviary/subsystems/mass/flops_based/mass_summation.py b/aviary/subsystems/mass/flops_based/mass_summation.py index d1294985e..2a3ae8103 100644 --- a/aviary/subsystems/mass/flops_based/mass_summation.py +++ b/aviary/subsystems/mass/flops_based/mass_summation.py @@ -3,8 +3,7 @@ import openmdao.api as om from aviary.subsystems.mass.flops_based.empty_margin import EmptyMassMargin -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -19,73 +18,67 @@ class MassSummation(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Design.USE_ALT_MASS) def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] - alt_mass = aviary_options.get_val(Aircraft.Design.USE_ALT_MASS) + alt_mass = self.options[Aircraft.Design.USE_ALT_MASS] self.add_subsystem( - 'structure_mass', StructureMass(aviary_options=aviary_options), + 'structure_mass', StructureMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( - 'propulsion_mass', PropulsionMass(aviary_options=aviary_options), + 'propulsion_mass', PropulsionMass(), promotes_inputs=['*'], promotes_outputs=['*']) if alt_mass: self.add_subsystem( 'system_equip_mass_base', - AltSystemsEquipMassBase(aviary_options=aviary_options), + AltSystemsEquipMassBase(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( 'system_equip_mass', - AltSystemsEquipMass(aviary_options=aviary_options), + AltSystemsEquipMass(), promotes_inputs=['*'], promotes_outputs=['*']) else: self.add_subsystem( - 'system_equip_mass', SystemsEquipMass(aviary_options=aviary_options), + 'system_equip_mass', SystemsEquipMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( - 'empty_mass_margin', EmptyMassMargin(aviary_options=aviary_options), + 'empty_mass_margin', EmptyMassMargin(), promotes_inputs=['*'], promotes_outputs=['*']) if alt_mass: self.add_subsystem( - 'empty_mass', AltEmptyMass(aviary_options=aviary_options), + 'empty_mass', AltEmptyMass(), promotes_inputs=['*'], promotes_outputs=['*']) else: - self.add_subsystem('empty_mass', EmptyMass(aviary_options=aviary_options), + self.add_subsystem('empty_mass', EmptyMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( - 'operating_mass', OperatingMass(aviary_options=aviary_options), + 'operating_mass', OperatingMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem( - 'zero_fuel_mass', ZeroFuelMass(aviary_options=aviary_options), + 'zero_fuel_mass', ZeroFuelMass(), promotes_inputs=['*'], promotes_outputs=['*']) - self.add_subsystem('fuel_mass', FuelMass(aviary_options=aviary_options), + self.add_subsystem('fuel_mass', FuelMass(), promotes_inputs=['*'], promotes_outputs=['*']) class StructureMass(om.ExplicitComponent): def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Canard.MASS, val=0.0) add_aviary_input(self, Aircraft.Fins.MASS, val=0.0) @@ -101,8 +94,7 @@ def setup(self): add_aviary_output(self, Aircraft.Design.STRUCTURE_MASS, val=0.0) def setup_partials(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) self.declare_partials(Aircraft.Design.STRUCTURE_MASS, '*', val=1) self.declare_partials(Aircraft.Design.STRUCTURE_MASS, Aircraft.Nacelle.MASS, @@ -127,11 +119,6 @@ def compute(self, inputs, outputs): class PropulsionMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Fuel.FUEL_SYSTEM_MASS, val=0.0) add_aviary_input(self, Aircraft.Propulsion.TOTAL_MISC_MASS, val=0.0) @@ -162,11 +149,6 @@ def compute(self, inputs, outputs): class SystemsEquipMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.AirConditioning.MASS, val=0.0) add_aviary_input(self, Aircraft.AntiIcing.MASS, val=0.0) @@ -204,11 +186,6 @@ def compute(self, inputs, outputs): class AltSystemsEquipMassBase(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.AirConditioning.MASS, val=0.0) add_aviary_input(self, Aircraft.AntiIcing.MASS, val=0.0) @@ -246,11 +223,6 @@ def compute(self, inputs, outputs): class AltSystemsEquipMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Design.SYSTEMS_EQUIP_MASS_BASE, val=0.0) add_aviary_input(self, Aircraft.Design.STRUCTURE_MASS, val=0.0) @@ -283,11 +255,6 @@ def compute(self, inputs, outputs): class EmptyMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Design.EMPTY_MASS_MARGIN, val=0.0) add_aviary_input(self, Aircraft.Design.STRUCTURE_MASS, val=0.0) @@ -311,11 +278,6 @@ def compute(self, inputs, outputs): class AltEmptyMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Design.EMPTY_MASS_MARGIN, val=0.0) add_aviary_input(self, Aircraft.Design.STRUCTURE_MASS, val=0.0) @@ -346,11 +308,6 @@ def compute(self, inputs, outputs): class OperatingMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.CrewPayload.CARGO_CONTAINER_MASS, val=0.0) add_aviary_input(self, Aircraft.CrewPayload.NON_FLIGHT_CREW_MASS, val=0.0) @@ -381,11 +338,6 @@ def compute(self, inputs, outputs): class ZeroFuelMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.CrewPayload.PASSENGER_MASS, val=0.0) add_aviary_input(self, Aircraft.CrewPayload.BAGGAGE_MASS, val=0.0) @@ -409,11 +361,6 @@ def compute(self, inputs, outputs): class FuelMass(om.ExplicitComponent): - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Mission.Design.GROSS_MASS, val=0.0) add_aviary_input(self, Aircraft.Design.ZERO_FUEL_MASS, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/misc_engine.py b/aviary/subsystems/mass/flops_based/misc_engine.py index dba079072..a77ca24c9 100644 --- a/aviary/subsystems/mass/flops_based/misc_engine.py +++ b/aviary/subsystems/mass/flops_based/misc_engine.py @@ -1,9 +1,8 @@ import numpy as np + import openmdao.api as om -import numpy as np -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -20,13 +19,10 @@ class EngineMiscMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input( self, Aircraft.Engine.ADDITIONAL_MASS, val=np.zeros(num_engine_type)) @@ -48,8 +44,7 @@ def setup(self): def compute(self, inputs, outputs): # TODO temporarily using engine-level additional mass and multiplying # by num_engines to get propulsion-level additional mass - options: AviaryValues = self.options['aviary_options'] - num_engines = options.get_val(Aircraft.Engine.NUM_ENGINES) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] addtl_mass = sum(inputs[Aircraft.Engine.ADDITIONAL_MASS] * num_engines) ctrl_mass = inputs[Aircraft.Propulsion.TOTAL_ENGINE_CONTROLS_MASS] @@ -63,8 +58,7 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): # TODO temporarily using engine-level additional mass and multiplying # by num_engines to get propulsion-level additional mass - options: AviaryValues = self.options['aviary_options'] - num_engines = options.get_val(Aircraft.Engine.NUM_ENGINES) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] addtl_mass = inputs[Aircraft.Engine.ADDITIONAL_MASS] * num_engines ctrl_mass = inputs[Aircraft.Propulsion.TOTAL_ENGINE_CONTROLS_MASS] diff --git a/aviary/subsystems/mass/flops_based/nacelle.py b/aviary/subsystems/mass/flops_based/nacelle.py index 398d8f0af..7ec531053 100644 --- a/aviary/subsystems/mass/flops_based/nacelle.py +++ b/aviary/subsystems/mass/flops_based/nacelle.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import nacelle_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -21,13 +20,10 @@ class NacelleMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Nacelle.AVG_DIAMETER, val=np.zeros(num_engine_type)) @@ -45,8 +41,7 @@ def setup(self): def setup_partials(self): # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) self.declare_partials(Aircraft.Nacelle.MASS, Aircraft.Nacelle.AVG_DIAMETER, @@ -59,8 +54,7 @@ def setup_partials(self): rows=shape, cols=shape, val=1.0) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - num_eng = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] avg_diam = inputs[Aircraft.Nacelle.AVG_DIAMETER] avg_length = inputs[Aircraft.Nacelle.AVG_LENGTH] scaler = inputs[Aircraft.Nacelle.MASS_SCALER] @@ -73,8 +67,7 @@ def compute(self, inputs, outputs): avg_diam * avg_length * thrust**0.36 * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_eng = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] avg_diam = inputs[Aircraft.Nacelle.AVG_DIAMETER] avg_length = inputs[Aircraft.Nacelle.AVG_LENGTH] scaler = inputs[Aircraft.Nacelle.MASS_SCALER] diff --git a/aviary/subsystems/mass/flops_based/paint.py b/aviary/subsystems/mass/flops_based/paint.py index 7e1df471a..4781a13e6 100644 --- a/aviary/subsystems/mass/flops_based/paint.py +++ b/aviary/subsystems/mass/flops_based/paint.py @@ -1,6 +1,5 @@ import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Aircraft @@ -10,11 +9,6 @@ class PaintMass(om.ExplicitComponent): Calculates the mass of paint based on total wetted area. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Design.TOTAL_WETTED_AREA, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/passenger_service.py b/aviary/subsystems/mass/flops_based/passenger_service.py index 7d1688085..f333b4011 100644 --- a/aviary/subsystems/mass/flops_based/passenger_service.py +++ b/aviary/subsystems/mass/flops_based/passenger_service.py @@ -5,8 +5,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -18,9 +17,10 @@ class PassengerServiceMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + 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_TOURIST_CLASS) + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): add_aviary_input( @@ -45,17 +45,12 @@ def setup_partials(self): self.declare_partials('*', '*') def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - first_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) + first_class_count = self.options[Aircraft.CrewPayload.Design.NUM_FIRST_CLASS] + business_class_count = self.options[Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS] + tourist_class_count = self.options[Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS] - business_class_count = \ - aviary_options.get_val(Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) - - tourist_class_count = \ - aviary_options.get_val(Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) design_range = inputs[Mission.Design.RANGE] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] passenger_service_mass_scaler = \ inputs[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_SCALER] @@ -72,17 +67,12 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): passenger_service_weight / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - first_class_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_FIRST_CLASS) - - business_class_count = \ - aviary_options.get_val(Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS) + first_class_count = self.options[Aircraft.CrewPayload.Design.NUM_FIRST_CLASS] + business_class_count = self.options[Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS] + tourist_class_count = self.options[Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS] - tourist_class_count = \ - aviary_options.get_val(Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS) design_range = inputs[Mission.Design.RANGE] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] passenger_service_mass_scaler = \ inputs[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_SCALER] @@ -116,9 +106,7 @@ class AltPassengerServiceMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) def setup(self): add_aviary_input( @@ -132,9 +120,7 @@ def setup_partials(self): def compute( self, inputs, outputs, discrete_inputs=None, discrete_outputs=None ): - aviary_options: AviaryValues = self.options['aviary_options'] - passenger_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + passenger_count = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] passenger_service_mass_scaler = \ inputs[Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_SCALER] @@ -146,9 +132,7 @@ def compute( passenger_service_weight / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J, discrete_inputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - passenger_count = aviary_options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') + passenger_count = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] J[ Aircraft.CrewPayload.PASSENGER_SERVICE_MASS, diff --git a/aviary/subsystems/mass/flops_based/starter.py b/aviary/subsystems/mass/flops_based/starter.py index e7b06a4d9..2bf04fb07 100644 --- a/aviary/subsystems/mass/flops_based/starter.py +++ b/aviary/subsystems/mass/flops_based/starter.py @@ -1,11 +1,11 @@ -import openmdao.api as om import numpy as np +import openmdao.api as om + from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import ( distributed_engine_count_factor, distributed_nacelle_diam_factor) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -17,13 +17,12 @@ class TransportStarterMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Nacelle.AVG_DIAMETER, val=np.zeros(num_engine_type)) @@ -34,12 +33,11 @@ def setup_partials(self): self.declare_partials("*", "*") def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - total_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + total_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] + max_mach = self.options[Mission.Constraints.MAX_MACH] d_nacelle = inputs[Aircraft.Nacelle.AVG_DIAMETER] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) num_engines_factor = distributed_engine_count_factor(total_engines) f_nacelle = distributed_nacelle_diam_factor(d_nacelle, num_engines) @@ -47,13 +45,12 @@ def compute(self, inputs, outputs): 11.0 * num_engines_factor * max_mach**0.32 * f_nacelle**1.6) / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - total_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) - num_engines = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + total_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] + max_mach = self.options[Mission.Constraints.MAX_MACH] d_nacelle = inputs[Aircraft.Nacelle.AVG_DIAMETER] eng_count_factor = distributed_engine_count_factor(total_engines) - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) d_avg = sum(d_nacelle * num_engines) / total_engines diff --git a/aviary/subsystems/mass/flops_based/surface_controls.py b/aviary/subsystems/mass/flops_based/surface_controls.py index 441a7fcde..fb109e427 100644 --- a/aviary/subsystems/mass/flops_based/surface_controls.py +++ b/aviary/subsystems/mass/flops_based/surface_controls.py @@ -1,8 +1,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -13,9 +12,7 @@ class SurfaceControlMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Mission.Constraints.MAX_MACH) def setup(self): add_aviary_input(self, Aircraft.Wing.SURFACE_CONTROL_MASS_SCALER, val=1.0) @@ -31,9 +28,8 @@ def setup(self): Aircraft.Wing.CONTROL_SURFACE_AREA_RATIO, Aircraft.Wing.AREA]) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] scaler = inputs[Aircraft.Wing.SURFACE_CONTROL_MASS_SCALER] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] gross_weight = inputs[Mission.Design.GROSS_MASS] * GRAV_ENGLISH_LBM flap_ratio = inputs[Aircraft.Wing.CONTROL_SURFACE_AREA_RATIO] wing_area = inputs[Aircraft.Wing.AREA] @@ -49,9 +45,8 @@ def compute(self, inputs, outputs): GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] scaler = inputs[Aircraft.Wing.SURFACE_CONTROL_MASS_SCALER] - max_mach = aviary_options.get_val(Mission.Constraints.MAX_MACH) + max_mach = self.options[Mission.Constraints.MAX_MACH] gross_weight = inputs[Mission.Design.GROSS_MASS] * GRAV_ENGLISH_LBM flap_ratio = inputs[Aircraft.Wing.CONTROL_SURFACE_AREA_RATIO] wing_area = inputs[Aircraft.Wing.AREA] @@ -93,11 +88,6 @@ class AltSurfaceControlMass(om.ExplicitComponent): output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Wing.SURFACE_CONTROL_MASS_SCALER, val=1.0) add_aviary_input(self, Aircraft.Wing.AREA, val=0.0) 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 b0becd20f..929bd0a12 100644 --- a/aviary/subsystems/mass/flops_based/test/test_air_conditioning.py +++ b/aviary/subsystems/mass/flops_based/test/test_air_conditioning.py @@ -10,7 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -28,11 +28,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "air_cond", - TransportAirCondMass(aviary_options=get_flops_inputs(case_name)), + TransportAirCondMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -67,12 +69,16 @@ def tearDown(self): def test_case(self): prob = om.Problem() + prob.model.add_subsystem( "air_cond", - TransportAirCondMass(aviary_options=get_flops_inputs("N3CC")), + TransportAirCondMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC") + prob.model.set_input_defaults( Aircraft.AirConditioning.MASS_SCALER, val=0.98094, units="unitless") prob.model.set_input_defaults( @@ -81,6 +87,7 @@ def test_case(self): Aircraft.Fuselage.MAX_HEIGHT, val=13., units="ft") prob.model.set_input_defaults( Aircraft.Fuselage.PLANFORM_AREA, val=1537.5, units="ft**2") + prob.setup(check=False, force_alloc_complex=True) partial_data = prob.check_partials(out_stream=None, method="cs") @@ -103,11 +110,13 @@ def test_case(self, case_name): prob.model.add_subsystem( 'air_cond', - AltAirCondMass(aviary_options=get_flops_inputs(case_name)), + AltAirCondMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -137,12 +146,16 @@ def tearDown(self): def test_case(self): prob = om.Problem() + prob.model.add_subsystem( 'air_cond', - AltAirCondMass(aviary_options=get_flops_inputs("N3CC")), + AltAirCondMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC") + prob.model.set_input_defaults( Aircraft.AirConditioning.MASS_SCALER, val=0.98094, units="unitless") prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/subsystems/mass/flops_based/test/test_anti_icing.py b/aviary/subsystems/mass/flops_based/test/test_anti_icing.py index b02844208..3cf156548 100644 --- a/aviary/subsystems/mass/flops_based/test/test_anti_icing.py +++ b/aviary/subsystems/mass/flops_based/test/test_anti_icing.py @@ -11,6 +11,7 @@ from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -28,11 +29,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "anti_icing", - AntiIcingMass(aviary_options=get_flops_inputs(case_name, preprocess=True)), + AntiIcingMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -50,17 +53,19 @@ def test_case_2(self): # test with more than four engines prob = self.prob - aviary_options = get_flops_inputs('LargeSingleAisle1FLOPS') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([5])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 5) + options = get_flops_options('LargeSingleAisle1FLOPS') + options[Aircraft.Engine.NUM_ENGINES] = np.array([5]) + options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] = 5 prob.model.add_subsystem( "anti_icing", - AntiIcingMass(aviary_options=aviary_options), + AntiIcingMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = options + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.AntiIcing.MASS_SCALER, 1.0) @@ -83,17 +88,19 @@ def test_case_3(self): # test with multiple engine types prob = self.prob - aviary_options = get_flops_inputs('LargeSingleAisle1FLOPS') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2, 2, 4])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 8) + options = get_flops_options('LargeSingleAisle1FLOPS') + options[Aircraft.Engine.NUM_ENGINES] = np.array([2, 2, 4]) + options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] = 8 prob.model.add_subsystem( "anti_icing", - AntiIcingMass(aviary_options=aviary_options), + AntiIcingMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = options + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.AntiIcing.MASS_SCALER, 1.0) @@ -132,15 +139,20 @@ def tearDown(self): def test_case_2(self): prob = om.Problem() - aviary_options = get_flops_inputs('N3CC') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([5])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 5) + + options = get_flops_options('N3CC') + options[Aircraft.Engine.NUM_ENGINES] = np.array([5]) + options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] = 5 + prob.model.add_subsystem( "anti_icing", - AntiIcingMass(aviary_options=aviary_options), + AntiIcingMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = options + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.AntiIcing.MASS_SCALER, 1.0) prob.set_val(Aircraft.Fuselage.MAX_WIDTH, 12.33, 'ft') diff --git a/aviary/subsystems/mass/flops_based/test/test_apu.py b/aviary/subsystems/mass/flops_based/test/test_apu.py index e9050e459..f0706f3fb 100644 --- a/aviary/subsystems/mass/flops_based/test/test_apu.py +++ b/aviary/subsystems/mass/flops_based/test/test_apu.py @@ -8,7 +8,7 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -26,11 +26,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "apu", - TransportAPUMass(aviary_options=get_flops_inputs(case_name)), + TransportAPUMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -62,10 +64,13 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "apu", - TransportAPUMass(aviary_options=get_flops_inputs("N3CC")), + TransportAPUMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.Fuselage.PLANFORM_AREA, 100.0, 'ft**2') diff --git a/aviary/subsystems/mass/flops_based/test/test_avionics.py b/aviary/subsystems/mass/flops_based/test/test_avionics.py index 3ce67ff86..084afb5ce 100644 --- a/aviary/subsystems/mass/flops_based/test/test_avionics.py +++ b/aviary/subsystems/mass/flops_based/test/test_avionics.py @@ -8,7 +8,7 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft, Mission @@ -29,12 +29,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "avionics", - TransportAvionicsMass(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + TransportAvionicsMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -68,11 +69,13 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "avionics", - TransportAvionicsMass(aviary_options=get_flops_inputs( - "N3CC", preprocess=True)), + TransportAvionicsMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.Fuselage.PLANFORM_AREA, 1500.0, 'ft**2') prob.set_val(Mission.Design.RANGE, 3500.0, 'nmi') diff --git a/aviary/subsystems/mass/flops_based/test/test_cargo.py b/aviary/subsystems/mass/flops_based/test/test_cargo.py index 7d388fc1c..7b6ea15b3 100644 --- a/aviary/subsystems/mass/flops_based/test/test_cargo.py +++ b/aviary/subsystems/mass/flops_based/test/test_cargo.py @@ -6,17 +6,14 @@ from aviary.subsystems.mass.flops_based.cargo import CargoMass from aviary.utils.aviary_values import AviaryValues from aviary.utils.test_utils.variable_test import assert_match_varnames -from aviary.validation_cases.validation_tests import do_validation_test, print_case +from aviary.validation_cases.validation_tests import do_validation_test, print_case, get_flops_options from aviary.variable_info.variables import Aircraft cargo_test_data = {} cargo_test_data['1'] = AviaryValues({ - Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER: (50, 'lbm'), Aircraft.CrewPayload.MISC_CARGO: (2000., 'lbm'), # custom - Aircraft.CrewPayload.MASS_PER_PASSENGER: (180., 'lbm'), Aircraft.CrewPayload.WING_CARGO: (1000., 'lbm'), # custom Aircraft.CrewPayload.BAGGAGE_MASS: (9200., 'lbm'), # custom - Aircraft.CrewPayload.NUM_PASSENGERS: (184, 'unitless'), # custom Aircraft.CrewPayload.PASSENGER_MASS: (33120., 'lbm'), # custom Aircraft.CrewPayload.CARGO_MASS: (3000., 'lbm'), # custom Aircraft.CrewPayload.TOTAL_PAYLOAD_MASS: (45320., 'lbm') # custom @@ -38,11 +35,17 @@ def test_case(self, case_name): prob.model.add_subsystem( 'cargo_passenger', - CargoMass(aviary_options=validation_data), + CargoMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = { + Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER: (50, 'lbm'), + Aircraft.CrewPayload.MASS_PER_PASSENGER: (180., 'lbm'), + Aircraft.CrewPayload.NUM_PASSENGERS: 184, # custom + } + prob.setup(check=False, force_alloc_complex=True) do_validation_test(prob, diff --git a/aviary/subsystems/mass/flops_based/test/test_cargo_containers.py b/aviary/subsystems/mass/flops_based/test/test_cargo_containers.py index 9b5c303c9..35eca64a4 100644 --- a/aviary/subsystems/mass/flops_based/test/test_cargo_containers.py +++ b/aviary/subsystems/mass/flops_based/test/test_cargo_containers.py @@ -9,7 +9,7 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -27,12 +27,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "cargo_containers", - TransportCargoContainersMass( - aviary_options=get_flops_inputs(case_name)), + TransportCargoContainersMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -67,12 +68,13 @@ def test_case(self): prob.model.add_subsystem( "cargo_containers", - TransportCargoContainersMass( - aviary_options=get_flops_inputs("N3CC")), + TransportCargoContainersMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.CrewPayload.BAGGAGE_MASS, 5000.0, 'lbm') diff --git a/aviary/subsystems/mass/flops_based/test/test_crew.py b/aviary/subsystems/mass/flops_based/test/test_crew.py index bcd0dc2ce..e4800e0a7 100644 --- a/aviary/subsystems/mass/flops_based/test/test_crew.py +++ b/aviary/subsystems/mass/flops_based/test/test_crew.py @@ -7,7 +7,7 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -25,12 +25,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "non_flight_crew", - NonFlightCrewMass(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + NonFlightCrewMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -57,11 +58,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "flight_crew", - FlightCrewMass(aviary_options=get_flops_inputs(case_name, preprocess=True)), + FlightCrewMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( diff --git a/aviary/subsystems/mass/flops_based/test/test_electrical.py b/aviary/subsystems/mass/flops_based/test/test_electrical.py index f9abb531a..42567dbb9 100644 --- a/aviary/subsystems/mass/flops_based/test/test_electrical.py +++ b/aviary/subsystems/mass/flops_based/test/test_electrical.py @@ -10,7 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -28,7 +28,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "electric_test", - ElectricalMass(aviary_options=get_flops_inputs(case_name, preprocess=True)), + ElectricalMass(), promotes_outputs=[ Aircraft.Electrical.MASS, ], @@ -39,6 +39,8 @@ def test_case(self, case_name): ] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -65,7 +67,7 @@ def test_case(self): prob.model.add_subsystem( "electric_test", - ElectricalMass(aviary_options=get_flops_inputs("N3CC", preprocess=True)), + ElectricalMass(), promotes_outputs=[ Aircraft.Electrical.MASS, ], @@ -76,6 +78,8 @@ def test_case(self): ] ) + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -106,7 +110,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "electric_test", - ElectricalMass(aviary_options=get_flops_inputs("N3CC", preprocess=True)), + ElectricalMass(), promotes_outputs=[ Aircraft.Electrical.MASS, ], @@ -116,6 +120,9 @@ def test_case(self): Aircraft.Electrical.MASS_SCALER ] ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.Fuselage.LENGTH, 100.0, 'ft') prob.set_val(Aircraft.Fuselage.MAX_WIDTH, 12.0, 'ft') @@ -137,8 +144,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "electric_test", - AltElectricalMass(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + AltElectricalMass(), promotes_outputs=[ Aircraft.Electrical.MASS, ], @@ -147,6 +153,8 @@ def test_case(self, case_name): ] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( diff --git a/aviary/subsystems/mass/flops_based/test/test_empty_margin.py b/aviary/subsystems/mass/flops_based/test/test_empty_margin.py index 29b45f3fb..20ca3cad3 100644 --- a/aviary/subsystems/mass/flops_based/test/test_empty_margin.py +++ b/aviary/subsystems/mass/flops_based/test/test_empty_margin.py @@ -7,7 +7,7 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -25,11 +25,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "margin", - EmptyMassMargin(aviary_options=get_flops_inputs(case_name)), + EmptyMassMargin(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( diff --git a/aviary/subsystems/mass/flops_based/test/test_engine.py b/aviary/subsystems/mass/flops_based/test/test_engine.py index 8f249a162..94ba9732e 100644 --- a/aviary/subsystems/mass/flops_based/test/test_engine.py +++ b/aviary/subsystems/mass/flops_based/test/test_engine.py @@ -13,7 +13,7 @@ from aviary.utils.functions import get_path from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft, Settings @@ -26,16 +26,17 @@ def setUp(self): @parameterized.expand(get_flops_case_names(), name_func=print_case) def test_case(self, case_name): - prob = self.prob prob.model.add_subsystem( "engine_mass", - EngineMass(aviary_options=get_flops_inputs(case_name, preprocess=True)), + EngineMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -81,8 +82,18 @@ def test_case_2(self): engine3 = EngineDeck(name='engine3', options=options) preprocess_propulsion(options, [engine, engine2, engine3]) - prob.model.add_subsystem('engine_mass', EngineMass( - aviary_options=options), promotes=['*']) + prob.model.add_subsystem('engine_mass', EngineMass(), promotes=['*']) + + opts = { + Aircraft.Engine.ADDITIONAL_MASS_FRACTION: options.get_val(Aircraft.Engine.ADDITIONAL_MASS_FRACTION), + Aircraft.Engine.NUM_ENGINES: options.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Engine.REFERENCE_MASS: options.get_item(Aircraft.Engine.REFERENCE_MASS), + Aircraft.Engine.REFERENCE_SLS_THRUST: options.get_item(Aircraft.Engine.REFERENCE_SLS_THRUST), + Aircraft.Engine.SCALE_MASS: options.get_val(Aircraft.Engine.SCALE_MASS), + } + + prob.model_options['*'] = opts + prob.setup(force_alloc_complex=True) prob.set_val(Aircraft.Engine.SCALED_SLS_THRUST, diff --git a/aviary/subsystems/mass/flops_based/test/test_engine_controls.py b/aviary/subsystems/mass/flops_based/test/test_engine_controls.py index 9df3af152..63cb871ed 100644 --- a/aviary/subsystems/mass/flops_based/test/test_engine_controls.py +++ b/aviary/subsystems/mass/flops_based/test/test_engine_controls.py @@ -9,7 +9,7 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -25,17 +25,18 @@ def setUp(self): @parameterized.expand(get_flops_case_names(omit='N3CC'), name_func=print_case) def test_case(self, case_name): - flops_inputs = get_flops_inputs(case_name, preprocess=True) prob = self.prob prob.model.add_subsystem( 'engine_ctrls', - TransportEngineCtrlsMass(aviary_options=flops_inputs), + TransportEngineCtrlsMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(force_alloc_complex=True) flops_validation_test( @@ -64,14 +65,17 @@ def tearDown(self): control.GRAV_ENGLISH_LBM = 1.0 def test_case(self): - flops_inputs = get_flops_inputs("LargeSingleAisle1FLOPS", preprocess=True) prob = om.Problem() prob.model.add_subsystem( 'engine_ctrls', - TransportEngineCtrlsMass(aviary_options=flops_inputs), + TransportEngineCtrlsMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + + prob.model_options['*'] = get_flops_options("LargeSingleAisle1FLOPS", + preprocess=True) + prob.setup(force_alloc_complex=True) prob.set_val(Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, 50000.0, 'lbf') diff --git a/aviary/subsystems/mass/flops_based/test/test_engine_oil.py b/aviary/subsystems/mass/flops_based/test/test_engine_oil.py index 8ec123917..6b3157175 100644 --- a/aviary/subsystems/mass/flops_based/test/test_engine_oil.py +++ b/aviary/subsystems/mass/flops_based/test/test_engine_oil.py @@ -10,6 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, + get_flops_options, get_flops_inputs, print_case) from aviary.variable_info.variables import Aircraft @@ -29,16 +30,19 @@ def test_case(self, case_name): prob = self.prob - options = get_flops_inputs(case_name) - options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 2) + options = { + Aircraft.Propulsion.TOTAL_NUM_ENGINES: 2, + } prob.model.add_subsystem( 'engine_oil', - TransportEngineOilMass(aviary_options=options), + TransportEngineOilMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = options + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -69,12 +73,14 @@ def tearDown(self): def test_case(self): prob = om.Problem() - options = get_flops_inputs("N3CC") - options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 2) + + options = { + Aircraft.Propulsion.TOTAL_NUM_ENGINES: 2, + } prob.model.add_subsystem( 'engine_oil', - TransportEngineOilMass(aviary_options=options), + TransportEngineOilMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -99,16 +105,21 @@ def test_case(self, case_name): prob = self.prob - options = get_flops_inputs(case_name) - options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 2) + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.CrewPayload.Design.NUM_PASSENGERS: inputs.get_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS), + } prob.model.add_subsystem( 'engine_oil', - AltEngineOilMass(aviary_options=options), + AltEngineOilMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = options + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -137,11 +148,16 @@ def tearDown(self): def test_case(self): prob = om.Problem() - options = get_flops_inputs("N3CC") - options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 2) + + inputs = get_flops_inputs("N3CC", preprocess=True) + + options = { + Aircraft.CrewPayload.Design.NUM_PASSENGERS: inputs.get_val(Aircraft.CrewPayload.Design.NUM_PASSENGERS), + } + prob.model.add_subsystem( 'engine_oil', - AltEngineOilMass(aviary_options=options), + AltEngineOilMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) diff --git a/aviary/subsystems/mass/flops_based/test/test_engine_pod.py b/aviary/subsystems/mass/flops_based/test/test_engine_pod.py index 7882b7178..a813abc69 100644 --- a/aviary/subsystems/mass/flops_based/test/test_engine_pod.py +++ b/aviary/subsystems/mass/flops_based/test/test_engine_pod.py @@ -30,13 +30,21 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + } + prob.model.add_subsystem( 'engine_pod', - EnginePodMass(aviary_options=get_flops_inputs(case_name, preprocess=True)), + EnginePodMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = options + prob.setup(check=False, force_alloc_complex=True) # Tol not that tight, but it is unclear where the pod mass values in files come from, @@ -62,13 +70,13 @@ def test_case_multiengine(self): # test with multiple engine types prob = self.prob - aviary_options = get_flops_inputs('LargeSingleAisle1FLOPS') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2, 2, 3])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 7) + options = { + Aircraft.Engine.NUM_ENGINES: np.array([2, 2, 3]), + } prob.model.add_subsystem( 'engine_pod', - EnginePodMass(aviary_options=aviary_options), + EnginePodMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) diff --git a/aviary/subsystems/mass/flops_based/test/test_fin.py b/aviary/subsystems/mass/flops_based/test/test_fin.py index 095ce75c2..fb75e20a9 100644 --- a/aviary/subsystems/mass/flops_based/test/test_fin.py +++ b/aviary/subsystems/mass/flops_based/test/test_fin.py @@ -36,9 +36,12 @@ def test_case(self, case_name): validation_data = fin_test_data[case_name] prob = self.prob + options = { + Aircraft.Fins.NUM_FINS: 1, + } prob.model.add_subsystem( "fin", - FinMass(aviary_options=validation_data), + FinMass(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -73,11 +76,14 @@ def tearDown(self): fin.GRAV_ENGLISH_LBM = 1.0 def test_case(self): - validation_data = fin_test_data["1"] prob = om.Problem() + + options = { + Aircraft.Fins.NUM_FINS: 1, + } prob.model.add_subsystem( "fin", - FinMass(aviary_options=validation_data), + FinMass(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_fuel_capacity.py b/aviary/subsystems/mass/flops_based/test/test_fuel_capacity.py index 1e2b94ad3..d9e7aff1d 100644 --- a/aviary/subsystems/mass/flops_based/test/test_fuel_capacity.py +++ b/aviary/subsystems/mass/flops_based/test/test_fuel_capacity.py @@ -31,11 +31,10 @@ def initialize(self): desc='Aircraft options dictionary') def setup(self): - aviary_options = self.options['aviary_options'] self.add_subsystem( 'fuel_capacity_group', - FuelCapacityGroup(aviary_options=aviary_options), + FuelCapacityGroup(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_fuel_system.py b/aviary/subsystems/mass/flops_based/test/test_fuel_system.py index c1c0f9dd8..7aa2ad9cc 100644 --- a/aviary/subsystems/mass/flops_based/test/test_fuel_system.py +++ b/aviary/subsystems/mass/flops_based/test/test_fuel_system.py @@ -12,7 +12,7 @@ get_flops_case_names, get_flops_inputs, print_case) -from aviary.variable_info.variables import Aircraft +from aviary.variable_info.variables import Aircraft, Mission class AltFuelSystemTest(unittest.TestCase): @@ -26,10 +26,15 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Fuel.NUM_TANKS: inputs.get_val(Aircraft.Fuel.NUM_TANKS), + } + prob.model.add_subsystem( "alt_fuel_sys_test", - AltFuelSystemMass(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + AltFuelSystemMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -63,10 +68,16 @@ def tearDown(self): def test_case(self): prob = om.Problem() + + inputs = get_flops_inputs("N3CC", preprocess=True) + + options = { + Aircraft.Fuel.NUM_TANKS: inputs.get_val(Aircraft.Fuel.NUM_TANKS), + } + prob.model.add_subsystem( "alt_fuel_sys_test", - AltFuelSystemMass(aviary_options=get_flops_inputs( - "N3CC", preprocess=True)), + AltFuelSystemMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -88,10 +99,16 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Propulsion.TOTAL_NUM_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES), + Mission.Constraints.MAX_MACH: inputs.get_val(Mission.Constraints.MAX_MACH), + } + prob.model.add_subsystem( "transport_fuel_sys_test", - TransportFuelSystemMass( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + TransportFuelSystemMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -126,10 +143,17 @@ def tearDown(self): def test_case(self): prob = om.Problem() + + inputs = get_flops_inputs("N3CC", preprocess=True) + + options = { + Aircraft.Propulsion.TOTAL_NUM_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES), + Mission.Constraints.MAX_MACH: inputs.get_val(Mission.Constraints.MAX_MACH), + } + prob.model.add_subsystem( "transport_fuel_sys_test", - TransportFuelSystemMass( - aviary_options=get_flops_inputs("N3CC", preprocess=True)), + TransportFuelSystemMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) diff --git a/aviary/subsystems/mass/flops_based/test/test_furnishings.py b/aviary/subsystems/mass/flops_based/test/test_furnishings.py index b6885b17b..7dab4cc72 100644 --- a/aviary/subsystems/mass/flops_based/test/test_furnishings.py +++ b/aviary/subsystems/mass/flops_based/test/test_furnishings.py @@ -11,6 +11,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, + get_flops_options, get_flops_inputs, print_case) from aviary.variable_info.variables import Aircraft, Mission @@ -32,12 +33,13 @@ def test_case(self, case_name): prob.model.add_subsystem( 'furnishings', - TransportFurnishingsGroupMass( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + TransportFurnishingsGroupMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -68,18 +70,25 @@ def test_case(self, case_name): prob = self.prob flops_inputs = get_flops_inputs(case_name, preprocess=True) - flops_inputs.update({ - Aircraft.Fuselage.MILITARY_CARGO_FLOOR: (False, 'unitless'), - Aircraft.BWB.NUM_BAYS: (5, 'unitless') - }) + + opts = { + Aircraft.BWB.NUM_BAYS: 5, + Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS: flops_inputs.get_val(Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS), + Aircraft.CrewPayload.NUM_FLIGHT_CREW: flops_inputs.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW), + Aircraft.CrewPayload.Design.NUM_FIRST_CLASS: flops_inputs.get_val(Aircraft.CrewPayload.Design.NUM_FIRST_CLASS), + Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS: flops_inputs.get_val(Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS), + Aircraft.Fuselage.MILITARY_CARGO_FLOOR: False, + } prob.model.add_subsystem( 'furnishings', - BWBFurnishingsGroupMass(aviary_options=flops_inputs), + BWBFurnishingsGroupMass(**opts), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) # TODO: add FLOPS tests cases with BWB furnishings mass calculations @@ -124,14 +133,21 @@ def tearDown(self): def test_case(self): prob = om.Problem() + flops_inputs = get_flops_inputs("N3CC", preprocess=True) - flops_inputs.update({ - Aircraft.Fuselage.MILITARY_CARGO_FLOOR: (False, 'unitless'), - Aircraft.BWB.NUM_BAYS: (5, 'unitless') - }) + + opts = { + Aircraft.BWB.NUM_BAYS: 5, + Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS: flops_inputs.get_val(Aircraft.CrewPayload.Design.NUM_BUSINESS_CLASS), + Aircraft.CrewPayload.NUM_FLIGHT_CREW: flops_inputs.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW), + Aircraft.CrewPayload.Design.NUM_FIRST_CLASS: flops_inputs.get_val(Aircraft.CrewPayload.Design.NUM_FIRST_CLASS), + Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS: flops_inputs.get_val(Aircraft.CrewPayload.Design.NUM_TOURIST_CLASS), + Aircraft.Fuselage.MILITARY_CARGO_FLOOR: False, + } + prob.model.add_subsystem( 'furnishings', - BWBFurnishingsGroupMass(aviary_options=flops_inputs), + BWBFurnishingsGroupMass(**opts), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -157,12 +173,13 @@ def test_case(self, case_name): prob.model.add_subsystem( 'furnishings', - AltFurnishingsGroupMassBase( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + AltFurnishingsGroupMassBase(), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -192,12 +209,13 @@ def test_case(self, case_name): prob.model.add_subsystem( 'furnishings', - AltFurnishingsGroupMass( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + AltFurnishingsGroupMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( diff --git a/aviary/subsystems/mass/flops_based/test/test_fuselage.py b/aviary/subsystems/mass/flops_based/test/test_fuselage.py index e9bda3a9d..554ae7284 100644 --- a/aviary/subsystems/mass/flops_based/test/test_fuselage.py +++ b/aviary/subsystems/mass/flops_based/test/test_fuselage.py @@ -10,7 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -28,12 +28,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "fuselage", - TransportFuselageMass(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + TransportFuselageMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -67,11 +68,13 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "fuselage", - TransportFuselageMass(aviary_options=get_flops_inputs( - "N3CC", preprocess=True)), + TransportFuselageMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.Fuselage.LENGTH, 100.0, 'ft') prob.set_val(Aircraft.Fuselage.AVG_DIAMETER, 10.0, 'ft') @@ -93,7 +96,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "fuselage", - AltFuselageMass(aviary_options=get_flops_inputs(case_name)), + AltFuselageMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -131,7 +134,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "fuselage", - AltFuselageMass(aviary_options=get_flops_inputs("N3CC")), + AltFuselageMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_horizontail_tail.py b/aviary/subsystems/mass/flops_based/test/test_horizontail_tail.py index 2269d0aec..ca45ce0fb 100644 --- a/aviary/subsystems/mass/flops_based/test/test_horizontail_tail.py +++ b/aviary/subsystems/mass/flops_based/test/test_horizontail_tail.py @@ -10,7 +10,6 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, print_case) from aviary.variable_info.variables import Aircraft, Mission @@ -28,7 +27,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "horizontal_tail", - HorizontalTailMass(aviary_options=get_flops_inputs(case_name)), + HorizontalTailMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -67,7 +66,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "horizontal_tail", - HorizontalTailMass(aviary_options=get_flops_inputs("N3CC")), + HorizontalTailMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -93,7 +92,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "horizontal_tail", - AltHorizontalTailMass(aviary_options=get_flops_inputs(case_name)), + AltHorizontalTailMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -129,7 +128,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "horizontal_tail", - AltHorizontalTailMass(aviary_options=get_flops_inputs("N3CC")), + AltHorizontalTailMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_hydraulics.py b/aviary/subsystems/mass/flops_based/test/test_hydraulics.py index 2ce70522d..f17d1f252 100644 --- a/aviary/subsystems/mass/flops_based/test/test_hydraulics.py +++ b/aviary/subsystems/mass/flops_based/test/test_hydraulics.py @@ -29,10 +29,17 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Mission.Constraints.MAX_MACH: inputs.get_val(Mission.Constraints.MAX_MACH), + } + prob.model.add_subsystem( 'hydraulics', - TransportHydraulicsGroupMass( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + TransportHydraulicsGroupMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -70,10 +77,18 @@ def tearDown(self): def test_case(self): prob = om.Problem() + + inputs = get_flops_inputs("N3CC", preprocess=True) + + options = { + Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Mission.Constraints.MAX_MACH: inputs.get_val(Mission.Constraints.MAX_MACH), + } + prob.model.add_subsystem( 'hydraulics', - TransportHydraulicsGroupMass( - aviary_options=get_flops_inputs("N3CC", preprocess=True)), + TransportHydraulicsGroupMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -102,8 +117,7 @@ def test_case(self, case_name): prob.model.add_subsystem( 'hydraulics', - AltHydraulicsGroupMass( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + AltHydraulicsGroupMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -142,8 +156,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( 'hydraulics', - AltHydraulicsGroupMass( - aviary_options=get_flops_inputs("N3CC", preprocess=True)), + AltHydraulicsGroupMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) diff --git a/aviary/subsystems/mass/flops_based/test/test_instruments.py b/aviary/subsystems/mass/flops_based/test/test_instruments.py index b8b5fabca..5a0521b5e 100644 --- a/aviary/subsystems/mass/flops_based/test/test_instruments.py +++ b/aviary/subsystems/mass/flops_based/test/test_instruments.py @@ -24,10 +24,18 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.CrewPayload.NUM_FLIGHT_CREW: inputs.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW), + Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Mission.Constraints.MAX_MACH: inputs.get_val(Mission.Constraints.MAX_MACH), + } + prob.model.add_subsystem( "instruments_tests", - TransportInstrumentMass( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + TransportInstrumentMass(**options), promotes_outputs=[ Aircraft.Instruments.MASS, ], @@ -66,10 +74,19 @@ def tearDown(self): def test_case(self): prob = om.Problem() + + inputs = get_flops_inputs("N3CC", preprocess=True) + + options = { + Aircraft.CrewPayload.NUM_FLIGHT_CREW: inputs.get_val(Aircraft.CrewPayload.NUM_FLIGHT_CREW), + Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Mission.Constraints.MAX_MACH: inputs.get_val(Mission.Constraints.MAX_MACH), + } + prob.model.add_subsystem( "instruments_tests", - TransportInstrumentMass( - aviary_options=get_flops_inputs("N3CC", preprocess=True)), + TransportInstrumentMass(**options), promotes_outputs=[ Aircraft.Instruments.MASS, ], diff --git a/aviary/subsystems/mass/flops_based/test/test_landing_gear.py b/aviary/subsystems/mass/flops_based/test/test_landing_gear.py index 59a056984..6f67d9ffd 100644 --- a/aviary/subsystems/mass/flops_based/test/test_landing_gear.py +++ b/aviary/subsystems/mass/flops_based/test/test_landing_gear.py @@ -30,7 +30,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "landing_gear", - LandingGearMass(aviary_options=get_flops_inputs(case_name)), + LandingGearMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -68,7 +68,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "landing_gear", - LandingGearMass(aviary_options=get_flops_inputs("N3CC")), + LandingGearMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -94,7 +94,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "landing_gear_alt", - AltLandingGearMass(aviary_options=get_flops_inputs(case_name)), + AltLandingGearMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -132,7 +132,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "landing_gear_alt", - AltLandingGearMass(aviary_options=get_flops_inputs("N3CC")), + AltLandingGearMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -158,14 +158,18 @@ def setUp(self): def test_derivs(self, case_name): prob = self.prob model = prob.model - flops_inputs = get_flops_inputs(case_name) - engine = build_engine_deck(flops_inputs) - preprocess_options(flops_inputs, engine_models=engine) + + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Engine.NUM_WING_ENGINES: inputs.get_val(Aircraft.Engine.NUM_WING_ENGINES), + } model.add_subsystem( - 'main', MainGearLength(aviary_options=flops_inputs), promotes=['*']) + 'main', MainGearLength(**options), promotes=['*']) model.add_subsystem( - 'nose', NoseGearLength(aviary_options=flops_inputs), promotes=['*']) + 'nose', NoseGearLength(), promotes=['*']) prob.setup(force_alloc_complex=True) diff --git a/aviary/subsystems/mass/flops_based/test/test_landing_mass.py b/aviary/subsystems/mass/flops_based/test/test_landing_mass.py index 0493c022a..60764ce66 100644 --- a/aviary/subsystems/mass/flops_based/test/test_landing_mass.py +++ b/aviary/subsystems/mass/flops_based/test/test_landing_mass.py @@ -7,7 +7,6 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, print_case) from aviary.variable_info.variables import Aircraft, Mission @@ -24,7 +23,7 @@ def test_case(self, case_name): prob = self.prob prob.model.add_subsystem( "landing_mass", - LandingMass(aviary_options=get_flops_inputs(case_name)), + LandingMass(), promotes=['*'] ) diff --git a/aviary/subsystems/mass/flops_based/test/test_mass_summation.py b/aviary/subsystems/mass/flops_based/test/test_mass_summation.py index dbb14b121..4d85dfa7e 100644 --- a/aviary/subsystems/mass/flops_based/test/test_mass_summation.py +++ b/aviary/subsystems/mass/flops_based/test/test_mass_summation.py @@ -30,7 +30,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "tot", - MassSummation(aviary_options=get_flops_inputs(case_name, preprocess=True)), + MassSummation(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -99,9 +99,15 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Design.USE_ALT_MASS: inputs.get_val(Aircraft.Design.USE_ALT_MASS), + } + prob.model.add_subsystem( "tot", - MassSummation(aviary_options=get_flops_inputs(case_name, preprocess=True)), + MassSummation(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -180,8 +186,12 @@ def test_case_multiengine(self): preprocess_propulsion(options, [engineModel1, engineModel2, engineModel3]) - prob.model.add_subsystem('structure_mass', StructureMass( - aviary_options=options), promotes=['*']) + comp_options = { + Aircraft.Engine.NUM_ENGINES: options.get_val(Aircraft.Engine.NUM_ENGINES), + } + + prob.model.add_subsystem('structure_mass', StructureMass(**comp_options), + promotes=['*']) prob.setup(force_alloc_complex=True) prob.set_val(Aircraft.Canard.MASS, val=10.0, units='lbm') diff --git a/aviary/subsystems/mass/flops_based/test/test_misc_engine.py b/aviary/subsystems/mass/flops_based/test/test_misc_engine.py index dc90b0b99..65f582752 100644 --- a/aviary/subsystems/mass/flops_based/test/test_misc_engine.py +++ b/aviary/subsystems/mass/flops_based/test/test_misc_engine.py @@ -28,9 +28,15 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + } + prob.model.add_subsystem( "misc_mass", - EngineMiscMass(aviary_options=get_flops_inputs(case_name, preprocess=True)), + EngineMiscMass(**options), promotes_inputs=['*'], promotes_outputs=['*'] ) @@ -65,9 +71,15 @@ def test_case_multiengine(self): preprocess_propulsion(options, [engineModel1, engineModel2, engineModel3]) - prob.model.add_subsystem('misc_engine_mass', EngineMiscMass( - aviary_options=options), promotes=['*']) + comp_options = { + Aircraft.Engine.NUM_ENGINES: options.get_val(Aircraft.Engine.NUM_ENGINES), + } + + prob.model.add_subsystem('misc_engine_mass', EngineMiscMass(**comp_options), + promotes=['*']) + prob.setup(force_alloc_complex=True) + prob.set_val(Aircraft.Engine.ADDITIONAL_MASS, np.array([100, 26, 30]), units='lbm') prob.set_val(Aircraft.Propulsion.MISC_MASS_SCALER, 1.02, units='unitless') diff --git a/aviary/subsystems/mass/flops_based/test/test_nacelle.py b/aviary/subsystems/mass/flops_based/test/test_nacelle.py index 975abc97e..9534dfb84 100644 --- a/aviary/subsystems/mass/flops_based/test/test_nacelle.py +++ b/aviary/subsystems/mass/flops_based/test/test_nacelle.py @@ -28,9 +28,15 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + } + prob.model.add_subsystem( "nacelle", - NacelleMass(aviary_options=get_flops_inputs(case_name, preprocess=True)), + NacelleMass(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -66,9 +72,15 @@ def test_case_multiengine(self): preprocess_propulsion(options, [engineModel1, engineModel2, engineModel3]) - prob.model.add_subsystem('nacelle_mass', NacelleMass( - aviary_options=options), promotes=['*']) + comp_options = { + Aircraft.Engine.NUM_ENGINES: options.get_val(Aircraft.Engine.NUM_ENGINES), + } + + prob.model.add_subsystem('nacelle_mass', NacelleMass(**comp_options), + promotes=['*']) + prob.setup(force_alloc_complex=True) + prob.set_val(Aircraft.Nacelle.AVG_DIAMETER, np.array([5.0, 3.0, 8.0]), units='ft') prob.set_val(Aircraft.Nacelle.AVG_LENGTH, @@ -104,9 +116,16 @@ def tearDown(self): def test_case(self): prob = om.Problem() + + inputs = get_flops_inputs("N3CC", preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + } + prob.model.add_subsystem( "nacelle", - NacelleMass(aviary_options=get_flops_inputs("N3CC", preprocess=True)), + NacelleMass(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -130,10 +149,18 @@ def test_case_multiengine(self): options.set_val(Aircraft.Engine.NUM_ENGINES, 2) engineModel2 = EngineDeck(options=options) engineModel3 = EngineDeck(options=options) + preprocess_propulsion(options, [engineModel1, engineModel2, engineModel3]) - prob.model.add_subsystem('nacelle_mass', NacelleMass( - aviary_options=options), promotes=['*']) + + comp_options = { + Aircraft.Engine.NUM_ENGINES: options.get_val(Aircraft.Engine.NUM_ENGINES), + } + + prob.model.add_subsystem('nacelle_mass', NacelleMass(**comp_options), + promotes=['*']) + prob.setup(force_alloc_complex=True) + prob.set_val(Aircraft.Nacelle.AVG_DIAMETER, np.array([5.0, 3.0, 8.0]), units='ft') prob.set_val(Aircraft.Nacelle.AVG_LENGTH, diff --git a/aviary/subsystems/mass/flops_based/test/test_paint.py b/aviary/subsystems/mass/flops_based/test/test_paint.py index bb434b136..046c4e33e 100644 --- a/aviary/subsystems/mass/flops_based/test/test_paint.py +++ b/aviary/subsystems/mass/flops_based/test/test_paint.py @@ -7,7 +7,6 @@ from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, - get_flops_inputs, print_case) from aviary.variable_info.variables import Aircraft @@ -24,7 +23,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "paint", - PaintMass(aviary_options=get_flops_inputs(case_name)), + PaintMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_passenger_service.py b/aviary/subsystems/mass/flops_based/test/test_passenger_service.py index 448eb8532..31cc6e115 100644 --- a/aviary/subsystems/mass/flops_based/test/test_passenger_service.py +++ b/aviary/subsystems/mass/flops_based/test/test_passenger_service.py @@ -10,7 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft, Mission @@ -28,11 +28,13 @@ def test_case(self, case_name): prob.model.add_subsystem( 'passenger_service_weight', - PassengerServiceMass(aviary_options=get_flops_inputs(case_name)), + PassengerServiceMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -65,10 +67,13 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( 'passenger_service_weight', - PassengerServiceMass(aviary_options=get_flops_inputs("N3CC")), + PassengerServiceMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Mission.Design.RANGE, 3500.0, 'nmi') @@ -89,11 +94,13 @@ def test_case(self, case_name): prob.model.add_subsystem( 'alternate_passenger_service_weight', - AltPassengerServiceMass(aviary_options=get_flops_inputs(case_name)), + AltPassengerServiceMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -124,10 +131,13 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( 'alternate_passenger_service_weight', - AltPassengerServiceMass(aviary_options=get_flops_inputs("N3CC")), + AltPassengerServiceMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) partial_data = prob.check_partials(out_stream=None, method="cs") diff --git a/aviary/subsystems/mass/flops_based/test/test_starter.py b/aviary/subsystems/mass/flops_based/test/test_starter.py index 426afa6bb..a8577c19d 100644 --- a/aviary/subsystems/mass/flops_based/test/test_starter.py +++ b/aviary/subsystems/mass/flops_based/test/test_starter.py @@ -25,10 +25,17 @@ def test_case_1(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES), + Mission.Constraints.MAX_MACH: inputs.get_val(Mission.Constraints.MAX_MACH), + } + prob.model.add_subsystem( "starter_test", - TransportStarterMass(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + TransportStarterMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -45,14 +52,15 @@ def test_case_2(self): # test with more than 4 engines prob = self.prob - aviary_options = get_flops_inputs('LargeSingleAisle1FLOPS') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([5])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 5) - aviary_options.set_val(Mission.Constraints.MAX_MACH, 0.785) + options = { + Aircraft.Engine.NUM_ENGINES: np.array([5]), + Aircraft.Propulsion.TOTAL_NUM_ENGINES: 5, + Mission.Constraints.MAX_MACH: 0.785, + } prob.model.add_subsystem( "starter_test", - TransportStarterMass(aviary_options=aviary_options), + TransportStarterMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -90,13 +98,16 @@ def tearDown(self): def test_case_2(self): prob = om.Problem() - aviary_options = get_flops_inputs('LargeSingleAisle1FLOPS') - aviary_options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([5])) - aviary_options.set_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES, 5) - aviary_options.set_val(Mission.Constraints.MAX_MACH, 0.785) + + options = { + Aircraft.Engine.NUM_ENGINES: np.array([5]), + Aircraft.Propulsion.TOTAL_NUM_ENGINES: 5, + Mission.Constraints.MAX_MACH: 0.785, + } + prob.model.add_subsystem( "starter_test", - TransportStarterMass(aviary_options=aviary_options), + TransportStarterMass(**options), promotes_outputs=['*'], promotes_inputs=['*'] ) diff --git a/aviary/subsystems/mass/flops_based/test/test_surface_controls.py b/aviary/subsystems/mass/flops_based/test/test_surface_controls.py index 0e96f7dc3..961f46502 100644 --- a/aviary/subsystems/mass/flops_based/test/test_surface_controls.py +++ b/aviary/subsystems/mass/flops_based/test/test_surface_controls.py @@ -10,7 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft, Mission @@ -28,10 +28,12 @@ def test_case(self, case_name): prob.model.add_subsystem( "surf_ctrl", - SurfaceControlMass(aviary_options=get_flops_inputs(case_name)), + SurfaceControlMass(), promotes=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -69,9 +71,12 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "surf_ctrl", - SurfaceControlMass(aviary_options=get_flops_inputs("N3CC")), + SurfaceControlMass(), promotes=['*'] ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Mission.Design.GROSS_MASS, 130000, 'lbm') prob.set_val(Aircraft.Wing.CONTROL_SURFACE_AREA_RATIO, 1, 'unitless') @@ -93,10 +98,12 @@ def test_case(self, case_name): prob.model.add_subsystem( "surf_ctrl", - AltSurfaceControlMass(aviary_options=get_flops_inputs(case_name)), + AltSurfaceControlMass(), promotes=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -133,9 +140,12 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "surf_ctrl", - AltSurfaceControlMass(aviary_options=get_flops_inputs("N3CC")), + AltSurfaceControlMass(), promotes=['*'] ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.Wing.AREA, 1000, 'ft**2') prob.set_val(Aircraft.HorizontalTail.WETTED_AREA, 100, 'ft**2') diff --git a/aviary/subsystems/mass/flops_based/test/test_thrust_reverser.py b/aviary/subsystems/mass/flops_based/test/test_thrust_reverser.py index d510427a6..965d4a5ee 100644 --- a/aviary/subsystems/mass/flops_based/test/test_thrust_reverser.py +++ b/aviary/subsystems/mass/flops_based/test/test_thrust_reverser.py @@ -28,10 +28,15 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + } + prob.model.add_subsystem( "thrust_rev", - ThrustReverserMass(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + ThrustReverserMass(**options), promotes=['*'] ) @@ -66,8 +71,12 @@ def test_case_multiengine(self): aviary_options, [engineModel1, engineModel2, engineModel3], verbosity=0 ) - prob.model.add_subsystem('thrust_reverser_mass', ThrustReverserMass( - aviary_options=aviary_options), promotes=['*']) + options = { + Aircraft.Engine.NUM_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_ENGINES), + } + + prob.model.add_subsystem('thrust_reverser_mass', ThrustReverserMass(**options), + promotes=['*']) prob.setup(force_alloc_complex=True) @@ -113,10 +122,16 @@ def tearDown(self): def test_case(self): prob = om.Problem() + + inputs = get_flops_inputs("N3CC", preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + } + prob.model.add_subsystem( "thrust_rev", - ThrustReverserMass(aviary_options=get_flops_inputs( - "N3CC", preprocess=True)), + ThrustReverserMass(**options), promotes=['*'] ) prob.setup(check=False, force_alloc_complex=True) 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 f479b7488..85f79aaf2 100644 --- a/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py +++ b/aviary/subsystems/mass/flops_based/test/test_unusable_fuel.py @@ -10,7 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft @@ -28,15 +28,16 @@ def setUp(self): def test_case(self, case_name): prob = self.prob - flops_inputs = get_flops_inputs(case_name, preprocess=True) prob.model.add_subsystem( 'unusable_fuel', - TransportUnusableFuelMass(aviary_options=flops_inputs), + TransportUnusableFuelMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -72,13 +73,16 @@ def tearDown(self): def test_case(self): prob = om.Problem() - flops_inputs = get_flops_inputs("N3CC", preprocess=True) + prob.model.add_subsystem( 'unusable_fuel', - TransportUnusableFuelMass(aviary_options=flops_inputs), + TransportUnusableFuelMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.Fuel.TOTAL_CAPACITY, 30000.0, 'lbm') prob.set_val(Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, 40000.0, 'lbf') @@ -104,7 +108,7 @@ def test_case(self, case_name): prob.model.add_subsystem( 'unusable_fuel', - AltUnusableFuelMass(aviary_options=get_flops_inputs(case_name)), + AltUnusableFuelMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) @@ -141,7 +145,7 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( 'unusable_fuel', - AltUnusableFuelMass(aviary_options=get_flops_inputs("N3CC")), + AltUnusableFuelMass(), promotes_outputs=['*'], promotes_inputs=['*'] ) diff --git a/aviary/subsystems/mass/flops_based/test/test_vertical_tail.py b/aviary/subsystems/mass/flops_based/test/test_vertical_tail.py index fc9801613..9df1f1748 100644 --- a/aviary/subsystems/mass/flops_based/test/test_vertical_tail.py +++ b/aviary/subsystems/mass/flops_based/test/test_vertical_tail.py @@ -10,7 +10,7 @@ from aviary.validation_cases.validation_tests import (Version, flops_validation_test, get_flops_case_names, - get_flops_inputs, + get_flops_options, print_case) from aviary.variable_info.variables import Aircraft, Mission @@ -28,11 +28,13 @@ def test_case(self, case_name): prob.model.add_subsystem( "vertical_tail", - VerticalTailMass(aviary_options=get_flops_inputs(case_name)), + VerticalTailMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + prob.model_options['*'] = get_flops_options(case_name, preprocess=True) + prob.setup(check=False, force_alloc_complex=True) flops_validation_test( @@ -66,10 +68,13 @@ def test_case(self): prob = om.Problem() prob.model.add_subsystem( "vertical_tail", - VerticalTailMass(aviary_options=get_flops_inputs("N3CC")), + VerticalTailMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) + + prob.model_options['*'] = get_flops_options("N3CC", preprocess=True) + prob.setup(check=False, force_alloc_complex=True) prob.set_val(Aircraft.VerticalTail.AREA, 100, 'ft**2') prob.set_val(Mission.Design.GROSS_MASS, 1000.0, 'lbm') @@ -91,7 +96,7 @@ def test_case(self, case_name): prob.model.add_subsystem( "vertical_tail", - AltVerticalTailMass(aviary_options=get_flops_inputs(case_name)), + AltVerticalTailMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_wing_common.py b/aviary/subsystems/mass/flops_based/test/test_wing_common.py index cfa95cb4a..5652de62c 100644 --- a/aviary/subsystems/mass/flops_based/test/test_wing_common.py +++ b/aviary/subsystems/mass/flops_based/test/test_wing_common.py @@ -6,7 +6,6 @@ from aviary.subsystems.mass.flops_based.wing_common import ( WingBendingMass, WingMiscMass, WingShearControlMass) -from aviary.variable_info.options import get_option_defaults from aviary.utils.test_utils.variable_test import assert_match_varnames from aviary.validation_cases.validation_tests import (flops_validation_test, get_flops_case_names, @@ -141,9 +140,14 @@ def test_case(self): class WingBendingMassTest(unittest.TestCase): def setUp(self): prob = self.prob = om.Problem() + + opts = { + Aircraft.Fuselage.NUM_FUSELAGES: 1, + } + prob.model.add_subsystem( "wing", - WingBendingMass(aviary_options=get_option_defaults()), + WingBendingMass(**opts), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -201,9 +205,10 @@ def tearDown(self): def test_case(self): prob = om.Problem() + prob.model.add_subsystem( "wing", - WingBendingMass(aviary_options=get_option_defaults()), + WingBendingMass(), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_wing_detailed.py b/aviary/subsystems/mass/flops_based/test/test_wing_detailed.py index 1b10c1e39..d6ac75263 100644 --- a/aviary/subsystems/mass/flops_based/test/test_wing_detailed.py +++ b/aviary/subsystems/mass/flops_based/test/test_wing_detailed.py @@ -35,10 +35,20 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Engine.NUM_ENGINES: inputs.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Engine.NUM_WING_ENGINES: inputs.get_val(Aircraft.Engine.NUM_WING_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Aircraft.Wing.INPUT_STATION_DIST: inputs.get_val(Aircraft.Wing.INPUT_STATION_DIST), + Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL: inputs.get_val(Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL), + Aircraft.Wing.NUM_INTEGRATION_STATIONS: inputs.get_val(Aircraft.Wing.NUM_INTEGRATION_STATIONS), + } + self.prob.model.add_subsystem( "wing", - DetailedWingBendingFact( - aviary_options=get_flops_inputs(case_name, preprocess=True)), + DetailedWingBendingFact(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -89,8 +99,17 @@ def test_case_multiengine(self): preprocess_propulsion(aviary_options, [engineModel1, engineModel2, engineModel3]) - prob.model.add_subsystem('detailed_wing', DetailedWingBendingFact( - aviary_options=aviary_options), promotes=['*']) + options = { + Aircraft.Engine.NUM_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Engine.NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Aircraft.Wing.INPUT_STATION_DIST: aviary_options.get_val(Aircraft.Wing.INPUT_STATION_DIST), + Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL: aviary_options.get_val(Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL), + Aircraft.Wing.NUM_INTEGRATION_STATIONS: aviary_options.get_val(Aircraft.Wing.NUM_INTEGRATION_STATIONS), + } + + prob.model.add_subsystem('detailed_wing', DetailedWingBendingFact(**options), + promotes=['*']) prob.setup(force_alloc_complex=True) @@ -155,8 +174,20 @@ def test_case_fuselage_engines(self): preprocess_propulsion(aviary_options, [engineModel]) - prob.model.add_subsystem('detailed_wing', DetailedWingBendingFact( - aviary_options=aviary_options), promotes=['*']) + options = { + Aircraft.Engine.NUM_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Engine.NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Aircraft.Wing.INPUT_STATION_DIST: aviary_options.get_val(Aircraft.Wing.INPUT_STATION_DIST), + Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL: aviary_options.get_val(Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL), + Aircraft.Wing.NUM_INTEGRATION_STATIONS: aviary_options.get_val(Aircraft.Wing.NUM_INTEGRATION_STATIONS), + } + + prob.model.add_subsystem( + 'detailed_wing', + DetailedWingBendingFact(**options), + promotes=['*'], + ) prob.setup(force_alloc_complex=True) @@ -216,8 +247,20 @@ def test_case_fuselage_multiengine(self): preprocess_propulsion(aviary_options, [engineModel1, engineModel2]) - prob.model.add_subsystem('detailed_wing', DetailedWingBendingFact( - aviary_options=aviary_options), promotes=['*']) + options = { + Aircraft.Engine.NUM_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Engine.NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Aircraft.Wing.INPUT_STATION_DIST: aviary_options.get_val(Aircraft.Wing.INPUT_STATION_DIST), + Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL: aviary_options.get_val(Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL), + Aircraft.Wing.NUM_INTEGRATION_STATIONS: aviary_options.get_val(Aircraft.Wing.NUM_INTEGRATION_STATIONS), + } + + prob.model.add_subsystem( + 'detailed_wing', + DetailedWingBendingFact(**options), + promotes=['*'], + ) prob.setup(force_alloc_complex=True) @@ -272,9 +315,18 @@ def test_extreme_engine_loc(self): preprocess_propulsion(aviary_options, [engineModel]) + options = { + Aircraft.Engine.NUM_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_ENGINES), + Aircraft.Engine.NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES), + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + Aircraft.Wing.INPUT_STATION_DIST: aviary_options.get_val(Aircraft.Wing.INPUT_STATION_DIST), + Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL: aviary_options.get_val(Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL), + Aircraft.Wing.NUM_INTEGRATION_STATIONS: aviary_options.get_val(Aircraft.Wing.NUM_INTEGRATION_STATIONS), + } + self.prob.model.add_subsystem( "wing", - DetailedWingBendingFact(aviary_options=aviary_options), + DetailedWingBendingFact(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/test/test_wing_simple.py b/aviary/subsystems/mass/flops_based/test/test_wing_simple.py index 4485c5954..cdb3fed54 100644 --- a/aviary/subsystems/mass/flops_based/test/test_wing_simple.py +++ b/aviary/subsystems/mass/flops_based/test/test_wing_simple.py @@ -23,10 +23,15 @@ def test_case(self, case_name): prob = self.prob + inputs = get_flops_inputs(case_name, preprocess=True) + + options = { + Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES: inputs.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES), + } + prob.model.add_subsystem( "wing", - SimpleWingBendingFact(aviary_options=get_flops_inputs( - case_name, preprocess=True)), + SimpleWingBendingFact(**options), promotes_inputs=['*'], promotes_outputs=['*'], ) diff --git a/aviary/subsystems/mass/flops_based/thrust_reverser.py b/aviary/subsystems/mass/flops_based/thrust_reverser.py index 028c2969c..6821f182b 100644 --- a/aviary/subsystems/mass/flops_based/thrust_reverser.py +++ b/aviary/subsystems/mass/flops_based/thrust_reverser.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import nacelle_count_factor -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -23,13 +22,10 @@ class ThrustReverserMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input( self, Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, val=np.zeros(num_engine_type)) @@ -43,8 +39,7 @@ def setup(self): def setup_partials(self): # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) self.declare_partials(Aircraft.Engine.THRUST_REVERSERS_MASS, @@ -64,8 +59,7 @@ def setup_partials(self): val=1.0) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - num_eng = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] scaler = inputs[Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER] max_thrust = inputs[Aircraft.Engine.SCALED_SLS_THRUST] nac_count = nacelle_count_factor(num_eng) @@ -76,8 +70,7 @@ def compute(self, inputs, outputs): thrust_reverser_mass) def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_eng = aviary_options.get_val(Aircraft.Engine.NUM_ENGINES) + num_eng = self.options[Aircraft.Engine.NUM_ENGINES] scaler = inputs[Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER] max_thrust = inputs[Aircraft.Engine.SCALED_SLS_THRUST] nac_count = nacelle_count_factor(num_eng) diff --git a/aviary/subsystems/mass/flops_based/unusable_fuel.py b/aviary/subsystems/mass/flops_based/unusable_fuel.py index 6b994718a..8913549ee 100644 --- a/aviary/subsystems/mass/flops_based/unusable_fuel.py +++ b/aviary/subsystems/mass/flops_based/unusable_fuel.py @@ -3,8 +3,7 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.subsystems.mass.flops_based.distributed_prop import ( distributed_engine_count_factor, distributed_thrust_factor) -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -21,9 +20,8 @@ class TransportUnusableFuelMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Fuel.NUM_TANKS) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): add_aviary_input( @@ -55,12 +53,11 @@ def setup_partials(self): Aircraft.Fuel.TOTAL_CAPACITY, Aircraft.Fuel.DENSITY_RATIO]) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - aviary_options: AviaryValues = self.options['aviary_options'] - tank_count = aviary_options.get_val(Aircraft.Fuel.NUM_TANKS) + tank_count = self.options[Aircraft.Fuel.NUM_TANKS] scaler = inputs[Aircraft.Fuel.UNUSABLE_FUEL_MASS_SCALER] density_ratio = inputs[Aircraft.Fuel.DENSITY_RATIO] total_capacity = inputs[Aircraft.Fuel.TOTAL_CAPACITY] - num_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_eng_fact = distributed_engine_count_factor(num_eng) max_sls_thrust = inputs[Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST] thrust_factor = distributed_thrust_factor(max_sls_thrust, num_eng) @@ -74,12 +71,11 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): total_capacity**0.28) * density_ratio) * scaler / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - tank_count = aviary_options.get_val(Aircraft.Fuel.NUM_TANKS) + tank_count = self.options[Aircraft.Fuel.NUM_TANKS] scaler = inputs[Aircraft.Fuel.UNUSABLE_FUEL_MASS_SCALER] density_ratio = inputs[Aircraft.Fuel.DENSITY_RATIO] total_capacity = inputs[Aircraft.Fuel.TOTAL_CAPACITY] - num_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] num_eng_fact = distributed_engine_count_factor(num_eng) max_sls_thrust = inputs[Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST] thrust_factor = distributed_thrust_factor(max_sls_thrust, num_eng) @@ -120,11 +116,6 @@ class AltUnusableFuelMass(om.ExplicitComponent): to output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Fuel.UNUSABLE_FUEL_MASS_SCALER, val=1.0) diff --git a/aviary/subsystems/mass/flops_based/vertical_tail.py b/aviary/subsystems/mass/flops_based/vertical_tail.py index 68df78b73..0f95fb3da 100644 --- a/aviary/subsystems/mass/flops_based/vertical_tail.py +++ b/aviary/subsystems/mass/flops_based/vertical_tail.py @@ -1,8 +1,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -13,9 +12,7 @@ class VerticalTailMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.VerticalTail.NUM_TAILS) def setup(self): add_aviary_input(self, Aircraft.VerticalTail.AREA, val=0.0) @@ -32,8 +29,7 @@ def setup_partials(self): self.declare_partials("*", "*") def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - num_tails = aviary_options.get_val(Aircraft.VerticalTail.NUM_TAILS) + num_tails = self.options[Aircraft.VerticalTail.NUM_TAILS] area = inputs[Aircraft.VerticalTail.AREA] taper_ratio = inputs[Aircraft.VerticalTail.TAPER_RATIO] @@ -45,8 +41,7 @@ def compute(self, inputs, outputs): num_tails ** 0.7 / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_tails = aviary_options.get_val(Aircraft.VerticalTail.NUM_TAILS) + num_tails = self.options[Aircraft.VerticalTail.NUM_TAILS] area = inputs[Aircraft.VerticalTail.AREA] gross_weight = inputs[Mission.Design.GROSS_MASS] * GRAV_ENGLISH_LBM @@ -81,11 +76,6 @@ class AltVerticalTailMass(om.ExplicitComponent): output mass instead of weight. ''' - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.VerticalTail.AREA, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/wing_common.py b/aviary/subsystems/mass/flops_based/wing_common.py index f673e29f3..a932a4e49 100644 --- a/aviary/subsystems/mass/flops_based/wing_common.py +++ b/aviary/subsystems/mass/flops_based/wing_common.py @@ -2,8 +2,7 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -14,9 +13,7 @@ class WingBendingMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Fuselage.NUM_FUSELAGES) def setup(self): add_aviary_input(self, Mission.Design.GROSS_MASS, val=0.0) @@ -56,8 +53,7 @@ def compute(self, inputs, outputs): CAYE = inputs[Aircraft.Wing.ENG_POD_INERTIA_FACTOR] scaler = inputs[Aircraft.Wing.BENDING_MATERIAL_MASS_SCALER] - num_fuse = self.options['aviary_options'].get_val( - Aircraft.Fuselage.NUM_FUSELAGES) + num_fuse = self.options[Aircraft.Fuselage.NUM_FUSELAGES] # Note: Calculation requires weights prior to being scaled, so we need to divide # by the scale factor. @@ -95,8 +91,7 @@ def compute_partials(self, inputs, J): W3scale = inputs[Aircraft.Wing.MISC_MASS_SCALER] scaler = inputs[Aircraft.Wing.BENDING_MATERIAL_MASS_SCALER] - num_fuse = self.options['aviary_options'].get_val( - Aircraft.Fuselage.NUM_FUSELAGES) + num_fuse = self.options[Aircraft.Fuselage.NUM_FUSELAGES] deg2rad = np.pi / 180. term = 0.96 / np.cos(deg2rad * sweep) @@ -210,10 +205,6 @@ class WingShearControlMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - self.options.declare( 'aircraft_type', default='Transport', @@ -291,10 +282,6 @@ class WingMiscMass(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - self.options.declare( 'aircraft_type', default='Transport', @@ -351,11 +338,6 @@ class WingTotalMass(om.ExplicitComponent): Computation of wing mass using FLOPS-based detailed wing mass equations. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - def setup(self): add_aviary_input(self, Aircraft.Wing.BENDING_MATERIAL_MASS, val=0.0) diff --git a/aviary/subsystems/mass/flops_based/wing_detailed.py b/aviary/subsystems/mass/flops_based/wing_detailed.py index 7763e50b9..65d01b9f9 100644 --- a/aviary/subsystems/mass/flops_based/wing_detailed.py +++ b/aviary/subsystems/mass/flops_based/wing_detailed.py @@ -3,8 +3,7 @@ import openmdao.api as om from openmdao.components.interp_util.interp import InterpND -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -15,20 +14,18 @@ class DetailedWingBendingFact(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Engine.NUM_WING_ENGINES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) + add_aviary_option(self, Aircraft.Wing.INPUT_STATION_DIST) + add_aviary_option(self, Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL) + add_aviary_option(self, Aircraft.Wing.NUM_INTEGRATION_STATIONS) def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] - input_station_dist = aviary_options.get_val(Aircraft.Wing.INPUT_STATION_DIST) + input_station_dist = self.options[Aircraft.Wing.INPUT_STATION_DIST] num_input_stations = len(input_station_dist) - total_num_wing_engines = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES - ) - num_engine_type = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) + total_num_wing_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES] + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) # wing locations are different for each engine type - ragged array! # this "tricks" numpy into allowing a ragged array, with limitations (each index @@ -88,13 +85,10 @@ def setup_partials(self): self.declare_partials("*", "*", method='cs') def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - input_station_dist = aviary_options.get_val(Aircraft.Wing.INPUT_STATION_DIST) + input_station_dist = self.options[Aircraft.Wing.INPUT_STATION_DIST] inp_stations = np.array(input_station_dist) - num_integration_stations = aviary_options.get_val( - Aircraft.Wing.NUM_INTEGRATION_STATIONS - ) - num_wing_engines = aviary_options.get_val(Aircraft.Engine.NUM_WING_ENGINES) + num_integration_stations = self.options[Aircraft.Wing.NUM_INTEGRATION_STATIONS] + num_wing_engines = self.options[Aircraft.Engine.NUM_WING_ENGINES] num_engine_type = len(num_wing_engines) # TODO: Support all options for this parameter. @@ -104,9 +98,7 @@ def compute(self, inputs, outputs): # 3.0 : rectangular distribution # 1.0-2.0 : blend of triangular and elliptical # 2.0-3.0 : blend of elliptical and rectangular - load_distribution_factor = aviary_options.get_val( - Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL - ) + load_distribution_factor = self.options[Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL] load_path_sweep = inputs[Aircraft.Wing.LOAD_PATH_SWEEP_DIST] thickness_to_chord = inputs[Aircraft.Wing.THICKNESS_TO_CHORD_DIST] diff --git a/aviary/subsystems/mass/flops_based/wing_group.py b/aviary/subsystems/mass/flops_based/wing_group.py index 284934f8f..2cd4fad1d 100644 --- a/aviary/subsystems/mass/flops_based/wing_group.py +++ b/aviary/subsystems/mass/flops_based/wing_group.py @@ -6,7 +6,7 @@ WingBendingMass, WingMiscMass, WingShearControlMass, WingTotalMass) from aviary.subsystems.mass.flops_based.wing_detailed import DetailedWingBendingFact from aviary.subsystems.mass.flops_based.wing_simple import SimpleWingBendingFact -from aviary.utils.aviary_values import AviaryValues +from aviary.variable_info.functions import add_aviary_option from aviary.variable_info.variables import Aircraft @@ -16,21 +16,18 @@ class WingMassGroup(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Wing.INPUT_STATION_DIST) def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] self.add_subsystem('engine_pod_mass', - EnginePodMass(aviary_options=aviary_options), + EnginePodMass(), promotes_inputs=['*'], promotes_outputs=['*']) - if Aircraft.Wing.INPUT_STATION_DIST in aviary_options: + if self.options[Aircraft.Wing.INPUT_STATION_DIST] is not None: self.add_subsystem( 'wing_BENDING_MATERIAL_FACTOR', - DetailedWingBendingFact(aviary_options=aviary_options), + DetailedWingBendingFact(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -38,23 +35,23 @@ def setup(self): else: self.add_subsystem( 'wing_BENDING_MATERIAL_FACTOR', - SimpleWingBendingFact(aviary_options=aviary_options), + SimpleWingBendingFact(), promotes_inputs=['*'], promotes_outputs=['*'], ) self.add_subsystem('wing_misc', - WingMiscMass(aviary_options=aviary_options), + WingMiscMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem('wing_shear_control', - WingShearControlMass(aviary_options=aviary_options), + WingShearControlMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem('wing_bending', - WingBendingMass(aviary_options=aviary_options), + WingBendingMass(), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem('wing_total', - WingTotalMass(aviary_options=aviary_options), + WingTotalMass(), promotes_inputs=['*'], promotes_outputs=['*']) diff --git a/aviary/subsystems/mass/flops_based/wing_simple.py b/aviary/subsystems/mass/flops_based/wing_simple.py index d41f5d321..04808ebdb 100644 --- a/aviary/subsystems/mass/flops_based/wing_simple.py +++ b/aviary/subsystems/mass/flops_based/wing_simple.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -13,9 +12,7 @@ class SimpleWingBendingFact(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) def setup(self): add_aviary_input(self, Aircraft.Wing.AREA, val=0.0) @@ -54,8 +51,7 @@ def setup_partials(self): ) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - num_wing_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) + num_wing_eng = self.options[Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES] fstrt = inputs[Aircraft.Wing.STRUT_BRACING_FACTOR] span = inputs[Aircraft.Wing.SPAN] tr = inputs[Aircraft.Wing.TAPER_RATIO] @@ -88,8 +84,6 @@ def compute(self, inputs, outputs): outputs[Aircraft.Wing.ENG_POD_INERTIA_FACTOR] = 1.0 - 0.03 * num_wing_eng def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_wing_eng = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES) fstrt = inputs[Aircraft.Wing.STRUT_BRACING_FACTOR] span = inputs[Aircraft.Wing.SPAN] tr = inputs[Aircraft.Wing.TAPER_RATIO] diff --git a/aviary/subsystems/mass/gasp_based/design_load.py b/aviary/subsystems/mass/gasp_based/design_load.py index fabde2be2..dac622bc0 100644 --- a/aviary/subsystems/mass/gasp_based/design_load.py +++ b/aviary/subsystems/mass/gasp_based/design_load.py @@ -2,8 +2,7 @@ import openmdao.api as om from aviary.constants import RHO_SEA_LEVEL_ENGLISH -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -27,17 +26,16 @@ class LoadSpeeds(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Design.PART25_STRUCTURAL_CATEGORY) + add_aviary_option(self, Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES) + add_aviary_option(self, Aircraft.Wing.LOADING_ABOVE_20) def setup(self): add_aviary_input(self, Aircraft.Design.MAX_STRUCTURAL_SPEED, val=200, units="mi/h") - if self.options["aviary_options"].get_val(Aircraft.Design.PART25_STRUCTURAL_CATEGORY, units='unitless') < 3: + if self.options[Aircraft.Design.PART25_STRUCTURAL_CATEGORY] < 3: add_aviary_input(self, Aircraft.Wing.LOADING, val=128) @@ -68,12 +66,9 @@ def compute(self, inputs, outputs): max_struct_speed_mph = inputs[Aircraft.Design.MAX_STRUCTURAL_SPEED] - CATD = self.options["aviary_options"].get_val( - Aircraft.Design.PART25_STRUCTURAL_CATEGORY, units='unitless') - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') - WGS_greater_than_20_flag = self.options["aviary_options"].get_val( - Aircraft.Wing.LOADING_ABOVE_20, units='unitless') + CATD = self.options[Aircraft.Design.PART25_STRUCTURAL_CATEGORY] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] + WGS_greater_than_20_flag = self.options[Aircraft.Wing.LOADING_ABOVE_20] max_struct_speed_kts = max_struct_speed_mph / 1.15 @@ -156,12 +151,9 @@ def compute_partials(self, inputs, partials): max_struct_speed_mph = inputs[Aircraft.Design.MAX_STRUCTURAL_SPEED] - CATD = self.options["aviary_options"].get_val( - Aircraft.Design.PART25_STRUCTURAL_CATEGORY, units='unitless') - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') - WGS_greater_than_20_flag = self.options["aviary_options"].get_val( - Aircraft.Wing.LOADING_ABOVE_20, units='unitless') + CATD = self.options[Aircraft.Design.PART25_STRUCTURAL_CATEGORY] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] + WGS_greater_than_20_flag = self.options[Aircraft.Wing.LOADING_ABOVE_20] max_struct_speed_kts = max_struct_speed_mph / 1.15 dmax_struct_speed_kts_dmax_struct_speed_mph = 1 / 1.15 @@ -382,10 +374,9 @@ class LoadParameters(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Design.PART25_STRUCTURAL_CATEGORY) + add_aviary_option(self, Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES) + add_aviary_option(self, Mission.Design.CRUISE_ALTITUDE, units='ft') def setup(self): @@ -428,12 +419,9 @@ def compute(self, inputs, outputs): vel_c = inputs["vel_c"] max_airspeed = inputs["max_airspeed"] - cruise_alt = self.options["aviary_options"].get_val( - Mission.Design.CRUISE_ALTITUDE, units='ft') - CATD = self.options["aviary_options"].get_val( - Aircraft.Design.PART25_STRUCTURAL_CATEGORY, units='unitless') - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + cruise_alt, _ = self.options[Mission.Design.CRUISE_ALTITUDE] + CATD = self.options[Aircraft.Design.PART25_STRUCTURAL_CATEGORY] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] if cruise_alt <= 22500.0: max_mach = max_airspeed / 486.33 @@ -499,12 +487,9 @@ def compute_partials(self, inputs, partials): vel_c = inputs["vel_c"] max_airspeed = inputs["max_airspeed"] - cruise_alt = self.options["aviary_options"].get_val( - Mission.Design.CRUISE_ALTITUDE, units='ft') - CATD = self.options["aviary_options"].get_val( - Aircraft.Design.PART25_STRUCTURAL_CATEGORY, units='unitless') - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + cruise_alt, _ = self.options[Mission.Design.CRUISE_ALTITUDE] + CATD = self.options[Aircraft.Design.PART25_STRUCTURAL_CATEGORY] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] if cruise_alt <= 22500.0: max_mach = max_airspeed / 486.33 @@ -695,10 +680,8 @@ class LoadFactors(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES) + add_aviary_option(self, Aircraft.Design.ULF_CALCULATED_FROM_MANEUVER) def setup(self): @@ -741,10 +724,8 @@ def compute(self, inputs, outputs): avg_chord = inputs[Aircraft.Wing.AVERAGE_CHORD] Cl_alpha = inputs[Aircraft.Design.LIFT_CURVE_SLOPE] - ULF_from_maneuver = self.options["aviary_options"].get_val( - Aircraft.Design.ULF_CALCULATED_FROM_MANEUVER, units='unitless') - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + ULF_from_maneuver = self.options[Aircraft.Design.ULF_CALCULATED_FROM_MANEUVER] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] mass_ratio = ( 2.0 * wing_loading / @@ -803,10 +784,8 @@ def compute_partials(self, inputs, partials): avg_chord = inputs[Aircraft.Wing.AVERAGE_CHORD] Cl_alpha = inputs[Aircraft.Design.LIFT_CURVE_SLOPE] - ULF_from_maneuver = self.options["aviary_options"].get_val( - Aircraft.Design.ULF_CALCULATED_FROM_MANEUVER, units='unitless') - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + ULF_from_maneuver = self.options[Aircraft.Design.ULF_CALCULATED_FROM_MANEUVER] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] mass_ratio = ( 2.0 * wing_loading / @@ -1251,22 +1230,11 @@ class DesignLoadGroup(om.Group): Design load group for GASP-based mass. """ - def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): - aviary_options = self.options['aviary_options'] - self.add_subsystem( "speeds", - LoadSpeeds( - aviary_options=aviary_options, - ), + LoadSpeeds(), promotes_inputs=['aircraft:*'], promotes_outputs=[ "max_airspeed", @@ -1278,10 +1246,11 @@ def setup(self): self.add_subsystem( "params", - LoadParameters( - aviary_options=aviary_options, - ), - promotes_inputs=["max_airspeed", "vel_c"], + LoadParameters(), + promotes_inputs=[ + "max_airspeed", + "vel_c", + ], promotes_outputs=["density_ratio", "V9", "max_mach"], ) @@ -1294,9 +1263,7 @@ def setup(self): self.add_subsystem( "factors", - LoadFactors( - aviary_options=aviary_options, - ), + LoadFactors(), promotes_inputs=[ "max_maneuver_factor", "min_dive_vel", diff --git a/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py b/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py index c229c11a4..443e523ab 100644 --- a/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py +++ b/aviary/subsystems/mass/gasp_based/equipment_and_useful_load.py @@ -2,9 +2,8 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import GASPEngineType -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -22,15 +21,15 @@ class EquipAndUsefulLoadMass(om.ExplicitComponent): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.CrewPayload.Design.NUM_PASSENGERS) + add_aviary_option(self, Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Engine.TYPE) + add_aviary_option(self, Aircraft.LandingGear.FIXED_GEAR) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input( self, Aircraft.AirConditioning.MASS_COEFFICIENT, val=1, units="unitless") @@ -80,21 +79,13 @@ def setup(self): def compute(self, inputs, outputs): - options: AviaryValues = self.options["aviary_options"] - PAX = options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') - smooth = options.get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + PAX = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] gross_wt_initial = inputs[Mission.Design.GROSS_MASS] * GRAV_ENGLISH_LBM - num_engines = self.options['aviary_options'].get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] fus_len = inputs[Aircraft.Fuselage.LENGTH] wingspan = inputs[Aircraft.Wing.SPAN] - if options.get_val(Aircraft.LandingGear.FIXED_GEAR, units='unitless'): - gear_type = 1 - else: - gear_type = 0 landing_gear_wt = inputs[Aircraft.LandingGear.TOTAL_MASS] * \ GRAV_ENGLISH_LBM @@ -108,7 +99,7 @@ def compute(self, inputs, outputs): fuel_vol_frac = inputs[Aircraft.Fuel.WING_FUEL_FRACTION] subsystems_wt = inputs[Aircraft.Design.EXTERNAL_SUBSYSTEMS_MASS] - engine_type = options.get_val(Aircraft.Engine.TYPE, units='unitless')[0] + engine_type = self.options[Aircraft.Engine.TYPE][0] APU_wt = 0.0 if PAX > 35.0: @@ -134,11 +125,10 @@ def compute(self, inputs, outputs): * fus_len**0.05 * wingspan**0.696 ) - gear_val = 1 - gear_type hydraulic_wt = ( inputs[Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT] * control_wt + inputs[Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT] * - landing_gear_wt * gear_val + landing_gear_wt * (not self.options[Aircraft.LandingGear.FIXED_GEAR]) ) electrical_wt = 16.0 * PAX + 170.0 @@ -392,20 +382,14 @@ def compute(self, inputs, outputs): GRAV_ENGLISH_LBM def compute_partials(self, inputs, partials): - options = self.options['aviary_options'] - PAX = options.get_val( - Aircraft.CrewPayload.Design.NUM_PASSENGERS, units='unitless') - smooth = options.get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + PAX = self.options[Aircraft.CrewPayload.Design.NUM_PASSENGERS] + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] + gross_wt_initial = inputs[Mission.Design.GROSS_MASS] * GRAV_ENGLISH_LBM - num_engines = self.options['aviary_options'].get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] fus_len = inputs[Aircraft.Fuselage.LENGTH] wingspan = inputs[Aircraft.Wing.SPAN] - if options.get_val(Aircraft.LandingGear.FIXED_GEAR, units='unitless'): - gear_type = 1 - else: - gear_type = 0 + landing_gear_wt = inputs[Aircraft.LandingGear.TOTAL_MASS] * \ GRAV_ENGLISH_LBM control_wt = inputs[Aircraft.Controls.TOTAL_MASS] * GRAV_ENGLISH_LBM @@ -416,7 +400,7 @@ def compute_partials(self, inputs, partials): cabin_width = inputs[Aircraft.Fuselage.AVG_DIAMETER] fuel_vol_frac = inputs[Aircraft.Fuel.WING_FUEL_FRACTION] - engine_type = options.get_val(Aircraft.Engine.TYPE, units='unitless')[0] + engine_type = self.options[Aircraft.Engine.TYPE][0] dAPU_wt_dmass_coeff_0 = 0.0 if ~( @@ -467,7 +451,7 @@ def compute_partials(self, inputs, partials): * wingspan ** (0.696 - 1) ) - gear_val = 1 - gear_type + gear_val = not self.options[Aircraft.LandingGear.FIXED_GEAR] dhydraulic_wt_dmass_coeff_2 = control_wt dhydraulic_wt_dcontrol_wt = inputs[Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT] diff --git a/aviary/subsystems/mass/gasp_based/fixed.py b/aviary/subsystems/mass/gasp_based/fixed.py index 75b85f2d7..8bf15c09d 100644 --- a/aviary/subsystems/mass/gasp_based/fixed.py +++ b/aviary/subsystems/mass/gasp_based/fixed.py @@ -3,9 +3,8 @@ from openmdao.components.ks_comp import KSfunction from aviary.constants import GRAV_ENGLISH_LBM, RHO_SEA_LEVEL_ENGLISH -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import FlapType -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission @@ -30,14 +29,13 @@ class MassParameters(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Engine.NUM_FUSELAGE_ENGINES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) + add_aviary_option(self, Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Wing.SWEEP, val=0.436, units='rad') add_aviary_input(self, Aircraft.Wing.TAPER_RATIO, val=0.33) @@ -102,14 +100,12 @@ def setup(self): "c_gear_loc", Aircraft.LandingGear.MAIN_GEAR_LOCATION) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] sweep_c4 = inputs[Aircraft.Wing.SWEEP] taper_ratio = inputs[Aircraft.Wing.TAPER_RATIO] AR = inputs[Aircraft.Wing.ASPECT_RATIO] wingspan = inputs[Aircraft.Wing.SPAN] - num_engines = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] max_mach = inputs["max_mach"] strut_x = inputs[Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS] gear_location = inputs[Aircraft.LandingGear.MAIN_GEAR_LOCATION] @@ -124,15 +120,12 @@ def compute(self, inputs, outputs): c_material = 1.0 + 2.5 / (struct_span**0.5) c_strut_braced = 1.0 - strut_x**2 - not_fuselage_mounted = self.options["aviary_options"].get_val( - Aircraft.Engine.NUM_FUSELAGE_ENGINES) == 0 + not_fuselage_mounted = self.options[Aircraft.Engine.NUM_FUSELAGE_ENGINES] == 0 # note: c_gear_loc doesn't actually depend on any of the inputs... perhaps use a # set_input_defaults call to declare this at a higher level c_gear_loc = 1.0 - if aviary_options.get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless' - ): + if self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES]: # smooth transition for c_gear_loc from 0.95 to 1 when gear_location varies # between 0 and 1% of span c_gear_loc = .95 * sigX((0.005 - gear_location)*100) + \ @@ -158,14 +151,12 @@ def compute(self, inputs, outputs): outputs["half_sweep"] = half_sweep def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] sweep_c4 = inputs[Aircraft.Wing.SWEEP] taper_ratio = inputs[Aircraft.Wing.TAPER_RATIO] AR = inputs[Aircraft.Wing.ASPECT_RATIO] wingspan = inputs[Aircraft.Wing.SPAN] - num_engines = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] max_mach = inputs["max_mach"] strut_x = inputs[Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS] gear_location = inputs[Aircraft.LandingGear.MAIN_GEAR_LOCATION] @@ -179,8 +170,7 @@ def compute_partials(self, inputs, J): struct_span = wingspan / cos_half_sweep c_material = 1.0 + 2.5 / (struct_span**0.5) - not_fuselage_mounted = self.options["aviary_options"].get_val( - Aircraft.Engine.NUM_FUSELAGE_ENGINES) == 0 + not_fuselage_mounted = self.options[Aircraft.Engine.NUM_FUSELAGE_ENGINES] == 0 dTanHS_dSC4 = (1 / np.cos(sweep_c4) ** 2) dTanHS_TR = ( @@ -250,9 +240,7 @@ def compute_partials(self, inputs, J): J["c_strut_braced", Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS] = \ -2 * strut_x - if aviary_options.get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless' - ): + if self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES]: J["c_gear_loc", Aircraft.LandingGear.MAIN_GEAR_LOCATION] = ( .95 * (-100) * dSigXdX((0.005 - gear_location)*100) + 1 * (100) * dSigXdX(100*(gear_location - 0.005))) @@ -264,10 +252,9 @@ class PayloadMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.CrewPayload.NUM_PASSENGERS) + add_aviary_option(self, Aircraft.CrewPayload.PASSENGER_MASS_WITH_BAGS, + units='lbm') def setup(self): add_aviary_input(self, Aircraft.CrewPayload.CARGO_MASS, val=10040) @@ -291,11 +278,8 @@ def setup(self): val=1.0) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options['aviary_options'] - pax_mass = aviary_options.get_val( - Aircraft.CrewPayload.PASSENGER_MASS_WITH_BAGS, units='lbm') - PAX = aviary_options.get_val( - Aircraft.CrewPayload.NUM_PASSENGERS, units='unitless') + pax_mass, _ = self.options[Aircraft.CrewPayload.PASSENGER_MASS_WITH_BAGS] + PAX = self.options[Aircraft.CrewPayload.NUM_PASSENGERS] cargo_mass = inputs[Aircraft.CrewPayload.CARGO_MASS] outputs[Aircraft.CrewPayload.PASSENGER_PAYLOAD_MASS] = \ @@ -310,10 +294,7 @@ class ElectricAugmentationMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): self.add_input( @@ -437,8 +418,7 @@ def compute(self, inputs, outputs): motor_spec_wt = inputs["motor_spec_mass"] / GRAV_ENGLISH_LBM inverter_spec_wt = inputs["inverter_spec_mass"] / GRAV_ENGLISH_LBM TMS_spec_wt = inputs["TMS_spec_mass"] * GRAV_ENGLISH_LBM - num_engines = self.options['aviary_options'].get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] motor_current = 1000.0 * motor_power / motor_voltage num_wires = motor_current / max_amp_per_wire @@ -479,8 +459,7 @@ def compute_partials(self, inputs, J): motor_spec_wt = inputs["motor_spec_mass"] / GRAV_ENGLISH_LBM inverter_spec_wt = inputs["inverter_spec_mass"] / GRAV_ENGLISH_LBM TMS_spec_wt = inputs["TMS_spec_mass"] * GRAV_ENGLISH_LBM - num_engines = self.options['aviary_options'].get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') + num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] motor_current = 1000.0 * motor_power / motor_voltage num_wires = motor_current / max_amp_per_wire @@ -594,20 +573,18 @@ def compute_partials(self, inputs, J): class EngineMass(om.ExplicitComponent): """ - Computation of total engine mass, nacelle mass, pylon mass, total engine POD mass, + Computation of total engine mass, nacelle mass, pylon mass, total engine POD mass, additional engine mass """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Electrical.HAS_HYBRID_SYSTEM) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Aircraft.Propulsion.TOTAL_NUM_ENGINES) def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] - num_engine_type = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) - total_num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) + total_num_engines = self.options[Aircraft.Propulsion.TOTAL_NUM_ENGINES] add_aviary_input(self, Aircraft.Engine.MASS_SPECIFIC, val=np.full(num_engine_type, 0.21366)) @@ -632,8 +609,7 @@ def setup(self): add_aviary_input(self, Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0.15) - has_hybrid_system = aviary_options.get_val( - Aircraft.Electrical.HAS_HYBRID_SYSTEM, units='unitless') + has_hybrid_system = self.options[Aircraft.Electrical.HAS_HYBRID_SYSTEM] if has_hybrid_system: self.add_input( @@ -685,8 +661,7 @@ def setup(self): self.declare_partials("wing_mounted_mass", "prop_mass") # derivatives w.r.t vectorized engine inputs have known sparsity pattern - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) shape = np.arange(num_engine_type) self.declare_partials( @@ -767,12 +742,10 @@ def setup(self): ) def compute(self, inputs, outputs): - aviary_options = self.options['aviary_options'] - num_engine_type = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] + num_engine_type = len(num_engines) eng_spec_wt = inputs[Aircraft.Engine.MASS_SPECIFIC] * GRAV_ENGLISH_LBM Fn_SLS = inputs[Aircraft.Engine.SCALED_SLS_THRUST] - num_engines = aviary_options.get_val( - Aircraft.Engine.NUM_ENGINES, units='unitless') spec_nacelle_wt = inputs[Aircraft.Nacelle.MASS_SPECIFIC] * GRAV_ENGLISH_LBM nacelle_area = inputs[Aircraft.Nacelle.SURFACE_AREA] @@ -802,15 +775,13 @@ def compute(self, inputs, outputs): outputs["eng_comb_mass"] = (sum( CK5 * dry_wt_eng * num_engines) + CK7 * eng_instl_wt_all) / GRAV_ENGLISH_LBM - if aviary_options.get_val( - Aircraft.Electrical.HAS_HYBRID_SYSTEM, units='unitless' - ): + if self.options[Aircraft.Electrical.HAS_HYBRID_SYSTEM]: aug_wt = inputs["aug_mass"] * GRAV_ENGLISH_LBM outputs["eng_comb_mass"] = (sum(CK5 * dry_wt_eng * num_engines) + CK7 * eng_instl_wt_all + aug_wt) / GRAV_ENGLISH_LBM # prop_wt = np.zeros(num_engine_type) - # prop_idx = np.where(aviary_options.get_val(Aircraft.Engine.HAS_PROPELLERS)) + # prop_idx = np.where(self.options[Aircraft.Engine.HAS_PROPELLERS)) # prop_wt[prop_idx] = inputs["prop_mass"] * GRAV_ENGLISH_LBM prop_wt = inputs["prop_mass"] * GRAV_ENGLISH_LBM outputs["prop_mass_all"] = sum(num_engines * prop_wt) / GRAV_ENGLISH_LBM @@ -828,15 +799,11 @@ def compute(self, inputs, outputs): ) + main_gear_wt * loc_main_gear / (loc_main_gear + 0.001)) / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options['aviary_options'] - num_engine_type = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) eng_spec_wt = inputs[Aircraft.Engine.MASS_SPECIFIC] * GRAV_ENGLISH_LBM Fn_SLS = inputs[Aircraft.Engine.SCALED_SLS_THRUST] - num_engines = self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES, units='unitless') - total_num_engines = self.options['aviary_options'].get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] spec_nacelle_wt = inputs[Aircraft.Nacelle.MASS_SPECIFIC] * GRAV_ENGLISH_LBM nacelle_area = inputs[Aircraft.Nacelle.SURFACE_AREA] @@ -918,7 +885,7 @@ def compute_partials(self, inputs, J): pod_wt = (nacelle_wt + pylon_wt) eng_instl_wt = c_instl * dry_wt_eng - # prop_idx = np.where(aviary_options.get_val(Aircraft.Engine.HAS_PROPELLERS)) + # prop_idx = np.where(self.options[Aircraft.Engine.HAS_PROPELLERS)) prop_wt = inputs["prop_mass"] * GRAV_ENGLISH_LBM # prop_wt_all = sum(num_engines * prop_wt) / GRAV_ENGLISH_LBM @@ -973,7 +940,7 @@ def compute_partials(self, inputs, J): J["wing_mounted_mass", "prop_mass"] = span_frac_factor_sum * num_engines - if self.options["aviary_options"].get_val(Aircraft.Electrical.HAS_HYBRID_SYSTEM, units='unitless'): + if self.options[Aircraft.Electrical.HAS_HYBRID_SYSTEM]: J["eng_comb_mass", "aug_mass"] = 1 @@ -982,12 +949,6 @@ class TailMass(om.ExplicitComponent): Computation of horizontal tail mass and vertical tail mass. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input(self, Aircraft.VerticalTail.TAPER_RATIO, val=0.801) add_aviary_input(self, Aircraft.VerticalTail.ASPECT_RATIO, val=1.67) @@ -1610,10 +1571,8 @@ class HighLiftMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.FLAP_TYPE) + add_aviary_option(self, Aircraft.Wing.NUM_FLAP_SEGMENTS) def setup(self): add_aviary_input(self, Aircraft.Wing.HIGH_LIFT_MASS_COEFFICIENT, val=2.66) @@ -1670,11 +1629,10 @@ def setup(self): Mission.Landing.LIFT_COEFFICIENT_MAX]) def compute(self, inputs, outputs): - aviary_options: AviaryValues = self.options["aviary_options"] - flap_type = aviary_options.get_val(Aircraft.Wing.FLAP_TYPE, units='unitless') + flap_type = self.options[Aircraft.Wing.FLAP_TYPE] c_mass_trend_high_lift = inputs[Aircraft.Wing.HIGH_LIFT_MASS_COEFFICIENT] wing_area = inputs[Aircraft.Wing.AREA] - num_flaps = aviary_options.get_val(Aircraft.Wing.NUM_FLAP_SEGMENTS) + num_flaps = self.options[Aircraft.Wing.NUM_FLAP_SEGMENTS] slat_chord_ratio = inputs[Aircraft.Wing.SLAT_CHORD_RATIO] flap_chord_ratio = inputs[Aircraft.Wing.FLAP_CHORD_RATIO] taper_ratio = inputs[Aircraft.Wing.TAPER_RATIO] @@ -1735,11 +1693,10 @@ def compute(self, inputs, outputs): WLED / GRAV_ENGLISH_LBM def compute_partials(self, inputs, J): - aviary_options: AviaryValues = self.options["aviary_options"] - flap_type = aviary_options.get_val(Aircraft.Wing.FLAP_TYPE, units='unitless') + flap_type = self.options[Aircraft.Wing.FLAP_TYPE] c_mass_trend_high_lift = inputs[Aircraft.Wing.HIGH_LIFT_MASS_COEFFICIENT] wing_area = inputs[Aircraft.Wing.AREA] - num_flaps = aviary_options.get_val(Aircraft.Wing.NUM_FLAP_SEGMENTS) + num_flaps = self.options[Aircraft.Wing.NUM_FLAP_SEGMENTS] slat_chord_ratio = inputs[Aircraft.Wing.SLAT_CHORD_RATIO] flap_chord_ratio = inputs[Aircraft.Wing.FLAP_CHORD_RATIO] taper_ratio = inputs[Aircraft.Wing.TAPER_RATIO] @@ -2085,12 +2042,6 @@ class ControlMass(om.ExplicitComponent): and mass of surface controls. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input( self, Aircraft.Wing.SURFACE_CONTROL_MASS_COEFFICIENT, val=0.95) @@ -2316,14 +2267,10 @@ class GearMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Aircraft.Wing.MOUNTING_TYPE, val=0) add_aviary_input(self, Aircraft.LandingGear.MASS_COEFFICIENT, val=0.04) @@ -2465,22 +2412,13 @@ class FixedMassGroup(om.Group): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Electrical.HAS_HYBRID_SYSTEM) def setup(self): - aviary_options: AviaryValues = self.options['aviary_options'] - - n_eng = aviary_options.get_val( - Aircraft.Propulsion.TOTAL_NUM_ENGINES, units='unitless') self.add_subsystem( "params", - MassParameters( - aviary_options=aviary_options, - ), + MassParameters(), promotes_inputs=["max_mach", ] + ["aircraft:*"], promotes_outputs=["c_strut_braced", "c_gear_loc", "half_sweep", ] + ["aircraft:*"], @@ -2488,54 +2426,51 @@ def setup(self): self.add_subsystem( "payload", - PayloadMass(aviary_options=aviary_options), + PayloadMass(), promotes_inputs=["aircraft:*"], promotes_outputs=["payload_mass_des", "payload_mass_max", ] + ["aircraft:*"], ) self.add_subsystem( "tail", - TailMass(aviary_options=aviary_options), + TailMass(), promotes_inputs=["min_dive_vel", ] + ["aircraft:*", "mission:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( "HL", - HighLiftMass(aviary_options=aviary_options), + HighLiftMass(), promotes_inputs=["density"] + ["aircraft:*", "mission:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( "controls", - ControlMass(aviary_options=aviary_options), + ControlMass(), promotes_inputs=["min_dive_vel", ] + ["aircraft:*", "mission:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( "gear", - GearMass(aviary_options=aviary_options), + GearMass(), promotes_inputs=["mission:*", "aircraft:*"], promotes_outputs=[Aircraft.LandingGear.MAIN_GEAR_MASS, ] + ["aircraft:*"], ) - has_hybrid_system = aviary_options.get_val( - Aircraft.Electrical.HAS_HYBRID_SYSTEM, units='unitless') + has_hybrid_system = self.options[Aircraft.Electrical.HAS_HYBRID_SYSTEM] if has_hybrid_system: self.add_subsystem( "augmentation", - ElectricAugmentationMass( - aviary_options=aviary_options, - ), + ElectricAugmentationMass(), promotes_inputs=["aircraft:*"], promotes_outputs=["aug_mass", ], ) self.add_subsystem( "engine", - EngineMass(aviary_options=aviary_options), + EngineMass(), promotes_inputs=["aircraft:*"] + [Aircraft.LandingGear.MAIN_GEAR_MASS, ], promotes_outputs=["wing_mounted_mass", "eng_comb_mass"] + ["aircraft:*"], ) diff --git a/aviary/subsystems/mass/gasp_based/fuel.py b/aviary/subsystems/mass/gasp_based/fuel.py index b9b973fc9..8a202aece 100644 --- a/aviary/subsystems/mass/gasp_based/fuel.py +++ b/aviary/subsystems/mass/gasp_based/fuel.py @@ -3,9 +3,8 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import Verbosity -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission, Settings check = 1 @@ -33,10 +32,8 @@ class BodyTankCalculations(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES) + add_aviary_option(self, Settings.VERBOSITY) def setup(self): @@ -135,14 +132,13 @@ def compute(self, inputs, outputs): fuel_wt_des = inputs[Mission.Design.FUEL_MASS] * GRAV_ENGLISH_LBM OEW = inputs[Aircraft.Design.OPERATING_MASS] * GRAV_ENGLISH_LBM - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] extra_fuel_volume = sigX(design_fuel_vol - max_wingfuel_vol) * ( design_fuel_vol - geometric_fuel_vol ) - verbosity = self.options['aviary_options'].get_val(Settings.VERBOSITY) + verbosity = self.options[Settings.VERBOSITY] if verbosity >= Verbosity.BRIEF: if (req_fuel_wt > max_wingfuel_wt) and (design_fuel_vol > max_wingfuel_vol): print("Warning: req_fuel_mass > max_wingfuel_mass, adding a body tank") @@ -187,8 +183,7 @@ def compute_partials(self, inputs, J): fuel_wt_des = inputs[Mission.Design.FUEL_MASS] * GRAV_ENGLISH_LBM OEW = inputs[Aircraft.Design.OPERATING_MASS] * GRAV_ENGLISH_LBM - smooth = self.options["aviary_options"].get_val( - Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, units='unitless') + smooth = self.options[Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES] extra_fuel_volume = sigX(design_fuel_vol - max_wingfuel_vol) * ( design_fuel_vol - geometric_fuel_vol @@ -361,12 +356,6 @@ class FuelAndOEMOutputs(om.ExplicitComponent): wing fuel weight). """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input(self, Aircraft.Fuel.DENSITY, val=6.687, units="lbm/ft**3") @@ -732,12 +721,6 @@ class FuelSysAndFullFuselageMass(om.ExplicitComponent): Computation of fuselage mass and fuel system mass """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input(self, Mission.Design.GROSS_MASS, val=175400) @@ -866,14 +849,10 @@ class FuselageAndStructMass(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) self.add_input( "fus_mass_full", @@ -1208,12 +1187,6 @@ class FuelMass(om.ExplicitComponent): and minimum value of fuel mass. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): add_aviary_input(self, Aircraft.Design.STRUCTURE_MASS, val=50461.0) @@ -1514,16 +1487,8 @@ class FuelMassGroup(om.Group): FuselageAndStructMass, FuelMass, FuelAndOEMOutputs, and BodyTankCalculations. """ - def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): - aviary_options = self.options['aviary_options'] - # variables that are calculated at a higher level higher_level_inputs1 = ["wing_mounted_mass"] higher_level_inputs2 = [ @@ -1556,7 +1521,7 @@ def setup(self): self.add_subsystem( "sys_and_full_fus", - FuelSysAndFullFuselageMass(aviary_options=aviary_options), + FuelSysAndFullFuselageMass(), promotes_inputs=connected_inputs1 + higher_level_inputs1 + ["aircraft:*", "mission:*"], @@ -1565,14 +1530,14 @@ def setup(self): self.add_subsystem( "fus_and_struct", - FuselageAndStructMass(aviary_options=aviary_options), + FuselageAndStructMass(), promotes_inputs=connected_inputs2 + higher_level_inputs2 + ["aircraft:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( "fuel", - FuelMass(aviary_options=aviary_options), + FuelMass(), promotes_inputs=higher_level_inputs3 + ["aircraft:*", "mission:*"], promotes_outputs=connected_outputs3 + ["aircraft:*", "mission:*"], @@ -1580,14 +1545,14 @@ def setup(self): self.add_subsystem( "fuel_and_oem", - FuelAndOEMOutputs(aviary_options=aviary_options), + FuelAndOEMOutputs(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=connected_outputs4 + ["aircraft:*"], ) self.add_subsystem( "body_tank", - BodyTankCalculations(aviary_options=aviary_options), + BodyTankCalculations(), promotes_inputs=connected_inputs5 + ["aircraft:*", "mission:*"], promotes_outputs=connected_outputs5 + ["aircraft:*"], diff --git a/aviary/subsystems/mass/gasp_based/mass_premission.py b/aviary/subsystems/mass/gasp_based/mass_premission.py index 187df60a2..df167c6a9 100644 --- a/aviary/subsystems/mass/gasp_based/mass_premission.py +++ b/aviary/subsystems/mass/gasp_based/mass_premission.py @@ -6,7 +6,6 @@ from aviary.subsystems.mass.gasp_based.fixed import FixedMassGroup from aviary.subsystems.mass.gasp_based.fuel import FuelMassGroup from aviary.subsystems.mass.gasp_based.wing import WingMassGroup -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft @@ -15,17 +14,8 @@ class MassPremission(om.Group): Pre-mission mass group for GASP-based mass. """ - def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) - def setup(self): - aviary_options = self.options['aviary_options'] - # output values from design_load that are connected to fixed_mass via promotion fixed_mass_design_load_values = [ "max_mach", "min_dive_vel"] @@ -66,43 +56,35 @@ def setup(self): self.add_subsystem( "design_load", - DesignLoadGroup( - aviary_options=aviary_options, - ), + DesignLoadGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=["*"], ) self.add_subsystem( "fixed_mass", - FixedMassGroup( - aviary_options=aviary_options, - ), + FixedMassGroup(), promotes_inputs=fixed_mass_inputs + ["aircraft:*", "mission:*"], promotes_outputs=fixed_mass_outputs + ["aircraft:*"], ) self.add_subsystem( "equip_and_useful_mass", - EquipAndUsefulLoadMass( - aviary_options=aviary_options, - ), + EquipAndUsefulLoadMass(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( "wing_mass", - WingMassGroup( - aviary_options=aviary_options, - ), + WingMassGroup(), promotes_inputs=wing_mass_inputs + ["aircraft:*", "mission:*"], promotes_outputs=["aircraft:*"], ) self.add_subsystem( "fuel_mass", - FuelMassGroup(aviary_options=aviary_options), + FuelMassGroup(), promotes_inputs=fuel_mass_inputs + ["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", "mission:*" diff --git a/aviary/subsystems/mass/gasp_based/test/test_design_load.py b/aviary/subsystems/mass/gasp_based/test/test_design_load.py index 5a9674f94..5df362720 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_design_load.py +++ b/aviary/subsystems/mass/gasp_based/test/test_design_load.py @@ -8,6 +8,7 @@ LoadParameters, LiftCurveSlopeAtCruise, LoadSpeeds) +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Mission @@ -20,7 +21,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds(aviary_options=get_option_defaults()), + LoadSpeeds(), promotes=["*"], ) @@ -54,7 +55,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds(aviary_options=options), + LoadSpeeds(), promotes=["*"], ) @@ -65,6 +66,8 @@ def setUp(self): Aircraft.Wing.LOADING, val=128, units="lbf/ft**2" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -98,7 +101,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds(aviary_options=options), + LoadSpeeds(), promotes=["*"], ) @@ -109,6 +112,8 @@ def setUp(self): Aircraft.Wing.LOADING, val=128, units="lbf/ft**2" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -141,7 +146,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds(aviary_options=options), + LoadSpeeds(), promotes=["*"], ) @@ -152,6 +157,8 @@ def setUp(self): Aircraft.Wing.LOADING, val=128, units="lbf/ft**2" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -185,7 +192,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds(aviary_options=options), + LoadSpeeds(), promotes=["*"], ) @@ -193,6 +200,8 @@ def setUp(self): Aircraft.Design.MAX_STRUCTURAL_SPEED, val=402.5, units="mi/h" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -223,9 +232,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds( - aviary_options=options - ), + LoadSpeeds(), promotes=["*"], ) @@ -233,6 +240,8 @@ def setUp(self): Aircraft.Design.MAX_STRUCTURAL_SPEED, val=402.5, units="mi/h" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -261,9 +270,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds( - aviary_options=options - ), + LoadSpeeds(), promotes=["*"], ) @@ -274,6 +281,8 @@ def setUp(self): Aircraft.Wing.LOADING, val=128, units="lbf/ft**2" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -309,9 +318,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds( - aviary_options=options, - ), + LoadSpeeds(), promotes=["*"], ) @@ -322,6 +329,8 @@ def setUp(self): Aircraft.Wing.LOADING, val=128, units="lbf/ft**2" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -356,9 +365,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds( - aviary_options=options, - ), + LoadSpeeds(), promotes=["*"], ) @@ -369,6 +376,8 @@ def setUp(self): Aircraft.Wing.LOADING, val=128, units="lbf/ft**2" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -404,9 +413,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "speeds", - LoadSpeeds( - aviary_options=options, - ), + LoadSpeeds(), promotes=["*"], ) @@ -414,6 +421,8 @@ def setUp(self): Aircraft.Design.MAX_STRUCTURAL_SPEED, val=402.5, units="mi/h" ) # not actual bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -441,7 +450,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "params", LoadParameters(aviary_options=options), promotes=["*"] + "params", LoadParameters(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -451,6 +460,8 @@ def setUp(self): "max_airspeed", val=350, units="kn" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -476,7 +487,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "params", LoadParameters(aviary_options=options), promotes=["*"] + "params", LoadParameters(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -486,6 +497,8 @@ def setUp(self): "max_airspeed", val=350, units="kn" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -512,7 +525,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "params", LoadParameters(aviary_options=options), promotes=["*"] + "params", LoadParameters(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -522,6 +535,8 @@ def setUp(self): "max_airspeed", val=350, units="kn" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -543,14 +558,14 @@ class LoadParametersTestCase4smooth(unittest.TestCase): def setUp(self): options = get_option_defaults() - options.set_val(Mission.Design.CRUISE_ALTITUDE, val=37500, units='ft') options.set_val(Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, val=True, units='unitless') + options.set_val(Mission.Design.CRUISE_ALTITUDE, val=37500, units='ft') self.prob = om.Problem() self.prob.model.add_subsystem( "params", - LoadParameters(aviary_options=options,), + LoadParameters(), promotes=["*"], ) @@ -561,6 +576,8 @@ def setUp(self): "max_airspeed", val=350, units="kn" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -582,14 +599,14 @@ def setUp(self): options = get_option_defaults() options.set_val(Aircraft.Design.PART25_STRUCTURAL_CATEGORY, val=2, units='unitless') - options.set_val(Mission.Design.CRUISE_ALTITUDE, val=30000, units='ft') options.set_val(Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, val=True, units='unitless') + options.set_val(Mission.Design.CRUISE_ALTITUDE, val=30000, units='ft') self.prob = om.Problem() self.prob.model.add_subsystem( "params", - LoadParameters(aviary_options=options,), + LoadParameters(), promotes=["*"], ) @@ -600,6 +617,8 @@ def setUp(self): "max_airspeed", val=350, units="kn" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -622,14 +641,14 @@ def setUp(self): options = get_option_defaults() options.set_val(Aircraft.Design.PART25_STRUCTURAL_CATEGORY, val=4, units='unitless') - options.set_val(Mission.Design.CRUISE_ALTITUDE, val=22000, units='ft') options.set_val(Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, val=True, units='unitless') + options.set_val(Mission.Design.CRUISE_ALTITUDE, val=22000, units='ft') self.prob = om.Problem() self.prob.model.add_subsystem( "params", - LoadParameters(aviary_options=options,), + LoadParameters(), promotes=["*"], ) @@ -640,6 +659,8 @@ def setUp(self): "max_airspeed", val=350, units="kn" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -689,7 +710,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "factors", LoadFactors(aviary_options=get_option_defaults()), promotes=["*"] + "factors", LoadFactors(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -735,7 +756,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "factors", LoadFactors(aviary_options=options), promotes=["*"] + "factors", LoadFactors(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -756,6 +777,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Design.LIFT_CURVE_SLOPE, val=7.1765, units="1/rad") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -781,7 +804,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "factors", - LoadFactors(aviary_options=options), + LoadFactors(), promotes=["*"], ) @@ -805,6 +828,8 @@ def setUp(self): Aircraft.Design.LIFT_CURVE_SLOPE, val=7.1765, units="1/rad" ) # bug fixed value and original value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -829,7 +854,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "factors", - LoadFactors(aviary_options=options,), + LoadFactors(), promotes=["*"], ) @@ -851,6 +876,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Design.LIFT_CURVE_SLOPE, val=7.1765, units="1/rad") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -876,9 +903,7 @@ def setUp(self): self.prob.model.add_subsystem( "Dload", - DesignLoadGroup( - aviary_options=options, - ), + DesignLoadGroup(), promotes=["*"], ) @@ -893,6 +918,8 @@ def setUp(self): Aircraft.Wing.AVERAGE_CHORD, val=12.71, units="ft" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -913,17 +940,15 @@ class DesignLoadGroupTestCase2smooth(unittest.TestCase): def setUp(self): options = get_option_defaults() - options.set_val(Mission.Design.CRUISE_ALTITUDE, val=37500, units='ft') options.set_val(Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, val=True, units='unitless') + options.set_val(Mission.Design.CRUISE_ALTITUDE, val=37500, units='ft') self.prob = om.Problem() self.prob.model.add_subsystem( "Dload", - DesignLoadGroup( - aviary_options=options, - ), + DesignLoadGroup(), promotes=["*"], ) @@ -938,6 +963,8 @@ def setUp(self): Aircraft.Wing.AVERAGE_CHORD, val=12.71, units="ft" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): diff --git a/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py b/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py index bb1328cf9..242ad7427 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py +++ b/aviary/subsystems/mass/gasp_based/test/test_equipment_and_useful_load.py @@ -7,6 +7,7 @@ from aviary.subsystems.mass.gasp_based.equipment_and_useful_load import \ EquipAndUsefulLoadMass from aviary.variable_info.enums import GASPEngineType +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Mission @@ -25,7 +26,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "equip", - EquipAndUsefulLoadMass(aviary_options=options), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -87,6 +88,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -115,7 +118,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "equip", - EquipAndUsefulLoadMass(aviary_options=options), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -177,6 +180,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -206,7 +211,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "equip", - EquipAndUsefulLoadMass(aviary_options=options), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -268,6 +273,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -301,9 +308,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "equip", - EquipAndUsefulLoadMass( - aviary_options=options, - ), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -365,6 +370,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -396,9 +403,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "equip", - EquipAndUsefulLoadMass( - aviary_options=options, - ), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -460,6 +465,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -493,9 +500,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "equip", - EquipAndUsefulLoadMass( - aviary_options=options - ), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -557,6 +562,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -588,7 +595,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - EquipAndUsefulLoadMass(aviary_options=options), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -652,6 +659,8 @@ def setUp(self): Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless" ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -691,7 +700,7 @@ def test_case1(self): prob = om.Problem() prob.model.add_subsystem( "equip", - EquipAndUsefulLoadMass(aviary_options=options), + EquipAndUsefulLoadMass(), promotes=["*"], ) @@ -744,6 +753,9 @@ def test_case1(self): Aircraft.Engine.SCALED_SLS_THRUST, val=[29500.0], units="lbf") prob.model.set_input_defaults( Aircraft.Fuel.WING_FUEL_FRACTION, val=0.6, units="unitless") + + setup_model_options(prob, options) + prob.setup(check=False, force_alloc_complex=True) partial_data = prob.check_partials(out_stream=None, method="cs") diff --git a/aviary/subsystems/mass/gasp_based/test/test_fixed.py b/aviary/subsystems/mass/gasp_based/test/test_fixed.py index 57e0f8afb..36bc36ffa 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_fixed.py +++ b/aviary/subsystems/mass/gasp_based/test/test_fixed.py @@ -16,6 +16,7 @@ MassParameters, PayloadMass, TailMass) from aviary.utils.aviary_values import AviaryValues, get_keys +from aviary.variable_info.functions import setup_model_options, extract_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Mission, Settings @@ -34,9 +35,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "parameters", - MassParameters( - aviary_options=options - ), + MassParameters(), promotes=["*"], ) @@ -56,6 +55,8 @@ def setUp(self): "max_mach", val=0.9, units="unitless" ) # bug fixed value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -87,9 +88,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "parameters", - MassParameters( - aviary_options=options, - ), + MassParameters(), promotes=["*"], ) @@ -110,6 +109,8 @@ def setUp(self): Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0 ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -142,9 +143,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "parameters", - MassParameters( - aviary_options=options, - ), + MassParameters(), promotes=["*"], ) @@ -165,6 +164,8 @@ def setUp(self): Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0 ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -198,9 +199,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "parameters", - MassParameters( - aviary_options=options, - ), + MassParameters(), promotes=["*"], ) @@ -221,6 +220,8 @@ def setUp(self): Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0 ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -254,9 +255,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "parameters", - MassParameters( - aviary_options=options, - ), + MassParameters(), promotes=["*"], ) @@ -277,6 +276,8 @@ def setUp(self): Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0 ) + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -310,12 +311,13 @@ def setUp(self): val=200, units="lbm") # bug fixed value and original value self.prob = om.Problem() - self.prob.model.add_subsystem("payload", PayloadMass( - aviary_options=options), promotes=["*"]) + self.prob.model.add_subsystem("payload", PayloadMass(), promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.CrewPayload.CARGO_MASS, val=10040, units="lbm" ) # bug fixed value and original value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -341,8 +343,12 @@ class ElectricAugmentationTestCase(unittest.TestCase): def setUp(self): self.prob = om.Problem() + + options = { + Aircraft.Propulsion.TOTAL_NUM_ENGINES: 2, + } self.prob.model.add_subsystem( - "aug", ElectricAugmentationMass(aviary_options=get_option_defaults()), promotes=["*"] + "aug", ElectricAugmentationMass(**options), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -393,6 +399,7 @@ def setUp(self): self.prob.model.set_input_defaults( "TMS_spec_mass", val=0.125, units="lbm/kW" ) # electrified diff configuration value v3.6 + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -418,7 +425,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "engine", - EngineMass(aviary_options=options), + EngineMass(), promotes=["*"], ) @@ -456,6 +463,8 @@ def setUp(self): Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0.15, units="unitless" ) # bug fixed value and original value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -492,7 +501,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "engine", - EngineMass(aviary_options=options), + EngineMass(), promotes=["*"], ) @@ -536,6 +545,8 @@ def setUp(self): Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0.15, units="unitless" ) # bug fixed value and original value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -580,7 +591,7 @@ def test_case_1(self): self.prob = om.Problem() self.prob.model.add_subsystem( "engine", - EngineMass(aviary_options=options), + EngineMass(), promotes=["*"], ) @@ -607,6 +618,8 @@ def test_case_1(self): self.prob.model.set_input_defaults( Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0.15, units="unitless") + self.prob.model_options['*'] = extract_options(options) + self.prob.setup(check=False, force_alloc_complex=True) self.prob.run_model() @@ -637,7 +650,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "tail", TailMass(aviary_options=get_option_defaults()), promotes=["*"] + "tail", TailMass(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -736,7 +749,7 @@ def setUp(self): aviary_options.set_val(Aircraft.Wing.NUM_FLAP_SEGMENTS, val=2) self.prob.model.add_subsystem( - "HL", HighLiftMass(aviary_options=aviary_options), promotes=["*"] + "HL", HighLiftMass(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -779,6 +792,8 @@ def setUp(self): Mission.Landing.LIFT_COEFFICIENT_MAX, val=2.3648, units="unitless" ) + setup_model_options(self.prob, aviary_options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -799,8 +814,8 @@ class ControlMassTestCase(unittest.TestCase): def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("payload", ControlMass( - aviary_options=get_option_defaults()), promotes=["*"]) + self.prob.model.add_subsystem("payload", ControlMass(), + promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.Wing.SURFACE_CONTROL_MASS_COEFFICIENT, val=0.95, units="unitless" @@ -855,7 +870,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "payload", GearMass(aviary_options=get_option_defaults()), promotes=["*"] + "payload", GearMass(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -900,7 +915,7 @@ def setUp(self): options = get_option_defaults() self.prob = om.Problem() self.prob.model.add_subsystem( - "payload", GearMass(aviary_options=options), promotes=["*"] + "payload", GearMass(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -915,6 +930,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Wing.MOUNTING_TYPE, val=0.1, units="unitless") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -942,7 +959,7 @@ def test_case1(self): self.prob = om.Problem() self.prob.model.add_subsystem( "gear_mass", - GearMass(aviary_options=options), + GearMass(), promotes=["*"], ) @@ -953,6 +970,8 @@ def test_case1(self): Aircraft.Nacelle.AVG_DIAMETER, val=[7.5, 8.22], units='ft' ) + self.prob.model_options['*'] = extract_options(options) + self.prob.setup(check=False, force_alloc_complex=True) self.prob.run_model() @@ -980,9 +999,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - FixedMassGroup( - aviary_options=options, - ), + FixedMassGroup(), promotes=["*"], ) @@ -1145,6 +1162,8 @@ def setUp(self): Aircraft.LandingGear.MAIN_GEAR_LOCATION, val=0.15, units="unitless" ) # bug fixed value and original value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -1235,9 +1254,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - FixedMassGroup( - aviary_options=options, - ), + FixedMassGroup(), promotes=["*"], ) @@ -1451,6 +1468,8 @@ def setUp(self): "engine.prop_mass", val=0, units="lbm" ) # bug fixed value and original value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -1537,9 +1556,12 @@ def _run_case(self, data): prob = om.Problem() prob.model.add_subsystem( 'fixed_mass', - FixedMassGroup(aviary_options=data), + FixedMassGroup(), promotes=['*'], ) + + setup_model_options(prob, data) + prob.setup(force_alloc_complex=True) for key in get_keys(data): diff --git a/aviary/subsystems/mass/gasp_based/test/test_fuel.py b/aviary/subsystems/mass/gasp_based/test/test_fuel.py index 6953f8a20..c0592d62b 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_fuel.py +++ b/aviary/subsystems/mass/gasp_based/test/test_fuel.py @@ -19,7 +19,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "wing_calcs", BodyTankCalculations(aviary_options=get_option_defaults(), ), promotes=["*"] + "wing_calcs", BodyTankCalculations(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -76,7 +76,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "wing_calcs", BodyTankCalculations(aviary_options=get_option_defaults(), ), promotes=["*"] + "wing_calcs", BodyTankCalculations(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -134,7 +134,7 @@ def tearDown(self): def test_case1(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "wing_calcs", BodyTankCalculations(aviary_options=get_option_defaults(), ), promotes=["*"] + "wing_calcs", BodyTankCalculations(), promotes=["*"] ) self.prob.model.set_input_defaults( Aircraft.Fuel.WING_VOLUME_DESIGN, val=989.2, units="ft**3") @@ -165,8 +165,9 @@ class FuelAndOEMTestCase(unittest.TestCase): def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("wing_calcs", FuelAndOEMOutputs( - aviary_options=get_option_defaults(), ), promotes=["*"]) + self.prob.model.add_subsystem("wing_calcs", + FuelAndOEMOutputs(), + promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.Fuel.DENSITY, val=6.687, units="lbm/galUS") @@ -229,8 +230,10 @@ def tearDown(self): def test_case1(self): prob = om.Problem() - prob.model.add_subsystem("wing_calcs", FuelAndOEMOutputs( - aviary_options=get_option_defaults(), ), promotes=["*"] + prob.model.add_subsystem( + "wing_calcs", + FuelAndOEMOutputs(), + promotes=["*"] ) prob.model.set_input_defaults( Aircraft.Fuel.DENSITY, val=6.687, units="lbm/galUS") @@ -267,7 +270,9 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "sys_and_fus", FuelSysAndFullFuselageMass(aviary_options=get_option_defaults(), ), promotes=["*"] + "sys_and_fus", + FuelSysAndFullFuselageMass(), + promotes=["*"] ) self.prob.model.set_input_defaults( @@ -320,7 +325,9 @@ def tearDown(self): def test_case1(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "sys_and_fus", FuelSysAndFullFuselageMass(aviary_options=get_option_defaults(), ), promotes=["*"] + "sys_and_fus", + FuelSysAndFullFuselageMass(), + promotes=["*"] ) self.prob.model.set_input_defaults( Mission.Design.GROSS_MASS, val=175400, units="lbm") @@ -351,7 +358,9 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "fus_and_struct", FuselageAndStructMass(aviary_options=get_option_defaults(), ), promotes=["*"] + "fus_and_struct", + FuselageAndStructMass(), + promotes=["*"] ) self.prob.model.set_input_defaults("fus_mass_full", val=102270, units="lbm") @@ -426,7 +435,9 @@ def tearDown(self): def test_case1(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "fus_and_struct", FuselageAndStructMass(aviary_options=get_option_defaults(), ), promotes=["*"] + "fus_and_struct", + FuselageAndStructMass(), + promotes=["*"] ) self.prob.model.set_input_defaults("fus_mass_full", val=102270, units="lbm") @@ -478,8 +489,8 @@ class FuelMassTestCase(unittest.TestCase): # this is the large single aisle 1 V def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("fuel", FuelMass( - aviary_options=get_option_defaults(), ), promotes=["*"]) + self.prob.model.add_subsystem("fuel", FuelMass(), + promotes=["*"]) self.prob.model.set_input_defaults( Aircraft.Design.STRUCTURE_MASS, val=50461.0, units="lbm") @@ -540,8 +551,7 @@ def tearDown(self): def test_case1(self): prob = om.Problem() - prob.model.add_subsystem("fuel", FuelMass( - aviary_options=get_option_defaults(), ), promotes=["*"]) + prob.model.add_subsystem("fuel", FuelMass(), promotes=["*"]) prob.model.set_input_defaults( Aircraft.Design.STRUCTURE_MASS, val=50461.0, units="lbm") prob.model.set_input_defaults( @@ -578,8 +588,7 @@ class FuelMassGroupTestCase1(unittest.TestCase): def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("group", FuelMassGroup( - aviary_options=get_option_defaults(), ), promotes=["*"]) + self.prob.model.add_subsystem("group", FuelMassGroup(), promotes=["*"]) # top level self.prob.model.set_input_defaults( @@ -718,8 +727,7 @@ class FuelMassGroupTestCase2( def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("group", FuelMassGroup( - aviary_options=get_option_defaults(), ), promotes=["*"]) + self.prob.model.add_subsystem("group", FuelMassGroup(), promotes=["*"]) # top level self.prob.model.set_input_defaults( @@ -858,8 +866,7 @@ class FuelMassGroupTestCase3( def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("group", FuelMassGroup( - aviary_options=get_option_defaults(), ), promotes=["*"]) + self.prob.model.add_subsystem("group", FuelMassGroup(), promotes=["*"]) # top level self.prob.model.set_input_defaults( diff --git a/aviary/subsystems/mass/gasp_based/test/test_mass_summation.py b/aviary/subsystems/mass/gasp_based/test/test_mass_summation.py index b1924dac6..94a671914 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_mass_summation.py +++ b/aviary/subsystems/mass/gasp_based/test/test_mass_summation.py @@ -7,6 +7,7 @@ from aviary.subsystems.geometry.gasp_based.size_group import SizeGroup from aviary.subsystems.mass.gasp_based.mass_premission import MassPremission from aviary.utils.aviary_values import get_items +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults, is_option from aviary.models.large_single_aisle_1.V3_bug_fixed_IO import ( V3_bug_fixed_non_metadata, V3_bug_fixed_options) @@ -25,9 +26,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "gasp_based_geom", - SizeGroup( - aviary_options=V3_bug_fixed_options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -35,9 +34,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "total_mass", - MassPremission( - aviary_options=V3_bug_fixed_options, - ), + MassPremission(), promotes=['*'], ) @@ -56,6 +53,8 @@ def setUp(self): self.prob.model.set_input_defaults( Aircraft.Fuselage.WETTED_AREA_SCALER, val=0.86215, units="unitless") + setup_model_options(self.prob, V3_bug_fixed_options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -196,9 +195,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -206,9 +203,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -448,6 +443,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -587,9 +584,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -597,9 +592,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -840,6 +833,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -969,9 +964,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -979,9 +972,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -1223,6 +1214,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -1352,9 +1345,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -1362,9 +1353,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -1606,6 +1595,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -1734,9 +1725,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -1744,9 +1733,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -1988,6 +1975,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -2117,9 +2106,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -2127,9 +2114,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -2375,6 +2360,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -2510,9 +2497,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -2520,9 +2505,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -2776,6 +2759,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -2906,9 +2891,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "size", - SizeGroup( - aviary_options=options, - ), + SizeGroup(), promotes_inputs=["aircraft:*", "mission:*"], promotes_outputs=[ "aircraft:*", @@ -2916,9 +2899,7 @@ def setUp(self): ) self.prob.model.add_subsystem( "GASP_mass", - MassPremission( - aviary_options=options, - ), + MassPremission(), promotes=["*"], ) @@ -3217,6 +3198,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=0.0, units="ft") + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): diff --git a/aviary/subsystems/mass/gasp_based/test/test_wing.py b/aviary/subsystems/mass/gasp_based/test/test_wing.py index 43f481488..3c9fbbcd7 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_wing.py +++ b/aviary/subsystems/mass/gasp_based/test/test_wing.py @@ -6,6 +6,7 @@ from aviary.subsystems.mass.gasp_based.wing import (WingMassGroup, WingMassSolve, WingMassTotal) +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Mission @@ -16,8 +17,8 @@ class WingMassSolveTestCase(unittest.TestCase): def setUp(self): self.prob = om.Problem() - self.prob.model.add_subsystem("wingfuel", WingMassSolve( - aviary_options=get_option_defaults()), promotes=["*"]) + self.prob.model.add_subsystem("wingfuel", WingMassSolve(), + promotes=["*"]) self.prob.model.set_input_defaults( Mission.Design.GROSS_MASS, val=175400, units="lbm" @@ -86,8 +87,8 @@ def tearDown(self): def test_case1(self): prob = om.Problem() - prob.model.add_subsystem("wingfuel", WingMassSolve( - aviary_options=get_option_defaults()), promotes=["*"]) + prob.model.add_subsystem("wingfuel", WingMassSolve(), + promotes=["*"]) prob.model.set_input_defaults( Mission.Design.GROSS_MASS, val=175400, units="lbm") prob.model.set_input_defaults( @@ -138,7 +139,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "total", - WingMassTotal(aviary_options=get_option_defaults()), + WingMassTotal(), promotes=["*"], ) @@ -171,7 +172,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "total", - WingMassTotal(aviary_options=options), + WingMassTotal(), promotes=["*"], ) @@ -187,6 +188,8 @@ def setUp(self): Aircraft.Wing.FOLD_MASS_COEFFICIENT, val=0.2, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -215,7 +218,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "total", - WingMassTotal(aviary_options=options), + WingMassTotal(), promotes=["*"], ) @@ -225,6 +228,8 @@ def setUp(self): Aircraft.Strut.MASS_COEFFICIENT, val=0.5, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -253,7 +258,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "total", WingMassTotal(aviary_options=options), promotes=["*"] + "total", WingMassTotal(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -271,6 +276,8 @@ def setUp(self): Aircraft.Strut.MASS_COEFFICIENT, val=0.5, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -304,7 +311,7 @@ def test_case1(self): prob = om.Problem() prob.model.add_subsystem( "total", - WingMassTotal(aviary_options=get_option_defaults()), + WingMassTotal(), promotes=["*"], ) prob.model.set_input_defaults( @@ -335,7 +342,7 @@ def test_case1(self): self.prob = om.Problem() self.prob.model.add_subsystem( "total", - WingMassTotal(aviary_options=options), + WingMassTotal(), promotes=["*"], ) self.prob.model.set_input_defaults( @@ -346,6 +353,9 @@ def test_case1(self): Aircraft.Wing.FOLDING_AREA, val=50, units="ft**2") self.prob.model.set_input_defaults( Aircraft.Wing.FOLD_MASS_COEFFICIENT, val=0.2, units="unitless") + + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) partial_data = self.prob.check_partials(out_stream=None, method="cs") @@ -372,13 +382,16 @@ def test_case1(self): prob = om.Problem() prob.model.add_subsystem( "total", - WingMassTotal(aviary_options=options), + WingMassTotal(), promotes=["*"], ) prob.model.set_input_defaults( "isolated_wing_mass", val=15830.0, units="lbm") prob.model.set_input_defaults( Aircraft.Strut.MASS_COEFFICIENT, val=0.5, units="unitless") + + setup_model_options(prob, options) + prob.setup(check=False, force_alloc_complex=True) partial_data = prob.check_partials(out_stream=None, method="cs") @@ -405,7 +418,7 @@ def test_case1(self): options.set_val(Aircraft.Wing.HAS_STRUT, val=True, units='unitless') prob = om.Problem() prob.model.add_subsystem( - "total", WingMassTotal(aviary_options=options), promotes=["*"]) + "total", WingMassTotal(), promotes=["*"]) prob.model.set_input_defaults( "isolated_wing_mass", val=15830.0, units="lbm") prob.model.set_input_defaults( @@ -416,6 +429,9 @@ def test_case1(self): Aircraft.Wing.FOLD_MASS_COEFFICIENT, val=0.2, units="unitless") prob.model.set_input_defaults( Aircraft.Strut.MASS_COEFFICIENT, val=0.5, units="unitless") + + setup_model_options(prob, options) + prob.setup(check=False, force_alloc_complex=True) partial_data = prob.check_partials(out_stream=None, method="cs") @@ -430,7 +446,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingMassGroup(aviary_options=get_option_defaults()), + WingMassGroup(), promotes=["*"], ) @@ -485,7 +501,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingMassGroup(aviary_options=options), + WingMassGroup(), promotes=["*"], ) @@ -526,6 +542,8 @@ def setUp(self): Aircraft.Wing.FOLD_MASS_COEFFICIENT, val=0.2, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -551,7 +569,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( "group", - WingMassGroup(aviary_options=options), + WingMassGroup(), promotes=["*"], ) @@ -586,6 +604,8 @@ def setUp(self): Aircraft.Strut.MASS_COEFFICIENT, val=0.5, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): @@ -611,7 +631,7 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem( - "group", WingMassGroup(aviary_options=options), promotes=["*"] + "group", WingMassGroup(), promotes=["*"] ) self.prob.model.set_input_defaults( @@ -654,6 +674,8 @@ def setUp(self): Aircraft.Strut.MASS_COEFFICIENT, val=0.5, units="unitless" ) # not actual GASP value + setup_model_options(self.prob, options) + self.prob.setup(check=False, force_alloc_complex=True) def test_case1(self): diff --git a/aviary/subsystems/mass/gasp_based/wing.py b/aviary/subsystems/mass/gasp_based/wing.py index 0c9954abb..6eb3eada8 100644 --- a/aviary/subsystems/mass/gasp_based/wing.py +++ b/aviary/subsystems/mass/gasp_based/wing.py @@ -2,26 +2,21 @@ import openmdao.api as om from aviary.constants import GRAV_ENGLISH_LBM -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Mission class WingMassSolve(om.ImplicitComponent): """ - Computation of isolated wing mass, namely wing mass including high lift devices + Computation of isolated wing mass, namely wing mass including high lift devices (but excluding struts and fold effects) using a nonlinear solver. """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input(self, Mission.Design.GROSS_MASS, val=175400) add_aviary_input(self, Aircraft.Wing.HIGH_LIFT_MASS, val=3645) @@ -298,11 +293,8 @@ class WingMassTotal(om.ExplicitComponent): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.HAS_FOLD) + add_aviary_option(self, Aircraft.Wing.HAS_STRUT) def setup(self): @@ -313,11 +305,10 @@ def setup(self): desc="WW: wing mass including high lift devices (but excluding struts and fold effects)", ) - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if self.options[Aircraft.Wing.HAS_STRUT]: add_aviary_input(self, Aircraft.Strut.MASS_COEFFICIENT, val=0.000000000001) - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless') == True: - + if self.options[Aircraft.Wing.HAS_FOLD]: add_aviary_input(self, Aircraft.Wing.AREA, val=100) add_aviary_input(self, Aircraft.Wing.FOLDING_AREA, val=50) add_aviary_input(self, Aircraft.Wing.FOLD_MASS_COEFFICIENT, val=0.2) @@ -327,10 +318,10 @@ def setup(self): add_aviary_output(self, Aircraft.Wing.FOLD_MASS, val=0) self.declare_partials(Aircraft.Wing.MASS, "*") - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if self.options[Aircraft.Wing.HAS_STRUT]: self.declare_partials(Aircraft.Strut.MASS, [ Aircraft.Strut.MASS_COEFFICIENT, "isolated_wing_mass"]) - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if self.options[Aircraft.Wing.HAS_FOLD]: self.declare_partials(Aircraft.Wing.FOLD_MASS, [ Aircraft.Wing.AREA, Aircraft.Wing.FOLDING_AREA, Aircraft.Wing.FOLD_MASS_COEFFICIENT, "isolated_wing_mass"]) @@ -338,7 +329,7 @@ def compute(self, inputs, outputs): isolated_wing_wt = inputs["isolated_wing_mass"] * GRAV_ENGLISH_LBM - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if self.options[Aircraft.Wing.HAS_STRUT]: c_strut_mass = inputs[Aircraft.Strut.MASS_COEFFICIENT] strut_wt = c_strut_mass * isolated_wing_wt @@ -347,7 +338,7 @@ def compute(self, inputs, outputs): else: outputs[Aircraft.Strut.MASS] = strut_wt = 0 - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if self.options[Aircraft.Wing.HAS_FOLD]: wing_area = inputs[Aircraft.Wing.AREA] folding_area = inputs[Aircraft.Wing.FOLDING_AREA] c_wing_fold = inputs[Aircraft.Wing.FOLD_MASS_COEFFICIENT] @@ -367,7 +358,7 @@ def compute_partials(self, inputs, J): isolated_wing_wt = inputs["isolated_wing_mass"] * GRAV_ENGLISH_LBM - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if self.options[Aircraft.Wing.HAS_STRUT]: c_strut_mass = inputs[Aircraft.Strut.MASS_COEFFICIENT] J[Aircraft.Wing.MASS, Aircraft.Strut.MASS_COEFFICIENT] = \ @@ -376,7 +367,7 @@ def compute_partials(self, inputs, J): J[Aircraft.Wing.MASS, "isolated_wing_mass"] = 1 + c_strut_mass J[Aircraft.Strut.MASS, "isolated_wing_mass"] = c_strut_mass - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless'): + if self.options[Aircraft.Wing.HAS_FOLD]: wing_area = inputs[Aircraft.Wing.AREA] folding_area = inputs[Aircraft.Wing.FOLDING_AREA] c_wing_fold = inputs[Aircraft.Wing.FOLD_MASS_COEFFICIENT] @@ -400,17 +391,16 @@ def compute_partials(self, inputs, J): J[Aircraft.Wing.FOLD_MASS, "isolated_wing_mass"] = c_wing_fold * \ folding_area / wing_area - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless') and \ - self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if self.options[Aircraft.Wing.HAS_FOLD] and \ + self.options[Aircraft.Wing.HAS_STRUT]: J[Aircraft.Wing.MASS, "isolated_wing_mass"] = ( 1 + c_wing_fold * folding_area / wing_area + c_strut_mass ) if ( - self.options["aviary_options"].get_val( - Aircraft.Wing.HAS_STRUT, units='unitless') == False - and self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless') == False + self.options[Aircraft.Wing.HAS_STRUT] == False + and self.options[Aircraft.Wing.HAS_FOLD] == False ): J[Aircraft.Wing.MASS, "isolated_wing_mass"] = 1 @@ -421,24 +411,19 @@ class WingMassGroup(om.Group): """ def initialize(self): - - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) + add_aviary_option(self, Aircraft.Wing.HAS_FOLD) + add_aviary_option(self, Aircraft.Wing.HAS_STRUT) def setup(self): - aviary_options = self.options['aviary_options'] - # variables that are calculated at a higher level higher_level_inputs_isolated = [ "c_strut_braced", "c_gear_loc", "half_sweep", ] - if self.options["aviary_options"].get_val(Aircraft.Wing.HAS_FOLD, units='unitless') or \ - self.options["aviary_options"].get_val(Aircraft.Wing.HAS_STRUT, units='unitless'): + if self.options[Aircraft.Wing.HAS_FOLD] or \ + self.options[Aircraft.Wing.HAS_STRUT]: higher_level_inputs_total = [ "aircraft:*" @@ -456,16 +441,14 @@ def setup(self): isolated_mass = self.add_subsystem( "isolated_mass", - WingMassSolve(aviary_options=aviary_options), + WingMassSolve(), promotes_inputs=higher_level_inputs_isolated + ["aircraft:*", "mission:*"], promotes_outputs=connected_outputs_isolated, ) total_mass = self.add_subsystem( "total_mass", - WingMassTotal( - aviary_options=aviary_options, - ), + WingMassTotal(), promotes_inputs=connected_inputs_total + higher_level_inputs_total, promotes_outputs=["aircraft:*"], ) diff --git a/aviary/subsystems/mass/mass_builder.py b/aviary/subsystems/mass/mass_builder.py index 07ee3a0df..772a9b838 100644 --- a/aviary/subsystems/mass/mass_builder.py +++ b/aviary/subsystems/mass/mass_builder.py @@ -59,10 +59,10 @@ def build_pre_mission(self, aviary_inputs): code_origin = self.code_origin if code_origin is GASP: - mass_premission = MassPremissionGASP(aviary_options=aviary_inputs,) + mass_premission = MassPremissionGASP() elif code_origin is FLOPS: - mass_premission = MassPremissionFLOPS(aviary_options=aviary_inputs) + mass_premission = MassPremissionFLOPS() return mass_premission diff --git a/aviary/subsystems/propulsion/engine_deck.py b/aviary/subsystems/propulsion/engine_deck.py index 9d391a536..1d5727423 100644 --- a/aviary/subsystems/propulsion/engine_deck.py +++ b/aviary/subsystems/propulsion/engine_deck.py @@ -784,7 +784,7 @@ def build_pre_mission(self, aviary_inputs) -> om.ExplicitComponent: scaling factors. """ - return SizeEngine(aviary_options=self.options) + return SizeEngine() def _build_engine_interpolator(self, num_nodes, aviary_inputs): """ @@ -980,7 +980,7 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: uncorrect_shp = True engine_group.add_subsystem( 'uncorrect_shaft_power', - subsys=UncorrectData(num_nodes=num_nodes, aviary_options=self.options), + subsys=UncorrectData(num_nodes=num_nodes), promotes_inputs=[ Dynamic.Atmosphere.TEMPERATURE, Dynamic.Atmosphere.STATIC_PRESSURE, @@ -1014,7 +1014,7 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: engine_group.add_subsystem( 'uncorrect_max_shaft_power', subsys=UncorrectData( - num_nodes=num_nodes, aviary_options=self.options + num_nodes=num_nodes, ), promotes_inputs=[ Dynamic.Atmosphere.TEMPERATURE, @@ -1035,7 +1035,6 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: 'engine_scaling', subsys=EngineScaling( num_nodes=num_nodes, - aviary_options=self.options, engine_variables=engine_outputs, ), promotes_inputs=[Aircraft.Engine.SCALE_FACTOR, Dynamic.Atmosphere.MACH], diff --git a/aviary/subsystems/propulsion/engine_scaling.py b/aviary/subsystems/propulsion/engine_scaling.py index 556df4603..d6ba7df44 100644 --- a/aviary/subsystems/propulsion/engine_scaling.py +++ b/aviary/subsystems/propulsion/engine_scaling.py @@ -1,9 +1,8 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.subsystems.propulsion.utils import EngineModelVariables, max_variables -from aviary.variable_info.functions import add_aviary_input +from aviary.variable_info.functions import add_aviary_input, add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic, Mission @@ -39,19 +38,22 @@ class EngineScaling(om.ExplicitComponent): def initialize(self): self.options.declare('num_nodes', types=int) - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') - self.options.declare( 'engine_variables', types=dict, desc='dict of variables to be scaled for this engine with units', ) + add_aviary_option(self, Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION, units='lbm/h') + add_aviary_option(self, Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM) + add_aviary_option(self, Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM) + add_aviary_option(self, Aircraft.Engine.SCALE_PERFORMANCE) + add_aviary_option(self, Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER) + add_aviary_option(self, Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER) + add_aviary_option(self, Mission.Summary.FUEL_FLOW_SCALER) + def setup(self): nn = self.options['num_nodes'] - options: AviaryValues = self.options['aviary_options'] engine_variables = self.options['engine_variables'] add_aviary_input(self, Aircraft.Engine.SCALE_FACTOR, val=1.0) @@ -100,20 +102,17 @@ def setup(self): ) def compute(self, inputs, outputs): - nn = self.options['num_nodes'] - options: AviaryValues = self.options['aviary_options'] - engine_variables = self.options['engine_variables'] - scale_performance = options.get_val(Aircraft.Engine.SCALE_PERFORMANCE) - - subsonic_fuel_factor = options.get_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER) - supersonic_fuel_factor = options.get_val( - Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER) - constant_fuel_term = options.get_val( - Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM) - linear_fuel_term = options.get_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM) - constant_fuel_flow = options.get_val( - Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION, units='lbm/h') - mission_fuel_scaler = options.get_val(Mission.Summary.FUEL_FLOW_SCALER) + options = self.options + nn = options['num_nodes'] + engine_variables = options['engine_variables'] + scale_performance = options[Aircraft.Engine.SCALE_PERFORMANCE] + + subsonic_fuel_factor = options[Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER] + supersonic_fuel_factor = options[Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER] + constant_fuel_term = options[Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM] + linear_fuel_term = options[Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM] + constant_fuel_flow, _ = options[Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION] + mission_fuel_scaler = options[Mission.Summary.FUEL_FLOW_SCALER] # thrust-based engine scaling factor engine_scale_factor = inputs[Aircraft.Engine.SCALE_FACTOR] @@ -214,18 +213,16 @@ def setup_partials(self): ) def compute_partials(self, inputs, J): - nn = self.options['num_nodes'] - options: AviaryValues = self.options['aviary_options'] - engine_variables = self.options['engine_variables'] - scale_performance = options.get_val(Aircraft.Engine.SCALE_PERFORMANCE) - - subsonic_fuel_factor = options.get_val(Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER) - supersonic_fuel_factor = options.get_val( - Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER) - constant_fuel_term = options.get_val( - Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, units='unitless') - linear_fuel_term = options.get_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM) - mission_fuel_scaler = options.get_val(Mission.Summary.FUEL_FLOW_SCALER) + options = self.options + nn = options['num_nodes'] + engine_variables = options['engine_variables'] + scale_performance = options[Aircraft.Engine.SCALE_PERFORMANCE] + + subsonic_fuel_factor = options[Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER] + supersonic_fuel_factor = options[Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER] + constant_fuel_term = options[Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM] + linear_fuel_term = options[Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM] + mission_fuel_scaler = options[Mission.Summary.FUEL_FLOW_SCALER] mach_number = inputs[Dynamic.Atmosphere.MACH] engine_scale_factor = inputs[Aircraft.Engine.SCALE_FACTOR] diff --git a/aviary/subsystems/propulsion/engine_sizing.py b/aviary/subsystems/propulsion/engine_sizing.py index 1dbb04cd3..a2dd7aab4 100644 --- a/aviary/subsystems/propulsion/engine_sizing.py +++ b/aviary/subsystems/propulsion/engine_sizing.py @@ -1,8 +1,7 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft @@ -16,9 +15,8 @@ class SizeEngine(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + add_aviary_option(self, Aircraft.Engine.REFERENCE_SLS_THRUST, units='lbf') + add_aviary_option(self, Aircraft.Engine.SCALE_PERFORMANCE) def setup(self): add_aviary_input(self, Aircraft.Engine.SCALE_FACTOR, val=1.0) @@ -34,12 +32,9 @@ def setup(self): # TODO - nacelle_wetted_area: if length, diam get scaled - this should be covered by geom def compute(self, inputs, outputs): - options: AviaryValues = self.options['aviary_options'] - scale_engine = options.get_val(Aircraft.Engine.SCALE_PERFORMANCE) - - reference_sls_thrust = options.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, - units='lbf') + scale_engine = self.options[Aircraft.Engine.SCALE_PERFORMANCE] + reference_sls_thrust, _ = self.options[Aircraft.Engine.REFERENCE_SLS_THRUST] engine_scale_factor = inputs[Aircraft.Engine.SCALE_FACTOR] @@ -53,14 +48,15 @@ def compute(self, inputs, outputs): outputs[Aircraft.Engine.SCALED_SLS_THRUST] = scaled_sls_thrust def setup_partials(self): - self.declare_partials( - Aircraft.Engine.SCALED_SLS_THRUST, Aircraft.Engine.SCALE_FACTOR - ) + scale_engine = self.options[Aircraft.Engine.SCALE_PERFORMANCE] + + if scale_engine: + self.declare_partials( + Aircraft.Engine.SCALED_SLS_THRUST, Aircraft.Engine.SCALE_FACTOR + ) def compute_partials(self, inputs, J): - options: AviaryValues = self.options['aviary_options'] - reference_sls_thrust = options.get_val( - Aircraft.Engine.REFERENCE_SLS_THRUST, units='lbf') + reference_sls_thrust, _ = self.options[Aircraft.Engine.REFERENCE_SLS_THRUST] J[Aircraft.Engine.SCALED_SLS_THRUST, Aircraft.Engine.SCALE_FACTOR] = ( reference_sls_thrust diff --git a/aviary/subsystems/propulsion/gearbox/gearbox_builder.py b/aviary/subsystems/propulsion/gearbox/gearbox_builder.py index 94c2f6b81..84d0b2dc7 100644 --- a/aviary/subsystems/propulsion/gearbox/gearbox_builder.py +++ b/aviary/subsystems/propulsion/gearbox/gearbox_builder.py @@ -26,11 +26,11 @@ def __init__(self, name='gearbox', include_constraints=True): def build_pre_mission(self, aviary_inputs): """Builds an OpenMDAO system for the pre-mission computations of the subsystem.""" - return GearboxPreMission(aviary_inputs=aviary_inputs, simple_mass=True) + return GearboxPreMission(simple_mass=True) def build_mission(self, num_nodes, aviary_inputs): """Builds an OpenMDAO system for the mission computations of the subsystem.""" - return GearboxMission(num_nodes=num_nodes, aviary_inputs=aviary_inputs) + return GearboxMission(num_nodes=num_nodes) def get_design_vars(self): """ diff --git a/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py b/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py index df0b4f97b..9f366dce2 100644 --- a/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py +++ b/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py @@ -1,7 +1,6 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Dynamic, Aircraft, Mission @@ -13,11 +12,6 @@ class GearboxMission(om.Group): def initialize(self): self.options.declare("num_nodes", types=int) - self.options.declare( - 'aviary_inputs', types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - default=None, - ) self.name = 'gearbox_mission' def setup(self): diff --git a/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py b/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py index 503ba933f..bce6f81fc 100644 --- a/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py +++ b/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py @@ -2,7 +2,6 @@ import numpy as np from aviary.variable_info.variables import Aircraft, Dynamic -from aviary.utils.aviary_values import AviaryValues class GearboxPreMission(om.Group): @@ -15,11 +14,6 @@ class GearboxPreMission(om.Group): def initialize(self, ): self.options.declare("simple_mass", types=bool, default=True) - self.options.declare( - "aviary_inputs", types=AviaryValues, - desc="collection of Aircraft/Mission specific options", - default=None, - ) self.name = 'gearbox_premission' def setup(self): diff --git a/aviary/subsystems/propulsion/propeller/hamilton_standard.py b/aviary/subsystems/propulsion/propeller/hamilton_standard.py index b9f245b28..0b502c9b9 100644 --- a/aviary/subsystems/propulsion/propeller/hamilton_standard.py +++ b/aviary/subsystems/propulsion/propeller/hamilton_standard.py @@ -4,11 +4,10 @@ import numpy as np import openmdao.api as om -from aviary.utils.aviary_values import AviaryValues +from aviary.constants import RHO_SEA_LEVEL_ENGLISH from aviary.variable_info.enums import Verbosity from aviary.variable_info.variables import Aircraft, Dynamic, Settings -from aviary.constants import RHO_SEA_LEVEL_ENGLISH -from aviary.utils.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option def _unint(xa, ya, x): @@ -626,11 +625,11 @@ class HamiltonStandard(om.ExplicitComponent): """ def initialize(self): - self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') self.options.declare('num_nodes', default=1, types=int) + add_aviary_option(self, Aircraft.Engine.Propeller.NUM_BLADES) + add_aviary_option(self, Settings.VERBOSITY) + def setup(self): nn = self.options['num_nodes'] @@ -657,12 +656,12 @@ def setup(self): self.declare_partials('*', '*', method='fd', form='forward') def compute(self, inputs, outputs): - verbosity = self.options['aviary_options'].get_val(Settings.VERBOSITY) + verbosity = self.options[Settings.VERBOSITY] + num_blades = self.options[Aircraft.Engine.Propeller.NUM_BLADES] + act_factor = inputs[Aircraft.Engine.Propeller.ACTIVITY_FACTOR][0] cli = inputs[Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT][0] - num_blades = self.options['aviary_options'].get_val( - Aircraft.Engine.Propeller.NUM_BLADES - ) + # TODO verify this works with multiple engine models (i.e. prop mission is # properly slicing these inputs) # ensure num_blades is an int, so it can be used as array index later diff --git a/aviary/subsystems/propulsion/propeller/propeller_performance.py b/aviary/subsystems/propulsion/propeller/propeller_performance.py index e124ffe69..15917c46f 100644 --- a/aviary/subsystems/propulsion/propeller/propeller_performance.py +++ b/aviary/subsystems/propulsion/propeller/propeller_performance.py @@ -12,8 +12,9 @@ ) from aviary.subsystems.propulsion.propeller.propeller_map import PropellerMap from aviary.utils.aviary_values import AviaryValues -from aviary.utils.functions import add_aviary_input, add_aviary_output + from aviary.variable_info.enums import OutMachType +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic @@ -611,11 +612,6 @@ def initialize(self): default=1, desc='Number of nodes to be evaluated in the RHS', ) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) def setup(self): nn = self.options['num_nodes'] @@ -721,6 +717,9 @@ def initialize(self): desc='collection of Aircraft/Mission specific options', ) + add_aviary_option(self, Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS) + add_aviary_option(self, Aircraft.Engine.Propeller.DATA_FILE) + def setup(self): options = self.options nn = options['num_nodes'] @@ -728,9 +727,10 @@ def setup(self): # TODO options are lists here when using full Aviary problem - need # further investigation - compute_installation_loss = aviary_options.get_val( + compute_installation_loss = options[ Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS - ) + ] + if isinstance(compute_installation_loss, (list, np.ndarray)): compute_installation_loss = compute_installation_loss[0] @@ -831,7 +831,7 @@ def setup(self): else: self.add_subsystem( name='hamilton_standard', - subsys=HamiltonStandard(num_nodes=nn, aviary_options=aviary_options), + subsys=HamiltonStandard(num_nodes=nn), promotes_inputs=[ Dynamic.Atmosphere.MACH, "power_coefficient", diff --git a/aviary/subsystems/propulsion/propulsion_builder.py b/aviary/subsystems/propulsion/propulsion_builder.py index 24d91112a..47109287e 100644 --- a/aviary/subsystems/propulsion/propulsion_builder.py +++ b/aviary/subsystems/propulsion/propulsion_builder.py @@ -115,7 +115,8 @@ def build_pre_mission(self, aviary_inputs): engine_models=self.engine_models) def build_mission(self, num_nodes, aviary_inputs, **kwargs): - return PropulsionMission(num_nodes=num_nodes, aviary_options=aviary_inputs, + return PropulsionMission(num_nodes=num_nodes, + aviary_options=aviary_inputs, engine_models=self.engine_models) # NOTE untested! diff --git a/aviary/subsystems/propulsion/propulsion_mission.py b/aviary/subsystems/propulsion/propulsion_mission.py index 8dc6f7a6f..3c79eee15 100644 --- a/aviary/subsystems/propulsion/propulsion_mission.py +++ b/aviary/subsystems/propulsion/propulsion_mission.py @@ -4,6 +4,7 @@ import openmdao.api as om from aviary.utils.aviary_values import AviaryValues +from aviary.variable_info.functions import add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic, Settings @@ -195,7 +196,7 @@ def setup(self): self.add_subsystem( 'propulsion_sum', - subsys=PropulsionSum(num_nodes=nn, aviary_options=options), + subsys=PropulsionSum(num_nodes=nn), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -316,17 +317,12 @@ class PropulsionSum(om.ExplicitComponent): def initialize(self): self.options.declare('num_nodes', types=int, lower=0) - - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): nn = self.options['num_nodes'] num_engine_type = len( - self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) + self.options[Aircraft.Engine.NUM_ENGINES] ) self.add_input( @@ -379,9 +375,8 @@ def setup(self): def setup_partials(self): nn = self.options['num_nodes'] - num_engines = self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES - ) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] + num_engine_type = len(num_engines) deriv = np.tile(num_engines, nn) @@ -425,9 +420,7 @@ def setup_partials(self): ) def compute(self, inputs, outputs): - num_engines = self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES - ) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST] thrust_max = inputs[Dynamic.Vehicle.Propulsion.THRUST_MAX] diff --git a/aviary/subsystems/propulsion/propulsion_premission.py b/aviary/subsystems/propulsion/propulsion_premission.py index 8c48bbfef..ec613c728 100644 --- a/aviary/subsystems/propulsion/propulsion_premission.py +++ b/aviary/subsystems/propulsion/propulsion_premission.py @@ -4,7 +4,7 @@ import openmdao.api as om from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.functions import add_aviary_input, add_aviary_output +from aviary.variable_info.functions import add_aviary_input, add_aviary_output, add_aviary_option from aviary.variable_info.variables import Aircraft, Settings from aviary.variable_info.enums import Verbosity @@ -24,6 +24,8 @@ def initialize(self): self.options.declare( 'engine_models', types=list, desc='list of EngineModels on aircraft' ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + add_aviary_option(self, Settings.VERBOSITY) def setup(self): options = self.options['aviary_options'] @@ -57,7 +59,7 @@ def setup(self): self.add_subsystem( 'propulsion_sum', - subsys=PropulsionSum(aviary_options=options), + subsys=PropulsionSum(), promotes_inputs=['*'], promotes_outputs=['*'], ) @@ -72,7 +74,7 @@ def configure(self): num_engine_type = len(engine_models) # determine if openMDAO messages and warnings should be suppressed - verbosity = self.options['aviary_options'].get_val(Settings.VERBOSITY) + verbosity = self.options[Settings.VERBOSITY] out_stream = None # DEBUG @@ -203,16 +205,10 @@ class PropulsionSum(om.ExplicitComponent): ''' def initialize(self): - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options', - ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) def setup(self): - num_engine_type = len( - self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) - ) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) add_aviary_input( self, Aircraft.Engine.SCALED_SLS_THRUST, val=np.zeros(num_engine_type) @@ -221,9 +217,7 @@ def setup(self): add_aviary_output(self, Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, val=0.0) def setup_partials(self): - num_engines = self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES - ) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] self.declare_partials( Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, @@ -232,9 +226,7 @@ def setup_partials(self): ) def compute(self, inputs, outputs): - num_engines = self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES - ) + num_engines = self.options[Aircraft.Engine.NUM_ENGINES] thrust = inputs[Aircraft.Engine.SCALED_SLS_THRUST] diff --git a/aviary/subsystems/propulsion/test/test_engine_scaling.py b/aviary/subsystems/propulsion/test/test_engine_scaling.py index a4fb5d2f3..cf2c0e29d 100644 --- a/aviary/subsystems/propulsion/test/test_engine_scaling.py +++ b/aviary/subsystems/propulsion/test/test_engine_scaling.py @@ -9,6 +9,7 @@ from aviary.utils.aviary_values import AviaryValues from aviary.utils.preprocessors import preprocess_propulsion from aviary.utils.functions import get_path +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic, Mission, Settings from aviary.subsystems.propulsion.utils import EngineModelVariables @@ -57,12 +58,14 @@ def test_case(self): self.prob.model.add_subsystem( 'engine', - EngineScaling( - num_nodes=nn, aviary_options=options, engine_variables=engine_variables - ), + EngineScaling(num_nodes=nn, engine_variables=engine_variables), promotes=['*'], ) + + setup_model_options(self.prob, options) + self.prob.setup(force_alloc_complex=True) + self.prob.set_val( 'thrust_net_unscaled', np.ones([nn, count]) * 1000, units='lbf' ) diff --git a/aviary/subsystems/propulsion/test/test_engine_sizing.py b/aviary/subsystems/propulsion/test/test_engine_sizing.py index a5bbd8e30..096d0a90e 100644 --- a/aviary/subsystems/propulsion/test/test_engine_sizing.py +++ b/aviary/subsystems/propulsion/test/test_engine_sizing.py @@ -13,7 +13,7 @@ class EngineSizingTest1(unittest.TestCase): def setUp(self): - self.prob = om.Problem(model=om.Group()) + self.prob = om.Problem() def test_case_multiengine(self): filename = 'models/engines/turbofan_28k.deck' @@ -30,15 +30,21 @@ def test_case_multiengine(self): options.set_val(Aircraft.Engine.GEOPOTENTIAL_ALT, False) engine = EngineDeck(name='engine', options=options) - options.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, engine.get_val( - Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf'), 'lbf') # options.set_val(Aircraft.Engine.SCALE_PERFORMANCE, False) # engine2 = EngineDeck(name='engine2', options=options) # preprocess_propulsion(options, [engine, engine2]) - self.prob.model.add_subsystem('engine', SizeEngine( - aviary_options=options), promotes=['*']) + ref_thrust = engine.get_item(Aircraft.Engine.REFERENCE_SLS_THRUST) + options = { + Aircraft.Engine.SCALE_PERFORMANCE: True, + Aircraft.Engine.REFERENCE_SLS_THRUST: ref_thrust, + } + + self.prob.model.add_subsystem('engine', SizeEngine(**options), + promotes=['*']) + self.prob.setup(force_alloc_complex=True) + self.prob.set_val(Aircraft.Engine.SCALE_FACTOR, np.array([0.52716908])) self.prob.run_model() diff --git a/aviary/subsystems/propulsion/test/test_hamilton_standard.py b/aviary/subsystems/propulsion/test/test_hamilton_standard.py index 14a972e25..c8ec6fbd0 100644 --- a/aviary/subsystems/propulsion/test/test_hamilton_standard.py +++ b/aviary/subsystems/propulsion/test/test_hamilton_standard.py @@ -7,7 +7,7 @@ from aviary.subsystems.propulsion.propeller.hamilton_standard import ( HamiltonStandard, PreHamiltonStandard, PostHamiltonStandard, ) -from aviary.variable_info.variables import Aircraft, Dynamic +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Dynamic from aviary.constants import RHO_SEA_LEVEL_ENGLISH @@ -98,11 +98,13 @@ def setUp(self): prob.model.add_subsystem( 'hs', - HamiltonStandard(num_nodes=num_nodes, aviary_options=options), + HamiltonStandard(num_nodes=num_nodes), promotes_inputs=['*'], promotes_outputs=["*"], ) + setup_model_options(prob, options) + prob.setup() self.prob = prob diff --git a/aviary/subsystems/propulsion/test/test_propeller_performance.py b/aviary/subsystems/propulsion/test/test_propeller_performance.py index 394d1edaf..d16ab2c72 100644 --- a/aviary/subsystems/propulsion/test/test_propeller_performance.py +++ b/aviary/subsystems/propulsion/test/test_propeller_performance.py @@ -10,9 +10,9 @@ OutMachs, PropellerPerformance, TipSpeed, AreaSquareRatio, AdvanceRatio ) from aviary.variable_info.enums import OutMachType -from aviary.variable_info.variables import Aircraft, Dynamic, Settings +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.options import get_option_defaults -from aviary.variable_info.variables import Aircraft, Dynamic +from aviary.variable_info.variables import Aircraft, Dynamic, Settings # Setting up truth values from GASP (The first 12 are actual truth values, the rest are intelligent guesses) # test values now are slightly different due to setup - max tip speed was limited to test @@ -193,7 +193,8 @@ def setUp(self): pp = prob.model.add_subsystem( 'pp', - PropellerPerformance(num_nodes=num_nodes, aviary_options=options), + PropellerPerformance(num_nodes=num_nodes, + aviary_options=options), promotes_inputs=['*'], promotes_outputs=["*"], ) @@ -216,6 +217,9 @@ def setUp(self): val=True, units='unitless', ) + + setup_model_options(prob, options) + prob.setup() prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10.5, units="ft") @@ -292,6 +296,9 @@ def test_case_3_4_5(self): val=False, units='unitless', ) + + setup_model_options(prob, options) + prob.setup() prob.set_val('install_loss_factor', [0.0, 0.05, 0.05], units="unitless") prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 12.0, units="ft") @@ -342,6 +349,9 @@ def test_case_6_7_8(self): val=False, units='unitless', ) + + setup_model_options(prob, options) + prob.setup() prob.set_val('install_loss_factor', [0.0, 0.05, 0.05], units="unitless") prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 12.0, units="ft") @@ -473,6 +483,8 @@ def test_case_15_16_17(self): options.set_val(Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless') + setup_model_options(prob, options) + prob.setup(force_alloc_complex=True) prob.set_val('install_loss_factor', [0.0, 0.05, 0.05], units="unitless") prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 12.0, units="ft") diff --git a/aviary/subsystems/propulsion/test/test_propulsion_mission.py b/aviary/subsystems/propulsion/test/test_propulsion_mission.py index cbb6d148e..ab9271849 100644 --- a/aviary/subsystems/propulsion/test/test_propulsion_mission.py +++ b/aviary/subsystems/propulsion/test/test_propulsion_mission.py @@ -13,6 +13,7 @@ from aviary.utils.preprocessors import preprocess_propulsion from aviary.utils.functions import get_path from aviary.validation_cases.validation_tests import get_flops_inputs +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic, Mission, Settings from aviary.subsystems.propulsion.utils import build_engine_deck @@ -68,6 +69,8 @@ def test_case_1(self): ) self.prob.model.add_subsystem('IVC', IVC, promotes=['*']) + setup_model_options(self.prob, options) + self.prob.setup(force_alloc_complex=True) self.prob.set_val(Aircraft.Engine.SCALE_FACTOR, options.get_val( Aircraft.Engine.SCALE_FACTOR), units='unitless') @@ -136,12 +139,13 @@ def test_case_1(self): def test_propulsion_sum(self): nn = 2 - options = self.options - options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([3, 2])) + options = { + Aircraft.Engine.NUM_ENGINES: np.array([3, 2]), + } self.prob.model = om.Group() self.prob.model.add_subsystem('propsum', PropulsionSum(num_nodes=nn, - aviary_options=options), + **options), promotes=['*']) self.prob.setup(force_alloc_complex=True) @@ -204,8 +208,14 @@ def test_case_multiengine(self): engine_models = [engine, engine2] preprocess_propulsion(options, engine_models=engine_models) - self.prob.model = PropulsionMission( - num_nodes=20, aviary_options=options, engine_models=engine_models) + model = self.prob.model + prop = PropulsionMission( + num_nodes=20, + aviary_options=options, + engine_models=engine_models, + ) + model.add_subsystem('core_propulsion', prop, + promotes=['*']) self.prob.model.add_subsystem( Dynamic.Atmosphere.MACH, @@ -233,6 +243,8 @@ def test_case_multiengine(self): promotes=['*'], ) + setup_model_options(self.prob, options, engine_models=engine_models) + self.prob.setup(force_alloc_complex=True) self.prob.set_val(Aircraft.Engine.SCALE_FACTOR, [0.975, 0.975], units='unitless') diff --git a/aviary/subsystems/propulsion/test/test_propulsion_premission.py b/aviary/subsystems/propulsion/test/test_propulsion_premission.py index cbfabff65..82c27d9e9 100644 --- a/aviary/subsystems/propulsion/test/test_propulsion_premission.py +++ b/aviary/subsystems/propulsion/test/test_propulsion_premission.py @@ -10,6 +10,7 @@ from aviary.subsystems.propulsion.utils import build_engine_deck from aviary.validation_cases.validation_tests import get_flops_inputs from aviary.models.multi_engine_single_aisle.multi_engine_single_aisle_data import engine_1_inputs, engine_2_inputs +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Settings from aviary.utils.preprocessors import preprocess_options @@ -29,6 +30,8 @@ def test_case(self): self.prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) + setup_model_options(self.prob, options) + self.prob.setup(force_alloc_complex=True) # self.prob.set_val(Aircraft.Engine.SCALED_SLS_THRUST, options.get_val( # Aircraft.Engine.SCALED_SLS_THRUST, units='lbf')) @@ -51,11 +54,17 @@ def test_multi_engine(self): engine1 = build_engine_deck(engine_1_inputs)[0] engine2 = build_engine_deck(engine_2_inputs)[0] engine_models = [engine1, engine2] - preprocess_options(options, engine_models=engine_models) - self.prob.model = PropulsionPreMission(aviary_options=options, - engine_models=engine_models) + setup_model_options(self.prob, options, engine_models=engine_models) + + model = self.prob.model + prop = PropulsionPreMission(aviary_options=options, + engine_models=engine_models) + model.add_subsystem('core_propulsion', prop, + promotes=['*']) + + setup_model_options(self.prob, options, engine_models=engine_models) self.prob.model.set_input_defaults( Aircraft.Engine.SCALE_FACTOR, np.ones(2) * 0.5 @@ -77,12 +86,12 @@ def test_multi_engine(self): assert_check_partials(partial_data, atol=1e-10, rtol=1e-10) def test_propulsion_sum(self): - options = AviaryValues() - options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([1, 2, 5])) - options.set_val(Settings.VERBOSITY, 0) + options = { + Aircraft.Engine.NUM_ENGINES: np.array([1, 2, 5]), + } self.prob.model = om.Group() self.prob.model.add_subsystem('propsum', - PropulsionSum(aviary_options=options), + PropulsionSum(**options), promotes=['*']) self.prob.setup(force_alloc_complex=True) diff --git a/aviary/subsystems/propulsion/test/test_throttle_allocation.py b/aviary/subsystems/propulsion/test/test_throttle_allocation.py index 969e28c60..6ec4aadbf 100644 --- a/aviary/subsystems/propulsion/test/test_throttle_allocation.py +++ b/aviary/subsystems/propulsion/test/test_throttle_allocation.py @@ -7,7 +7,6 @@ from openmdao.utils.assert_utils import assert_check_partials from aviary.subsystems.propulsion.throttle_allocation import ThrottleAllocator -from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import ThrottleAllocation from aviary.variable_info.variables import Aircraft @@ -15,17 +14,16 @@ class ThrottleAllocationTest(unittest.TestCase): def setUp(self): - aviary_inputs = AviaryValues() - aviary_inputs.set_val(Aircraft.Engine.NUM_ENGINES, np.array([1, 1, 1])) - - self.aviary_inputs = aviary_inputs + self.options = { + Aircraft.Engine.NUM_ENGINES: np.array([1, 1, 1]), + } def test_derivs_fixed_or_static(self): prob = om.Problem() model = prob.model model.add_subsystem('comp', ThrottleAllocator(num_nodes=4, - aviary_options=self.aviary_inputs, - throttle_allocation=ThrottleAllocation.FIXED), + throttle_allocation=ThrottleAllocation.FIXED, + **self.options), promotes=['*']) prob.setup(force_alloc_complex=True) @@ -41,8 +39,8 @@ def test_derivs_dynamic(self): prob = om.Problem() model = prob.model model.add_subsystem('comp', ThrottleAllocator(num_nodes=4, - aviary_options=self.aviary_inputs, - throttle_allocation=ThrottleAllocation.DYNAMIC), + throttle_allocation=ThrottleAllocation.DYNAMIC, + **self.options), promotes=['*']) prob.setup(force_alloc_complex=True) diff --git a/aviary/subsystems/propulsion/test/test_turboprop_model.py b/aviary/subsystems/propulsion/test/test_turboprop_model.py index 2ade19493..a461a363d 100644 --- a/aviary/subsystems/propulsion/test/test_turboprop_model.py +++ b/aviary/subsystems/propulsion/test/test_turboprop_model.py @@ -14,6 +14,7 @@ ) from aviary.utils.preprocessors import preprocess_propulsion from aviary.utils.functions import get_path +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic, Mission from aviary.variable_info.enums import SpeedType from aviary.variable_info.options import get_option_defaults @@ -98,6 +99,8 @@ def prepare_model( promotes_outputs=['*'], ) + setup_model_options(self.prob, options) + self.prob.setup(force_alloc_complex=False) self.prob.set_val(Aircraft.Engine.SCALE_FACTOR, 1, units='unitless') diff --git a/aviary/subsystems/propulsion/throttle_allocation.py b/aviary/subsystems/propulsion/throttle_allocation.py index 57719cf52..f898a8049 100644 --- a/aviary/subsystems/propulsion/throttle_allocation.py +++ b/aviary/subsystems/propulsion/throttle_allocation.py @@ -4,6 +4,7 @@ from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.enums import ThrottleAllocation +from aviary.variable_info.functions import add_aviary_option from aviary.variable_info.variables import Aircraft, Dynamic @@ -19,21 +20,17 @@ def initialize(self): types=int, lower=0 ) - self.options.declare( - 'aviary_options', - types=AviaryValues, - desc='collection of Aircraft/Mission specific options' - ) self.options.declare( 'throttle_allocation', default=ThrottleAllocation.FIXED, types=ThrottleAllocation, desc='Flag that determines how to handle throttles for multiple engines.' ) + add_aviary_option(self, Aircraft.Engine.NUM_ENGINES) + def setup(self): - options: AviaryValues = self.options['aviary_options'] nn = self.options['num_nodes'] - num_engine_type = len(options.get_val(Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) alloc_mode = self.options['throttle_allocation'] self.add_input( @@ -110,7 +107,6 @@ def setup(self): val=1.0) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - nn = self.options['num_nodes'] alloc_mode = self.options['throttle_allocation'] agg_throttle = inputs["aggregate_throttle"] @@ -134,10 +130,9 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): outputs["throttle_allocation_sum"] = sum_alloc def compute_partials(self, inputs, partials, discrete_inputs=None): - options: AviaryValues = self.options['aviary_options'] nn = self.options['num_nodes'] alloc_mode = self.options['throttle_allocation'] - num_engine_type = len(options.get_val(Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len(self.options[Aircraft.Engine.NUM_ENGINES]) agg_throttle = inputs["aggregate_throttle"] allocation = inputs["throttle_allocations"] diff --git a/aviary/subsystems/test/subsystem_tester.py b/aviary/subsystems/test/subsystem_tester.py index 771ceb003..636a7685f 100644 --- a/aviary/subsystems/test/subsystem_tester.py +++ b/aviary/subsystems/test/subsystem_tester.py @@ -7,6 +7,7 @@ from aviary.subsystems.subsystem_builder_base import SubsystemBuilderBase from aviary.utils.aviary_values import AviaryValues +from aviary.variable_info.functions import setup_model_options def skipIfMissingDependencies(builder): @@ -249,6 +250,9 @@ def test_check_state_variables(self): group = om.Group() group.add_subsystem('mission', mission_sys, promotes=['*']) prob = om.Problem(group) + + setup_model_options(prob, self.aviary_values) + prob.setup() prob.final_setup() @@ -273,6 +277,9 @@ def test_check_pre_mission(self): group = om.Group() group.add_subsystem('pre_mission_sys', pre_mission_sys) prob = om.Problem(group) + + setup_model_options(prob, self.aviary_values) + prob.setup() prob.final_setup() @@ -305,6 +312,9 @@ def test_check_parameters(self): group = om.Group() group.add_subsystem('mission', mission_sys, promotes=['*']) prob = om.Problem(group) + + setup_model_options(prob, self.aviary_values) + prob.setup() prob.final_setup() @@ -330,6 +340,9 @@ def test_check_constraints(self): group = om.Group() group.add_subsystem('mission', mission_sys, promotes=['*']) prob = om.Problem(group) + + setup_model_options(prob, self.aviary_values) + prob.setup() prob.final_setup() @@ -359,6 +372,9 @@ def test_check_design_variables(self): group = om.Group() group.add_subsystem('pre_mission', pre_mission_sys, promotes=['*']) prob = om.Problem(group) + + setup_model_options(prob, self.aviary_values) + prob.setup() prob.final_setup() @@ -385,6 +401,9 @@ def test_check_initial_guesses(self): group = om.Group() group.add_subsystem('mission', mission_sys, promotes=['*']) prob = om.Problem(group) + + setup_model_options(prob, self.aviary_values) + prob.setup() prob.final_setup() diff --git a/aviary/subsystems/test/test_flops_based_premission.py b/aviary/subsystems/test/test_flops_based_premission.py index 7d8934b44..0650564f9 100644 --- a/aviary/subsystems/test/test_flops_based_premission.py +++ b/aviary/subsystems/test/test_flops_based_premission.py @@ -5,15 +5,17 @@ from openmdao.utils.assert_utils import assert_near_equal, assert_check_partials from aviary.subsystems.premission import CorePreMission +from aviary.subsystems.propulsion.utils import build_engine_deck from aviary.utils.aviary_values import AviaryValues from aviary.utils.functions import set_aviary_initial_values +from aviary.utils.preprocessors import preprocess_options +from aviary.utils.test_utils.default_subsystems import get_default_premission_subsystems from aviary.validation_cases.validation_tests import ( flops_validation_test, get_flops_inputs, get_flops_outputs, get_flops_case_names, print_case ) + +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Mission, Settings -from aviary.subsystems.propulsion.utils import build_engine_deck -from aviary.utils.test_utils.default_subsystems import get_default_premission_subsystems -from aviary.utils.preprocessors import preprocess_options class PreMissionGroupTest(unittest.TestCase): @@ -45,6 +47,8 @@ def test_case(self, case_name): promotes_outputs=['*'], ) + setup_model_options(prob, flops_inputs) + prob.setup(check=False, force_alloc_complex=True) prob.set_solver_print(2) @@ -104,6 +108,8 @@ def test_diff_configuration_mass(self): promotes_outputs=['*'], ) + setup_model_options(prob, flops_inputs) + prob.setup(check=False) set_aviary_initial_values(prob, flops_inputs) diff --git a/aviary/subsystems/test/test_premission.py b/aviary/subsystems/test/test_premission.py index 4ed926b35..cd5b678f5 100644 --- a/aviary/subsystems/test/test_premission.py +++ b/aviary/subsystems/test/test_premission.py @@ -16,7 +16,9 @@ from aviary.variable_info.variable_meta_data import _MetaData as BaseMetaData from aviary.models.large_single_aisle_1.V3_bug_fixed_IO import V3_bug_fixed_options, V3_bug_fixed_non_metadata from aviary.utils.functions import set_aviary_initial_values +from aviary.utils.preprocessors import preprocess_options from aviary.variable_info.enums import LegacyCode +from aviary.variable_info.functions import setup_model_options from aviary.subsystems.propulsion.utils import build_engine_deck @@ -104,6 +106,8 @@ def setUp(self): self.prob.model.set_input_defaults(Aircraft.Wing.SPAN, val=1.0, units='ft') + setup_model_options(self.prob, input_options) + self.prob.setup(check=False, force_alloc_complex=True) self.prob.set_solver_print(2) @@ -274,6 +278,7 @@ def test_manual_override(self): aviary_inputs.delete(Aircraft.Fuselage.WETTED_AREA) engine = build_engine_deck(aviary_inputs) + preprocess_options(aviary_inputs, engine_models=engine) prob = om.Problem() model = prob.model @@ -310,6 +315,8 @@ def test_manual_override(self): for (key, (val, units)) in get_items(V3_bug_fixed_non_metadata): prob.model.set_input_defaults(key, val=val, units=units) + setup_model_options(prob, aviary_inputs) + prob.setup() # Problem in setup is FLOPS prioritized, so shared inputs for FLOPS will be manually overriden. diff --git a/aviary/utils/aviary_values.py b/aviary/utils/aviary_values.py index 23736a4ca..e0d559592 100644 --- a/aviary/utils/aviary_values.py +++ b/aviary/utils/aviary_values.py @@ -58,16 +58,21 @@ def set_val(self, key, val, units='unitless', meta_data=_MetaData): # Special handling to access an Enum member from either the member name or its value. my_val = val if key in _MetaData.keys(): + expected_types = _MetaData[key]['types'] - if type(expected_types) is EnumMeta: - if self._is_iterable(val): - my_val = [self._convert_to_enum( - item, expected_types) for item in val] - else: - my_val = self._convert_to_enum(val, expected_types) - - # Special handling if the variable is supposed to be an array - if key in _MetaData.keys(): + if not isinstance(expected_types, tuple): + expected_types = (expected_types, ) + + for _type in expected_types: + if type(_type) is EnumMeta: + if self._is_iterable(val): + my_val = [self._convert_to_enum( + item, _type) for item in val] + else: + my_val = self._convert_to_enum(val, _type) + break + + # Special handling if the variable is supposed to be an array default_value = _MetaData[key]['default_value'] # if the item is supposed to be an iterable... if self._is_iterable(default_value): @@ -79,61 +84,64 @@ def set_val(self, key, val, units='unitless', meta_data=_MetaData): else: my_val = np.array([my_val], dtype=type(default_value[0])) - self._check_type(key, my_val, meta_data=meta_data) - self._check_units_compatability(key, my_val, units, meta_data=meta_data) + self._check_type(key, my_val, meta_data=meta_data) + self._check_units_compatability(key, my_val, units, meta_data=meta_data) super().set_val(key=key, val=my_val, units=units) def _check_type(self, key, val, meta_data=_MetaData): - if key in meta_data.keys(): - expected_types = meta_data[key]['types'] - if expected_types is not None: - if self._is_iterable(expected_types): - expected_types = tuple(expected_types) - # if val is not iterable, add it to a list (length 1), checks assume - # val is iterable - if not self._is_iterable(val): - val = [val] - # numpy arrays have special typings. Extract item of equivalent built-in python type - # numpy arrays do not allow mixed types, only have to check first entry - # empty arrays do not need this check - if isinstance(val, np.ndarray) and len(val) > 0: - # NoneType numpy arrays do not need to be "converted" to built-in python types - if val.dtype == type(None): - val = [val[0]] - else: - # item() gets us native Python equivalent object (i.e. int vs. numpy.int64) - # wrap first index in np array to ensures works on any dtype - val = [np.array(val[0]).item()] - for item in val: - has_bool = False # needs some fancy shenanigans because bools will register as ints - if (isinstance(expected_types, type)): - if expected_types is bool: - has_bool = True - elif bool in expected_types: - has_bool = True - if (not isinstance(item, expected_types)) or ( - (has_bool == False) and (isinstance(item, bool))): - raise TypeError( - f'{key} is of type(s) {meta_data[key]["types"]} but you ' - f'have provided a value of type {type(item)}.') - def _check_units_compatability(self, key, val, units, meta_data=_MetaData): - if key in meta_data.keys(): - expected_units = meta_data[key]['units'] - - try: - # NOTE the value here is unimportant, we only care if OpenMDAO will - # convert the units - _convert_units(10, expected_units, units) - except ValueError: - raise ValueError( - f'The units {units} which you have provided for {key} are invalid.') - except TypeError: + expected_types = meta_data[key]['types'] + if expected_types is None: + # MetaData item has no type requirement. + return + + if self._is_iterable(expected_types): + expected_types = tuple(expected_types) + + # if val is not iterable, add it to a list (length 1), checks assume + # val is iterable + if not self._is_iterable(val): + val = [val] + # numpy arrays have special typings. Extract item of equivalent built-in python type + # numpy arrays do not allow mixed types, only have to check first entry + # empty arrays do not need this check + if isinstance(val, np.ndarray) and len(val) > 0: + # NoneType numpy arrays do not need to be "converted" to built-in python types + if val.dtype == type(None): + val = [val[0]] + else: + # item() gets us native Python equivalent object (i.e. int vs. numpy.int64) + # wrap first index in np array to ensures works on any dtype + val = [np.array(val[0]).item()] + for item in val: + has_bool = False # needs some fancy shenanigans because bools will register as ints + if (isinstance(expected_types, type)): + if expected_types is bool: + has_bool = True + elif bool in expected_types: + has_bool = True + if (not isinstance(item, expected_types)) or ( + (has_bool == False) and (isinstance(item, bool))): raise TypeError( - f'The base units of {key} are {expected_units}, and you have tried to set {key} with units of {units}, which are not compatible.') - except BaseException: - raise KeyError('There is an unknown error with your units.') + f'{key} is of type(s) {meta_data[key]["types"]} but you ' + f'have provided a value of type {type(item)}.') + + def _check_units_compatability(self, key, val, units, meta_data=_MetaData): + expected_units = meta_data[key]['units'] + + try: + # NOTE the value here is unimportant, we only care if OpenMDAO will + # convert the units + _convert_units(10, expected_units, units) + except ValueError: + raise ValueError( + f'The units {units} which you have provided for {key} are invalid.') + except TypeError: + raise TypeError( + f'The base units of {key} are {expected_units}, and you have tried to set {key} with units of {units}, which are not compatible.') + except BaseException: + raise KeyError('There is an unknown error with your units.') def _is_iterable(self, val): return isinstance(val, _valid_iterables) diff --git a/aviary/utils/conflict_checks.py b/aviary/utils/conflict_checks.py index fd79461ed..0fafa70a2 100644 --- a/aviary/utils/conflict_checks.py +++ b/aviary/utils/conflict_checks.py @@ -3,13 +3,10 @@ from aviary.variable_info.variables import Aircraft -def check_fold_location_definition(inputs, options: AviaryValues): +def check_fold_location_definition(choose_fold_location, has_strut): """ If there is no strut, then CHOOSE_FOLD_LOCATION must be true. """ - choose_fold_location = options.get_val( - Aircraft.Wing.CHOOSE_FOLD_LOCATION, units='unitless') - has_strut = options.get_val(Aircraft.Wing.HAS_STRUT, units='unitless') if not choose_fold_location and not has_strut: raise RuntimeError( "The option CHOOSE_FOLD_LOCATION can only be False if the option HAS_STRUT is True.") diff --git a/aviary/utils/develop_metadata.py b/aviary/utils/develop_metadata.py index 4950a2d60..c7f2e0e45 100644 --- a/aviary/utils/develop_metadata.py +++ b/aviary/utils/develop_metadata.py @@ -6,6 +6,7 @@ def add_meta_data( default_value=0.0, option=False, types=None, + multivalue=False, historical_name=None, _check_unique=True): ''' @@ -36,7 +37,11 @@ def add_meta_data( indicates that this variable is an option, rather than a normal input types : type - gives the allowable type(s) of the variable + gives the allowable type(s) of the variable in the aviary API. + + multivalue : bool + when True, the variable can become a list of elements whose type is in types. + This is mainly used when there are multiple engine types. historical_name : dict or None dictionary of names that the variable held in prior codes @@ -67,7 +72,7 @@ def add_meta_data( of the provided key. This should only be set to false when update_meta_data is the calling function. Returns - ------- + ------- None No variables returned by this method. @@ -90,7 +95,8 @@ def add_meta_data( 'desc': desc, 'option': option, 'default_value': default_value, - 'types': types + 'types': types, + 'multivalue': multivalue, } @@ -102,6 +108,7 @@ def update_meta_data( default_value=0.0, option=False, types=None, + multivalue=False, historical_name=None): ''' Update existing meta data associated with variables in the Aviary data hierarchy. @@ -133,6 +140,10 @@ def update_meta_data( types : type gives the allowable type(s) of the variable + multivalue : bool + when True, the variable can become a list of elements whose type is in types. + This is mainly used when there are multiple engine types. + historical_name : dict or None dictionary of names that the variable held in prior codes @@ -158,7 +169,7 @@ def update_meta_data( represents the GWTOL variable of the ANALYS subroutine Returns - ------- + ------- None No variables returned by this method. @@ -173,4 +184,6 @@ def update_meta_data( f'You provided the variable {key} to a variable metadata dictionary via the update_meta_data function, but {key} does not exist in the dictionary. If you are sure you want to add this variable to the dictionary, call the add_meta_data function instead.') add_meta_data(key=key, meta_data=meta_data, units=units, desc=desc, - default_value=default_value, option=option, types=types, historical_name=historical_name, _check_unique=False) + default_value=default_value, option=option, types=types, + multivalue=multivalue, historical_name=historical_name, + _check_unique=False) diff --git a/aviary/utils/doctape.py b/aviary/utils/doctape.py index 149469570..bef803ff4 100644 --- a/aviary/utils/doctape.py +++ b/aviary/utils/doctape.py @@ -1,8 +1,8 @@ import inspect import subprocess import tempfile -import os import numpy as np +import re """ @@ -89,6 +89,7 @@ def get_previous_line(n=1) -> str: def get_variable_name(*variables) -> str: """ returns the name of the variable passed to the function as a string + # NOTE: You cannot call this function multiple times on one line Parameters ---------- @@ -107,8 +108,20 @@ def get_variable_name(*variables) -> str: # get the line number that called this function lineno = pframe.f_lineno - first_line if first_line else pframe.f_lineno - 1 # extract the argument and remove all whitespace - arg: str = ''.join(lines[lineno].split( - 'get_variable_name(')[1].split(')')[0].split()) + arg = ''.join(lines[lineno].split()).split('get_variable_name(', 1)[1] + + # Use regex to match balanced parentheses + match = re.match(r'([^()]*\([^()]*\))*[^()]*', arg) + if match: + arg = match.group(0) + + # # Requires Python 3.11, but allows this to be called multiple times on one line + # positions = inspect.getframeinfo(pframe).positions + # calling_lines = lines[positions.lineno-1:positions.end_lineno] + # calling_lines[-1] = calling_lines[-1][:positions.end_col_offset-1] + # calling_lines[0] = calling_lines[0][positions.col_offset:].removeprefix('get_variable_name(') + # arg = ''.join([l.strip() for l in calling_lines]) + if ',' in arg: return arg.split(',') else: @@ -295,6 +308,7 @@ def get_attribute_name(object: object, attribute, error_type=AttributeError) -> def get_all_keys(dict_of_dicts: dict, track_layers=False, all_keys=None) -> list: """ Recursively get all of the keys from a dict of dicts + This can also be used to recursively get all of the attributes from a complex object, like the Aircraft hierarchy Note: this will not add duplicates of keys, but will continue deeper even if a key is duplicated @@ -314,9 +328,14 @@ def get_all_keys(dict_of_dicts: dict, track_layers=False, all_keys=None) -> list all_keys : list A list of all the keys in the dict_of_dicts """ + if not isinstance(dict_of_dicts, dict): + dict_of_dicts = dict_of_dicts.__dict__ if all_keys is None: all_keys = [] + for key, val in dict_of_dicts.items(): + if key.startswith('__') and key.endswith('__'): + continue if track_layers is True: current_layer = '' elif track_layers: @@ -325,7 +344,7 @@ def get_all_keys(dict_of_dicts: dict, track_layers=False, all_keys=None) -> list key = current_layer+'.'+key if key not in all_keys: all_keys.append(key) - if isinstance(val, dict): + if isinstance(val, dict) or hasattr(val, '__dict__'): if track_layers: current_layer = key else: @@ -352,6 +371,8 @@ def get_value(dict_of_dicts: dict, comlpete_key: str): """ for key in comlpete_key.split('.'): + if not isinstance(dict_of_dicts, dict): + dict_of_dicts = dict_of_dicts.__dict__ dict_of_dicts = dict_of_dicts[key] return dict_of_dicts @@ -377,13 +398,18 @@ def glue_variable(name: str, val=None, md_code=False, display=True): # local import so myst isn't required unless glue is being used from myst_nb import glue from IPython.display import Markdown + from IPython.utils import io if val is None: val = name if md_code: val = Markdown('`'+val+'`') else: val = Markdown(val) - glue(name, val, display) + + with io.capture_output() as captured: + glue(name, val, display) + # if display: + captured.show() def glue_keys(dict_of_dicts: dict, display=True) -> list: @@ -400,7 +426,12 @@ def glue_keys(dict_of_dicts: dict, display=True) -> list: all_keys : list A list of all the keys that were glued """ - all_keys = get_all_keys(dict_of_dicts) + if not isinstance(dict_of_dicts, dict): + track_layers = dict_of_dicts.__name__ + else: + track_layers = False + all_keys = get_all_keys(dict_of_dicts, track_layers) + for key in all_keys: glue_variable(key, md_code=True, display=display) return all_keys diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index 1f1b220d0..93b380f7c 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -294,6 +294,8 @@ def preprocess_propulsion( # if default value is a list/tuple, find type inside that if isinstance(default_value, (list, tuple)): dtype = type(default_value[0]) + elif isinstance(default_value, np.ndarray): + dtype = default_value.dtype elif default_value is None: # With no default value, we cannot determine a dtype. dtype = None diff --git a/aviary/utils/process_input_decks.py b/aviary/utils/process_input_decks.py index eeb24a37d..4b0249040 100644 --- a/aviary/utils/process_input_decks.py +++ b/aviary/utils/process_input_decks.py @@ -375,13 +375,19 @@ def initialization_guessing(aircraft_values: AviaryValues, initialization_guesse # TODO this does not work at all for mixed-type engines (some propeller and some not) try: + num_engines = aircraft_values.get_val(Aircraft.Engine.NUM_ENGINES) + + # This happens before preprocessing, and we end up with the default when unspecified. + if isinstance(num_engines, list): + num_engines = num_engines[0] + if aircraft_values.get_val(Aircraft.Engine.HAS_PROPELLERS): # For large turboprops, 1 pound of thrust per hp at takeoff seems to be close enough total_thrust = aircraft_values.get_val( - Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN, 'hp') * aircraft_values.get_val(Aircraft.Engine.NUM_ENGINES) + Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN, 'hp') * num_engines else: total_thrust = aircraft_values.get_val( - Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') * aircraft_values.get_val(Aircraft.Engine.NUM_ENGINES) + Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') * num_engines except KeyError: if engine_builders is not None and len(engine_builders) > 1: diff --git a/aviary/utils/test/test_aviary_values.py b/aviary/utils/test/test_aviary_values.py index abc014e02..9d6fc4883 100644 --- a/aviary/utils/test/test_aviary_values.py +++ b/aviary/utils/test/test_aviary_values.py @@ -90,9 +90,9 @@ def test_aircraft(self): try: vals.set_val(Aircraft.Engine.TYPE, 'turbojet') self.assertTrue(vals.get_val(Aircraft.Engine.TYPE) - is GASPEngineType.TURBOJET) + == GASPEngineType.TURBOJET) except: - self.fail('Expecting to be able to set the value of an Enum from a string.') + self.fail('Expecting to be able to set the value of an Enum from an int.') try: vals.set_val(Aircraft.Engine.TYPE, 'TURBOJET') @@ -144,8 +144,8 @@ def test_mission(self): except TypeError as err: self.assertEqual( str(err), - f"{Mission.Design.CRUISE_ALTITUDE} is of type(s) [, ] but you have provided a value of type .") + f"{Mission.Design.CRUISE_ALTITUDE} is of type(s) (, ) but you have provided a value of type .") else: self.fail('Expecting TypeError.') @@ -154,8 +154,8 @@ def test_mission(self): except TypeError as err: self.assertEqual( str(err), - f"{Mission.Design.CRUISE_ALTITUDE} is of type(s) [, ] but you have provided a value of type .") + f"{Mission.Design.CRUISE_ALTITUDE} is of type(s) (, ) but you have provided a value of type .") else: self.fail('Expecting TypeError.') diff --git a/aviary/utils/test/test_doctape.py b/aviary/utils/test/test_doctape.py index d13b8d1c1..6e9db35c4 100644 --- a/aviary/utils/test/test_doctape.py +++ b/aviary/utils/test/test_doctape.py @@ -3,7 +3,9 @@ from openmdao.utils.assert_utils import assert_near_equal, assert_equal_numstrings, assert_equal_arrays -from aviary.utils.doctape import gramatical_list, check_value, check_contains, check_args, run_command_no_file_error, get_attribute_name, get_all_keys, get_value, get_previous_line, get_variable_name +from aviary.utils.doctape import (gramatical_list, check_value, check_contains, check_args, + run_command_no_file_error, get_attribute_name, get_all_keys, get_value, get_previous_line, + get_variable_name, glue_variable, glue_keys) class DocTAPETests(unittest.TestCase): @@ -55,12 +57,12 @@ def test_get_variable_name(self): assert_equal_numstrings(name, 'var') # requires IPython shell - # def test_glue_variable(self): - # glue_variable('plain_text') + def test_glue_variable(self): + glue_variable('plain_text', display=False) # requires IPython shell - # def test_glue_keys(self): - # glue_keys({'d1':{'d2':2}}) + def test_glue_keys(self): + glue_keys({'d1': {'d2': 2}}, display=False) if __name__ == '__main__': diff --git a/aviary/validation_cases/benchmark_tests/test_FLOPS_balanced_field_length.py b/aviary/validation_cases/benchmark_tests/test_FLOPS_balanced_field_length.py index 92ae6fb52..fd66f9d75 100644 --- a/aviary/validation_cases/benchmark_tests/test_FLOPS_balanced_field_length.py +++ b/aviary/validation_cases/benchmark_tests/test_FLOPS_balanced_field_length.py @@ -22,6 +22,7 @@ from aviary.utils.functions import \ set_aviary_initial_values, set_aviary_input_defaults from aviary.utils.preprocessors import preprocess_options +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Dynamic, Aircraft @@ -107,6 +108,8 @@ def _do_run(self, driver: Driver, optimizer, *args): varnames = [Aircraft.Wing.ASPECT_RATIO] set_aviary_input_defaults(takeoff.model, varnames, aviary_options) + setup_model_options(takeoff, aviary_options) + # suppress warnings: # "input variable '...' promoted using '*' was already promoted using 'aircraft:*' with warnings.catch_warnings(): diff --git a/aviary/validation_cases/benchmark_tests/test_FLOPS_based_sizing_N3CC.py b/aviary/validation_cases/benchmark_tests/test_FLOPS_based_sizing_N3CC.py index 84753ddb9..3afb8330b 100644 --- a/aviary/validation_cases/benchmark_tests/test_FLOPS_based_sizing_N3CC.py +++ b/aviary/validation_cases/benchmark_tests/test_FLOPS_based_sizing_N3CC.py @@ -34,7 +34,7 @@ from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems from aviary.validation_cases.validation_tests import get_flops_inputs from aviary.variable_info.enums import LegacyCode -from aviary.variable_info.functions import setup_trajectory_params +from aviary.variable_info.functions import setup_trajectory_params, setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic, Mission from aviary.variable_info.variable_meta_data import _MetaData as BaseMetaData @@ -437,6 +437,8 @@ def run_trajectory(sim=True): ] set_aviary_input_defaults(prob.model, varnames, aviary_inputs) + setup_model_options(prob, aviary_inputs) + prob.setup(force_alloc_complex=True) set_aviary_initial_values(prob, aviary_inputs) diff --git a/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_landing.py b/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_landing.py index 950506bcf..1610ba160 100644 --- a/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_landing.py +++ b/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_landing.py @@ -19,6 +19,7 @@ set_aviary_initial_values, set_aviary_input_defaults from aviary.utils.preprocessors import preprocess_options from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic @@ -101,6 +102,8 @@ def _do_run(self, driver: Driver, optimizer, *args): varnames = [Aircraft.Wing.ASPECT_RATIO] set_aviary_input_defaults(landing.model, varnames, aviary_options) + setup_model_options(landing, aviary_options) + # suppress warnings: # "input variable '...' promoted using '*' was already promoted using 'aircraft:*' with warnings.catch_warnings(): diff --git a/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_takeoff.py b/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_takeoff.py index 49dd1ee69..032905087 100644 --- a/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_takeoff.py +++ b/aviary/validation_cases/benchmark_tests/test_FLOPS_detailed_takeoff.py @@ -19,6 +19,7 @@ set_aviary_initial_values, set_aviary_input_defaults from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems from aviary.utils.preprocessors import preprocess_options +from aviary.variable_info.functions import setup_model_options from aviary.variable_info.variables import Aircraft, Dynamic @@ -116,6 +117,8 @@ def _do_run(self, driver: Driver, optimizer, *args): varnames = [Aircraft.Wing.ASPECT_RATIO] set_aviary_input_defaults(takeoff.model, varnames, aviary_options) + setup_model_options(takeoff, aviary_options) + # suppress warnings: # "input variable '...' promoted using '*' was already promoted using 'aircraft:*' with warnings.catch_warnings(): diff --git a/aviary/validation_cases/benchmark_tests/test_bench_FwFm.py b/aviary/validation_cases/benchmark_tests/test_bench_FwFm.py index df9925bf1..2d5861fb2 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_FwFm.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_FwFm.py @@ -20,7 +20,7 @@ class ProblemPhaseTestCase(unittest.TestCase): """ - Setup of a large single aisle commercial transport aircraft using + Setup of a large single aisle commercial transport aircraft using FLOPS mass method and HEIGHT_ENERGY mission method. Expected outputs based on 'models/test_aircraft/aircraft_for_bench_FwFm.csv' model. """ @@ -273,7 +273,7 @@ def test_bench_FwFm_SNOPT_MPI(self): if __name__ == '__main__': - unittest.main() - # test = TestBenchFwFmSerial() - # test.setUp() - # test.test_bench_FwFm_SNOPT() + # unittest.main() + test = TestBenchFwFmSerial() + test.setUp() + test.test_bench_FwFm_SNOPT() diff --git a/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py b/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py index 82304cd17..59d823bb7 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py @@ -14,7 +14,7 @@ @use_tempdirs class ProblemPhaseTestCase(unittest.TestCase): """ - Test the setup and run of a large single aisle commercial transport aircraft using + Test the setup and run of a large single aisle commercial transport aircraft using GASP mass method and TWO_DEGREES_OF_FREEDOM mission method. Expected outputs based on 'models/test_aircraft/aircraft_for_bench_FwFm.csv' model. """ diff --git a/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py b/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py index cc7ecb8c7..86501117c 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py @@ -130,8 +130,8 @@ def test_multiengine_static(self): alloc_descent = prob.get_val('traj.descent.parameter_vals:throttle_allocations') assert_near_equal(alloc_climb[0], 0.5, tolerance=1e-2) - assert_near_equal(alloc_cruise[0], 0.574, tolerance=1e-2) - assert_near_equal(alloc_descent[0], 0.75, tolerance=1e-2) + assert_near_equal(alloc_cruise[0], 0.593, tolerance=1e-2) + assert_near_equal(alloc_descent[0], 0.408, tolerance=1e-2) @require_pyoptsparse(optimizer="SNOPT") def test_multiengine_dynamic(self): @@ -171,7 +171,7 @@ def test_multiengine_dynamic(self): alloc_descent = prob.get_val('traj.descent.controls:throttle_allocations') # Cruise is pretty constant, check exact value. - assert_near_equal(alloc_cruise[0], 0.576, tolerance=1e-2) + assert_near_equal(alloc_cruise[0], 0.595, tolerance=1e-2) # Check general trend: favors engine 1. self.assertGreater(alloc_climb[2], 0.55) diff --git a/aviary/validation_cases/validation_tests.py b/aviary/validation_cases/validation_tests.py index 3cfd3a61c..b0cc69fd2 100644 --- a/aviary/validation_cases/validation_tests.py +++ b/aviary/validation_cases/validation_tests.py @@ -11,6 +11,7 @@ from aviary.utils.preprocessors import preprocess_options from aviary.validation_cases.validation_data.flops_data.FLOPS_Test_Data import \ FLOPS_Test_Data, FLOPS_Lacking_Test_Data +from aviary.variable_info.functions import extract_options from aviary.variable_info.variables import Aircraft Version = Enum('Version', ['ALL', 'TRANSPORT', 'ALTERNATE', 'BWB']) @@ -271,6 +272,9 @@ def get_flops_data(case_name: str, keys: str = None, preprocess: bool = False) - keys : str, or iter of str List of variables whose values will be transferred from the validation data. The default is all variables. + preprocess: bool + If true, the input data will be passed through preprocess_options() to + fill in any missing options before being returned. The default is False. """ flops_data_copy: AviaryValues = get_flops_inputs(case_name, preprocess=preprocess) flops_data_copy.update(get_flops_outputs(case_name)) @@ -316,6 +320,40 @@ def get_flops_inputs(case_name: str, keys: str = None, preprocess: bool = False) return AviaryValues({key: flops_inputs_copy.get_item(key) for key in keys_list}) +def get_flops_options(case_name: str, keys: str = None, preprocess: bool = False) -> AviaryValues: + """ + Returns a dictionary containing options for the named FLOPS validation case. + + Parameters + ---------- + case_name : str + Name of the case being run. Input data will be looked up from + the corresponding case in the FLOPS validation data collection. + keys : str, or iter of str + List of variables whose values will be transferred from the input data. + The default is all variables. + preprocess: bool + If true, the input data will be passed through preprocess_options() to + fill in any missing options before being returned. The default is False. + """ + try: + flops_data: dict = FLOPS_Test_Data[case_name] + except KeyError: + flops_data: dict = FLOPS_Lacking_Test_Data[case_name] + + flops_inputs_copy: AviaryValues = flops_data['inputs'].deepcopy() + if preprocess: + preprocess_options(flops_inputs_copy, + engine_models=build_engine_deck(flops_inputs_copy)) + + if keys is None: + options = extract_options(flops_inputs_copy) + else: + options = extract_options(keys) + + return options + + def get_flops_outputs(case_name: str, keys: str = None) -> AviaryValues: """ Returns an AviaryValues object containing output data for the named FLOPS validation case. diff --git a/aviary/variable_info/functions.py b/aviary/variable_info/functions.py index 8c28147a0..9961ae891 100644 --- a/aviary/variable_info/functions.py +++ b/aviary/variable_info/functions.py @@ -1,10 +1,15 @@ -import dymos as dm +from enum import Enum + +import numpy as np + import openmdao.api as om -from dymos.utils.misc import _unspecified from openmdao.core.component import Component +from openmdao.utils.units import convert_units +import dymos as dm +from dymos.utils.misc import _unspecified from aviary.utils.aviary_values import AviaryValues -from aviary.variable_info.variables import Settings +from aviary.variable_info.variables import Aircraft, Settings from aviary.variable_info.variable_meta_data import _MetaData # --------------------------- @@ -12,14 +17,35 @@ # --------------------------- -def add_aviary_input(comp, varname, val=None, units=None, desc=None, shape_by_conn=False, meta_data=_MetaData, shape=None): - ''' +def add_aviary_input(comp, varname, val=None, units=None, desc=None, shape_by_conn=False, + meta_data=_MetaData, shape=None): + """ This function provides a clean way to add variables from the variable hierarchy into components as Aviary inputs. It takes the standard OpenMDAO inputs of the variable's name, initial value, units, and description, as well as the component which the variable is being added to. - ''' + + Parameters + ---------- + comp: Component + OpenMDAO component to add this variable. + varname: str + Name of variable. + val: float or ndarray + Default value for variable. + units: str + (Optional) when speficying val, units should also be specified. + desc: str + (Optional) description text for the variable. + shape_by_conn: bool + Set to True to infer the shape from the connected output. + meta_data: dict + (Optional) Aviary metadata dictionary. If unspecified, the built-in metadata will + be used. + shape: tuple + (Optional) shape for this input. + """ meta = meta_data[varname] if units: input_units = units @@ -38,14 +64,34 @@ def add_aviary_input(comp, varname, val=None, units=None, desc=None, shape_by_co desc=input_desc, shape_by_conn=shape_by_conn, shape=shape) -def add_aviary_output(comp, varname, val, units=None, desc=None, shape_by_conn=False, meta_data=_MetaData): - ''' +def add_aviary_output(comp, varname, val, units=None, desc=None, shape_by_conn=False, + meta_data=_MetaData): + """ This function provides a clean way to add variables from the variable hierarchy into components as Aviary outputs. It takes the standard OpenMDAO inputs of the variable's name, initial value, units, and description, as well as the component which the variable is being added to. - ''' + + Parameters + ---------- + comp: Component + OpenMDAO component to add this variable. + varname: str + Name of variable. + val: float or ndarray + (Optional) Default value for variable. If not specified, the value from metadata + is used. + units: str + (Optional) when speficying val, units should also be specified. + desc: str + (Optional) description text for the variable. + shape_by_conn: bool + Set to True to infer the shape from the connected output. + meta_data: dict + (Optional) Aviary metadata dictionary. If unspecified, the built-in metadata will + be used. + """ meta = meta_data[varname] if units: output_units = units @@ -62,6 +108,130 @@ def add_aviary_output(comp, varname, val, units=None, desc=None, shape_by_conn=F desc=output_desc, shape_by_conn=shape_by_conn) +def units_setter(opt_meta, value): + """ + Check and convert new units tuple into + + Parameters + ---------- + opt_meta : dict + Dictionary of entries for the option. + value : any + New value for the option. + + Returns + ------- + any + Post processed value to set into the option. + """ + new_val, new_units = value + old_val, units = opt_meta['val'] + + converted_val = convert_units(new_val, new_units, units) + return (converted_val, units) + + +def int_enum_setter(opt_meta, value): + """ + Support setting the option with a string or int and converting it to the + proper enum object. + + Parameters + ---------- + opt_meta : dict + Dictionary of entries for the option. + value : any + New value for the option. + + Returns + ------- + any + Post processed value to set into the option. + """ + types = opt_meta['types'] + for type_ in types: + if type_ not in (list, np.ndarray): + enum_class = type_ + break + + if isinstance(value, Enum): + return value + + elif isinstance(value, int): + return enum_class(value) + + elif isinstance(value, str): + return getattr(enum_class, value) + + elif isinstance(value, list): + values = [] + for val in value: + if isinstance(val, Enum): + values.append(val) + elif isinstance(val, int): + values.append(enum_class(val)) + elif isinstance(val, str): + values.append(getattr(enum_class, val)) + else: + break + else: + return values + + msg = f"Value '{value}' not valid for option with types {enum_class}" + raise TypeError(msg) + + +def add_aviary_option(comp, name, val=_unspecified, units=None, desc=None, meta_data=_MetaData): + """ + Adds an option to an Aviary component. Default values from the metadata are used + unless a new value is specified. + + Parameters + ---------- + comp: Component + OpenMDAO component to add this option. + name: str + Name of variable. + val: float or ndarray + (Optional) Default value for option. If not specified, the value from metadata + is used. + desc: str + (Optional) description text for the variable. + units: str + (Optional) OpenMDAO units string. This can be specified for variables with units. + meta_data: dict + (Optional) Aviary metadata dictionary. If unspecified, the built-in metadata will + be used. + """ + meta = meta_data[name] + if not desc: + desc = meta['desc'] + if val is _unspecified: + val = meta['default_value'] + + types = meta['types'] + if meta['multivalue']: + if isinstance(types, tuple): + types = (list, *types) + else: + types = (list, types) + + if units not in [None, 'unitless']: + types = tuple + comp.options.declare(name, default=(val, units), + types=types, desc=desc, + set_function=units_setter) + + elif isinstance(val, Enum): + comp.options.declare(name, default=val, + types=types, desc=desc, + set_function=int_enum_setter) + + else: + comp.options.declare(name, default=val, + types=types, desc=desc) + + def override_aviary_vars(group: om.Group, aviary_inputs: AviaryValues, manual_overrides=None, external_overrides=None): ''' @@ -256,3 +426,104 @@ def get_units(key, meta_data=None) -> str: meta_data = _MetaData return meta_data[key]['units'] + + +def extract_options(aviary_inputs: AviaryValues, metadata=_MetaData) -> dict: + """ + Extract a dictionary of options from the given aviary_inputs. + + Parameters + ---------- + aviary_inputs : AviaryValues + Instance of AviaryValues containing all initial values. + meta_data : dict + (Optional) Dictionary of aircraft metadata. Uses Aviary's built-in + metadata by default. + + Returns + ------- + dict + Dictionary of option names and values. + """ + options = {} + for key, meta in metadata.items(): + + if key not in aviary_inputs: + continue + + if not meta['option']: + continue + + val, units = aviary_inputs.get_item(key) + meta_units = meta['units'] + + if meta_units == 'unitless' or meta_units is None: + options[key] = val + + else: + # Implement as (quanitity, unit) + options[key] = (val, units) + + return options + + +def setup_model_options(prob: om.Problem, aviary_inputs: AviaryValues, + meta_data=_MetaData, engine_models=None, prefix=''): + """ + Setup the correct model options for an aviary problem. + + Parameters + ---------- + prob: Problem + OpenMDAO problem prior to setup. + aviary_inputs : AviaryValues + Instance of AviaryValues containing all initial values. + meta_data : dict + (Optional) Dictionary of aircraft metadata. Uses Aviary's built-in + metadata by default. + engine_models : List of EngineModels or None + (Optional) Engine models + prefix : str + Prefix for model options. Used for multi-mission. + """ + + # Use OpenMDAO's model options to pass all options through the system hierarchy. + prob.model_options[f'{prefix}*'] = extract_options(aviary_inputs, + meta_data) + + # Multi-engines need to index into their options. + try: + num_engine_models = len(aviary_inputs.get_val(Aircraft.Engine.NUM_ENGINES)) + except KeyError: + # No engine data. + return + + if num_engine_models > 1: + + if engine_models is None: + engine_models = prob.engine_builders + + for idx in range(num_engine_models): + eng_name = engine_models[idx].name + + # TODO: For future flexibility, need to tag the required engine options. + opt_names = [ + Aircraft.Engine.SCALE_PERFORMANCE, + Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, + Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, + Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, + Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, + ] + opt_names_units = [ + Aircraft.Engine.REFERENCE_SLS_THRUST, + Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION, + ] + opts = {} + for key in opt_names: + opts[key] = aviary_inputs.get_item(key)[0][idx] + for key in opt_names_units: + val, units = aviary_inputs.get_item(key) + opts[key] = (val[idx], units) + + path = f"{prefix}*core_propulsion.{eng_name}*" + prob.model_options[path] = opts diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index a87c69465..22862daa9 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -1773,9 +1773,12 @@ "LEAPS1": 'aircraft.inputs.L0_propulsion.misc_weight', }, units='unitless', + option=True, desc='fraction of (scaled) engine mass used to calculate additional propulsion ' - 'system mass added to engine control and starter mass, or used to ' - 'calculate engine installation mass', + 'system mass added to engine control and starter mass, or used to ' + 'calculate engine installation mass', + types=(float, int, np.ndarray), + multivalue=True, default_value=0.0, ) @@ -2063,9 +2066,10 @@ units='unitless', desc='total number of engines per model on the aircraft ' '(fuselage, wing, or otherwise)', - types=int, + types=(np.ndarray, int), + multivalue=True, option=True, - default_value=2, + default_value=[2] ) add_meta_data( @@ -2079,8 +2083,9 @@ units='unitless', desc='number of fuselage mounted engines per model', option=True, - types=int, - default_value=0, + types=(np.ndarray, int), + multivalue=True, + default_value=0 ) add_meta_data( @@ -2095,8 +2100,9 @@ units='unitless', desc='number of wing mounted engines per model', option=True, - types=int, - default_value=0, + types=(np.ndarray, int), + multivalue=True, + default_value=[0] ) add_meta_data( @@ -2214,6 +2220,7 @@ desc='Toggle for enabling scaling of engine mass', option=True, types=bool, + multivalue=True, default_value=True, ) @@ -2232,6 +2239,7 @@ 'and electric power', option=True, types=bool, + multivalue=True, default_value=True, ) @@ -2333,7 +2341,8 @@ historical_name={"GASP": 'INGASP.NTYE', "FLOPS": None, "LEAPS1": None}, option=True, default_value=GASPEngineType.TURBOJET, - types=GASPEngineType, + types=(GASPEngineType, int, str), + multivalue=True, units="unitless", desc='specifies engine type used for GASP-based engine mass calculation', ) @@ -2456,6 +2465,7 @@ option=True, default_value=True, types=bool, + multivalue=True, desc='if true, compute installation loss factor based on blockage factor', ) @@ -2495,8 +2505,9 @@ units='unitless', desc='number of blades per propeller', option=True, - types=int, - default_value=0, + types=(int, np.ndarray), + multivalue=True, + default_value=0 ) add_meta_data( @@ -4938,6 +4949,7 @@ 'conventional technology wing (Default); 2.0 represents advanced ' 'technology wing.', default_value=1.0, + types=float, option=True, ) @@ -5300,7 +5312,8 @@ historical_name={"GASP": 'INGASP.JFLTYP', "FLOPS": None, "LEAPS1": None}, units="unitless", default_value=FlapType.DOUBLE_SLOTTED, - types=FlapType, + types=(FlapType, int, str), + multivalue=True, option=True, desc='Set the flap type. Available choices are: plain, split, single_slotted, ' 'double_slotted, triple_slotted, fowler, and double_slotted_fowler. ' @@ -6684,11 +6697,11 @@ Mission.Design.CRUISE_ALTITUDE, meta_data=_MetaData, historical_name={"GASP": 'INGASP.CRALT', "FLOPS": None, "LEAPS1": None}, - option=True, units='ft', - default_value=25000, + option=True, + default_value=25000.0, + types=(int, float), desc='design mission cruise altitude', - types=[int, float], ) add_meta_data( diff --git a/setup.py b/setup.py index 143676dd5..465292ffd 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ pkgname = "aviary" extras_require = { - "test": ["testflo", "pre-commit", "sphinx_book_theme==1.1.0"], + "test": ["testflo", "pre-commit", "sphinx_book_theme==1.1.0", "myst-nb"], "examples": ["openaerostruct", "ambiance", "itables"], }